From abc93f8eb6e46a480485f19256bdbda36ec78a84 Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Mon, 30 Jun 2014 19:52:56 +0200 Subject: efi: Use early_mem*() instead of early_io*() Use early_mem*() instead of early_io*() because all mapped EFI regions are memory (usually RAM but they could also be ROM, EPROM, EEPROM, flash, etc.) not I/O regions. Additionally, I/O family calls do not work correctly under Xen in our case. early_ioremap() skips the PFN to MFN conversion when building the PTE. Using it for memory will attempt to map the wrong machine frame. However, all artificial EFI structures created under Xen live in dom0 memory and should be mapped/unmapped using early_mem*() family calls which map domain memory. Signed-off-by: Daniel Kiper Cc: Leif Lindholm Cc: Mark Salter Signed-off-by: Matt Fleming --- drivers/firmware/efi/efi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/firmware/efi/efi.c') diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index cd36deb619fa..023937a63a48 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -298,7 +298,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables) if (table64 >> 32) { pr_cont("\n"); pr_err("Table located above 4GB, disabling EFI.\n"); - early_iounmap(config_tables, + early_memunmap(config_tables, efi.systab->nr_tables * sz); return -EINVAL; } @@ -314,7 +314,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables) tablep += sz; } pr_cont("\n"); - early_iounmap(config_tables, efi.systab->nr_tables * sz); + early_memunmap(config_tables, efi.systab->nr_tables * sz); set_bit(EFI_CONFIG_TABLES, &efi.flags); -- cgit v1.2.3 From 9f27bc543bdf92e179927037e2ab8ed0261579a9 Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Mon, 30 Jun 2014 19:52:58 +0200 Subject: efi: Introduce EFI_PARAVIRT flag Introduce EFI_PARAVIRT flag. If it is set then kernel runs on EFI platform but it has not direct control on EFI stuff like EFI runtime, tables, structures, etc. If not this means that Linux Kernel has direct access to EFI infrastructure and everything runs as usual. This functionality is used in Xen dom0 because hypervisor has full control on EFI stuff and all calls from dom0 to EFI must be requested via special hypercall which in turn executes relevant EFI code in behalf of dom0. Signed-off-by: Daniel Kiper Signed-off-by: Matt Fleming --- drivers/firmware/efi/efi.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'drivers/firmware/efi/efi.c') diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 023937a63a48..ac88ec05eb70 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -104,16 +104,19 @@ static struct attribute *efi_subsys_attrs[] = { static umode_t efi_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n) { - umode_t mode = attr->mode; - - if (attr == &efi_attr_fw_vendor.attr) - return (efi.fw_vendor == EFI_INVALID_TABLE_ADDR) ? 0 : mode; - else if (attr == &efi_attr_runtime.attr) - return (efi.runtime == EFI_INVALID_TABLE_ADDR) ? 0 : mode; - else if (attr == &efi_attr_config_table.attr) - return (efi.config_table == EFI_INVALID_TABLE_ADDR) ? 0 : mode; + 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 mode; + return attr->mode; } static struct attribute_group efi_subsys_attr_group = { -- cgit v1.2.3 From 28d54022e6ff9c16bf4dacb5f64a97443a38caa9 Mon Sep 17 00:00:00 2001 From: "Lee, Chun-Yi" Date: Wed, 9 Jul 2014 18:39:29 +0800 Subject: efi: Autoload efivars The original patch is from Ben Hutchings's contribution to debian kernel. Got Ben's permission to remove the code of efi-pstore.c and send to linux-efi: https://github.com/BlankOn/linux-debian/blob/master/debian/patches/features/all/efi-autoload-efivars.patch efivars is generally useful to have on EFI systems, and in some cases it may be impossible to load it after a kernel upgrade in order to complete a boot loader update. At the same time we don't want to waste memory on non-EFI systems by making them built-in. Instead, give them module aliases as if they are platform drivers, and register a corresponding platform device whenever EFI runtime services are available. This should trigger udev to load them. Signed-off-by: Lee, Chun-Yi Cc: Ben Hutchings Tested-by: Ard Biesheuvel Signed-off-by: Matt Fleming --- drivers/firmware/efi/efi.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers/firmware/efi/efi.c') diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index ac88ec05eb70..36ffa1747e84 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -23,6 +23,7 @@ #include #include #include +#include struct efi __read_mostly efi = { .mps = EFI_INVALID_TABLE_ADDR, @@ -324,6 +325,20 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables) return 0; } +#ifdef CONFIG_EFI_VARS_MODULE +static int __init efi_load_efivars(void) +{ + struct platform_device *pdev; + + if (!efi_enabled(EFI_RUNTIME_SERVICES)) + return 0; + + pdev = platform_device_register_simple("efivars", 0, NULL, 0); + return IS_ERR(pdev) ? PTR_ERR(pdev) : 0; +} +device_initcall(efi_load_efivars); +#endif + #ifdef CONFIG_EFI_PARAMS_FROM_FDT #define UEFI_PARAM(name, prop, field) \ -- cgit v1.2.3