[patch 5/9 v3] efi: export more efi table variable to sysfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Export fw_vendor, runtime and config tables physical
addresses to /sys/firmware/efi/systab becaue kexec
kernel will 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.

changelog:
Greg: add standalone sysfs files instead of add lines to systab
Document them as testing ABI

Signed-off-by: Dave Young <dyoung@xxxxxxxxxx>
---
 Documentation/ABI/testing/sysfs-firmware-efi |   26 +++++++++
 arch/x86/platform/efi/efi.c                  |    4 +
 drivers/firmware/efi/efi.c                   |   71 +++++++++++++++++++++++++--
 include/linux/efi.h                          |    3 +
 4 files changed, 101 insertions(+), 3 deletions(-)

--- efi.orig/drivers/firmware/efi/efi.c
+++ efi/drivers/firmware/efi/efi.c
@@ -32,6 +32,9 @@ struct efi __read_mostly efi = {
 	.hcdp       = EFI_INVALID_TABLE_ADDR,
 	.uga        = EFI_INVALID_TABLE_ADDR,
 	.uv_systab  = EFI_INVALID_TABLE_ADDR,
+	.fw_vendor  = EFI_INVALID_TABLE_ADDR,
+	.runtime    = EFI_INVALID_TABLE_ADDR,
+	.config_table  = EFI_INVALID_TABLE_ADDR,
 };
 EXPORT_SYMBOL(efi);
 
@@ -71,6 +74,31 @@ static ssize_t systab_show(struct kobjec
 static struct kobj_attribute efi_attr_systab =
 			__ATTR(systab, 0400, systab_show, NULL);
 
+static ssize_t fw_vendor_show(struct kobject *kobj,
+				struct kobj_attribute *attr, char *buf)
+{
+	return sprintf(buf, "0x%lx\n", efi.fw_vendor);
+}
+
+static ssize_t runtime_show(struct kobject *kobj,
+				struct kobj_attribute *attr, char *buf)
+{
+	return sprintf(buf, "0x%lx\n", efi.runtime);
+}
+
+static ssize_t config_table_show(struct kobject *kobj,
+				struct kobj_attribute *attr, char *buf)
+{
+	return sprintf(buf, "0x%lx\n", efi.config_table);
+}
+
+static struct kobj_attribute efi_attr_fw_vendor =
+				__ATTR(fw_vendor, 0400, fw_vendor_show, NULL);
+static struct kobj_attribute efi_attr_runtime =
+			__ATTR(runtime, 0400, runtime_show, NULL);
+static struct kobj_attribute efi_attr_config_table =
+			__ATTR(config_table, 0400, config_table_show, NULL);
+
 static struct attribute *efi_subsys_attrs[] = {
 	&efi_attr_systab.attr,
 	NULL,	/* maybe more in the future? */
@@ -123,21 +151,58 @@ static int __init efisubsys_init(void)
 
 	error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
 	if (error) {
-		pr_err("efi: Sysfs attribute export failed with error %d.\n",
-		       error);
+		pr_err("efi: Sysfs attribute %s export failed with error %d.\n",
+		       efi_attr_systab.attr.name, error);
 		goto err_unregister;
 	}
 
+	if (efi.fw_vendor != EFI_INVALID_TABLE_ADDR) {
+		error = sysfs_create_file(efi_kobj, &efi_attr_fw_vendor.attr);
+		if (error) {
+			pr_err("efi: Sysfs attribute %s export failed with error %d.\n",
+				efi_attr_fw_vendor.attr.name, error);
+			goto err_remove_group;
+		}
+	}
+
+	if (efi.runtime != EFI_INVALID_TABLE_ADDR) {
+		error = sysfs_create_file(efi_kobj, &efi_attr_runtime.attr);
+		if (error) {
+			pr_err("efi: Sysfs attribute %s export failed with error %d.\n",
+				efi_attr_runtime.attr.name, error);
+			goto err_remove_fw_vendor;
+		}
+	}
+
+	if (efi.config_table != EFI_INVALID_TABLE_ADDR) {
+		error = sysfs_create_file(efi_kobj,
+					&efi_attr_config_table.attr);
+		if (error) {
+			pr_err("efi: Sysfs attribute %s export failed with error %d.\n",
+				efi_attr_config_table.attr.name, error);
+			goto err_remove_runtime;
+		}
+	}
+
 	/* and the standard mountpoint for efivarfs */
 	efivars_kobj = kobject_create_and_add("efivars", efi_kobj);
 	if (!efivars_kobj) {
 		pr_err("efivars: Subsystem registration failed.\n");
 		error = -ENOMEM;
-		goto err_remove_group;
+		goto err_remove_config_table;
 	}
 
 	return 0;
 
+err_remove_config_table:
+	if (efi.config_table != EFI_INVALID_TABLE_ADDR)
+		sysfs_remove_file(efi_kobj, &efi_attr_config_table.attr);
+err_remove_runtime:
+	if (efi.runtime != EFI_INVALID_TABLE_ADDR)
+		sysfs_remove_file(efi_kobj, &efi_attr_runtime.attr);
+err_remove_fw_vendor:
+	if (efi.fw_vendor != EFI_INVALID_TABLE_ADDR)
+		sysfs_remove_file(efi_kobj, &efi_attr_fw_vendor.attr);
 err_remove_group:
 	sysfs_remove_group(efi_kobj, &efi_subsys_attr_group);
 err_unregister:
--- efi.orig/include/linux/efi.h
+++ efi/include/linux/efi.h
@@ -556,6 +556,9 @@ extern struct efi {
 	unsigned long hcdp;		/* HCDP table */
 	unsigned long uga;		/* UGA table */
 	unsigned long uv_systab;	/* UV system table */
+	unsigned long fw_vendor;	/* fw_vendor */
+	unsigned long runtime;		/* runtime table */
+	unsigned long config_table;	/* config tables */
 	efi_get_time_t *get_time;
 	efi_set_time_t *set_time;
 	efi_get_wakeup_time_t *get_wakeup_time;
--- efi.orig/arch/x86/platform/efi/efi.c
+++ efi/arch/x86/platform/efi/efi.c
@@ -653,6 +653,10 @@ void __init efi_init(void)
 
 	set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility);
 
+	efi.fw_vendor = (unsigned long)efi.systab->fw_vendor;
+	efi.runtime = (unsigned long)efi.systab->runtime;
+	efi.config_table = (unsigned long)efi.systab->tables;
+
 	/*
 	 * Show what we know for posterity
 	 */
--- /dev/null
+++ efi/Documentation/ABI/testing/sysfs-firmware-efi
@@ -0,0 +1,26 @@
+What:		/sys/firmware/efi/fw_vendor
+Date:		Nov 2013
+Contact:	Dave Young <dyoung@xxxxxxxxxx>
+Description:
+		Shows the physical address of firmware vendor in the EFI
+		system table.
+Users:
+		Kexec Mailing List <kexec@xxxxxxxxxxxxxxxxxxx>
+
+What:		/sys/firmware/efi/runtime
+Date:		Nov 2013
+Contact:	Dave Young <dyoung@xxxxxxxxxx>
+Description:
+		Shows the physical address of runtime service table in the
+		EFI system table.
+Users:
+		Kexec Mailing List <kexec@xxxxxxxxxxxxxxxxxxx>
+
+What:		/sys/firmware/efi/config_table
+Date:		Nov 2013
+Contact:	Dave Young <dyoung@xxxxxxxxxx>
+Description:
+		Shows the physical address of config table in the EFI
+		system table.
+Users:
+		Kexec Mailing List <kexec@xxxxxxxxxxxxxxxxxxx>

--
To unsubscribe from this list: send the line "unsubscribe linux-efi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux