[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.