aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-01 12:10:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-01 12:10:17 -0400
commite18aca0236a2dac4a134ace4685e97ad09d3605b (patch)
treeed071ab72fa4d27cf5397f3bcd09cdf84206d813
parenta527bf61404cd36fedd81dc165a03b6f5529092e (diff)
parent79298acc4ba097e9ab78644e3e38902d73547c92 (diff)
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Thomas Gleixner: "Fixlets for x86: - Prevent kexec crash when KASLR is enabled, which was caused by an address calculation bug - Restore the freeing of PUDs on memory hot remove - Correct a negated pointer check in the intel uncore performance monitoring driver - Plug a memory leak in an error exit path in the RDT code" * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/intel_rdt: Fix memory leak on mount failure x86/boot/KASLR: Fix kexec crash due to 'virt_addr' calculation bug x86/boot/KASLR: Add checking for the offset of kernel virtual address randomization perf/x86/intel/uncore: Fix wrong box pointer check x86/mm/hotplug: Fix BUG_ON() after hot-remove by not freeing PUD
-rw-r--r--arch/x86/boot/compressed/kaslr.c3
-rw-r--r--arch/x86/boot/compressed/misc.c6
-rw-r--r--arch/x86/boot/compressed/misc.h2
-rw-r--r--arch/x86/events/intel/uncore.c2
-rw-r--r--arch/x86/kernel/cpu/intel_rdt_rdtgroup.c4
-rw-r--r--arch/x86/mm/init_64.c8
6 files changed, 15 insertions, 10 deletions
diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
index 54c24f0a43d3..56a7e9201741 100644
--- a/arch/x86/boot/compressed/kaslr.c
+++ b/arch/x86/boot/compressed/kaslr.c
@@ -564,9 +564,6 @@ void choose_random_location(unsigned long input,
564{ 564{
565 unsigned long random_addr, min_addr; 565 unsigned long random_addr, min_addr;
566 566
567 /* By default, keep output position unchanged. */
568 *virt_addr = *output;
569
570 if (cmdline_find_option_bool("nokaslr")) { 567 if (cmdline_find_option_bool("nokaslr")) {
571 warn("KASLR disabled: 'nokaslr' on cmdline."); 568 warn("KASLR disabled: 'nokaslr' on cmdline.");
572 return; 569 return;
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index b3c5a5f030ce..00241c815524 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -338,7 +338,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
338 unsigned long output_len) 338 unsigned long output_len)
339{ 339{
340 const unsigned long kernel_total_size = VO__end - VO__text; 340 const unsigned long kernel_total_size = VO__end - VO__text;
341 unsigned long virt_addr = (unsigned long)output; 341 unsigned long virt_addr = LOAD_PHYSICAL_ADDR;
342 342
343 /* Retain x86 boot parameters pointer passed from startup_32/64. */ 343 /* Retain x86 boot parameters pointer passed from startup_32/64. */
344 boot_params = rmode; 344 boot_params = rmode;
@@ -390,6 +390,8 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
390#ifdef CONFIG_X86_64 390#ifdef CONFIG_X86_64
391 if (heap > 0x3fffffffffffUL) 391 if (heap > 0x3fffffffffffUL)
392 error("Destination address too large"); 392 error("Destination address too large");
393 if (virt_addr + max(output_len, kernel_total_size) > KERNEL_IMAGE_SIZE)
394 error("Destination virtual address is beyond the kernel mapping area");
393#else 395#else
394 if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff)) 396 if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff))
395 error("Destination address too large"); 397 error("Destination address too large");
@@ -397,7 +399,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
397#ifndef CONFIG_RELOCATABLE 399#ifndef CONFIG_RELOCATABLE
398 if ((unsigned long)output != LOAD_PHYSICAL_ADDR) 400 if ((unsigned long)output != LOAD_PHYSICAL_ADDR)
399 error("Destination address does not match LOAD_PHYSICAL_ADDR"); 401 error("Destination address does not match LOAD_PHYSICAL_ADDR");
400 if ((unsigned long)output != virt_addr) 402 if (virt_addr != LOAD_PHYSICAL_ADDR)
401 error("Destination virtual address changed when not relocatable"); 403 error("Destination virtual address changed when not relocatable");
402#endif 404#endif
403 405
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
index 1c8355eadbd1..766a5211f827 100644
--- a/arch/x86/boot/compressed/misc.h
+++ b/arch/x86/boot/compressed/misc.h
@@ -81,8 +81,6 @@ static inline void choose_random_location(unsigned long input,
81 unsigned long output_size, 81 unsigned long output_size,
82 unsigned long *virt_addr) 82 unsigned long *virt_addr)
83{ 83{
84 /* No change from existing output location. */
85 *virt_addr = *output;
86} 84}
87#endif 85#endif
88 86
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 758c1aa5009d..44ec523287f6 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1170,7 +1170,7 @@ static int uncore_event_cpu_online(unsigned int cpu)
1170 pmu = type->pmus; 1170 pmu = type->pmus;
1171 for (i = 0; i < type->num_boxes; i++, pmu++) { 1171 for (i = 0; i < type->num_boxes; i++, pmu++) {
1172 box = pmu->boxes[pkg]; 1172 box = pmu->boxes[pkg];
1173 if (!box && atomic_inc_return(&box->refcnt) == 1) 1173 if (box && atomic_inc_return(&box->refcnt) == 1)
1174 uncore_box_init(box); 1174 uncore_box_init(box);
1175 } 1175 }
1176 } 1176 }
diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
index f5af0cc7eb0d..9257bd9dc664 100644
--- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
+++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
@@ -856,11 +856,13 @@ static struct dentry *rdt_mount(struct file_system_type *fs_type,
856 dentry = kernfs_mount(fs_type, flags, rdt_root, 856 dentry = kernfs_mount(fs_type, flags, rdt_root,
857 RDTGROUP_SUPER_MAGIC, NULL); 857 RDTGROUP_SUPER_MAGIC, NULL);
858 if (IS_ERR(dentry)) 858 if (IS_ERR(dentry))
859 goto out_cdp; 859 goto out_destroy;
860 860
861 static_branch_enable(&rdt_enable_key); 861 static_branch_enable(&rdt_enable_key);
862 goto out; 862 goto out;
863 863
864out_destroy:
865 kernfs_remove(kn_info);
864out_cdp: 866out_cdp:
865 cdp_disable(); 867 cdp_disable();
866out: 868out:
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 95651dc58e09..0a59daf799f8 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -990,7 +990,13 @@ remove_p4d_table(p4d_t *p4d_start, unsigned long addr, unsigned long end,
990 990
991 pud_base = pud_offset(p4d, 0); 991 pud_base = pud_offset(p4d, 0);
992 remove_pud_table(pud_base, addr, next, direct); 992 remove_pud_table(pud_base, addr, next, direct);
993 free_pud_table(pud_base, p4d); 993 /*
994 * For 4-level page tables we do not want to free PUDs, but in the
995 * 5-level case we should free them. This code will have to change
996 * to adapt for boot-time switching between 4 and 5 level page tables.
997 */
998 if (CONFIG_PGTABLE_LEVELS == 5)
999 free_pud_table(pud_base, p4d);
994 } 1000 }
995 1001
996 if (direct) 1002 if (direct)