diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-01 12:10:17 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-01 12:10:17 -0400 |
| commit | e18aca0236a2dac4a134ace4685e97ad09d3605b (patch) | |
| tree | ed071ab72fa4d27cf5397f3bcd09cdf84206d813 | |
| parent | a527bf61404cd36fedd81dc165a03b6f5529092e (diff) | |
| parent | 79298acc4ba097e9ab78644e3e38902d73547c92 (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.c | 3 | ||||
| -rw-r--r-- | arch/x86/boot/compressed/misc.c | 6 | ||||
| -rw-r--r-- | arch/x86/boot/compressed/misc.h | 2 | ||||
| -rw-r--r-- | arch/x86/events/intel/uncore.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 4 | ||||
| -rw-r--r-- | arch/x86/mm/init_64.c | 8 |
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 | ||
| 864 | out_destroy: | ||
| 865 | kernfs_remove(kn_info); | ||
| 864 | out_cdp: | 866 | out_cdp: |
| 865 | cdp_disable(); | 867 | cdp_disable(); |
| 866 | out: | 868 | out: |
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) |
