[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v3 2/4] Add a dedicated memory region for the ESRT



This allows the ESRT to be marked as reserved without having to waste a
potentially large amount of memory.  This patch assumes that Xen can
handle memory regions that are not page-aligned.  If it cannot,
additional code will need to be added to align the regions.
---
 xen/arch/x86/efi/efi-boot.h     | 69 +++++++++++++++++++++++++--------
 xen/arch/x86/include/asm/e820.h |  2 +-
 2 files changed, 54 insertions(+), 17 deletions(-)

diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
index 75937c8a11..edf1fea3e0 100644
--- a/xen/arch/x86/efi/efi-boot.h
+++ b/xen/arch/x86/efi/efi-boot.h
@@ -165,13 +165,14 @@ static void __init 
efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
     {
         EFI_MEMORY_DESCRIPTOR *desc = map + i;
         u64 len = desc->NumberOfPages << EFI_PAGE_SHIFT;
+        UINTN physical_start = desc->PhysicalStart;
         u32 type;
 
         switch ( desc->Type )
         {
         case EfiBootServicesCode:
         case EfiBootServicesData:
-            if ( map_bs || desc == (EFI_MEMORY_DESCRIPTOR *)esrt_desc )
+            if ( map_bs )
             {
         default:
                 type = E820_RESERVED;
@@ -179,9 +180,9 @@ static void __init 
efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
             }
             /* fall through */
         case EfiConventionalMemory:
-            if ( !trampoline_phys && desc->PhysicalStart + len <= 0x100000 &&
-                 len >= cfg.size && desc->PhysicalStart + len > cfg.addr )
-                cfg.addr = (desc->PhysicalStart + len - cfg.size) & PAGE_MASK;
+            if ( !trampoline_phys && physical_start + len <= 0x100000 &&
+                 len >= cfg.size && physical_start + len > cfg.addr )
+                cfg.addr = (physical_start + len - cfg.size) & PAGE_MASK;
             /* fall through */
         case EfiLoaderCode:
         case EfiLoaderData:
@@ -198,21 +199,57 @@ static void __init 
efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
             type = E820_NVS;
             break;
         }
-        if ( e820_raw.nr_map && type == e->type &&
-             desc->PhysicalStart == e->addr + e->size )
-            e->size += len;
-        else if ( !len || e820_raw.nr_map >= ARRAY_SIZE(e820_raw.map) )
-            continue;
-        else
+
+#define ADD_ENTRY(len, type_, physical_start)                           \
+        if ( len )                                                      \
+        {                                                               \
+            if ( e820_raw.nr_map && (type_) == e->type &&               \
+                 (physical_start) == e->addr + e->size )                \
+                e->size += (len);                                       \
+            else if ( e820_raw.nr_map < ARRAY_SIZE(e820_raw.map) )      \
+                continue;                                               \
+            else                                                        \
+            {                                                           \
+                ++e;                                                    \
+                e->addr = (physical_start);                             \
+                e->size = (len);                                        \
+                e->type = (type_);                                      \
+                ++e820_raw.nr_map;                                      \
+            }                                                           \
+        }                                                               \
+        else                                                            \
+            do {} while (0)
+
+        if ( desc == (EFI_MEMORY_DESCRIPTOR *)esrt_desc )
         {
-            ++e;
-            e->addr = desc->PhysicalStart;
-            e->size = len;
-            e->type = type;
-            ++e820_raw.nr_map;
+            const ESRT *esrt_ptr;
+            UINTN esrt_offset, esrt_len;
+
+            BUG_ON(physical_start > esrt);
+            BUG_ON(len < sizeof(*esrt_ptr));
+            esrt_offset = esrt - physical_start;
+
+            BUG_ON(len - sizeof(*esrt_ptr) < esrt_offset);
+            esrt_ptr = (const ESRT *)esrt;
+
+            BUG_ON(esrt_ptr->Version != 1);
+            BUG_ON(esrt_ptr->Count < 1);
+
+            esrt_len = (esrt_ptr->Count + 1) * sizeof(*esrt_ptr);
+
+            BUG_ON( len - esrt_offset < esrt_len );
+
+            ADD_ENTRY(esrt_offset, type, physical_start);
+
+            ADD_ENTRY(esrt_len, E820_RESERVED, esrt);
+
+            physical_start = esrt + esrt_len;
+            len -= esrt_offset + esrt_len;
         }
-    }
 
+        ADD_ENTRY(len, type, physical_start);
+    }
+#undef ADD_ENTRY
 }
 
 static void *__init efi_arch_allocate_mmap_buffer(UINTN map_size)
diff --git a/xen/arch/x86/include/asm/e820.h b/xen/arch/x86/include/asm/e820.h
index 92f5efa4f5..98eca96425 100644
--- a/xen/arch/x86/include/asm/e820.h
+++ b/xen/arch/x86/include/asm/e820.h
@@ -16,7 +16,7 @@ struct __packed e820entry {
     uint32_t type;
 };
 
-#define E820MAX        1024
+#define E820MAX        1026
 
 struct e820map {
     unsigned int nr_map;
-- 
Sincerely,
Demi Marie Obenour (she/her/hers)
Invisible Things Lab

Attachment: signature.asc
Description: PGP signature


 


Rackspace

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