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
Unified · Split
| @@ -564,9 +564,6 @@ void choose_random_location(unsigned long input, · 563 unmodified lines | ||
| 564 | 564 | { |
| 565 | 565 | unsigned long random_addr, min_addr; |
| 566 | 566 | |
| 567 | − /* By default, keep output position unchanged. */ | |
| 568 | − *virt_addr = *output; | |
| 569 | − | |
| 570 | 567 | if (cmdline_find_option_bool("nokaslr")) { |
| 571 | 568 | warn("KASLR disabled: 'nokaslr' on cmdline."); |
| 572 | 569 | return; |
| @@ -338,7 +338,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, · 337 unmodified lines | ||
| 338 | 338 | unsigned long output_len) |
| 339 | 339 | { |
| 340 | 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 | 343 | /* Retain x86 boot parameters pointer passed from startup_32/64. */ |
| 344 | 344 | boot_params = rmode; |
| @@ -390,6 +390,8 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, · 45 unmodified lines | ||
| 390 | 390 | #ifdef CONFIG_X86_64 |
| 391 | 391 | if (heap > 0x3fffffffffffUL) |
| 392 | 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 | 395 | #else |
| 394 | 396 | if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff)) |
| 395 | 397 | error("Destination address too large"); |
| @@ -397,7 +399,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, · 1 unmodified line | ||
| 397 | 399 | #ifndef CONFIG_RELOCATABLE |
| 398 | 400 | if ((unsigned long)output != LOAD_PHYSICAL_ADDR) |
| 399 | 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 | 403 | error("Destination virtual address changed when not relocatable"); |
| 402 | 404 | #endif |
| 403 | 405 | |
| @@ -81,8 +81,6 @@ static inline void choose_random_location(unsigned long input, · 80 unmodified lines | ||
| 81 | 81 | unsigned long output_size, |
| 82 | 82 | unsigned long *virt_addr) |
| 83 | 83 | { |
| 84 | − /* No change from existing output location. */ | |
| 85 | − *virt_addr = *output; | |
| 86 | 84 | } |
| 87 | 85 | #endif |
| 88 | 86 | |
| @@ -1170,7 +1170,7 @@ static int uncore_event_cpu_online(unsigned int cpu) · 1169 unmodified lines | ||
| 1170 | 1170 | pmu = type->pmus; |
| 1171 | 1171 | for (i = 0; i < type->num_boxes; i++, pmu++) { |
| 1172 | 1172 | box = pmu->boxes[pkg]; |
| 1173 | − if (!box && atomic_inc_return(&box->refcnt) == 1) | |
| 1173 | + if (box && atomic_inc_return(&box->refcnt) == 1) | |
| 1174 | 1174 | uncore_box_init(box); |
| 1175 | 1175 | } |
| 1176 | 1176 | } |
| @@ -856,11 +856,13 @@ static struct dentry *rdt_mount(struct file_system_type *fs_type, · 855 unmodified lines | ||
| 856 | 856 | dentry = kernfs_mount(fs_type, flags, rdt_root, |
| 857 | 857 | RDTGROUP_SUPER_MAGIC, NULL); |
| 858 | 858 | if (IS_ERR(dentry)) |
| 859 | − goto out_cdp; | |
| 859 | + goto out_destroy; | |
| 860 | 860 | |
| 861 | 861 | static_branch_enable(&rdt_enable_key); |
| 862 | 862 | goto out; |
| 863 | 863 | |
| 864 | +out_destroy: | |
| 865 | + kernfs_remove(kn_info); | |
| 864 | 866 | out_cdp: |
| 865 | 867 | cdp_disable(); |
| 866 | 868 | out: |
| @@ -990,7 +990,13 @@ remove_p4d_table(p4d_t *p4d_start, unsigned long addr, unsigned long end, · 989 unmodified lines | ||
| 990 | 990 | |
| 991 | 991 | pud_base = pud_offset(p4d, 0); |
| 992 | 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 | 1002 | if (direct) |