From: Greg Kroah-Hartman Date: Mon, 11 Feb 2013 20:00:56 +0000 (-0800) Subject: 3.4-stable patches X-Git-Tag: v3.0.64~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=229f69005c742b6e44ed7b848033316afc773f7d;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: efi-make-efi_enabled-a-function-to-query-efi-facilities.patch --- diff --git a/queue-3.4/efi-make-efi_enabled-a-function-to-query-efi-facilities.patch b/queue-3.4/efi-make-efi_enabled-a-function-to-query-efi-facilities.patch new file mode 100644 index 00000000000..1e24e92a1a3 --- /dev/null +++ b/queue-3.4/efi-make-efi_enabled-a-function-to-query-efi-facilities.patch @@ -0,0 +1,464 @@ +From 83e68189745ad931c2afd45d8ee3303929233e7f Mon Sep 17 00:00:00 2001 +From: Matt Fleming +Date: Wed, 14 Nov 2012 09:42:35 +0000 +Subject: efi: Make 'efi_enabled' a function to query EFI facilities + +From: Matt Fleming + +commit 83e68189745ad931c2afd45d8ee3303929233e7f upstream. + +Originally 'efi_enabled' indicated whether a kernel was booted from +EFI firmware. Over time its semantics have changed, and it now +indicates whether or not we are booted on an EFI machine with +bit-native firmware, e.g. 64-bit kernel with 64-bit firmware. + +The immediate motivation for this patch is the bug report at, + + https://bugs.launchpad.net/ubuntu-cdimage/+bug/1040557 + +which details how running a platform driver on an EFI machine that is +designed to run under BIOS can cause the machine to become +bricked. Also, the following report, + + https://bugzilla.kernel.org/show_bug.cgi?id=47121 + +details how running said driver can also cause Machine Check +Exceptions. Drivers need a new means of detecting whether they're +running on an EFI machine, as sadly the expression, + + if (!efi_enabled) + +hasn't been a sufficient condition for quite some time. + +Users actually want to query 'efi_enabled' for different reasons - +what they really want access to is the list of available EFI +facilities. + +For instance, the x86 reboot code needs to know whether it can invoke +the ResetSystem() function provided by the EFI runtime services, while +the ACPI OSL code wants to know whether the EFI config tables were +mapped successfully. There are also checks in some of the platform +driver code to simply see if they're running on an EFI machine (which +would make it a bad idea to do BIOS-y things). + +This patch is a prereq for the samsung-laptop fix patch. + +Cc: David Airlie +Cc: Corentin Chary +Cc: Matthew Garrett +Cc: Dave Jiang +Cc: Olof Johansson +Cc: Peter Jones +Cc: Colin Ian King +Cc: Steve Langasek +Cc: Tony Luck +Cc: Konrad Rzeszutek Wilk +Cc: Rafael J. Wysocki +Signed-off-by: Matt Fleming +Signed-off-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/efi.h | 1 + arch/x86/kernel/reboot.c | 2 - + arch/x86/kernel/setup.c | 28 ++++++++-------- + arch/x86/platform/efi/efi.c | 57 +++++++++++++++++++-------------- + drivers/acpi/osl.c | 2 - + drivers/firmware/dmi_scan.c | 2 - + drivers/firmware/efivars.c | 4 +- + drivers/firmware/iscsi_ibft_find.c | 2 - + drivers/gpu/drm/radeon/radeon_device.c | 3 + + drivers/platform/x86/ibm_rtl.c | 2 - + drivers/scsi/isci/init.c | 2 - + include/linux/efi.h | 24 ++++++++++--- + init/main.c | 4 +- + 13 files changed, 79 insertions(+), 54 deletions(-) + +--- a/arch/x86/include/asm/efi.h ++++ b/arch/x86/include/asm/efi.h +@@ -94,6 +94,7 @@ extern void __iomem *efi_ioremap(unsigne + #endif /* CONFIG_X86_32 */ + + extern int add_efi_memmap; ++extern unsigned long x86_efi_facility; + extern void efi_set_executable(efi_memory_desc_t *md, bool executable); + extern int efi_memblock_x86_reserve_range(void); + extern void efi_call_phys_prelog(void); +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -619,7 +619,7 @@ static void native_machine_emergency_res + break; + + case BOOT_EFI: +- if (efi_enabled) ++ if (efi_enabled(EFI_RUNTIME_SERVICES)) + efi.reset_system(reboot_mode ? + EFI_RESET_WARM : + EFI_RESET_COLD, +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -818,15 +818,15 @@ void __init setup_arch(char **cmdline_p) + #ifdef CONFIG_EFI + if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature, + "EL32", 4)) { +- efi_enabled = 1; +- efi_64bit = false; ++ set_bit(EFI_BOOT, &x86_efi_facility); + } else if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature, + "EL64", 4)) { +- efi_enabled = 1; +- efi_64bit = true; ++ set_bit(EFI_BOOT, &x86_efi_facility); ++ set_bit(EFI_64BIT, &x86_efi_facility); + } +- if (efi_enabled && efi_memblock_x86_reserve_range()) +- efi_enabled = 0; ++ ++ if (efi_enabled(EFI_BOOT)) ++ efi_memblock_x86_reserve_range(); + #endif + + x86_init.oem.arch_setup(); +@@ -899,7 +899,7 @@ void __init setup_arch(char **cmdline_p) + + finish_e820_parsing(); + +- if (efi_enabled) ++ if (efi_enabled(EFI_BOOT)) + efi_init(); + + dmi_scan_machine(); +@@ -982,7 +982,7 @@ void __init setup_arch(char **cmdline_p) + * The EFI specification says that boot service code won't be called + * after ExitBootServices(). This is, in fact, a lie. + */ +- if (efi_enabled) ++ if (efi_enabled(EFI_MEMMAP)) + efi_reserve_boot_services(); + + /* preallocate 4k for mptable mpc */ +@@ -1119,7 +1119,7 @@ void __init setup_arch(char **cmdline_p) + + #ifdef CONFIG_VT + #if defined(CONFIG_VGA_CONSOLE) +- if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY)) ++ if (!efi_enabled(EFI_BOOT) || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY)) + conswitchp = &vga_con; + #elif defined(CONFIG_DUMMY_CONSOLE) + conswitchp = &dummy_con; +@@ -1136,14 +1136,14 @@ void __init setup_arch(char **cmdline_p) + arch_init_ideal_nops(); + + #ifdef CONFIG_EFI +- /* Once setup is done above, disable efi_enabled on mismatched +- * firmware/kernel archtectures since there is no support for +- * runtime services. ++ /* Once setup is done above, unmap the EFI memory map on ++ * mismatched firmware/kernel archtectures since there is no ++ * support for runtime services. + */ +- if (efi_enabled && IS_ENABLED(CONFIG_X86_64) != efi_64bit) { ++ if (efi_enabled(EFI_BOOT) && ++ IS_ENABLED(CONFIG_X86_64) != efi_enabled(EFI_64BIT)) { + pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); + efi_unmap_memmap(); +- efi_enabled = 0; + } + #endif + } +--- a/arch/x86/platform/efi/efi.c ++++ b/arch/x86/platform/efi/efi.c +@@ -50,9 +50,6 @@ + + #define EFI_DEBUG 1 + +-int efi_enabled; +-EXPORT_SYMBOL(efi_enabled); +- + struct efi __read_mostly efi = { + .mps = EFI_INVALID_TABLE_ADDR, + .acpi = EFI_INVALID_TABLE_ADDR, +@@ -68,19 +65,28 @@ EXPORT_SYMBOL(efi); + + struct efi_memory_map memmap; + +-bool efi_64bit; +- + static struct efi efi_phys __initdata; + static efi_system_table_t efi_systab __initdata; + + static inline bool efi_is_native(void) + { +- return IS_ENABLED(CONFIG_X86_64) == efi_64bit; ++ return IS_ENABLED(CONFIG_X86_64) == efi_enabled(EFI_64BIT); ++} ++ ++unsigned long x86_efi_facility; ++ ++/* ++ * Returns 1 if 'facility' is enabled, 0 otherwise. ++ */ ++int efi_enabled(int facility) ++{ ++ return test_bit(facility, &x86_efi_facility) != 0; + } ++EXPORT_SYMBOL(efi_enabled); + + static int __init setup_noefi(char *arg) + { +- efi_enabled = 0; ++ clear_bit(EFI_BOOT, &x86_efi_facility); + return 0; + } + early_param("noefi", setup_noefi); +@@ -425,6 +431,7 @@ void __init efi_reserve_boot_services(vo + + void __init efi_unmap_memmap(void) + { ++ clear_bit(EFI_MEMMAP, &x86_efi_facility); + if (memmap.map) { + early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); + memmap.map = NULL; +@@ -459,7 +466,7 @@ void __init efi_free_boot_services(void) + + static int __init efi_systab_init(void *phys) + { +- if (efi_64bit) { ++ if (efi_enabled(EFI_64BIT)) { + efi_system_table_64_t *systab64; + u64 tmp = 0; + +@@ -551,7 +558,7 @@ static int __init efi_config_init(u64 ta + void *config_tables, *tablep; + int i, sz; + +- if (efi_64bit) ++ if (efi_enabled(EFI_64BIT)) + sz = sizeof(efi_config_table_64_t); + else + sz = sizeof(efi_config_table_32_t); +@@ -571,7 +578,7 @@ static int __init efi_config_init(u64 ta + efi_guid_t guid; + unsigned long table; + +- if (efi_64bit) { ++ if (efi_enabled(EFI_64BIT)) { + u64 table64; + guid = ((efi_config_table_64_t *)tablep)->guid; + table64 = ((efi_config_table_64_t *)tablep)->table; +@@ -683,7 +690,6 @@ void __init efi_init(void) + if (boot_params.efi_info.efi_systab_hi || + boot_params.efi_info.efi_memmap_hi) { + pr_info("Table located above 4GB, disabling EFI.\n"); +- efi_enabled = 0; + return; + } + efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab; +@@ -693,10 +699,10 @@ void __init efi_init(void) + ((__u64)boot_params.efi_info.efi_systab_hi<<32)); + #endif + +- if (efi_systab_init(efi_phys.systab)) { +- efi_enabled = 0; ++ if (efi_systab_init(efi_phys.systab)) + return; +- } ++ ++ set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility); + + /* + * Show what we know for posterity +@@ -714,10 +720,10 @@ void __init efi_init(void) + efi.systab->hdr.revision >> 16, + efi.systab->hdr.revision & 0xffff, vendor); + +- if (efi_config_init(efi.systab->tables, efi.systab->nr_tables)) { +- efi_enabled = 0; ++ if (efi_config_init(efi.systab->tables, efi.systab->nr_tables)) + return; +- } ++ ++ set_bit(EFI_CONFIG_TABLES, &x86_efi_facility); + + /* + * Note: We currently don't support runtime services on an EFI +@@ -726,15 +732,17 @@ void __init efi_init(void) + + if (!efi_is_native()) + pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); +- else if (efi_runtime_init()) { +- efi_enabled = 0; +- return; ++ else { ++ if (efi_runtime_init()) ++ return; ++ set_bit(EFI_RUNTIME_SERVICES, &x86_efi_facility); + } + +- if (efi_memmap_init()) { +- efi_enabled = 0; ++ if (efi_memmap_init()) + return; +- } ++ ++ set_bit(EFI_MEMMAP, &x86_efi_facility); ++ + #ifdef CONFIG_X86_32 + if (efi_is_native()) { + x86_platform.get_wallclock = efi_get_time; +@@ -943,6 +951,9 @@ u64 efi_mem_attributes(unsigned long phy + efi_memory_desc_t *md; + void *p; + ++ if (!efi_enabled(EFI_MEMMAP)) ++ return 0; ++ + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { + md = p; + if ((md->phys_addr <= phys_addr) && +--- a/drivers/acpi/osl.c ++++ b/drivers/acpi/osl.c +@@ -250,7 +250,7 @@ acpi_physical_address __init acpi_os_get + return acpi_rsdp; + #endif + +- if (efi_enabled) { ++ if (efi_enabled(EFI_CONFIG_TABLES)) { + if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) + return efi.acpi20; + else if (efi.acpi != EFI_INVALID_TABLE_ADDR) +--- a/drivers/firmware/dmi_scan.c ++++ b/drivers/firmware/dmi_scan.c +@@ -471,7 +471,7 @@ void __init dmi_scan_machine(void) + char __iomem *p, *q; + int rc; + +- if (efi_enabled) { ++ if (efi_enabled(EFI_CONFIG_TABLES)) { + if (efi.smbios == EFI_INVALID_TABLE_ADDR) + goto error; + +--- a/drivers/firmware/efivars.c ++++ b/drivers/firmware/efivars.c +@@ -1224,7 +1224,7 @@ efivars_init(void) + printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION, + EFIVARS_DATE); + +- if (!efi_enabled) ++ if (!efi_enabled(EFI_RUNTIME_SERVICES)) + return 0; + + /* For now we'll register the efi directory at /sys/firmware/efi */ +@@ -1262,7 +1262,7 @@ err_put: + static void __exit + efivars_exit(void) + { +- if (efi_enabled) { ++ if (efi_enabled(EFI_RUNTIME_SERVICES)) { + unregister_efivars(&__efivars); + kobject_put(efi_kobj); + } +--- a/drivers/firmware/iscsi_ibft_find.c ++++ b/drivers/firmware/iscsi_ibft_find.c +@@ -99,7 +99,7 @@ unsigned long __init find_ibft_region(un + /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will + * only use ACPI for this */ + +- if (!efi_enabled) ++ if (!efi_enabled(EFI_BOOT)) + find_ibft_in_mem(); + + if (ibft_addr) { +--- a/drivers/gpu/drm/radeon/radeon_device.c ++++ b/drivers/gpu/drm/radeon/radeon_device.c +@@ -358,7 +358,8 @@ bool radeon_card_posted(struct radeon_de + { + uint32_t reg; + +- if (efi_enabled && rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) ++ if (efi_enabled(EFI_BOOT) && ++ rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) + return false; + + /* first check CRTCs */ +--- a/drivers/platform/x86/ibm_rtl.c ++++ b/drivers/platform/x86/ibm_rtl.c +@@ -244,7 +244,7 @@ static int __init ibm_rtl_init(void) { + if (force) + pr_warn("module loaded by force\n"); + /* first ensure that we are running on IBM HW */ +- else if (efi_enabled || !dmi_check_system(ibm_rtl_dmi_table)) ++ else if (efi_enabled(EFI_BOOT) || !dmi_check_system(ibm_rtl_dmi_table)) + return -ENODEV; + + /* Get the address for the Extended BIOS Data Area */ +--- a/drivers/scsi/isci/init.c ++++ b/drivers/scsi/isci/init.c +@@ -470,7 +470,7 @@ static int __devinit isci_pci_probe(stru + return -ENOMEM; + pci_set_drvdata(pdev, pci_info); + +- if (efi_enabled) ++ if (efi_enabled(EFI_RUNTIME_SERVICES)) + orom = isci_get_efi_var(pdev); + + if (!orom) +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -539,18 +539,30 @@ extern int __init efi_setup_pcdp_console + #endif + + /* +- * We play games with efi_enabled so that the compiler will, if possible, remove +- * EFI-related code altogether. ++ * We play games with efi_enabled so that the compiler will, if ++ * possible, remove EFI-related code altogether. + */ ++#define EFI_BOOT 0 /* Were we booted from EFI? */ ++#define EFI_SYSTEM_TABLES 1 /* Can we use EFI system tables? */ ++#define EFI_CONFIG_TABLES 2 /* Can we use EFI config tables? */ ++#define EFI_RUNTIME_SERVICES 3 /* Can we use runtime services? */ ++#define EFI_MEMMAP 4 /* Can we use EFI memory map? */ ++#define EFI_64BIT 5 /* Is the firmware 64-bit? */ ++ + #ifdef CONFIG_EFI + # ifdef CONFIG_X86 +- extern int efi_enabled; +- extern bool efi_64bit; ++extern int efi_enabled(int facility); + # else +-# define efi_enabled 1 ++static inline int efi_enabled(int facility) ++{ ++ return 1; ++} + # endif + #else +-# define efi_enabled 0 ++static inline int efi_enabled(int facility) ++{ ++ return 0; ++} + #endif + + /* +--- a/init/main.c ++++ b/init/main.c +@@ -602,7 +602,7 @@ asmlinkage void __init start_kernel(void + pidmap_init(); + anon_vma_init(); + #ifdef CONFIG_X86 +- if (efi_enabled) ++ if (efi_enabled(EFI_RUNTIME_SERVICES)) + efi_enter_virtual_mode(); + #endif + thread_info_cache_init(); +@@ -630,7 +630,7 @@ asmlinkage void __init start_kernel(void + acpi_early_init(); /* before LAPIC and SMP init */ + sfi_init_late(); + +- if (efi_enabled) ++ if (efi_enabled(EFI_RUNTIME_SERVICES)) + efi_free_boot_services(); + + ftrace_init(); diff --git a/queue-3.4/series b/queue-3.4/series index 60ceb9d4c8c..caf2c97d432 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -3,3 +3,4 @@ rtlwifi-fix-scheduling-while-atomic-bug.patch virtio_console-don-t-access-uninitialized-data.patch kernel-resource.c-fix-stack-overflow-in-__reserve_region_with_split.patch bluetooth-fix-handling-of-unexpected-smp-pdus.patch +efi-make-efi_enabled-a-function-to-query-efi-facilities.patch