|
@@ -304,6 +304,40 @@ static void __init print_efi_memmap(void)
|
|
|
}
|
|
|
#endif /* EFI_DEBUG */
|
|
|
|
|
|
+void __init efi_reserve_boot_services(void)
|
|
|
+{
|
|
|
+ void *p;
|
|
|
+
|
|
|
+ for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
|
|
|
+ efi_memory_desc_t *md = p;
|
|
|
+ unsigned long long start = md->phys_addr;
|
|
|
+ unsigned long long size = md->num_pages << EFI_PAGE_SHIFT;
|
|
|
+
|
|
|
+ if (md->type != EFI_BOOT_SERVICES_CODE &&
|
|
|
+ md->type != EFI_BOOT_SERVICES_DATA)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ memblock_x86_reserve_range(start, start + size, "EFI Boot");
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void __init efi_free_boot_services(void)
|
|
|
+{
|
|
|
+ void *p;
|
|
|
+
|
|
|
+ for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
|
|
|
+ efi_memory_desc_t *md = p;
|
|
|
+ unsigned long long start = md->phys_addr;
|
|
|
+ unsigned long long size = md->num_pages << EFI_PAGE_SHIFT;
|
|
|
+
|
|
|
+ if (md->type != EFI_BOOT_SERVICES_CODE &&
|
|
|
+ md->type != EFI_BOOT_SERVICES_DATA)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ free_bootmem_late(start, size);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void __init efi_init(void)
|
|
|
{
|
|
|
efi_config_table_t *config_tables;
|
|
@@ -536,7 +570,9 @@ void __init efi_enter_virtual_mode(void)
|
|
|
|
|
|
for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
|
|
|
md = p;
|
|
|
- if (!(md->attribute & EFI_MEMORY_RUNTIME))
|
|
|
+ if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
|
|
|
+ md->type != EFI_BOOT_SERVICES_CODE &&
|
|
|
+ md->type != EFI_BOOT_SERVICES_DATA)
|
|
|
continue;
|
|
|
|
|
|
size = md->num_pages << EFI_PAGE_SHIFT;
|
|
@@ -592,6 +628,13 @@ void __init efi_enter_virtual_mode(void)
|
|
|
panic("EFI call to SetVirtualAddressMap() failed!");
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * Thankfully, it does seem that no runtime services other than
|
|
|
+ * SetVirtualAddressMap() will touch boot services code, so we can
|
|
|
+ * get rid of it all at this point
|
|
|
+ */
|
|
|
+ efi_free_boot_services();
|
|
|
+
|
|
|
/*
|
|
|
* Now that EFI is in virtual mode, update the function
|
|
|
* pointers in the runtime service table to the new virtual addresses.
|