efi/x86: Make fw_vendor, config_table and runtime sysfs nodes x86 specific
authorArd Biesheuvel <ardb@kernel.org>
Mon, 20 Jan 2020 16:23:21 +0000 (17:23 +0100)
committerArd Biesheuvel <ardb@kernel.org>
Sun, 23 Feb 2020 20:59:42 +0000 (21:59 +0100)
There is some code that exposes physical addresses of certain parts of
the EFI firmware implementation via sysfs nodes. These nodes are only
used on x86, and are of dubious value to begin with, so let's move
their handling into the x86 arch code.

Tested-by: Tony Luck <tony.luck@intel.com> # arch/ia64
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
arch/x86/include/asm/efi.h
arch/x86/kernel/kexec-bzimage64.c
arch/x86/platform/efi/efi.c
arch/x86/platform/efi/quirks.c
drivers/firmware/efi/arm-init.c
drivers/firmware/efi/efi.c
include/linux/efi.h

index ee867f01b2f68a16eabf18ec43678bc7e78457fe..78fc28da2e29e486a9614e6cb55ba50f799497c5 100644 (file)
@@ -10,6 +10,8 @@
 #include <asm/mmu_context.h>
 #include <linux/build_bug.h>
 
+extern unsigned long efi_fw_vendor, efi_config_table;
+
 /*
  * We map the EFI regions needed for runtime services non-contiguously,
  * with preserved alignment on virtual addresses starting from -4G down
index f400678bd345371b82fdf355c6cea06b344f842b..db6578d45157e539aa48dd62453ad6efdcbbbd79 100644 (file)
@@ -141,8 +141,8 @@ prepare_add_efi_setup_data(struct boot_params *params,
        struct setup_data *sd = (void *)params + efi_setup_data_offset;
        struct efi_setup_data *esd = (void *)sd + sizeof(struct setup_data);
 
-       esd->fw_vendor = efi.fw_vendor;
-       esd->tables = efi.config_table;
+       esd->fw_vendor = efi_fw_vendor;
+       esd->tables = efi_config_table;
        esd->smbios = efi.smbios;
 
        sd->type = SETUP_EFI;
index 7d932452a40f7f9bddcaa218af0250116b97ed06..6fa412e156c7a548fda9033c253a918d6cfae80b 100644 (file)
@@ -59,6 +59,9 @@ static u64 efi_systab_phys __initdata;
 
 static unsigned long prop_phys = EFI_INVALID_TABLE_ADDR;
 static unsigned long uga_phys = EFI_INVALID_TABLE_ADDR;
+static unsigned long efi_runtime, efi_nr_tables;
+
+unsigned long efi_fw_vendor, efi_config_table;
 
 static const efi_config_table_type_t arch_tables[] __initconst = {
        {EFI_PROPERTIES_TABLE_GUID, "PROP", &prop_phys},
@@ -78,9 +81,9 @@ static const unsigned long * const efi_tables[] = {
 #ifdef CONFIG_X86_UV
        &uv_systab_phys,
 #endif
-       &efi.fw_vendor,
-       &efi.runtime,
-       &efi.config_table,
+       &efi_fw_vendor,
+       &efi_runtime,
+       &efi_config_table,
        &efi.esrt,
        &prop_phys,
        &efi_mem_attr_table,
@@ -434,7 +437,7 @@ static int __init efi_config_init(const efi_config_table_type_t *arch_tables)
        void *config_tables;
        int sz, ret;
 
-       if (efi.systab->nr_tables == 0)
+       if (efi_nr_tables == 0)
                return 0;
 
        if (efi_enabled(EFI_64BIT))
@@ -445,17 +448,16 @@ static int __init efi_config_init(const efi_config_table_type_t *arch_tables)
        /*
         * Let's see what config tables the firmware passed to us.
         */
-       config_tables = early_memremap(efi.systab->tables,
-                                      efi.systab->nr_tables * sz);
+       config_tables = early_memremap(efi_config_table, efi_nr_tables * sz);
        if (config_tables == NULL) {
                pr_err("Could not map Configuration table!\n");
                return -ENOMEM;
        }
 
-       ret = efi_config_parse_tables(config_tables, efi.systab->nr_tables,
+       ret = efi_config_parse_tables(config_tables, efi_nr_tables,
                                      arch_tables);
 
-       early_memunmap(config_tables, efi.systab->nr_tables * sz);
+       early_memunmap(config_tables, efi_nr_tables * sz);
        return ret;
 }
 
@@ -474,11 +476,12 @@ void __init efi_init(void)
        if (efi_systab_init(efi_systab_phys))
                return;
 
-       efi.config_table = (unsigned long)efi.systab->tables;
-       efi.fw_vendor    = (unsigned long)efi.systab->fw_vendor;
-       efi.runtime      = (unsigned long)efi.systab->runtime;
+       efi_config_table = (unsigned long)efi.systab->tables;
+       efi_nr_tables    = efi.systab->nr_tables;
+       efi_fw_vendor    = (unsigned long)efi.systab->fw_vendor;
+       efi_runtime      = (unsigned long)efi.systab->runtime;
 
-       if (efi_reuse_config(efi.systab->tables, efi.systab->nr_tables))
+       if (efi_reuse_config(efi_config_table, efi_nr_tables))
                return;
 
        if (efi_config_init(arch_tables))
@@ -1023,3 +1026,36 @@ char *efi_systab_show_arch(char *str)
                str += sprintf(str, "UGA=0x%lx\n", uga_phys);
        return str;
 }
+
+#define EFI_FIELD(var) efi_ ## var
+
+#define EFI_ATTR_SHOW(name) \
+static ssize_t name##_show(struct kobject *kobj, \
+                               struct kobj_attribute *attr, char *buf) \
+{ \
+       return sprintf(buf, "0x%lx\n", EFI_FIELD(name)); \
+}
+
+EFI_ATTR_SHOW(fw_vendor);
+EFI_ATTR_SHOW(runtime);
+EFI_ATTR_SHOW(config_table);
+
+struct kobj_attribute efi_attr_fw_vendor = __ATTR_RO(fw_vendor);
+struct kobj_attribute efi_attr_runtime = __ATTR_RO(runtime);
+struct kobj_attribute efi_attr_config_table = __ATTR_RO(config_table);
+
+umode_t efi_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n)
+{
+       if (attr == &efi_attr_fw_vendor.attr) {
+               if (efi_enabled(EFI_PARAVIRT) ||
+                               efi_fw_vendor == EFI_INVALID_TABLE_ADDR)
+                       return 0;
+       } else if (attr == &efi_attr_runtime.attr) {
+               if (efi_runtime == EFI_INVALID_TABLE_ADDR)
+                       return 0;
+       } else if (attr == &efi_attr_config_table.attr) {
+               if (efi_config_table == EFI_INVALID_TABLE_ADDR)
+                       return 0;
+       }
+       return attr->mode;
+}
index 88d32c06cffafe3c1777d05fc20b7d2871a34ba9..b0e0161e2e8ea1dc51b73780a763015502a75084 100644 (file)
@@ -537,7 +537,7 @@ int __init efi_reuse_config(u64 tables, int nr_tables)
                goto out_memremap;
        }
 
-       for (i = 0; i < efi.systab->nr_tables; i++) {
+       for (i = 0; i < nr_tables; i++) {
                efi_guid_t guid;
 
                guid = ((efi_config_table_64_t *)p)->guid;
index d1f44c84784112e52d39126e74a22c57df60196e..5fc2f6813b847e619d9bc61620387e97ae51d77b 100644 (file)
@@ -120,9 +120,6 @@ static int __init uefi_init(void)
        retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables,
                                         arch_tables);
 
-       if (!retval)
-               efi.config_table = (unsigned long)efi.systab->tables;
-
        early_memunmap(config_tables, table_size);
 out:
        early_memunmap(efi.systab,  sizeof(efi_system_table_t));
index 45de4c4a696b357f666de0e9244e31087d294442..718dddfa0a0b3786470922bf1414a5dac71d6f56 100644 (file)
@@ -39,9 +39,6 @@ struct efi __read_mostly efi = {
        .acpi20                 = EFI_INVALID_TABLE_ADDR,
        .smbios                 = EFI_INVALID_TABLE_ADDR,
        .smbios3                = EFI_INVALID_TABLE_ADDR,
-       .fw_vendor              = EFI_INVALID_TABLE_ADDR,
-       .runtime                = EFI_INVALID_TABLE_ADDR,
-       .config_table           = EFI_INVALID_TABLE_ADDR,
        .esrt                   = EFI_INVALID_TABLE_ADDR,
        .tpm_log                = EFI_INVALID_TABLE_ADDR,
        .tpm_final_log          = EFI_INVALID_TABLE_ADDR,
@@ -142,55 +139,30 @@ static ssize_t systab_show(struct kobject *kobj,
 
 static struct kobj_attribute efi_attr_systab = __ATTR_RO_MODE(systab, 0400);
 
-#define EFI_FIELD(var) efi.var
-
-#define EFI_ATTR_SHOW(name) \
-static ssize_t name##_show(struct kobject *kobj, \
-                               struct kobj_attribute *attr, char *buf) \
-{ \
-       return sprintf(buf, "0x%lx\n", EFI_FIELD(name)); \
-}
-
-EFI_ATTR_SHOW(fw_vendor);
-EFI_ATTR_SHOW(runtime);
-EFI_ATTR_SHOW(config_table);
-
 static ssize_t fw_platform_size_show(struct kobject *kobj,
                                     struct kobj_attribute *attr, char *buf)
 {
        return sprintf(buf, "%d\n", efi_enabled(EFI_64BIT) ? 64 : 32);
 }
 
-static struct kobj_attribute efi_attr_fw_vendor = __ATTR_RO(fw_vendor);
-static struct kobj_attribute efi_attr_runtime = __ATTR_RO(runtime);
-static struct kobj_attribute efi_attr_config_table = __ATTR_RO(config_table);
+extern __weak struct kobj_attribute efi_attr_fw_vendor;
+extern __weak struct kobj_attribute efi_attr_runtime;
+extern __weak struct kobj_attribute efi_attr_config_table;
 static struct kobj_attribute efi_attr_fw_platform_size =
        __ATTR_RO(fw_platform_size);
 
 static struct attribute *efi_subsys_attrs[] = {
        &efi_attr_systab.attr,
+       &efi_attr_fw_platform_size.attr,
        &efi_attr_fw_vendor.attr,
        &efi_attr_runtime.attr,
        &efi_attr_config_table.attr,
-       &efi_attr_fw_platform_size.attr,
        NULL,
 };
 
-static umode_t efi_attr_is_visible(struct kobject *kobj,
-                                  struct attribute *attr, int n)
+umode_t __weak efi_attr_is_visible(struct kobject *kobj, struct attribute *attr,
+                                  int n)
 {
-       if (attr == &efi_attr_fw_vendor.attr) {
-               if (efi_enabled(EFI_PARAVIRT) ||
-                               efi.fw_vendor == EFI_INVALID_TABLE_ADDR)
-                       return 0;
-       } else if (attr == &efi_attr_runtime.attr) {
-               if (efi.runtime == EFI_INVALID_TABLE_ADDR)
-                       return 0;
-       } else if (attr == &efi_attr_config_table.attr) {
-               if (efi.config_table == EFI_INVALID_TABLE_ADDR)
-                       return 0;
-       }
-
        return attr->mode;
 }
 
index 99a7fcbe5e9bfc77d96ebe465ddee9997229d9c0..a42045568df351dfb03c55305718061cd5393c54 100644 (file)
@@ -535,9 +535,6 @@ extern struct efi {
        unsigned long acpi20;           /* ACPI table  (ACPI 2.0) */
        unsigned long smbios;           /* SMBIOS table (32 bit entry point) */
        unsigned long smbios3;          /* SMBIOS table (64 bit entry point) */
-       unsigned long fw_vendor;        /* fw_vendor */
-       unsigned long runtime;          /* runtime table */
-       unsigned long config_table;     /* config tables */
        unsigned long esrt;             /* ESRT table */
        unsigned long tpm_log;          /* TPM2 Event Log table */
        unsigned long tpm_final_log;    /* TPM2 Final Events Log table */