# 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
|