]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge tag 'efi-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi...
authorIngo Molnar <mingo@kernel.org>
Tue, 26 Nov 2013 11:23:04 +0000 (12:23 +0100)
committerIngo Molnar <mingo@kernel.org>
Tue, 26 Nov 2013 11:23:04 +0000 (12:23 +0100)
Pull EFI virtual mapping changes from Matt Fleming:

  * New static EFI runtime services virtual mapping layout which is
    groundwork for kexec support on EFI. (Borislav Petkov)

Signed-off-by: Ingo Molnar <mingo@kernel.org>
1  2 
Documentation/kernel-parameters.txt
arch/x86/include/asm/pgtable_types.h
arch/x86/platform/efi/efi.c

index 50680a59a2ff9a913e449a1d71ced9fab3004fe4,ed43e92b0e7e8e6e84d366ee17bfb3c2099763d0..e06e99303dd3f544dff67b7b657885b749b7ae5a
@@@ -235,61 -235,10 +235,61 @@@ bytes respectively. Such letter suffixe
                        Format: To spoof as Windows 98: ="Microsoft Windows"
  
        acpi_osi=       [HW,ACPI] Modify list of supported OS interface strings
 -                      acpi_osi="string1"      # add string1 -- only one string
 -                      acpi_osi="!string2"     # remove built-in string2
 +                      acpi_osi="string1"      # add string1
 +                      acpi_osi="!string2"     # remove string2
 +                      acpi_osi=!*             # remove all strings
 +                      acpi_osi=!              # disable all built-in OS vendor
 +                                                strings
                        acpi_osi=               # disable all strings
  
 +                      'acpi_osi=!' can be used in combination with single or
 +                      multiple 'acpi_osi="string1"' to support specific OS
 +                      vendor string(s).  Note that such command can only
 +                      affect the default state of the OS vendor strings, thus
 +                      it cannot affect the default state of the feature group
 +                      strings and the current state of the OS vendor strings,
 +                      specifying it multiple times through kernel command line
 +                      is meaningless.  This command is useful when one do not
 +                      care about the state of the feature group strings which
 +                      should be controlled by the OSPM.
 +                      Examples:
 +                        1. 'acpi_osi=! acpi_osi="Windows 2000"' is equivalent
 +                           to 'acpi_osi="Windows 2000" acpi_osi=!', they all
 +                           can make '_OSI("Windows 2000")' TRUE.
 +
 +                      'acpi_osi=' cannot be used in combination with other
 +                      'acpi_osi=' command lines, the _OSI method will not
 +                      exist in the ACPI namespace.  NOTE that such command can
 +                      only affect the _OSI support state, thus specifying it
 +                      multiple times through kernel command line is also
 +                      meaningless.
 +                      Examples:
 +                        1. 'acpi_osi=' can make 'CondRefOf(_OSI, Local1)'
 +                           FALSE.
 +
 +                      'acpi_osi=!*' can be used in combination with single or
 +                      multiple 'acpi_osi="string1"' to support specific
 +                      string(s).  Note that such command can affect the
 +                      current state of both the OS vendor strings and the
 +                      feature group strings, thus specifying it multiple times
 +                      through kernel command line is meaningful.  But it may
 +                      still not able to affect the final state of a string if
 +                      there are quirks related to this string.  This command
 +                      is useful when one want to control the state of the
 +                      feature group strings to debug BIOS issues related to
 +                      the OSPM features.
 +                      Examples:
 +                        1. 'acpi_osi="Module Device" acpi_osi=!*' can make
 +                           '_OSI("Module Device")' FALSE.
 +                        2. 'acpi_osi=!* acpi_osi="Module Device"' can make
 +                           '_OSI("Module Device")' TRUE.
 +                        3. 'acpi_osi=! acpi_osi=!* acpi_osi="Windows 2000"' is
 +                           equivalent to
 +                           'acpi_osi=!* acpi_osi=! acpi_osi="Windows 2000"'
 +                           and
 +                           'acpi_osi=!* acpi_osi="Windows 2000" acpi_osi=!',
 +                           they all will make '_OSI("Windows 2000")' TRUE.
 +
        acpi_pm_good    [X86]
                        Override the pmtimer bug detection: force the kernel
                        to assume that this machine's pmtimer latches its value
                        Format: <io>,<irq>,<mode>
                        See header of drivers/net/hamradio/baycom_ser_hdx.c.
  
 +      blkdevparts=    Manual partition parsing of block device(s) for
 +                      embedded devices based on command line input.
 +                      See Documentation/block/cmdline-partition.txt
 +
        boot_delay=     Milliseconds to delay each printk during boot.
                        Values larger than 10 seconds (10000) are changed to
                        no delay (0).
        edd=            [EDD]
                        Format: {"off" | "on" | "skip[mbr]"}
  
+       efi=            [EFI]
+                       Format: { "old_map" }
+                       old_map [X86-64]: switch to the old ioremap-based EFI
+                       runtime services mapping. 32-bit still uses this one by
+                       default.
        efi_no_storage_paranoia [EFI; X86]
                        Using this parameter you can use more than 50% of
                        your efi variable storage. Use this parameter only if
                                VIA, nVidia)
                        verbose: show contents of HPET registers during setup
  
 +      hpet_mmap=      [X86, HPET_MMAP] Allow userspace to mmap HPET
 +                      registers.  Default set by CONFIG_HPET_MMAP_DEFAULT.
 +
        hugepages=      [HW,X86-32,IA-64] HugeTLB pages to allocate at boot.
        hugepagesz=     [HW,IA-64,PPC,X86-64] The size of the HugeTLB pages.
                        On x86-64 and powerpc, this option can be specified
                        owned by uid=0.
  
        ima_hash=       [IMA]
 -                      Format: { "sha1" | "md5" }
 +                      Format: { md5 | sha1 | rmd160 | sha256 | sha384
 +                                 | sha512 | ... }
                        default: "sha1"
  
 +                      The list of supported hash algorithms is defined
 +                      in crypto/hash_info.h.
 +
        ima_tcb         [IMA]
                        Load a policy which meets the needs of the Trusted
                        Computing Base.  This means IMA will measure all
                        programs exec'd, files mmap'd for exec, and all files
                        opened for read by uid=0.
  
 +      ima_template=   [IMA]
 +                      Select one of defined IMA measurements template formats.
 +                      Formats: { "ima" | "ima-ng" }
 +                      Default: "ima-ng"
 +
        init=           [KNL]
                        Format: <full_path>
                        Run specified binary instead of /sbin/init as init
                        pages. In the event, a node is too small to have both
                        kernelcore and Movable pages, kernelcore pages will
                        take priority and other nodes will have a larger number
 -                      of kernelcore pages.  The Movable zone is used for the
 +                      of Movable pages.  The Movable zone is used for the
                        allocation of pages that may be reclaimed or moved
                        by the page migration subsystem.  This means that
                        HugeTLB pages may not be allocated from this zone.
                        that the amount of memory usable for all allocations
                        is not too small.
  
 +      movable_node    [KNL,X86] Boot-time switch to enable the effects
 +                      of CONFIG_MOVABLE_NODE=y. See mm/Kconfig for details.
 +
        MTD_Partition=  [MTD]
                        Format: <name>,<region-number>,<size>,<offset>
  
                        will be sent.
                        The default is to send the implementation identification
                        information.
 +      
 +      nfs.recover_lost_locks =
 +                      [NFSv4] Attempt to recover locks that were lost due
 +                      to a lease timeout on the server. Please note that
 +                      doing this risks data corruption, since there are
 +                      no guarantees that the file will remain unchanged
 +                      after the locks are lost.
 +                      If you want to enable the kernel legacy behaviour of
 +                      attempting to recover these locks, then set this
 +                      parameter to '1'.
 +                      The default parameter value of '0' causes the kernel
 +                      not to attempt recovery of lost locks.
  
        nfsd.nfs4_disable_idmapping=
                        [NFSv4] When set to the default of '1', the NFSv4
        ramdisk_size=   [RAM] Sizes of RAM disks in kilobytes
                        See Documentation/blockdev/ramdisk.txt.
  
 -      rcu_nocbs=      [KNL,BOOT]
 +      rcu_nocbs=      [KNL]
                        In kernels built with CONFIG_RCU_NOCB_CPU=y, set
                        the specified list of CPUs to be no-callback CPUs.
                        Invocation of these CPUs' RCU callbacks will
                        real-time workloads.  It can also improve energy
                        efficiency for asymmetric multiprocessors.
  
 -      rcu_nocb_poll   [KNL,BOOT]
 +      rcu_nocb_poll   [KNL]
                        Rather than requiring that offloaded CPUs
                        (specified by rcu_nocbs= above) explicitly
                        awaken the corresponding "rcuoN" kthreads,
                        energy efficiency by requiring that the kthreads
                        periodically wake up to do the polling.
  
 -      rcutree.blimit= [KNL,BOOT]
 +      rcutree.blimit= [KNL]
                        Set maximum number of finished RCU callbacks to process
                        in one batch.
  
 -      rcutree.fanout_leaf=    [KNL,BOOT]
 +      rcutree.rcu_fanout_leaf= [KNL]
                        Increase the number of CPUs assigned to each
                        leaf rcu_node structure.  Useful for very large
                        systems.
  
 -      rcutree.jiffies_till_first_fqs= [KNL,BOOT]
 +      rcutree.jiffies_till_first_fqs= [KNL]
                        Set delay from grace-period initialization to
                        first attempt to force quiescent states.
                        Units are jiffies, minimum value is zero,
                        and maximum value is HZ.
  
 -      rcutree.jiffies_till_next_fqs= [KNL,BOOT]
 +      rcutree.jiffies_till_next_fqs= [KNL]
                        Set delay between subsequent attempts to force
                        quiescent states.  Units are jiffies, minimum
                        value is one, and maximum value is HZ.
  
 -      rcutree.qhimark=        [KNL,BOOT]
 +      rcutree.qhimark= [KNL]
                        Set threshold of queued
                        RCU callbacks over which batch limiting is disabled.
  
 -      rcutree.qlowmark=       [KNL,BOOT]
 +      rcutree.qlowmark= [KNL]
                        Set threshold of queued RCU callbacks below which
                        batch limiting is re-enabled.
  
 -      rcutree.rcu_cpu_stall_suppress= [KNL,BOOT]
 -                      Suppress RCU CPU stall warning messages.
 -
 -      rcutree.rcu_cpu_stall_timeout= [KNL,BOOT]
 -                      Set timeout for RCU CPU stall warning messages.
 -
 -      rcutree.rcu_idle_gp_delay=      [KNL,BOOT]
 +      rcutree.rcu_idle_gp_delay= [KNL]
                        Set wakeup interval for idle CPUs that have
                        RCU callbacks (RCU_FAST_NO_HZ=y).
  
 -      rcutree.rcu_idle_lazy_gp_delay= [KNL,BOOT]
 +      rcutree.rcu_idle_lazy_gp_delay= [KNL]
                        Set wakeup interval for idle CPUs that have
                        only "lazy" RCU callbacks (RCU_FAST_NO_HZ=y).
                        Lazy RCU callbacks are those which RCU can
                        prove do nothing more than free memory.
  
 -      rcutorture.fqs_duration= [KNL,BOOT]
 +      rcutorture.fqs_duration= [KNL]
                        Set duration of force_quiescent_state bursts.
  
 -      rcutorture.fqs_holdoff= [KNL,BOOT]
 +      rcutorture.fqs_holdoff= [KNL]
                        Set holdoff time within force_quiescent_state bursts.
  
 -      rcutorture.fqs_stutter= [KNL,BOOT]
 +      rcutorture.fqs_stutter= [KNL]
                        Set wait time between force_quiescent_state bursts.
  
 -      rcutorture.irqreader= [KNL,BOOT]
 -                      Test RCU readers from irq handlers.
 +      rcutorture.gp_exp= [KNL]
 +                      Use expedited update-side primitives.
 +
 +      rcutorture.gp_normal= [KNL]
 +                      Use normal (non-expedited) update-side primitives.
 +                      If both gp_exp and gp_normal are set, do both.
 +                      If neither gp_exp nor gp_normal are set, still
 +                      do both.
  
 -      rcutorture.n_barrier_cbs= [KNL,BOOT]
 +      rcutorture.n_barrier_cbs= [KNL]
                        Set callbacks/threads for rcu_barrier() testing.
  
 -      rcutorture.nfakewriters= [KNL,BOOT]
 +      rcutorture.nfakewriters= [KNL]
                        Set number of concurrent RCU writers.  These just
                        stress RCU, they don't participate in the actual
                        test, hence the "fake".
  
 -      rcutorture.nreaders= [KNL,BOOT]
 +      rcutorture.nreaders= [KNL]
                        Set number of RCU readers.
  
 -      rcutorture.onoff_holdoff= [KNL,BOOT]
 +      rcutorture.object_debug= [KNL]
 +                      Enable debug-object double-call_rcu() testing.
 +
 +      rcutorture.onoff_holdoff= [KNL]
                        Set time (s) after boot for CPU-hotplug testing.
  
 -      rcutorture.onoff_interval= [KNL,BOOT]
 +      rcutorture.onoff_interval= [KNL]
                        Set time (s) between CPU-hotplug operations, or
                        zero to disable CPU-hotplug testing.
  
 -      rcutorture.shuffle_interval= [KNL,BOOT]
 +      rcutorture.rcutorture_runnable= [BOOT]
 +                      Start rcutorture running at boot time.
 +
 +      rcutorture.shuffle_interval= [KNL]
                        Set task-shuffle interval (s).  Shuffling tasks
                        allows some CPUs to go into dyntick-idle mode
                        during the rcutorture test.
  
 -      rcutorture.shutdown_secs= [KNL,BOOT]
 +      rcutorture.shutdown_secs= [KNL]
                        Set time (s) after boot system shutdown.  This
                        is useful for hands-off automated testing.
  
 -      rcutorture.stall_cpu= [KNL,BOOT]
 +      rcutorture.stall_cpu= [KNL]
                        Duration of CPU stall (s) to test RCU CPU stall
                        warnings, zero to disable.
  
 -      rcutorture.stall_cpu_holdoff= [KNL,BOOT]
 +      rcutorture.stall_cpu_holdoff= [KNL]
                        Time to wait (s) after boot before inducing stall.
  
 -      rcutorture.stat_interval= [KNL,BOOT]
 +      rcutorture.stat_interval= [KNL]
                        Time (s) between statistics printk()s.
  
 -      rcutorture.stutter= [KNL,BOOT]
 +      rcutorture.stutter= [KNL]
                        Time (s) to stutter testing, for example, specifying
                        five seconds causes the test to run for five seconds,
                        wait for five seconds, and so on.  This tests RCU's
                        ability to transition abruptly to and from idle.
  
 -      rcutorture.test_boost= [KNL,BOOT]
 +      rcutorture.test_boost= [KNL]
                        Test RCU priority boosting?  0=no, 1=maybe, 2=yes.
                        "Maybe" means test if the RCU implementation
                        under test support RCU priority boosting.
  
 -      rcutorture.test_boost_duration= [KNL,BOOT]
 +      rcutorture.test_boost_duration= [KNL]
                        Duration (s) of each individual boost test.
  
 -      rcutorture.test_boost_interval= [KNL,BOOT]
 +      rcutorture.test_boost_interval= [KNL]
                        Interval (s) between each boost test.
  
 -      rcutorture.test_no_idle_hz= [KNL,BOOT]
 +      rcutorture.test_no_idle_hz= [KNL]
                        Test RCU's dyntick-idle handling.  See also the
                        rcutorture.shuffle_interval parameter.
  
 -      rcutorture.torture_type= [KNL,BOOT]
 +      rcutorture.torture_type= [KNL]
                        Specify the RCU implementation to test.
  
 -      rcutorture.verbose= [KNL,BOOT]
 +      rcutorture.verbose= [KNL]
                        Enable additional printk() statements.
  
 +      rcupdate.rcu_expedited= [KNL]
 +                      Use expedited grace-period primitives, for
 +                      example, synchronize_rcu_expedited() instead
 +                      of synchronize_rcu().  This reduces latency,
 +                      but can increase CPU utilization, degrade
 +                      real-time latency, and degrade energy efficiency.
 +
 +      rcupdate.rcu_cpu_stall_suppress= [KNL]
 +                      Suppress RCU CPU stall warning messages.
 +
 +      rcupdate.rcu_cpu_stall_timeout= [KNL]
 +                      Set timeout for RCU CPU stall warning messages.
 +
        rdinit=         [KNL]
                        Format: <full_path>
                        Run specified binary instead of /init from the ramdisk,
                                    them quite hard to use for exploits but
                                    might break your system.
  
 +      vt.color=       [VT] Default text color.
 +                      Format: 0xYX, X = foreground, Y = background.
 +                      Default: 0x07 = light gray on black.
 +
        vt.cur_default= [VT] Default cursor shape.
                        Format: 0xCCBBAA, where AA, BB, and CC are the same as
                        the parameters of the <Esc>[?A;B;Cc escape sequence;
                        overridden by individual drivers. 0 will hide
                        cursors, 1 will display them.
  
 +      vt.italic=      [VT] Default color for italic text; 0-15.
 +                      Default: 2 = green.
 +
 +      vt.underline=   [VT] Default color for underlined text; 0-15.
 +                      Default: 3 = cyan.
 +
        watchdog timers [HW,WDT] For information on watchdog timers,
                        see Documentation/watchdog/watchdog-parameters.txt
                        or other driver-specific files in the
                        default x2apic cluster mode on platforms
                        supporting x2apic.
  
 -      x86_mrst_timer= [X86-32,APBT]
 -                      Choose timer option for x86 Moorestown MID platform.
 +      x86_intel_mid_timer= [X86-32,APBT]
 +                      Choose timer option for x86 Intel MID platform.
                        Two valid options are apbt timer only and lapic timer
                        plus one apbt timer for broadcast timer.
 -                      x86_mrst_timer=apbt_only | lapic_and_apbt
 +                      x86_intel_mid_timer=apbt_only | lapic_and_apbt
  
        xen_emul_unplug=                [HW,X86,XEN]
                        Unplug Xen emulated devices
                                the unplug protocol
                        never -- do not unplug even if version check succeeds
  
 +      xen_nopvspin    [X86,XEN]
 +                      Disables the ticketlock slowpath using Xen PV
 +                      optimizations.
 +
        xirc2ps_cs=     [NET,PCMCIA]
                        Format:
                        <irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]]
index 0ecac257fb26cffd2bb9a6ece7b7a5976eca3c84,028e28b6fc2c4d598f81887f75f7793d9805b38e..a83aa44bb1fb831cac7cda82a590c05ea0e47235
@@@ -75,9 -75,6 +75,9 @@@
   * with swap entry format. On x86 bits 6 and 7 are *not* involved
   * into swap entry computation, but bit 6 is used for nonlinear
   * file mapping, so we borrow bit 7 for soft dirty tracking.
 + *
 + * Please note that this bit must be treated as swap dirty page
 + * mark if and only if the PTE has present bit clear!
   */
  #ifdef CONFIG_MEM_SOFT_DIRTY
  #define _PAGE_SWP_SOFT_DIRTY  _PAGE_PSE
@@@ -382,7 -379,8 +382,8 @@@ static inline void update_page_count(in
   */
  extern pte_t *lookup_address(unsigned long address, unsigned int *level);
  extern phys_addr_t slow_virt_to_phys(void *__address);
+ extern int kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,
+                                  unsigned numpages, unsigned long page_flags);
  #endif        /* !__ASSEMBLY__ */
  
  #endif /* _ASM_X86_PGTABLE_DEFS_H */
index 92c02344a060f2dacc7997185d6fd6bc04ed225e,3fac4dee492fd6f3fa88ea9c1df4197665570537..f8ec4dafc74e5e94011c3f092f17f4c1b3f40109
@@@ -12,6 -12,8 +12,8 @@@
   *    Bibo Mao <bibo.mao@intel.com>
   *    Chandramouli Narayanan <mouli@linux.intel.com>
   *    Huang Ying <ying.huang@intel.com>
+  * Copyright (C) 2013 SuSE Labs
+  *    Borislav Petkov <bp@suse.de> - runtime services VA mapping
   *
   * Copied from efi_32.c to eliminate the duplicated code between EFI
   * 32/64 support code. --ying 2007-10-26
@@@ -51,7 -53,7 +53,7 @@@
  #include <asm/x86_init.h>
  #include <asm/rtc.h>
  
- #define EFI_DEBUG     1
+ #define EFI_DEBUG
  
  #define EFI_MIN_RESERVE 5120
  
@@@ -398,9 -400,9 +400,9 @@@ int __init efi_memblock_x86_reserve_ran
        return 0;
  }
  
- #if EFI_DEBUG
  static void __init print_efi_memmap(void)
  {
+ #ifdef EFI_DEBUG
        efi_memory_desc_t *md;
        void *p;
        int i;
                        md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
                        (md->num_pages >> (20 - EFI_PAGE_SHIFT)));
        }
- }
  #endif  /*  EFI_DEBUG  */
+ }
  
  void __init efi_reserve_boot_services(void)
  {
@@@ -696,10 -698,7 +698,7 @@@ void __init efi_init(void
                x86_platform.set_wallclock = efi_set_rtc_mmss;
        }
  #endif
- #if EFI_DEBUG
        print_efi_memmap();
- #endif
  }
  
  void __init efi_late_init(void)
@@@ -748,21 -747,56 +747,56 @@@ void efi_memory_uc(u64 addr, unsigned l
        set_memory_uc(addr, npages);
  }
  
+ void __init old_map_region(efi_memory_desc_t *md)
+ {
+       u64 start_pfn, end_pfn, end;
+       unsigned long size;
+       void *va;
+       start_pfn = PFN_DOWN(md->phys_addr);
+       size      = md->num_pages << PAGE_SHIFT;
+       end       = md->phys_addr + size;
+       end_pfn   = PFN_UP(end);
+       if (pfn_range_is_mapped(start_pfn, end_pfn)) {
+               va = __va(md->phys_addr);
+               if (!(md->attribute & EFI_MEMORY_WB))
+                       efi_memory_uc((u64)(unsigned long)va, size);
+       } else
+               va = efi_ioremap(md->phys_addr, size,
+                                md->type, md->attribute);
+       md->virt_addr = (u64) (unsigned long) va;
+       if (!va)
+               pr_err("ioremap of 0x%llX failed!\n",
+                      (unsigned long long)md->phys_addr);
+ }
  /*
   * This function will switch the EFI runtime services to virtual mode.
-  * Essentially, look through the EFI memmap and map every region that
-  * has the runtime attribute bit set in its memory descriptor and update
-  * that memory descriptor with the virtual address obtained from ioremap().
-  * This enables the runtime services to be called without having to
+  * Essentially, we look through the EFI memmap and map every region that
+  * has the runtime attribute bit set in its memory descriptor into the
+  * ->trampoline_pgd page table using a top-down VA allocation scheme.
+  *
+  * The old method which used to update that memory descriptor with the
+  * virtual address obtained from ioremap() is still supported when the
+  * kernel is booted with efi=old_map on its command line. Same old
+  * method enabled the runtime services to be called without having to
   * thunk back into physical mode for every invocation.
+  *
+  * The new method does a pagetable switch in a preemption-safe manner
+  * so that we're in a different address space when calling a runtime
+  * function. For function arguments passing we do copy the PGDs of the
+  * kernel page table into ->trampoline_pgd prior to each call.
   */
  void __init efi_enter_virtual_mode(void)
  {
        efi_memory_desc_t *md, *prev_md = NULL;
-       efi_status_t status;
+       void *p, *new_memmap = NULL;
        unsigned long size;
-       u64 end, systab, start_pfn, end_pfn;
-       void *p, *va, *new_memmap = NULL;
+       efi_status_t status;
+       u64 end, systab;
        int count = 0;
  
        efi.systab = NULL;
         * We don't do virtual mode, since we don't do runtime services, on
         * non-native EFI
         */
        if (!efi_is_native()) {
                efi_unmap_memmap();
                return;
                        continue;
                }
                prev_md = md;
        }
  
        for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
                md = p;
 -              if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
 -                  md->type != EFI_BOOT_SERVICES_CODE &&
 -                  md->type != EFI_BOOT_SERVICES_DATA)
 -                      continue;
 +              if (!(md->attribute & EFI_MEMORY_RUNTIME)) {
 +#ifdef CONFIG_X86_64
 +                      if (md->type != EFI_BOOT_SERVICES_CODE &&
 +                          md->type != EFI_BOOT_SERVICES_DATA)
 +#endif
 +                              continue;
 +              }
  
+               efi_map_region(md);
                size = md->num_pages << EFI_PAGE_SHIFT;
                end = md->phys_addr + size;
  
-               start_pfn = PFN_DOWN(md->phys_addr);
-               end_pfn = PFN_UP(end);
-               if (pfn_range_is_mapped(start_pfn, end_pfn)) {
-                       va = __va(md->phys_addr);
-                       if (!(md->attribute & EFI_MEMORY_WB))
-                               efi_memory_uc((u64)(unsigned long)va, size);
-               } else
-                       va = efi_ioremap(md->phys_addr, size,
-                                        md->type, md->attribute);
-               md->virt_addr = (u64) (unsigned long) va;
-               if (!va) {
-                       pr_err("ioremap of 0x%llX failed!\n",
-                              (unsigned long long)md->phys_addr);
-                       continue;
-               }
                systab = (u64) (unsigned long) efi_phys.systab;
                if (md->phys_addr <= systab && systab < end) {
                        systab += md->virt_addr - md->phys_addr;
                        efi.systab = (efi_system_table_t *) (unsigned long) systab;
                }
                new_memmap = krealloc(new_memmap,
                                      (count + 1) * memmap.desc_size,
                                      GFP_KERNEL);
+               if (!new_memmap)
+                       goto err_out;
                memcpy(new_memmap + (count * memmap.desc_size), md,
                       memmap.desc_size);
                count++;
  
        BUG_ON(!efi.systab);
  
+       efi_setup_page_tables();
+       efi_sync_low_kernel_mappings();
        status = phys_efi_set_virtual_address_map(
                memmap.desc_size * count,
                memmap.desc_size,
        efi.query_variable_info = virt_efi_query_variable_info;
        efi.update_capsule = virt_efi_update_capsule;
        efi.query_capsule_caps = virt_efi_query_capsule_caps;
-       if (__supported_pte_mask & _PAGE_NX)
+       if (efi_enabled(EFI_OLD_MEMMAP) && (__supported_pte_mask & _PAGE_NX))
                runtime_code_page_mkexec();
  
        kfree(new_memmap);
                         EFI_VARIABLE_BOOTSERVICE_ACCESS |
                         EFI_VARIABLE_RUNTIME_ACCESS,
                         0, NULL);
+       return;
+  err_out:
+       pr_err("Error reallocating memory, EFI runtime non-functional!\n");
  }
  
  /*
@@@ -1013,3 -1041,15 +1044,15 @@@ efi_status_t efi_query_variable_store(u
        return EFI_SUCCESS;
  }
  EXPORT_SYMBOL_GPL(efi_query_variable_store);
+ static int __init parse_efi_cmdline(char *str)
+ {
+       if (*str == '=')
+               str++;
+       if (!strncmp(str, "old_map", 7))
+               set_bit(EFI_OLD_MEMMAP, &x86_efi_facility);
+       return 0;
+ }
+ early_param("efi", parse_efi_cmdline);