Allow EFI systems to override the set of supported runtime services declared via the RT_PROP table, by checking for the existence of a 'OverrideSupported' EFI variable of the appropriate size under the RT_PROP table GUID, and if it does, combine the supported mask using logical AND. (This means the override can only remove support, not add it back). Cc: Jeffrey Hugo <jhugo@xxxxxxxxxxxxxx>, Cc: Bjorn Andersson <bjorn.andersson@xxxxxxxxxx> Cc: Shawn Guo <shawn.guo@xxxxxxxxxx> Cc: Rob Clark <robdclark@xxxxxxxxx> Cc: Leif Lindholm <leif@xxxxxxxxxxxx> Cc: linux-arm-msm@xxxxxxxxxxxxxxx Signed-off-by: Ard Biesheuvel <ardb@xxxxxxxxxx> --- drivers/firmware/efi/libstub/efi-stub.c | 37 ++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c index 26e69788f27a..a23d95039b2a 100644 --- a/drivers/firmware/efi/libstub/efi-stub.c +++ b/drivers/firmware/efi/libstub/efi-stub.c @@ -96,6 +96,41 @@ static void install_memreserve_table(void) efi_err("Failed to install memreserve config table!\n"); } +static void check_rt_properties_table_override(void) +{ + static const efi_guid_t rt_prop_guid = EFI_RT_PROPERTIES_TABLE_GUID; + efi_rt_properties_table_t *table; + unsigned long size = sizeof(u32); + efi_status_t status; + u32 override; + + status = get_efi_var(L"OverrideSupported", &rt_prop_guid, NULL, &size, &override); + if (status != EFI_SUCCESS || size != sizeof(override)) + return; + + table = get_efi_config_table(rt_prop_guid); + if (!table) { + /* no table exists yet - allocate a new one */ + status = efi_bs_call(allocate_pool, EFI_RUNTIME_SERVICES_DATA, + sizeof(*table), (void **)&table); + if (status != EFI_SUCCESS) + return; + table->version = EFI_RT_PROPERTIES_TABLE_VERSION; + table->length = sizeof(*table); + table->runtime_services_supported = EFI_RT_SUPPORTED_ALL; + + status = efi_bs_call(install_configuration_table, + (efi_guid_t *)&rt_prop_guid, table); + if (status != EFI_SUCCESS) { + efi_warn("Failed to install RT_PROP override table\n"); + return; + } + } + + efi_info("Applying RT_PROP table override from EFI variable\n"); + table->runtime_services_supported &= override; +} + static u32 get_supported_rt_services(void) { const efi_rt_properties_table_t *rt_prop_table; @@ -210,6 +245,8 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, secure_boot = efi_get_secureboot(); + check_rt_properties_table_override(); + /* * Unauthenticated device tree data is a security hazard, so ignore * 'dtb=' unless UEFI Secure Boot is disabled. We assume that secure -- 2.30.1