]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
x86, efi: Make "noefi" really disable EFI runtime serivces
authorMatt Fleming <matt.fleming@intel.com>
Wed, 20 Feb 2013 20:36:12 +0000 (20:36 +0000)
committerBen Hutchings <ben@decadent.org.uk>
Wed, 6 Mar 2013 03:24:08 +0000 (03:24 +0000)
commit fb834c7acc5e140cf4f9e86da93a66de8c0514da upstream.

commit 1de63d60cd5b ("efi: Clear EFI_RUNTIME_SERVICES rather than
EFI_BOOT by "noefi" boot parameter") attempted to make "noefi" true to
its documentation and disable EFI runtime services to prevent the
bricking bug described in commit e0094244e41c ("samsung-laptop:
Disable on EFI hardware"). However, it's not possible to clear
EFI_RUNTIME_SERVICES from an early param function because
EFI_RUNTIME_SERVICES is set in efi_init() *after* parse_early_param().

This resulted in "noefi" effectively becoming a no-op and no longer
providing users with a way to disable EFI, which is bad for those
users that have buggy machines.

Reported-by: Walt Nelson Jr <walt0924@gmail.com>
Cc: Satoru Takeuchi <takeuchi_satoru@jp.fujitsu.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Link: http://lkml.kernel.org/r/1361392572-25657-1-git-send-email-matt@console-pimps.org
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
[bwh: Backported to 3.2: efi_runtime_init() is not a separate function,
 so put a whole set of statements in an if (!disable_runtime) block]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
arch/x86/platform/efi/efi.c

index 764e8919386bb1a0a5d65120f610767a06ac4e10..1de542b3299cc4381bf89ba89d9d58eb9728c7e0 100644 (file)
@@ -83,9 +83,10 @@ int efi_enabled(int facility)
 }
 EXPORT_SYMBOL(efi_enabled);
 
+static bool disable_runtime = false;
 static int __init setup_noefi(char *arg)
 {
-       clear_bit(EFI_RUNTIME_SERVICES, &x86_efi_facility);
+       disable_runtime = true;
        return 0;
 }
 early_param("noefi", setup_noefi);
@@ -549,35 +550,37 @@ void __init efi_init(void)
 
        set_bit(EFI_CONFIG_TABLES, &x86_efi_facility);
 
-       /*
-        * Check out the runtime services table. We need to map
-        * the runtime services table so that we can grab the physical
-        * address of several of the EFI runtime functions, needed to
-        * set the firmware into virtual mode.
-        */
-       runtime = early_ioremap((unsigned long)efi.systab->runtime,
-                               sizeof(efi_runtime_services_t));
-       if (runtime != NULL) {
-               /*
-                * We will only need *early* access to the following
-                * two EFI runtime services before set_virtual_address_map
-                * is invoked.
-                */
-               efi_phys.get_time = (efi_get_time_t *)runtime->get_time;
-               efi_phys.set_virtual_address_map =
-                       (efi_set_virtual_address_map_t *)
-                       runtime->set_virtual_address_map;
+       if (!disable_runtime) {
                /*
-                * Make efi_get_time can be called before entering
-                * virtual mode.
+                * Check out the runtime services table. We need to map
+                * the runtime services table so that we can grab the physical
+                * address of several of the EFI runtime functions, needed to
+                * set the firmware into virtual mode.
                 */
-               efi.get_time = phys_efi_get_time;
-
-               set_bit(EFI_RUNTIME_SERVICES, &x86_efi_facility);
-       } else
-               printk(KERN_ERR "Could not map the EFI runtime service "
-                      "table!\n");
-       early_iounmap(runtime, sizeof(efi_runtime_services_t));
+               runtime = early_ioremap((unsigned long)efi.systab->runtime,
+                                       sizeof(efi_runtime_services_t));
+               if (runtime != NULL) {
+                       /*
+                        * We will only need *early* access to the following
+                        * two EFI runtime services before set_virtual_address_map
+                        * is invoked.
+                        */
+                       efi_phys.get_time = (efi_get_time_t *)runtime->get_time;
+                       efi_phys.set_virtual_address_map =
+                               (efi_set_virtual_address_map_t *)
+                               runtime->set_virtual_address_map;
+                       /*
+                        * Make efi_get_time can be called before entering
+                        * virtual mode.
+                        */
+                       efi.get_time = phys_efi_get_time;
+                       
+                       set_bit(EFI_RUNTIME_SERVICES, &x86_efi_facility);
+               } else
+                       printk(KERN_ERR "Could not map the EFI runtime service "
+                              "table!\n");
+               early_iounmap(runtime, sizeof(efi_runtime_services_t));
+       }
 
        /* Map the EFI memory map */
        memmap.map = early_ioremap((unsigned long)memmap.phys_map,