Pull x86 fixes from Thomas Gleixner: "A set of fixes for x86: - Make Xen PV guest deal with speculative store bypass correctly - Address more fallout from the 5-Level pagetable handling. Undo an __initdata annotation to avoid section mismatch and malfunction when post init code would touch the freed variable. - Handle exception fixup in math_error() before calling notify_die(). The reverse call order incorrectly triggers notify_die() listeners for soemthing which is handled correctly at the site which issues the floating point instruction. - Fix an off by one in the LLC topology calculation on AMD - Handle non standard memory block sizes gracefully un UV platforms - Plug a memory leak in the microcode loader - Sanitize the purgatory build magic - Add the x86 specific device tree bindings directory to the x86 MAINTAINER file patterns" * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/mm: Fix 'no5lvl' handling Revert "x86/mm: Mark __pgtable_l5_enabled __initdata" x86/CPU/AMD: Fix LLC ID bit-shift calculation MAINTAINERS: Add file patterns for x86 device tree bindings x86/microcode/intel: Fix memleak in save_microcode_patch() x86/platform/UV: Add kernel parameter to set memory block size x86/platform/UV: Use new set memory block size function x86/platform/UV: Add adjustable set memory block size function x86/build: Remove unnecessary preparation for purgatory Revert "kexec/purgatory: Add clean-up for purgatory directory" x86/xen: Add call of speculative_store_bypass_ht_init() to PV paths x86: Call fixup_exception() before notify_die() in math_error()
Unified · Split
| @@ -15572,6 +15572,7 @@ M: x86@kernel.org · 15571 unmodified lines | |||
| 15572 | L: linux-kernel@vger.kernel.org | 15572 | L: linux-kernel@vger.kernel.org |
| 15573 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core | 15573 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core |
| 15574 | S: Maintained | 15574 | S: Maintained |
| 15575 | F: Documentation/devicetree/bindings/x86/ | ||
| 15575 | F: Documentation/x86/ | 15576 | F: Documentation/x86/ |
| 15576 | F: arch/x86/ | 15577 | F: arch/x86/ |
| 15577 | 15578 | ||
| @@ -258,11 +258,6 @@ archscripts: scripts_basic · 257 unmodified lines | |||
| 258 | archheaders: | 258 | archheaders: |
| 259 | $(Q)$(MAKE) $(build)=arch/x86/entry/syscalls all | 259 | $(Q)$(MAKE) $(build)=arch/x86/entry/syscalls all |
| 260 | 260 | ||
| 261 | archprepare: | ||
| 262 | ifeq ($(CONFIG_KEXEC_FILE),y) | ||
| 263 | $(Q)$(MAKE) $(build)=arch/x86/purgatory arch/x86/purgatory/kexec-purgatory.c | ||
| 264 | endif | ||
| 265 | |||
| 266 | ### | 261 | ### |
| 267 | # Kernel objects | 262 | # Kernel objects |
| 268 | 263 | ||
| @@ -327,7 +322,6 @@ archclean: · 58 unmodified lines | |||
| 327 | $(Q)rm -rf $(objtree)/arch/x86_64 | 322 | $(Q)rm -rf $(objtree)/arch/x86_64 |
| 328 | $(Q)$(MAKE) $(clean)=$(boot) | 323 | $(Q)$(MAKE) $(clean)=$(boot) |
| 329 | $(Q)$(MAKE) $(clean)=arch/x86/tools | 324 | $(Q)$(MAKE) $(clean)=arch/x86/tools |
| 330 | $(Q)$(MAKE) $(clean)=arch/x86/purgatory | ||
| 331 | 325 | ||
| 332 | define archhelp | 326 | define archhelp |
| 333 | echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)' | 327 | echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)' |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | |||
| 26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
| 27 | #include <linux/crash_dump.h> | 27 | #include <linux/crash_dump.h> |
| 28 | #include <linux/reboot.h> | 28 | #include <linux/reboot.h> |
| 29 | #include <linux/memory.h> | ||
| 29 | 30 | ||
| 30 | #include <asm/uv/uv_mmrs.h> | 31 | #include <asm/uv/uv_mmrs.h> |
| 31 | #include <asm/uv/uv_hub.h> | 32 | #include <asm/uv/uv_hub.h> |
| @@ -392,6 +393,51 @@ extern int uv_hub_info_version(void) · 360 unmodified lines | |||
| 392 | } | 393 | } |
| 393 | EXPORT_SYMBOL(uv_hub_info_version); | 394 | EXPORT_SYMBOL(uv_hub_info_version); |
| 394 | 395 | ||
| 396 | /* Default UV memory block size is 2GB */ | ||
| 397 | static unsigned long mem_block_size = (2UL << 30); | ||
| 398 | |||
| 399 | /* Kernel parameter to specify UV mem block size */ | ||
| 400 | static int parse_mem_block_size(char *ptr) | ||
| 401 | { | ||
| 402 | unsigned long size = memparse(ptr, NULL); | ||
| 403 | |||
| 404 | /* Size will be rounded down by set_block_size() below */ | ||
| 405 | mem_block_size = size; | ||
| 406 | return 0; | ||
| 407 | } | ||
| 408 | early_param("uv_memblksize", parse_mem_block_size); | ||
| 409 | |||
| 410 | static __init int adj_blksize(u32 lgre) | ||
| 411 | { | ||
| 412 | unsigned long base = (unsigned long)lgre << UV_GAM_RANGE_SHFT; | ||
| 413 | unsigned long size; | ||
| 414 | |||
| 415 | for (size = mem_block_size; size > MIN_MEMORY_BLOCK_SIZE; size >>= 1) | ||
| 416 | if (IS_ALIGNED(base, size)) | ||
| 417 | break; | ||
| 418 | |||
| 419 | if (size >= mem_block_size) | ||
| 420 | return 0; | ||
| 421 | |||
| 422 | mem_block_size = size; | ||
| 423 | return 1; | ||
| 424 | } | ||
| 425 | |||
| 426 | static __init void set_block_size(void) | ||
| 427 | { | ||
| 428 | unsigned int order = ffs(mem_block_size); | ||
| 429 | |||
| 430 | if (order) { | ||
| 431 | /* adjust for ffs return of 1..64 */ | ||
| 432 | set_memory_block_size_order(order - 1); | ||
| 433 | pr_info("UV: mem_block_size set to 0x%lx\n", mem_block_size); | ||
| 434 | } else { | ||
| 435 | /* bad or zero value, default to 1UL << 31 (2GB) */ | ||
| 436 | pr_err("UV: mem_block_size error with 0x%lx\n", mem_block_size); | ||
| 437 | set_memory_block_size_order(31); | ||
| 438 | } | ||
| 439 | } | ||
| 440 | |||
| 395 | /* Build GAM range lookup table: */ | 441 | /* Build GAM range lookup table: */ |
| 396 | static __init void build_uv_gr_table(void) | 442 | static __init void build_uv_gr_table(void) |
| 397 | { | 443 | { |
| @@ -1180,23 +1226,30 @@ static void __init decode_gam_rng_tbl(unsigned long ptr) · 782 unmodified lines | |||
| 1180 | << UV_GAM_RANGE_SHFT); | 1226 | << UV_GAM_RANGE_SHFT); |
| 1181 | int order = 0; | 1227 | int order = 0; |
| 1182 | char suffix[] = " KMGTPE"; | 1228 | char suffix[] = " KMGTPE"; |
| 1229 | int flag = ' '; | ||
| 1183 | 1230 | ||
| 1184 | while (size > 9999 && order < sizeof(suffix)) { | 1231 | while (size > 9999 && order < sizeof(suffix)) { |
| 1185 | size /= 1024; | 1232 | size /= 1024; |
| 1186 | order++; | 1233 | order++; |
| 1187 | } | 1234 | } |
| 1188 | 1235 | ||
| 1236 | /* adjust max block size to current range start */ | ||
| 1237 | if (gre->type == 1 || gre->type == 2) | ||
| 1238 | if (adj_blksize(lgre)) | ||
| 1239 | flag = '*'; | ||
| 1240 | |||
| 1189 | if (!index) { | 1241 | if (!index) { |
| 1190 | pr_info("UV: GAM Range Table...\n"); | 1242 | pr_info("UV: GAM Range Table...\n"); |
| 1191 | pr_info("UV: # %20s %14s %5s %4s %5s %3s %2s\n", "Range", "", "Size", "Type", "NASID", "SID", "PN"); | 1243 | pr_info("UV: # %20s %14s %6s %4s %5s %3s %2s\n", "Range", "", "Size", "Type", "NASID", "SID", "PN"); |
| 1192 | } | 1244 | } |
| 1193 | pr_info("UV: %2d: 0x%014lx-0x%014lx %5lu%c %3d %04x %02x %02x\n", | 1245 | pr_info("UV: %2d: 0x%014lx-0x%014lx%c %5lu%c %3d %04x %02x %02x\n", |
| 1194 | index++, | 1246 | index++, |
| 1195 | (unsigned long)lgre << UV_GAM_RANGE_SHFT, | 1247 | (unsigned long)lgre << UV_GAM_RANGE_SHFT, |
| 1196 | (unsigned long)gre->limit << UV_GAM_RANGE_SHFT, | 1248 | (unsigned long)gre->limit << UV_GAM_RANGE_SHFT, |
| 1197 | size, suffix[order], | 1249 | flag, size, suffix[order], |
| 1198 | gre->type, gre->nasid, gre->sockid, gre->pnode); | 1250 | gre->type, gre->nasid, gre->sockid, gre->pnode); |
| 1199 | 1251 | ||
| 1252 | /* update to next range start */ | ||
| 1200 | lgre = gre->limit; | 1253 | lgre = gre->limit; |
| 1201 | if (sock_min > gre->sockid) | 1254 | if (sock_min > gre->sockid) |
| 1202 | sock_min = gre->sockid; | 1255 | sock_min = gre->sockid; |
| @@ -1427,6 +1480,7 @@ static void __init uv_system_init_hub(void) · 224 unmodified lines | |||
| 1427 | 1480 | ||
| 1428 | build_socket_tables(); | 1481 | build_socket_tables(); |
| 1429 | build_uv_gr_table(); | 1482 | build_uv_gr_table(); |
| 1483 | set_block_size(); | ||
| 1430 | uv_init_hub_info(&hub_info); | 1484 | uv_init_hub_info(&hub_info); |
| 1431 | uv_possible_blades = num_possible_nodes(); | 1485 | uv_possible_blades = num_possible_nodes(); |
| 1432 | if (!_node_to_pnode) | 1486 | if (!_node_to_pnode) |
| @@ -671,7 +671,7 @@ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id) · 670 unmodified lines | |||
| 671 | num_sharing_cache = ((eax >> 14) & 0xfff) + 1; | 671 | num_sharing_cache = ((eax >> 14) & 0xfff) + 1; |
| 672 | 672 | ||
| 673 | if (num_sharing_cache) { | 673 | if (num_sharing_cache) { |
| 674 | int bits = get_count_order(num_sharing_cache) - 1; | 674 | int bits = get_count_order(num_sharing_cache); |
| 675 | 675 | ||
| 676 | per_cpu(cpu_llc_id, cpu) = c->apicid >> bits; | 676 | per_cpu(cpu_llc_id, cpu) = c->apicid >> bits; |
| 677 | } | 677 | } |
| @@ -1,3 +1,6 @@ | |||
| 1 | /* cpu_feature_enabled() cannot be used this early */ | ||
| 2 | #define USE_EARLY_PGTABLE_L5 | ||
| 3 | |||
| 1 | #include <linux/bootmem.h> | 4 | #include <linux/bootmem.h> |
| 2 | #include <linux/linkage.h> | 5 | #include <linux/linkage.h> |
| 3 | #include <linux/bitops.h> | 6 | #include <linux/bitops.h> |
| @@ -190,8 +190,11 @@ static void save_microcode_patch(void *data, unsigned int size) · 189 unmodified lines | |||
| 190 | p = memdup_patch(data, size); | 190 | p = memdup_patch(data, size); |
| 191 | if (!p) | 191 | if (!p) |
| 192 | pr_err("Error allocating buffer %p\n", data); | 192 | pr_err("Error allocating buffer %p\n", data); |
| 193 | else | 193 | else { |
| 194 | list_replace(&iter->plist, &p->plist); | 194 | list_replace(&iter->plist, &p->plist); |
| 195 | kfree(iter->data); | ||
| 196 | kfree(iter); | ||
| 197 | } | ||
| 195 | } | 198 | } |
| 196 | } | 199 | } |
| 197 | 200 | ||
| @@ -44,7 +44,7 @@ static unsigned int __initdata next_early_pgt; · 43 unmodified lines | |||
| 44 | pmdval_t early_pmd_flags = __PAGE_KERNEL_LARGE & ~(_PAGE_GLOBAL | _PAGE_NX); | 44 | pmdval_t early_pmd_flags = __PAGE_KERNEL_LARGE & ~(_PAGE_GLOBAL | _PAGE_NX); |
| 45 | 45 | ||
| 46 | #ifdef CONFIG_X86_5LEVEL | 46 | #ifdef CONFIG_X86_5LEVEL |
| 47 | unsigned int __pgtable_l5_enabled __initdata; | 47 | unsigned int __pgtable_l5_enabled __ro_after_init; |
| 48 | unsigned int pgdir_shift __ro_after_init = 39; | 48 | unsigned int pgdir_shift __ro_after_init = 39; |
| 49 | EXPORT_SYMBOL(pgdir_shift); | 49 | EXPORT_SYMBOL(pgdir_shift); |
| 50 | unsigned int ptrs_per_p4d __ro_after_init = 1; | 50 | unsigned int ptrs_per_p4d __ro_after_init = 1; |
| @@ -835,16 +835,18 @@ static void math_error(struct pt_regs *regs, int error_code, int trapnr) · 834 unmodified lines | |||
| 835 | char *str = (trapnr == X86_TRAP_MF) ? "fpu exception" : | 835 | char *str = (trapnr == X86_TRAP_MF) ? "fpu exception" : |
| 836 | "simd exception"; | 836 | "simd exception"; |
| 837 | 837 | ||
| 838 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) == NOTIFY_STOP) | ||
| 839 | return; | ||
| 840 | cond_local_irq_enable(regs); | 838 | cond_local_irq_enable(regs); |
| 841 | 839 | ||
| 842 | if (!user_mode(regs)) { | 840 | if (!user_mode(regs)) { |
| 843 | if (!fixup_exception(regs, trapnr)) { | 841 | if (fixup_exception(regs, trapnr)) |
| 844 | task->thread.error_code = error_code; | 842 | return; |
| 845 | task->thread.trap_nr = trapnr; | 843 | |
| 844 | task->thread.error_code = error_code; | ||
| 845 | task->thread.trap_nr = trapnr; | ||
| 846 | |||
| 847 | if (notify_die(DIE_TRAP, str, regs, error_code, | ||
| 848 | trapnr, SIGFPE) != NOTIFY_STOP) | ||
| 846 | die(str, regs, error_code); | 849 | die(str, regs, error_code); |
| 847 | } | ||
| 848 | return; | 850 | return; |
| 849 | } | 851 | } |
| 850 | 852 | ||
| @@ -1350,16 +1350,28 @@ int kern_addr_valid(unsigned long addr) · 1349 unmodified lines | |||
| 1350 | /* Amount of ram needed to start using large blocks */ | 1350 | /* Amount of ram needed to start using large blocks */ |
| 1351 | #define MEM_SIZE_FOR_LARGE_BLOCK (64UL << 30) | 1351 | #define MEM_SIZE_FOR_LARGE_BLOCK (64UL << 30) |
| 1352 | 1352 | ||
| 1353 | /* Adjustable memory block size */ | ||
| 1354 | static unsigned long set_memory_block_size; | ||
| 1355 | int __init set_memory_block_size_order(unsigned int order) | ||
| 1356 | { | ||
| 1357 | unsigned long size = 1UL << order; | ||
| 1358 | |||
| 1359 | if (size > MEM_SIZE_FOR_LARGE_BLOCK || size < MIN_MEMORY_BLOCK_SIZE) | ||
| 1360 | return -EINVAL; | ||
| 1361 | |||
| 1362 | set_memory_block_size = size; | ||
| 1363 | return 0; | ||
| 1364 | } | ||
| 1365 | |||
| 1353 | static unsigned long probe_memory_block_size(void) | 1366 | static unsigned long probe_memory_block_size(void) |
| 1354 | { | 1367 | { |
| 1355 | unsigned long boot_mem_end = max_pfn << PAGE_SHIFT; | 1368 | unsigned long boot_mem_end = max_pfn << PAGE_SHIFT; |
| 1356 | unsigned long bz; | 1369 | unsigned long bz; |
| 1357 | 1370 | ||
| 1358 | /* If this is UV system, always set 2G block size */ | 1371 | /* If memory block size has been set, then use it */ |
| 1359 | if (is_uv_system()) { | 1372 | bz = set_memory_block_size; |
| 1360 | bz = MAX_BLOCK_SIZE; | 1373 | if (bz) |
| 1361 | goto done; | 1374 | goto done; |
| 1362 | } | ||
| 1363 | 1375 | ||
| 1364 | /* Use regular block if RAM is smaller than MEM_SIZE_FOR_LARGE_BLOCK */ | 1376 | /* Use regular block if RAM is smaller than MEM_SIZE_FOR_LARGE_BLOCK */ |
| 1365 | if (boot_mem_end < MEM_SIZE_FOR_LARGE_BLOCK) { | 1377 | if (boot_mem_end < MEM_SIZE_FOR_LARGE_BLOCK) { |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | |||
| 32 | #include <xen/interface/vcpu.h> | 32 | #include <xen/interface/vcpu.h> |
| 33 | #include <xen/interface/xenpmu.h> | 33 | #include <xen/interface/xenpmu.h> |
| 34 | 34 | ||
| 35 | #include <asm/spec-ctrl.h> | ||
| 35 | #include <asm/xen/interface.h> | 36 | #include <asm/xen/interface.h> |
| 36 | #include <asm/xen/hypercall.h> | 37 | #include <asm/xen/hypercall.h> |
| 37 | 38 | ||
| @@ -70,6 +71,8 @@ static void cpu_bringup(void) · 32 unmodified lines | |||
| 70 | cpu_data(cpu).x86_max_cores = 1; | 71 | cpu_data(cpu).x86_max_cores = 1; |
| 71 | set_cpu_sibling_map(cpu); | 72 | set_cpu_sibling_map(cpu); |
| 72 | 73 | ||
| 74 | speculative_store_bypass_ht_init(); | ||
| 75 | |||
| 73 | xen_setup_cpu_clockevents(); | 76 | xen_setup_cpu_clockevents(); |
| 74 | 77 | ||
| 75 | notify_cpu_starting(cpu); | 78 | notify_cpu_starting(cpu); |
| @@ -250,6 +253,8 @@ static void __init xen_pv_smp_prepare_cpus(unsigned int max_cpus) · 174 unmodified lines | |||
| 250 | } | 253 | } |
| 251 | set_cpu_sibling_map(0); | 254 | set_cpu_sibling_map(0); |
| 252 | 255 | ||
| 256 | speculative_store_bypass_ht_init(); | ||
| 257 | |||
| 253 | xen_pmu_init(0); | 258 | xen_pmu_init(0); |
| 254 | 259 | ||
| 255 | if (xen_smp_intr_init(0) || xen_smp_intr_init_pv(0)) | 260 | if (xen_smp_intr_init(0) || xen_smp_intr_init_pv(0)) |
| @@ -38,6 +38,7 @@ struct memory_block { · 37 unmodified lines | |||
| 38 | 38 | ||
| 39 | int arch_get_memory_phys_device(unsigned long start_pfn); | 39 | int arch_get_memory_phys_device(unsigned long start_pfn); |
| 40 | unsigned long memory_block_size_bytes(void); | 40 | unsigned long memory_block_size_bytes(void); |
| 41 | int set_memory_block_size_order(unsigned int order); | ||
| 41 | 42 | ||
| 42 | /* These states are exposed to userspace as text strings in sysfs */ | 43 | /* These states are exposed to userspace as text strings in sysfs */ |
| 43 | #define MEM_ONLINE (1<<0) /* exposed to userspace */ | 44 | #define MEM_ONLINE (1<<0) /* exposed to userspace */ |