Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 21 Feb 2015 18:41:29 +0000 (10:41 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 21 Feb 2015 18:41:29 +0000 (10:41 -0800)
Pull misc x86 fixes from Ingo Molnar:
 "This contains:

   - EFI fixes
   - a boot printout fix
   - ASLR/kASLR fixes
   - intel microcode driver fixes
   - other misc fixes

  Most of the linecount comes from an EFI revert"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/mm/ASLR: Avoid PAGE_SIZE redefinition for UML subarch
  x86/microcode/intel: Handle truncated microcode images more robustly
  x86/microcode/intel: Guard against stack overflow in the loader
  x86, mm/ASLR: Fix stack randomization on 64-bit systems
  x86/mm/init: Fix incorrect page size in init_memory_mapping() printks
  x86/mm/ASLR: Propagate base load address calculation
  Documentation/x86: Fix path in zero-page.txt
  x86/apic: Fix the devicetree build in certain configs
  Revert "efi/libstub: Call get_memory_map() to obtain map and desc sizes"
  x86/efi: Avoid triple faults during EFI mixed mode calls

1  2 
arch/x86/boot/compressed/Makefile
arch/x86/boot/compressed/misc.h
arch/x86/kernel/module.c
arch/x86/kernel/setup.c
arch/x86/mm/init.c
drivers/firmware/efi/libstub/efi-stub-helper.c

index 843feb3eb20bd781bf8df6cd2b004450eb2d1c5e,8bd44e8ee6e2a52b20b3cc254e394d19b8cbd451..0a291cdfaf77100117baf53b2e3af75a43a8af4c
@@@ -16,8 -16,6 +16,8 @@@
  #     (see scripts/Makefile.lib size_append)
  #     compressed vmlinux.bin.all + u32 size of vmlinux.bin.all
  
 +KASAN_SANITIZE := n
 +
  targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
        vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4
  
@@@ -51,6 -49,7 +51,7 @@@ $(obj)/eboot.o: KBUILD_CFLAGS += -fshor
  
  vmlinux-objs-$(CONFIG_EFI_STUB) += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o \
        $(objtree)/drivers/firmware/efi/libstub/lib.a
+ vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_thunk_$(BITS).o
  
  $(obj)/vmlinux: $(vmlinux-objs-y) FORCE
        $(call if_changed,ld)
index 04477d68403f1fe6197d82276033ce27338c1bac,6d67307430249d609bd60efcca28b13aa9ccbb92..ee3576b2666b8139eedf25077ce769da10712c11
@@@ -7,7 -7,6 +7,7 @@@
   * we just keep it from happening
   */
  #undef CONFIG_PARAVIRT
 +#undef CONFIG_KASAN
  #ifdef CONFIG_X86_32
  #define _ASM_X86_DESC_H 1
  #endif
@@@ -57,7 -56,8 +57,8 @@@ int cmdline_find_option_bool(const cha
  
  #if CONFIG_RANDOMIZE_BASE
  /* aslr.c */
- unsigned char *choose_kernel_location(unsigned char *input,
+ unsigned char *choose_kernel_location(struct boot_params *params,
+                                     unsigned char *input,
                                      unsigned long input_size,
                                      unsigned char *output,
                                      unsigned long output_size);
@@@ -65,7 -65,8 +66,8 @@@
  bool has_cpuflag(int flag);
  #else
  static inline
- unsigned char *choose_kernel_location(unsigned char *input,
+ unsigned char *choose_kernel_location(struct boot_params *params,
+                                     unsigned char *input,
                                      unsigned long input_size,
                                      unsigned char *output,
                                      unsigned long output_size)
diff --combined arch/x86/kernel/module.c
index d1ac80b72c72184a0b999c2b299b5e265d26de7a,ef00116e8270ada51254765ca5a546fb8ca35aae..9bbb9b35c144a4f721ed4e7dcfc07aee6abdc2cb
@@@ -24,7 -24,6 +24,7 @@@
  #include <linux/fs.h>
  #include <linux/string.h>
  #include <linux/kernel.h>
 +#include <linux/kasan.h>
  #include <linux/bug.h>
  #include <linux/mm.h>
  #include <linux/gfp.h>
@@@ -47,21 -46,13 +47,13 @@@ do {                                                       
  
  #ifdef CONFIG_RANDOMIZE_BASE
  static unsigned long module_load_offset;
- static int randomize_modules = 1;
  
  /* Mutex protects the module_load_offset. */
  static DEFINE_MUTEX(module_kaslr_mutex);
  
- static int __init parse_nokaslr(char *p)
- {
-       randomize_modules = 0;
-       return 0;
- }
- early_param("nokaslr", parse_nokaslr);
  static unsigned long int get_module_load_offset(void)
  {
-       if (randomize_modules) {
+       if (kaslr_enabled) {
                mutex_lock(&module_kaslr_mutex);
                /*
                 * Calculate the module_load_offset the first time this
@@@ -84,22 -75,13 +76,22 @@@ static unsigned long int get_module_loa
  
  void *module_alloc(unsigned long size)
  {
 +      void *p;
 +
        if (PAGE_ALIGN(size) > MODULES_LEN)
                return NULL;
 -      return __vmalloc_node_range(size, 1,
 +
 +      p = __vmalloc_node_range(size, MODULE_ALIGN,
                                    MODULES_VADDR + get_module_load_offset(),
                                    MODULES_END, GFP_KERNEL | __GFP_HIGHMEM,
 -                                  PAGE_KERNEL_EXEC, NUMA_NO_NODE,
 +                                  PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
                                    __builtin_return_address(0));
 +      if (p && (kasan_module_alloc(p, size) < 0)) {
 +              vfree(p);
 +              return NULL;
 +      }
 +
 +      return p;
  }
  
  #ifdef CONFIG_X86_32
diff --combined arch/x86/kernel/setup.c
index 0a2421cca01fad095bbb7caa8e7c779d910d751b,0d8071d7addbee19d956fcda2d929d2d16f09746..98dc9317286e1e0fad25f3d10efaa3134a9134c0
@@@ -89,7 -89,6 +89,7 @@@
  #include <asm/cacheflush.h>
  #include <asm/processor.h>
  #include <asm/bugs.h>
 +#include <asm/kasan.h>
  
  #include <asm/vsyscall.h>
  #include <asm/cpu.h>
  unsigned long max_low_pfn_mapped;
  unsigned long max_pfn_mapped;
  
+ bool __read_mostly kaslr_enabled = false;
  #ifdef CONFIG_DMI
  RESERVE_BRK(dmi_alloc, 65536);
  #endif
@@@ -425,6 -426,11 +427,11 @@@ static void __init reserve_initrd(void
  }
  #endif /* CONFIG_BLK_DEV_INITRD */
  
+ static void __init parse_kaslr_setup(u64 pa_data, u32 data_len)
+ {
+       kaslr_enabled = (bool)(pa_data + sizeof(struct setup_data));
+ }
  static void __init parse_setup_data(void)
  {
        struct setup_data *data;
                case SETUP_EFI:
                        parse_efi_setup(pa_data, data_len);
                        break;
+               case SETUP_KASLR:
+                       parse_kaslr_setup(pa_data, data_len);
+                       break;
                default:
                        break;
                }
@@@ -832,10 -841,14 +842,14 @@@ static void __init trim_low_memory_rang
  static int
  dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p)
  {
-       pr_emerg("Kernel Offset: 0x%lx from 0x%lx "
-                "(relocation range: 0x%lx-0x%lx)\n",
-                (unsigned long)&_text - __START_KERNEL, __START_KERNEL,
-                __START_KERNEL_map, MODULES_VADDR-1);
+       if (kaslr_enabled)
+               pr_emerg("Kernel Offset: 0x%lx from 0x%lx (relocation range: 0x%lx-0x%lx)\n",
+                        (unsigned long)&_text - __START_KERNEL,
+                        __START_KERNEL,
+                        __START_KERNEL_map,
+                        MODULES_VADDR-1);
+       else
+               pr_emerg("Kernel Offset: disabled\n");
  
        return 0;
  }
@@@ -1175,11 -1188,9 +1189,11 @@@ void __init setup_arch(char **cmdline_p
  
        x86_init.paging.pagetable_init();
  
 +      kasan_init();
 +
        if (boot_cpu_data.cpuid_level >= 0) {
                /* A CPU has %cr4 if and only if it has CPUID */
 -              mmu_cr4_features = read_cr4();
 +              mmu_cr4_features = __read_cr4();
                if (trampoline_cr4_features)
                        *trampoline_cr4_features = mmu_cr4_features;
        }
diff --combined arch/x86/mm/init.c
index 553c094b9cd7984b7334a95122931a93249f1ddf,7ff24240d863137ad3c07c9f3ce6e1f86854c276..a110efca6d068f7d881f8c1d955d8a6906457f64
@@@ -173,11 -173,11 +173,11 @@@ static void __init probe_page_size_mask
  
        /* Enable PSE if available */
        if (cpu_has_pse)
 -              set_in_cr4(X86_CR4_PSE);
 +              cr4_set_bits_and_update_boot(X86_CR4_PSE);
  
        /* Enable PGE if available */
        if (cpu_has_pge) {
 -              set_in_cr4(X86_CR4_PGE);
 +              cr4_set_bits_and_update_boot(X86_CR4_PGE);
                __supported_pte_mask |= _PAGE_GLOBAL;
        }
  }
@@@ -238,6 -238,31 +238,31 @@@ static void __init_refok adjust_range_p
        }
  }
  
+ static const char *page_size_string(struct map_range *mr)
+ {
+       static const char str_1g[] = "1G";
+       static const char str_2m[] = "2M";
+       static const char str_4m[] = "4M";
+       static const char str_4k[] = "4k";
+       if (mr->page_size_mask & (1<<PG_LEVEL_1G))
+               return str_1g;
+       /*
+        * 32-bit without PAE has a 4M large page size.
+        * PG_LEVEL_2M is misnamed, but we can at least
+        * print out the right size in the string.
+        */
+       if (IS_ENABLED(CONFIG_X86_32) &&
+           !IS_ENABLED(CONFIG_X86_PAE) &&
+           mr->page_size_mask & (1<<PG_LEVEL_2M))
+               return str_4m;
+       if (mr->page_size_mask & (1<<PG_LEVEL_2M))
+               return str_2m;
+       return str_4k;
+ }
  static int __meminit split_mem_range(struct map_range *mr, int nr_range,
                                     unsigned long start,
                                     unsigned long end)
        for (i = 0; i < nr_range; i++)
                printk(KERN_DEBUG " [mem %#010lx-%#010lx] page %s\n",
                                mr[i].start, mr[i].end - 1,
-                       (mr[i].page_size_mask & (1<<PG_LEVEL_1G))?"1G":(
-                        (mr[i].page_size_mask & (1<<PG_LEVEL_2M))?"2M":"4k"));
+                               page_size_string(&mr[i]));
  
        return nr_range;
  }
@@@ -608,7 -632,7 +632,7 @@@ void __init init_mem_mapping(void
   *
   *
   * On x86, access has to be given to the first megabyte of ram because that area
 - * contains bios code and data regions used by X and dosemu and similar apps.
 + * contains BIOS code and data regions used by X and dosemu and similar apps.
   * Access has to be given to non-kernel-ram areas as well, these contain the PCI
   * mmio resources as well as potential bios/acpi data regions.
   */
@@@ -713,15 -737,6 +737,15 @@@ void __init zone_sizes_init(void
        free_area_init_nodes(max_zone_pfns);
  }
  
 +DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) = {
 +#ifdef CONFIG_SMP
 +      .active_mm = &init_mm,
 +      .state = 0,
 +#endif
 +      .cr4 = ~0UL,    /* fail hard if we screw up cr4 shadow initialization */
 +};
 +EXPORT_SYMBOL_GPL(cpu_tlbstate);
 +
  void update_cache_mode_entry(unsigned entry, enum page_cache_mode cache)
  {
        /* entry 0 MUST be WB (hardwired to speed up translations) */
index af5d63c7cc53ded6b5ab4130b2b9279a5d52e988,9bd9fbb5bea821da5ef6f68c986e906c47292129..2fe195002021d079ec36515a7ebba4385c1f3600
  
  static unsigned long __chunk_size = EFI_READ_CHUNK_SIZE;
  
 +/*
 + * Allow the platform to override the allocation granularity: this allows
 + * systems that have the capability to run with a larger page size to deal
 + * with the allocations for initrd and fdt more efficiently.
 + */
 +#ifndef EFI_ALLOC_ALIGN
 +#define EFI_ALLOC_ALIGN               EFI_PAGE_SIZE
 +#endif
 +
  struct file_info {
        efi_file_handle_t *handle;
        u64 size;
@@@ -75,29 -66,25 +75,25 @@@ efi_status_t efi_get_memory_map(efi_sys
        unsigned long key;
        u32 desc_version;
  
-       *map_size = 0;
-       *desc_size = 0;
-       key = 0;
-       status = efi_call_early(get_memory_map, map_size, NULL,
-                               &key, desc_size, &desc_version);
-       if (status != EFI_BUFFER_TOO_SMALL)
-               return EFI_LOAD_ERROR;
+       *map_size = sizeof(*m) * 32;
+ again:
        /*
         * Add an additional efi_memory_desc_t because we're doing an
         * allocation which may be in a new descriptor region.
         */
-       *map_size += *desc_size;
+       *map_size += sizeof(*m);
        status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
                                *map_size, (void **)&m);
        if (status != EFI_SUCCESS)
                goto fail;
  
+       *desc_size = 0;
+       key = 0;
        status = efi_call_early(get_memory_map, map_size, m,
                                &key, desc_size, &desc_version);
        if (status == EFI_BUFFER_TOO_SMALL) {
                efi_call_early(free_pool, m);
-               return EFI_LOAD_ERROR;
+               goto again;
        }
  
        if (status != EFI_SUCCESS)
@@@ -163,10 -150,10 +159,10 @@@ efi_status_t efi_high_alloc(efi_system_
         * a specific address.  We are doing page-based allocations,
         * so we must be aligned to a page.
         */
 -      if (align < EFI_PAGE_SIZE)
 -              align = EFI_PAGE_SIZE;
 +      if (align < EFI_ALLOC_ALIGN)
 +              align = EFI_ALLOC_ALIGN;
  
 -      nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
 +      nr_pages = round_up(size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
  again:
        for (i = 0; i < map_size / desc_size; i++) {
                efi_memory_desc_t *desc;
@@@ -248,10 -235,10 +244,10 @@@ efi_status_t efi_low_alloc(efi_system_t
         * a specific address.  We are doing page-based allocations,
         * so we must be aligned to a page.
         */
 -      if (align < EFI_PAGE_SIZE)
 -              align = EFI_PAGE_SIZE;
 +      if (align < EFI_ALLOC_ALIGN)
 +              align = EFI_ALLOC_ALIGN;
  
 -      nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
 +      nr_pages = round_up(size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
        for (i = 0; i < map_size / desc_size; i++) {
                efi_memory_desc_t *desc;
                unsigned long m = (unsigned long)map;
@@@ -305,7 -292,7 +301,7 @@@ void efi_free(efi_system_table_t *sys_t
        if (!size)
                return;
  
 -      nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
 +      nr_pages = round_up(size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
        efi_call_early(free_pages, addr, nr_pages);
  }
  
@@@ -574,7 -561,7 +570,7 @@@ efi_status_t efi_relocate_kernel(efi_sy
         * to the preferred address.  If that fails, allocate as low
         * as possible while respecting the required alignment.
         */
 -      nr_pages = round_up(alloc_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
 +      nr_pages = round_up(alloc_size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
        status = efi_call_early(allocate_pages,
                                EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
                                nr_pages, &efi_addr);