OSDN Git Service

Merge tag 'efi-for-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/mfleming...
authorIngo Molnar <mingo@kernel.org>
Fri, 26 Oct 2012 08:17:38 +0000 (10:17 +0200)
committerIngo Molnar <mingo@kernel.org>
Fri, 26 Oct 2012 08:17:38 +0000 (10:17 +0200)
Pull EFI fixes from Matt Fleming:

 "Fix oops with EFI variables on mixed 32/64-bit firmware/kernels and
  document EFI git repository location on kernel.org."

Conflicts:
arch/x86/include/asm/efi.h

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

diff --combined MAINTAINERS
@@@ -235,7 -235,6 +235,7 @@@ F: drivers/platform/x86/acer-wmi.
  
  ACPI
  M:    Len Brown <lenb@kernel.org>
 +M:    Rafael J. Wysocki <rjw@sisk.pl>
  L:    linux-acpi@vger.kernel.org
  W:    http://www.lesswatts.org/projects/acpi/
  Q:    http://patchwork.kernel.org/project/linux-acpi/list/
@@@ -2802,6 -2801,7 +2802,7 @@@ F:      sound/usb/misc/ua101.
  EXTENSIBLE FIRMWARE INTERFACE (EFI)
  M:    Matt Fleming <matt.fleming@intel.com>
  L:    linux-efi@vger.kernel.org
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
  S:    Maintained
  F:    Documentation/x86/efi-stub.txt
  F:    arch/ia64/kernel/efi.c
@@@ -4373,7 -4373,7 +4374,7 @@@ F:      Documentation/scsi/53c700.tx
  F:    drivers/scsi/53c700*
  
  LED SUBSYSTEM
 -M:    Bryan Wu <bryan.wu@canonical.com>
 +M:    Bryan Wu <cooloney@gmail.com>
  M:    Richard Purdie <rpurdie@rpsys.net>
  L:    linux-leds@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds.git
@@@ -5020,20 -5020,6 +5021,20 @@@ F:    net/ipv6
  F:    include/net/ip*
  F:    arch/x86/net/*
  
 +NETWORKING [IPSEC]
 +M:    Steffen Klassert <steffen.klassert@secunet.com>
 +M:    Herbert Xu <herbert@gondor.apana.org.au>
 +M:    "David S. Miller" <davem@davemloft.net>
 +L:    netdev@vger.kernel.org
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
 +S:    Maintained
 +F:    net/xfrm/
 +F:    net/key/
 +F:    net/ipv4/xfrm*
 +F:    net/ipv6/xfrm*
 +F:    include/uapi/linux/xfrm.h
 +F:    include/net/xfrm.h
 +
  NETWORKING [LABELED] (NetLabel, CIPSO, Labeled IPsec, SECMARK)
  M:    Paul Moore <paul@paul-moore.com>
  L:    netdev@vger.kernel.org
@@@ -7746,13 -7732,6 +7747,13 @@@ W:    http://www.ideasonboard.org/uvc
  S:    Maintained
  F:    drivers/media/usb/uvc/
  
 +USB WEBCAM GADGET
 +M:    Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 +L:    linux-usb@vger.kernel.org
 +S:    Maintained
 +F:    drivers/usb/gadget/*uvc*.c
 +F:    drivers/usb/gadget/webcam.c
 +
  USB WIRELESS RNDIS DRIVER (rndis_wlan)
  M:    Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
  L:    linux-wireless@vger.kernel.org
@@@ -35,7 -35,7 +35,7 @@@ extern unsigned long asmlinkage efi_cal
  #define efi_call_virt6(f, a1, a2, a3, a4, a5, a6)     \
        efi_call_virt(f, a1, a2, a3, a4, a5, a6)
  
 -#define efi_ioremap(addr, size, type)         ioremap_cache(addr, size)
 +#define efi_ioremap(addr, size, type, attr)   ioremap_cache(addr, size)
  
  #else /* !CONFIG_X86_32 */
  
@@@ -89,7 -89,7 +89,7 @@@ extern u64 efi_call6(void *fp, u64 arg1
                  (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6))
  
  extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
 -                               u32 type);
 +                               u32 type, u64 attribute);
  
  #endif /* CONFIG_X86_32 */
  
@@@ -98,7 -98,7 +98,8 @@@ extern void efi_set_executable(efi_memo
  extern int efi_memblock_x86_reserve_range(void);
  extern void efi_call_phys_prelog(void);
  extern void efi_call_phys_epilog(void);
+ extern void efi_unmap_memmap(void);
 +extern void efi_memory_uc(u64 addr, unsigned long size);
  
  #ifndef CONFIG_EFI
  /*
diff --combined arch/x86/kernel/setup.c
@@@ -920,22 -920,8 +920,22 @@@ void __init setup_arch(char **cmdline_p
  
  #ifdef CONFIG_X86_64
        if (max_pfn > max_low_pfn) {
 -              max_pfn_mapped = init_memory_mapping(1UL<<32,
 -                                                   max_pfn<<PAGE_SHIFT);
 +              int i;
 +              unsigned long start, end;
 +              unsigned long start_pfn, end_pfn;
 +
 +              for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn,
 +                                                       NULL) {
 +
 +                      end = PFN_PHYS(end_pfn);
 +                      if (end <= (1UL<<32))
 +                              continue;
 +
 +                      start = PFN_PHYS(start_pfn);
 +                      max_pfn_mapped = init_memory_mapping(
 +                                              max((1UL<<32), start), end);
 +              }
 +
                /* can we preseve max_low_pfn ?*/
                max_low_pfn = max_pfn;
        }
        arch_init_ideal_nops();
  
        register_refined_jiffies(CLOCK_TICK_RATE);
+ #ifdef CONFIG_EFI
+       /* Once setup is done above, disable efi_enabled on mismatched
+        * firmware/kernel archtectures since there is no support for
+        * runtime services.
+        */
+       if (efi_enabled && IS_ENABLED(CONFIG_X86_64) != efi_64bit) {
+               pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n");
+               efi_unmap_memmap();
+               efi_enabled = 0;
+       }
+ #endif
  }
  
  #ifdef CONFIG_X86_32
@@@ -70,11 -70,15 +70,15 @@@ EXPORT_SYMBOL(efi)
  struct efi_memory_map memmap;
  
  bool efi_64bit;
- static bool efi_native;
  
  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;
+ }
  static int __init setup_noefi(char *arg)
  {
        efi_enabled = 0;
@@@ -420,7 -424,7 +424,7 @@@ void __init efi_reserve_boot_services(v
        }
  }
  
static void __init efi_unmap_memmap(void)
+ void __init efi_unmap_memmap(void)
  {
        if (memmap.map) {
                early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
@@@ -432,7 -436,7 +436,7 @@@ void __init efi_free_boot_services(void
  {
        void *p;
  
-       if (!efi_native)
+       if (!efi_is_native())
                return;
  
        for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
@@@ -684,12 -688,10 +688,10 @@@ void __init efi_init(void
                return;
        }
        efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab;
-       efi_native = !efi_64bit;
  #else
        efi_phys.systab = (efi_system_table_t *)
                          (boot_params.efi_info.efi_systab |
                          ((__u64)boot_params.efi_info.efi_systab_hi<<32));
-       efi_native = efi_64bit;
  #endif
  
        if (efi_systab_init(efi_phys.systab)) {
         * that doesn't match the kernel 32/64-bit mode.
         */
  
-       if (!efi_native)
+       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;
        }
  #ifdef CONFIG_X86_32
-       if (efi_native) {
+       if (efi_is_native()) {
                x86_platform.get_wallclock = efi_get_time;
                x86_platform.set_wallclock = efi_set_rtc_mmss;
        }
@@@ -810,16 -812,6 +812,16 @@@ void __iomem *efi_lookup_mapped_addr(u6
        return NULL;
  }
  
 +void efi_memory_uc(u64 addr, unsigned long size)
 +{
 +      unsigned long page_shift = 1UL << EFI_PAGE_SHIFT;
 +      u64 npages;
 +
 +      npages = round_up(size, page_shift) / page_shift;
 +      memrange_efi_to_native(&addr, &npages);
 +      set_memory_uc(addr, npages);
 +}
 +
  /*
   * This function will switch the EFI runtime services to virtual mode.
   * Essentially, look through the EFI memmap and map every region that
@@@ -833,7 -825,7 +835,7 @@@ void __init efi_enter_virtual_mode(void
        efi_memory_desc_t *md, *prev_md = NULL;
        efi_status_t status;
        unsigned long size;
 -      u64 end, systab, addr, npages, end_pfn;
 +      u64 end, systab, end_pfn;
        void *p, *va, *new_memmap = NULL;
        int count = 0;
  
         * non-native EFI
         */
  
-       if (!efi_native) {
+       if (!efi_is_native()) {
                efi_unmap_memmap();
                return;
        }
                end_pfn = PFN_UP(end);
                if (end_pfn <= max_low_pfn_mapped
                    || (end_pfn > (1UL << (32 - PAGE_SHIFT))
 -                      && end_pfn <= max_pfn_mapped))
 +                      && end_pfn <= max_pfn_mapped)) {
                        va = __va(md->phys_addr);
 -              else
 -                      va = efi_ioremap(md->phys_addr, size, md->type);
 +
 +                      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;
  
                        continue;
                }
  
 -              if (!(md->attribute & EFI_MEMORY_WB)) {
 -                      addr = md->virt_addr;
 -                      npages = md->num_pages;
 -                      memrange_efi_to_native(&addr, &npages);
 -                      set_memory_uc(addr, npages);
 -              }
 -
                systab = (u64) (unsigned long) efi_phys.systab;
                if (md->phys_addr <= systab && systab < end) {
                        systab += md->virt_addr - md->phys_addr;