[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [IA64] Fix virtualized EFI memory mapping creation for dom0.
# HG changeset patch # User Alex Williamson <alex.williamson@xxxxxx> # Date 1209067336 21600 # Node ID 239b44eeb2d6d235ddee581b6e89398c80278a2f # Parent 1fbc9073a566630a93b3e16a2121b8a1cab9fd41 [IA64] Fix virtualized EFI memory mapping creation for dom0. EFI uses 4k page, while xen uses 16k page. For dom0, identity mappings are setup for EFI_ACPI_RECLAIM_MEMORY etc. It is possible when seting up dom0 memory ranges to include some EFI_ACPI_RECLAIM_MEMORY ranges due to 4k/16k alignment difference. This patch fixes this issue by scaning memory descriptors twice. In the first scan, setup dom0 identity mapping. In the second scan, setup dom0 memory mapping. Signed-off-by: Anthony Xu <anthony.xu@xxxxxxxxx> --- xen/arch/ia64/xen/dom_fw_dom0.c | 120 ++++++++++++++++++++++++++-------------- 1 files changed, 78 insertions(+), 42 deletions(-) diff -r 1fbc9073a566 -r 239b44eeb2d6 xen/arch/ia64/xen/dom_fw_dom0.c --- a/xen/arch/ia64/xen/dom_fw_dom0.c Tue Apr 15 11:15:20 2008 -0600 +++ b/xen/arch/ia64/xen/dom_fw_dom0.c Thu Apr 24 14:02:16 2008 -0600 @@ -352,6 +352,15 @@ complete_dom0_memmap(struct domain *d, s efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; efi_desc_size = ia64_boot_param->efi_memdesc_size; + + /* EFI memory descriptor is using 4k page, while xen is using 16k page. + * To avoid identity mapping for EFI_ACPI_RECLAIM_MEMORY etc. being + * blocked by WB mapping, scan memory descriptor twice. + * First: setup identity mapping for EFI_ACPI_RECLAIM_MEMORY etc. + * Second: setup mapping for EFI_CONVENTIONAL_MEMORY etc. + */ + + /* first scan, setup identity mapping for EFI_ACPI_RECLAIM_MEMORY etc. */ for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { const efi_memory_desc_t *md = p; efi_memory_desc_t *dom_md = &tables->efi_memmap[tables->num_mds]; @@ -415,48 +424,8 @@ complete_dom0_memmap(struct domain *d, s case EFI_LOADER_CODE: case EFI_LOADER_DATA: case EFI_BOOT_SERVICES_CODE: - case EFI_BOOT_SERVICES_DATA: { - u64 dom_md_start; - u64 dom_md_end; - unsigned long left_mem = - (unsigned long)(d->max_pages - d->tot_pages) << - PAGE_SHIFT; - - if (!(md->attribute & EFI_MEMORY_WB)) - break; - - dom_md_start = max(tables->fw_end_paddr, start); - dom_md_end = dom_md_start; - do { - dom_md_end = min(dom_md_end + left_mem, end); - if (dom_md_end < dom_md_start + PAGE_SIZE) - break; - - dom_md->type = EFI_CONVENTIONAL_MEMORY; - dom_md->phys_addr = dom_md_start; - dom_md->virt_addr = 0; - dom_md->num_pages = - (dom_md_end - dom_md_start) >> - EFI_PAGE_SHIFT; - dom_md->attribute = EFI_MEMORY_WB; - - assign_new_domain0_range(d, dom_md); - /* - * recalculate left_mem. - * we might already allocated memory in - * this region because of kernel loader. - * So we might consumed less than - * (dom_md_end - dom_md_start) above. - */ - left_mem = (unsigned long) - (d->max_pages - d->tot_pages) << - PAGE_SHIFT; - } while (left_mem > 0 && dom_md_end < end); - - if (!(dom_md_end < dom_md_start + PAGE_SIZE)) - tables->num_mds++; - break; - } + case EFI_BOOT_SERVICES_DATA: + break; case EFI_UNUSABLE_MEMORY: case EFI_PAL_CODE: @@ -479,6 +448,73 @@ complete_dom0_memmap(struct domain *d, s "unhandled MDT entry type %u\n", md->type); } } + + + /* secend scan, setup mapping for EFI_CONVENTIONAL_MEMORY etc. */ + for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { + const efi_memory_desc_t *md = p; + efi_memory_desc_t *dom_md = &tables->efi_memmap[tables->num_mds]; + u64 start = md->phys_addr; + u64 size = md->num_pages << EFI_PAGE_SHIFT; + u64 end = start + size; + u64 mpaddr; + unsigned long flags; + + switch (md->type) { + + case EFI_CONVENTIONAL_MEMORY: + case EFI_LOADER_CODE: + case EFI_LOADER_DATA: + case EFI_BOOT_SERVICES_CODE: + case EFI_BOOT_SERVICES_DATA: { + u64 dom_md_start; + u64 dom_md_end; + unsigned long left_mem = + (unsigned long)(d->max_pages - d->tot_pages) << + PAGE_SHIFT; + + if (!(md->attribute & EFI_MEMORY_WB)) + break; + + dom_md_start = max(tables->fw_end_paddr, start); + dom_md_end = dom_md_start; + do { + dom_md_end = min(dom_md_end + left_mem, end); + if (dom_md_end < dom_md_start + PAGE_SIZE) + break; + + dom_md->type = EFI_CONVENTIONAL_MEMORY; + dom_md->phys_addr = dom_md_start; + dom_md->virt_addr = 0; + dom_md->num_pages = + (dom_md_end - dom_md_start) >> + EFI_PAGE_SHIFT; + dom_md->attribute = EFI_MEMORY_WB; + + assign_new_domain0_range(d, dom_md); + /* + * recalculate left_mem. + * we might already allocated memory in + * this region because of kernel loader. + * So we might consumed less than + * (dom_md_end - dom_md_start) above. + */ + left_mem = (unsigned long) + (d->max_pages - d->tot_pages) << + PAGE_SHIFT; + } while (left_mem > 0 && dom_md_end < end); + + if (!(dom_md_end < dom_md_start + PAGE_SIZE)) + tables->num_mds++; + break; + } + + + default: + break; + } + } + BUG_ON(tables->fw_tables_size < sizeof(*tables) + sizeof(tables->efi_memmap[0]) * tables->num_mds); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |