Skip to content

Commit

Permalink
efi/x86: Drop two near identical versions of efi_runtime_init()
Browse files Browse the repository at this point in the history
The routines efi_runtime_init32() and efi_runtime_init64() are
almost indistinguishable, and the only relevant difference is
the offset in the runtime struct from where to obtain the physical
address of the SetVirtualAddressMap() routine.

However, this address is only used once, when installing the virtual
address map that the OS will use to invoke EFI runtime services, and
at the time of the call, we will necessarily be running with a 1:1
mapping, and so there is no need to do the map/unmap dance here to
retrieve the address. In fact, in the preceding changes to these users,
we stopped using the address recorded here entirely.

So let's just get rid of all this code since it no longer serves a
purpose. While at it, tweak the logic so that we handle unsupported
and disable EFI runtime services in the same way, and unmap the EFI
memory map in both cases.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Arvind Sankar <nivedita@alum.mit.edu>
Cc: Matthew Garrett <mjg59@google.com>
Cc: linux-efi@vger.kernel.org
Link: https://lkml.kernel.org/r/20200103113953.9571-12-ardb@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Ard Biesheuvel authored and Ingo Molnar committed Jan 10, 2020
1 parent ea5e191 commit 33b8544
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 109 deletions.
95 changes: 5 additions & 90 deletions arch/x86/platform/efi/efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,87 +429,6 @@ static int __init efi_systab_init(void *phys)
return 0;
}

static int __init efi_runtime_init32(void)
{
efi_runtime_services_32_t *runtime;

runtime = early_memremap((unsigned long)efi.systab->runtime,
sizeof(efi_runtime_services_32_t));
if (!runtime) {
pr_err("Could not map the runtime service table!\n");
return -ENOMEM;
}

/*
* We will only need *early* access to the SetVirtualAddressMap
* EFI runtime service. All other runtime services will be called
* via the virtual mapping.
*/
efi_phys.set_virtual_address_map =
(efi_set_virtual_address_map_t *)
(unsigned long)runtime->set_virtual_address_map;
early_memunmap(runtime, sizeof(efi_runtime_services_32_t));

return 0;
}

static int __init efi_runtime_init64(void)
{
efi_runtime_services_64_t *runtime;

runtime = early_memremap((unsigned long)efi.systab->runtime,
sizeof(efi_runtime_services_64_t));
if (!runtime) {
pr_err("Could not map the runtime service table!\n");
return -ENOMEM;
}

/*
* We will only need *early* access to the SetVirtualAddressMap
* EFI runtime service. All other runtime services will be called
* via the virtual mapping.
*/
efi_phys.set_virtual_address_map =
(efi_set_virtual_address_map_t *)
(unsigned long)runtime->set_virtual_address_map;
early_memunmap(runtime, sizeof(efi_runtime_services_64_t));

return 0;
}

static int __init efi_runtime_init(void)
{
int rv;

/*
* Check out the runtime services table. We need to map
* the runtime services table so that we can grab the physical
* address of several of the EFI runtime functions, needed to
* set the firmware into virtual mode.
*
* When EFI_PARAVIRT is in force then we could not map runtime
* service memory region because we do not have direct access to it.
* However, runtime services are available through proxy functions
* (e.g. in case of Xen dom0 EFI implementation they call special
* hypercall which executes relevant EFI functions) and that is why
* they are always enabled.
*/

if (!efi_enabled(EFI_PARAVIRT)) {
if (efi_enabled(EFI_64BIT))
rv = efi_runtime_init64();
else
rv = efi_runtime_init32();

if (rv)
return rv;
}

set_bit(EFI_RUNTIME_SERVICES, &efi.flags);

return 0;
}

void __init efi_init(void)
{
efi_char16_t *c16;
Expand Down Expand Up @@ -567,13 +486,13 @@ void __init efi_init(void)

if (!efi_runtime_supported())
pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n");
else {
if (efi_runtime_disabled() || efi_runtime_init()) {
efi_memmap_unmap();
return;
}

if (!efi_runtime_supported() || efi_runtime_disabled()) {
efi_memmap_unmap();
return;
}

set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
efi_clean_memmap();

if (efi_enabled(EFI_DBG))
Expand Down Expand Up @@ -934,8 +853,6 @@ static void __init kexec_enter_virtual_mode(void)

efi_native_runtime_setup();

efi.set_virtual_address_map = NULL;

if (efi_enabled(EFI_OLD_MEMMAP) && (__supported_pte_mask & _PAGE_NX))
runtime_code_page_mkexec();
#endif
Expand Down Expand Up @@ -1040,8 +957,6 @@ static void __init __efi_enter_virtual_mode(void)
else
efi_thunk_runtime_setup();

efi.set_virtual_address_map = NULL;

/*
* Apply more restrictive page table mapping attributes now that
* SVAM() has been called and the firmware has performed all
Expand Down
19 changes: 0 additions & 19 deletions include/linux/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -539,24 +539,6 @@ typedef struct {
u32 query_variable_info;
} efi_runtime_services_32_t;

typedef struct {
efi_table_hdr_t hdr;
u64 get_time;
u64 set_time;
u64 get_wakeup_time;
u64 set_wakeup_time;
u64 set_virtual_address_map;
u64 convert_pointer;
u64 get_variable;
u64 get_next_variable;
u64 set_variable;
u64 get_next_high_mono_count;
u64 reset_system;
u64 update_capsule;
u64 query_capsule_caps;
u64 query_variable_info;
} efi_runtime_services_64_t;

typedef efi_status_t efi_get_time_t (efi_time_t *tm, efi_time_cap_t *tc);
typedef efi_status_t efi_set_time_t (efi_time_t *tm);
typedef efi_status_t efi_get_wakeup_time_t (efi_bool_t *enabled, efi_bool_t *pending,
Expand Down Expand Up @@ -946,7 +928,6 @@ extern struct efi {
efi_query_capsule_caps_t *query_capsule_caps;
efi_get_next_high_mono_count_t *get_next_high_mono_count;
efi_reset_system_t *reset_system;
efi_set_virtual_address_map_t *set_virtual_address_map;
struct efi_memory_map memmap;
unsigned long flags;
} efi;
Expand Down

0 comments on commit 33b8544

Please sign in to comment.