Commit bad267f9 authored by Johan Hovold's avatar Johan Hovold Committed by Ard Biesheuvel

efi: verify that variable services are supported

Current Qualcomm UEFI firmware does not implement the variable services
but not all revisions clear the corresponding bits in the RT_PROP table
services mask and instead the corresponding calls return
EFI_UNSUPPORTED.

This leads to efi core registering the generic efivar ops even when the
variable services are not supported or when they are accessed through
some other interface (e.g. Google SMI or the upcoming Qualcomm SCM
implementation).

Instead of playing games with init call levels to make sure that the
custom implementations are registered after the generic one, make sure
that get_next_variable() is actually supported before registering the
generic ops.
Signed-off-by: default avatarJohan Hovold <johan+linaro@kernel.org>
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
parent 301de9a2
...@@ -187,8 +187,27 @@ static const struct attribute_group efi_subsys_attr_group = { ...@@ -187,8 +187,27 @@ static const struct attribute_group efi_subsys_attr_group = {
static struct efivars generic_efivars; static struct efivars generic_efivars;
static struct efivar_operations generic_ops; static struct efivar_operations generic_ops;
static bool generic_ops_supported(void)
{
unsigned long name_size;
efi_status_t status;
efi_char16_t name;
efi_guid_t guid;
name_size = sizeof(name);
status = efi.get_next_variable(&name_size, &name, &guid);
if (status == EFI_UNSUPPORTED)
return false;
return true;
}
static int generic_ops_register(void) static int generic_ops_register(void)
{ {
if (!generic_ops_supported())
return 0;
generic_ops.get_variable = efi.get_variable; generic_ops.get_variable = efi.get_variable;
generic_ops.get_next_variable = efi.get_next_variable; generic_ops.get_next_variable = efi.get_next_variable;
generic_ops.query_variable_store = efi_query_variable_store; generic_ops.query_variable_store = efi_query_variable_store;
...@@ -202,6 +221,9 @@ static int generic_ops_register(void) ...@@ -202,6 +221,9 @@ static int generic_ops_register(void)
static void generic_ops_unregister(void) static void generic_ops_unregister(void)
{ {
if (!generic_ops.get_variable)
return;
efivars_unregister(&generic_efivars); efivars_unregister(&generic_efivars);
} }
......
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