|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |