]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 11 Feb 2013 20:00:56 +0000 (12:00 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 11 Feb 2013 20:00:56 +0000 (12:00 -0800)
added patches:
efi-make-efi_enabled-a-function-to-query-efi-facilities.patch

queue-3.4/efi-make-efi_enabled-a-function-to-query-efi-facilities.patch [new file with mode: 0644]
queue-3.4/series

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 (file)
index 0000000..1e24e92
--- /dev/null
@@ -0,0 +1,464 @@
+From 83e68189745ad931c2afd45d8ee3303929233e7f Mon Sep 17 00:00:00 2001
+From: Matt Fleming <matt.fleming@intel.com>
+Date: Wed, 14 Nov 2012 09:42:35 +0000
+Subject: efi: Make 'efi_enabled' a function to query EFI facilities
+
+From: Matt Fleming <matt.fleming@intel.com>
+
+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 <airlied@linux.ie>
+Cc: Corentin Chary <corentincj@iksaif.net>
+Cc: Matthew Garrett <mjg59@srcf.ucam.org>
+Cc: Dave Jiang <dave.jiang@intel.com>
+Cc: Olof Johansson <olof@lixom.net>
+Cc: Peter Jones <pjones@redhat.com>
+Cc: Colin Ian King <colin.king@canonical.com>
+Cc: Steve Langasek <steve.langasek@canonical.com>
+Cc: Tony Luck <tony.luck@intel.com>
+Cc: Konrad Rzeszutek Wilk <konrad@kernel.org>
+Cc: Rafael J. Wysocki <rjw@sisk.pl>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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();
index 60ceb9d4c8c58bfbf6955e1ac445e22d2450d198..caf2c97d43216c65b62bd3896abbd7f42af2a3e8 100644 (file)
@@ -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