diff options
author | Dave Young <dyoung@redhat.com> | 2013-12-20 05:02:17 -0500 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2013-12-21 10:29:36 -0500 |
commit | a0998eb15afeffbf52a2c2829318f67df9ac57b8 (patch) | |
tree | 5f19084e93f018407d8dfc3521d073250719e67f /drivers/firmware | |
parent | 481f75c043cf44ec11c7fbdbbf37d43463f1e719 (diff) |
efi: Export more EFI table variables to sysfs
Export fw_vendor, runtime and config table physical addresses to
/sys/firmware/efi/{fw_vendor,runtime,config_table} because kexec kernels
need them.
From EFI spec these 3 variables will be updated to virtual address after
entering virtual mode. But kernel startup code will need the physical
address.
Signed-off-by: Dave Young <dyoung@redhat.com>
Tested-by: Toshi Kani <toshi.kani@hp.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/efi/efi.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 2e2fbdec0845..72533af72b98 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c | |||
@@ -32,6 +32,9 @@ struct efi __read_mostly efi = { | |||
32 | .hcdp = EFI_INVALID_TABLE_ADDR, | 32 | .hcdp = EFI_INVALID_TABLE_ADDR, |
33 | .uga = EFI_INVALID_TABLE_ADDR, | 33 | .uga = EFI_INVALID_TABLE_ADDR, |
34 | .uv_systab = EFI_INVALID_TABLE_ADDR, | 34 | .uv_systab = EFI_INVALID_TABLE_ADDR, |
35 | .fw_vendor = EFI_INVALID_TABLE_ADDR, | ||
36 | .runtime = EFI_INVALID_TABLE_ADDR, | ||
37 | .config_table = EFI_INVALID_TABLE_ADDR, | ||
35 | }; | 38 | }; |
36 | EXPORT_SYMBOL(efi); | 39 | EXPORT_SYMBOL(efi); |
37 | 40 | ||
@@ -71,13 +74,49 @@ static ssize_t systab_show(struct kobject *kobj, | |||
71 | static struct kobj_attribute efi_attr_systab = | 74 | static struct kobj_attribute efi_attr_systab = |
72 | __ATTR(systab, 0400, systab_show, NULL); | 75 | __ATTR(systab, 0400, systab_show, NULL); |
73 | 76 | ||
77 | #define EFI_FIELD(var) efi.var | ||
78 | |||
79 | #define EFI_ATTR_SHOW(name) \ | ||
80 | static ssize_t name##_show(struct kobject *kobj, \ | ||
81 | struct kobj_attribute *attr, char *buf) \ | ||
82 | { \ | ||
83 | return sprintf(buf, "0x%lx\n", EFI_FIELD(name)); \ | ||
84 | } | ||
85 | |||
86 | EFI_ATTR_SHOW(fw_vendor); | ||
87 | EFI_ATTR_SHOW(runtime); | ||
88 | EFI_ATTR_SHOW(config_table); | ||
89 | |||
90 | static struct kobj_attribute efi_attr_fw_vendor = __ATTR_RO(fw_vendor); | ||
91 | static struct kobj_attribute efi_attr_runtime = __ATTR_RO(runtime); | ||
92 | static struct kobj_attribute efi_attr_config_table = __ATTR_RO(config_table); | ||
93 | |||
74 | static struct attribute *efi_subsys_attrs[] = { | 94 | static struct attribute *efi_subsys_attrs[] = { |
75 | &efi_attr_systab.attr, | 95 | &efi_attr_systab.attr, |
76 | NULL, /* maybe more in the future? */ | 96 | &efi_attr_fw_vendor.attr, |
97 | &efi_attr_runtime.attr, | ||
98 | &efi_attr_config_table.attr, | ||
99 | NULL, | ||
77 | }; | 100 | }; |
78 | 101 | ||
102 | static umode_t efi_attr_is_visible(struct kobject *kobj, | ||
103 | struct attribute *attr, int n) | ||
104 | { | ||
105 | umode_t mode = attr->mode; | ||
106 | |||
107 | if (attr == &efi_attr_fw_vendor.attr) | ||
108 | return (efi.fw_vendor == EFI_INVALID_TABLE_ADDR) ? 0 : mode; | ||
109 | else if (attr == &efi_attr_runtime.attr) | ||
110 | return (efi.runtime == EFI_INVALID_TABLE_ADDR) ? 0 : mode; | ||
111 | else if (attr == &efi_attr_config_table.attr) | ||
112 | return (efi.config_table == EFI_INVALID_TABLE_ADDR) ? 0 : mode; | ||
113 | |||
114 | return mode; | ||
115 | } | ||
116 | |||
79 | static struct attribute_group efi_subsys_attr_group = { | 117 | static struct attribute_group efi_subsys_attr_group = { |
80 | .attrs = efi_subsys_attrs, | 118 | .attrs = efi_subsys_attrs, |
119 | .is_visible = efi_attr_is_visible, | ||
81 | }; | 120 | }; |
82 | 121 | ||
83 | static struct efivars generic_efivars; | 122 | static struct efivars generic_efivars; |