Commit 37926f96 authored by Ard Biesheuvel's avatar Ard Biesheuvel

efi: runtime: Don't assume virtual mappings are missing if VA == PA == 0

The generic EFI stub can be instructed to avoid SetVirtualAddressMap(),
and simply run with the firmware's 1:1 mapping. In this case, it
populates the virtual address fields of the runtime regions in the
memory map with the physical address of each region, so that the mapping
code has to be none the wiser. Only if SetVirtualAddressMap() fails, the
virtual addresses are wiped and the kernel code knows that the regions
cannot be mapped.

However, wiping amounts to setting it to zero, and if a runtime region
happens to live at physical address 0, its valid 1:1 mapped virtual
address could be mistaken for a wiped field, resulting on loss of access
to the EFI services at runtime.

So let's only assume that VA == 0 means 'no runtime services' if the
region in question does not live at PA 0x0.
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
parent 53a7ea28
...@@ -63,7 +63,7 @@ static bool __init efi_virtmap_init(void) ...@@ -63,7 +63,7 @@ static bool __init efi_virtmap_init(void)
if (!(md->attribute & EFI_MEMORY_RUNTIME)) if (!(md->attribute & EFI_MEMORY_RUNTIME))
continue; continue;
if (md->virt_addr == 0) if (md->virt_addr == U64_MAX)
return false; return false;
ret = efi_create_mapping(&efi_mm, md); ret = efi_create_mapping(&efi_mm, md);
......
...@@ -313,16 +313,16 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, ...@@ -313,16 +313,16 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
/* /*
* Set the virtual address field of all * Set the virtual address field of all
* EFI_MEMORY_RUNTIME entries to 0. This will signal * EFI_MEMORY_RUNTIME entries to U64_MAX. This will
* the incoming kernel that no virtual translation has * signal the incoming kernel that no virtual
* been installed. * translation has been installed.
*/ */
for (l = 0; l < priv.boot_memmap->map_size; for (l = 0; l < priv.boot_memmap->map_size;
l += priv.boot_memmap->desc_size) { l += priv.boot_memmap->desc_size) {
p = (void *)priv.boot_memmap->map + l; p = (void *)priv.boot_memmap->map + l;
if (p->attribute & EFI_MEMORY_RUNTIME) if (p->attribute & EFI_MEMORY_RUNTIME)
p->virt_addr = 0; p->virt_addr = U64_MAX;
} }
} }
return EFI_SUCCESS; return EFI_SUCCESS;
......
...@@ -41,7 +41,7 @@ static bool __init efi_virtmap_init(void) ...@@ -41,7 +41,7 @@ static bool __init efi_virtmap_init(void)
if (!(md->attribute & EFI_MEMORY_RUNTIME)) if (!(md->attribute & EFI_MEMORY_RUNTIME))
continue; continue;
if (md->virt_addr == 0) if (md->virt_addr == U64_MAX)
return false; return false;
ret = efi_create_mapping(&efi_mm, md); ret = efi_create_mapping(&efi_mm, md);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment