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 | 15572 | L: linux-kernel@vger.kernel.org |
| 15573 | 15573 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core |
| 15574 | 15574 | S: Maintained |
| 15575 | +F: Documentation/devicetree/bindings/x86/ | |
| 15575 | 15576 | F: Documentation/x86/ |
| 15576 | 15577 | F: arch/x86/ |
| 15577 | 15578 | |
| @@ -258,11 +258,6 @@ archscripts: scripts_basic · 257 unmodified lines | ||
| 258 | 258 | archheaders: |
| 259 | 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 | 262 | # Kernel objects |
| 268 | 263 | |
| @@ -327,7 +322,6 @@ archclean: · 58 unmodified lines | ||
| 327 | 322 | $(Q)rm -rf $(objtree)/arch/x86_64 |
| 328 | 323 | $(Q)$(MAKE) $(clean)=$(boot) |
| 329 | 324 | $(Q)$(MAKE) $(clean)=arch/x86/tools |
| 330 | − $(Q)$(MAKE) $(clean)=arch/x86/purgatory | |
| 331 | 325 | |
| 332 | 326 | define archhelp |
| 333 | 327 | echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)' |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/delay.h> |
| 27 | 27 | #include <linux/crash_dump.h> |
| 28 | 28 | #include <linux/reboot.h> |
| 29 | +#include <linux/memory.h> | |
| 29 | 30 | |
| 30 | 31 | #include <asm/uv/uv_mmrs.h> |
| 31 | 32 | #include <asm/uv/uv_hub.h> |
| @@ -392,6 +393,51 @@ extern int uv_hub_info_version(void) · 360 unmodified lines | ||
| 392 | 393 | } |
| 393 | 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 | 441 | /* Build GAM range lookup table: */ |
| 396 | 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 | 1226 | << UV_GAM_RANGE_SHFT); |
| 1181 | 1227 | int order = 0; |
| 1182 | 1228 | char suffix[] = " KMGTPE"; |
| 1229 | + int flag = ' '; | |
| 1183 | 1230 | |
| 1184 | 1231 | while (size > 9999 && order < sizeof(suffix)) { |
| 1185 | 1232 | size /= 1024; |
| 1186 | 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 | 1241 | if (!index) { |
| 1190 | 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 | 1246 | index++, |
| 1195 | 1247 | (unsigned long)lgre << UV_GAM_RANGE_SHFT, |
| 1196 | 1248 | (unsigned long)gre->limit << UV_GAM_RANGE_SHFT, |
| 1197 | − size, suffix[order], | |
| 1249 | + flag, size, suffix[order], | |
| 1198 | 1250 | gre->type, gre->nasid, gre->sockid, gre->pnode); |
| 1199 | 1251 | |
| 1252 | + /* update to next range start */ | |
| 1200 | 1253 | lgre = gre->limit; |
| 1201 | 1254 | if (sock_min > gre->sockid) |
| 1202 | 1255 | sock_min = gre->sockid; |
| @@ -1427,6 +1480,7 @@ static void __init uv_system_init_hub(void) · 224 unmodified lines | ||
| 1427 | 1480 | |
| 1428 | 1481 | build_socket_tables(); |
| 1429 | 1482 | build_uv_gr_table(); |
| 1483 | + set_block_size(); | |
| 1430 | 1484 | uv_init_hub_info(&hub_info); |
| 1431 | 1485 | uv_possible_blades = num_possible_nodes(); |
| 1432 | 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 | 671 | num_sharing_cache = ((eax >> 14) & 0xfff) + 1; |
| 672 | 672 | |
| 673 | 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 | 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 | 4 | #include <linux/bootmem.h> |
| 2 | 5 | #include <linux/linkage.h> |
| 3 | 6 | #include <linux/bitops.h> |
| @@ -190,8 +190,11 @@ static void save_microcode_patch(void *data, unsigned int size) · 189 unmodified lines | ||
| 190 | 190 | p = memdup_patch(data, size); |
| 191 | 191 | if (!p) |
| 192 | 192 | pr_err("Error allocating buffer %p\n", data); |
| 193 | − else | |
| 193 | + else { | |
| 194 | 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 | 44 | pmdval_t early_pmd_flags = __PAGE_KERNEL_LARGE & ~(_PAGE_GLOBAL | _PAGE_NX); |
| 45 | 45 | |
| 46 | 46 | #ifdef CONFIG_X86_5LEVEL |
| 47 | −unsigned int __pgtable_l5_enabled __initdata; | |
| 47 | +unsigned int __pgtable_l5_enabled __ro_after_init; | |
| 48 | 48 | unsigned int pgdir_shift __ro_after_init = 39; |
| 49 | 49 | EXPORT_SYMBOL(pgdir_shift); |
| 50 | 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 | 835 | char *str = (trapnr == X86_TRAP_MF) ? "fpu exception" : |
| 836 | 836 | "simd exception"; |
| 837 | 837 | |
| 838 | − if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) == NOTIFY_STOP) | |
| 839 | − return; | |
| 840 | 838 | cond_local_irq_enable(regs); |
| 841 | 839 | |
| 842 | 840 | if (!user_mode(regs)) { |
| 843 | − if (!fixup_exception(regs, trapnr)) { | |
| 844 | − task->thread.error_code = error_code; | |
| 845 | − task->thread.trap_nr = trapnr; | |
| 841 | + if (fixup_exception(regs, trapnr)) | |
| 842 | + return; | |
| 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 | 849 | die(str, regs, error_code); |
| 847 | − } | |
| 848 | 850 | return; |
| 849 | 851 | } |
| 850 | 852 | |
| @@ -1350,16 +1350,28 @@ int kern_addr_valid(unsigned long addr) · 1349 unmodified lines | ||
| 1350 | 1350 | /* Amount of ram needed to start using large blocks */ |
| 1351 | 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 | 1366 | static unsigned long probe_memory_block_size(void) |
| 1354 | 1367 | { |
| 1355 | 1368 | unsigned long boot_mem_end = max_pfn << PAGE_SHIFT; |
| 1356 | 1369 | unsigned long bz; |
| 1357 | 1370 | |
| 1358 | − /* If this is UV system, always set 2G block size */ | |
| 1359 | − if (is_uv_system()) { | |
| 1360 | − bz = MAX_BLOCK_SIZE; | |
| 1371 | + /* If memory block size has been set, then use it */ | |
| 1372 | + bz = set_memory_block_size; | |
| 1373 | + if (bz) | |
| 1361 | 1374 | goto done; |
| 1362 | − } | |
| 1363 | 1375 | |
| 1364 | 1376 | /* Use regular block if RAM is smaller than MEM_SIZE_FOR_LARGE_BLOCK */ |
| 1365 | 1377 | if (boot_mem_end < MEM_SIZE_FOR_LARGE_BLOCK) { |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | #include <xen/interface/vcpu.h> |
| 33 | 33 | #include <xen/interface/xenpmu.h> |
| 34 | 34 | |
| 35 | +#include <asm/spec-ctrl.h> | |
| 35 | 36 | #include <asm/xen/interface.h> |
| 36 | 37 | #include <asm/xen/hypercall.h> |
| 37 | 38 | |
| @@ -70,6 +71,8 @@ static void cpu_bringup(void) · 32 unmodified lines | ||
| 70 | 71 | cpu_data(cpu).x86_max_cores = 1; |
| 71 | 72 | set_cpu_sibling_map(cpu); |
| 72 | 73 | |
| 74 | + speculative_store_bypass_ht_init(); | |
| 75 | + | |
| 73 | 76 | xen_setup_cpu_clockevents(); |
| 74 | 77 | |
| 75 | 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 | 254 | set_cpu_sibling_map(0); |
| 252 | 255 | |
| 256 | + speculative_store_bypass_ht_init(); | |
| 257 | + | |
| 253 | 258 | xen_pmu_init(0); |
| 254 | 259 | |
| 255 | 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 | 39 | int arch_get_memory_phys_device(unsigned long start_pfn); |
| 40 | 40 | unsigned long memory_block_size_bytes(void); |
| 41 | +int set_memory_block_size_order(unsigned int order); | |
| 41 | 42 | |
| 42 | 43 | /* These states are exposed to userspace as text strings in sysfs */ |
| 43 | 44 | #define MEM_ONLINE (1<<0) /* exposed to userspace */ |