Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Thomas Gleixner:
"A few fixes for x86:

- Fix a boot regression caused by the recent bootparam sanitizing
change, which escaped the attention of all people who reviewed that
code.

- Address a boot problem on machines with broken E820 tables caused
by an underflow which ended up placing the trampoline start at
physical address 0.

- Handle machines which do not advertise a legacy timer of any form,
but need calibration of the local APIC timer gracefully by making
the calibration routine independent from the tick interrupt. Marked
for stable as well as there seems to be quite some new laptops
rolled out which expose this.

- Clear the RDRAND CPUID bit on AMD family 15h and 16h CPUs which are
affected by broken firmware which does not initialize RDRAND
correctly after resume. Add a command line parameter to override
this for machine which either do not use suspend/resume or have a
fixed BIOS. Unfortunately there is no way to detect this on boot,
so the only safe decision is to turn it off by default.

- Prevent RFLAGS from being clobbers in CALL_NOSPEC on 32bit which
caused fast KVM instruction emulation to break.

- Explain the Intel CPU model naming convention so that the repeating
discussions come to an end"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/retpoline: Don't clobber RFLAGS during CALL_NOSPEC on i386
x86/boot: Fix boot regression caused by bootparam sanitizing
x86/CPU/AMD: Clear RDRAND CPUID bit on AMD family 15h/16h
x86/boot/compressed/64: Fix boot on machines with broken E820 table
x86/apic: Handle missing global clockevent gracefully
x86/cpu: Explain Intel model naming convention

+227 -33
+7
Documentation/admin-guide/kernel-parameters.txt
··· 4090 4090 Run specified binary instead of /init from the ramdisk, 4091 4091 used for early userspace startup. See initrd. 4092 4092 4093 + rdrand= [X86] 4094 + force - Override the decision by the kernel to hide the 4095 + advertisement of RDRAND support (this affects 4096 + certain AMD processors because of buggy BIOS 4097 + support, specifically around the suspend/resume 4098 + path). 4099 + 4093 4100 rdt= [HW,X86,RDT] 4094 4101 Turn on/off individual RDT features. List is: 4095 4102 cmt, mbmtotal, mbmlocal, l3cat, l3cdp, l2cat, l2cdp,
+10 -3
arch/x86/boot/compressed/pgtable_64.c
··· 72 72 73 73 /* Find the first usable memory region under bios_start. */ 74 74 for (i = boot_params->e820_entries - 1; i >= 0; i--) { 75 + unsigned long new; 76 + 75 77 entry = &boot_params->e820_table[i]; 76 78 77 79 /* Skip all entries above bios_start. */ ··· 86 84 87 85 /* Adjust bios_start to the end of the entry if needed. */ 88 86 if (bios_start > entry->addr + entry->size) 89 - bios_start = entry->addr + entry->size; 87 + new = entry->addr + entry->size; 90 88 91 89 /* Keep bios_start page-aligned. */ 92 - bios_start = round_down(bios_start, PAGE_SIZE); 90 + new = round_down(new, PAGE_SIZE); 93 91 94 92 /* Skip the entry if it's too small. */ 95 - if (bios_start - TRAMPOLINE_32BIT_SIZE < entry->addr) 93 + if (new - TRAMPOLINE_32BIT_SIZE < entry->addr) 96 94 continue; 97 95 96 + /* Protect against underflow. */ 97 + if (new - TRAMPOLINE_32BIT_SIZE > bios_start) 98 + break; 99 + 100 + bios_start = new; 98 101 break; 99 102 } 100 103
+1 -1
arch/x86/include/asm/bootparam_utils.h
··· 59 59 BOOT_PARAM_PRESERVE(apm_bios_info), 60 60 BOOT_PARAM_PRESERVE(tboot_addr), 61 61 BOOT_PARAM_PRESERVE(ist_info), 62 - BOOT_PARAM_PRESERVE(acpi_rsdp_addr), 63 62 BOOT_PARAM_PRESERVE(hd0_info), 64 63 BOOT_PARAM_PRESERVE(hd1_info), 65 64 BOOT_PARAM_PRESERVE(sys_desc_table), ··· 70 71 BOOT_PARAM_PRESERVE(eddbuf_entries), 71 72 BOOT_PARAM_PRESERVE(edd_mbr_sig_buf_entries), 72 73 BOOT_PARAM_PRESERVE(edd_mbr_sig_buffer), 74 + BOOT_PARAM_PRESERVE(hdr), 73 75 BOOT_PARAM_PRESERVE(e820_table), 74 76 BOOT_PARAM_PRESERVE(eddbuf), 75 77 };
+15
arch/x86/include/asm/intel-family.h
··· 11 11 * While adding a new CPUID for a new microarchitecture, add a new 12 12 * group to keep logically sorted out in chronological order. Within 13 13 * that group keep the CPUID for the variants sorted by model number. 14 + * 15 + * The defined symbol names have the following form: 16 + * INTEL_FAM6{OPTFAMILY}_{MICROARCH}{OPTDIFF} 17 + * where: 18 + * OPTFAMILY Describes the family of CPUs that this belongs to. Default 19 + * is assumed to be "_CORE" (and should be omitted). Other values 20 + * currently in use are _ATOM and _XEON_PHI 21 + * MICROARCH Is the code name for the micro-architecture for this core. 22 + * N.B. Not the platform name. 23 + * OPTDIFF If needed, a short string to differentiate by market segment. 24 + * Exact strings here will vary over time. _DESKTOP, _MOBILE, and 25 + * _X (short for Xeon server) should be used when they are 26 + * appropriate. 27 + * 28 + * The #define line may optionally include a comment including platform names. 14 29 */ 15 30 16 31 #define INTEL_FAM6_CORE_YONAH 0x0E
+1
arch/x86/include/asm/msr-index.h
··· 381 381 #define MSR_AMD64_PATCH_LEVEL 0x0000008b 382 382 #define MSR_AMD64_TSC_RATIO 0xc0000104 383 383 #define MSR_AMD64_NB_CFG 0xc001001f 384 + #define MSR_AMD64_CPUID_FN_1 0xc0011004 384 385 #define MSR_AMD64_PATCH_LOADER 0xc0010020 385 386 #define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140 386 387 #define MSR_AMD64_OSVW_STATUS 0xc0010141
+1 -1
arch/x86/include/asm/nospec-branch.h
··· 192 192 " lfence;\n" \ 193 193 " jmp 902b;\n" \ 194 194 " .align 16\n" \ 195 - "903: addl $4, %%esp;\n" \ 195 + "903: lea 4(%%esp), %%esp;\n" \ 196 196 " pushl %[thunk_target];\n" \ 197 197 " ret;\n" \ 198 198 " .align 16\n" \
+53 -15
arch/x86/kernel/apic/apic.c
··· 722 722 static __initdata unsigned long lapic_cal_j1, lapic_cal_j2; 723 723 724 724 /* 725 - * Temporary interrupt handler. 725 + * Temporary interrupt handler and polled calibration function. 726 726 */ 727 727 static void __init lapic_cal_handler(struct clock_event_device *dev) 728 728 { ··· 851 851 static int __init calibrate_APIC_clock(void) 852 852 { 853 853 struct clock_event_device *levt = this_cpu_ptr(&lapic_events); 854 - void (*real_handler)(struct clock_event_device *dev); 854 + u64 tsc_perj = 0, tsc_start = 0; 855 + unsigned long jif_start; 855 856 unsigned long deltaj; 856 857 long delta, deltatsc; 857 858 int pm_referenced = 0; ··· 879 878 apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n" 880 879 "calibrating APIC timer ...\n"); 881 880 881 + /* 882 + * There are platforms w/o global clockevent devices. Instead of 883 + * making the calibration conditional on that, use a polling based 884 + * approach everywhere. 885 + */ 882 886 local_irq_disable(); 883 - 884 - /* Replace the global interrupt handler */ 885 - real_handler = global_clock_event->event_handler; 886 - global_clock_event->event_handler = lapic_cal_handler; 887 887 888 888 /* 889 889 * Setup the APIC counter to maximum. There is no way the lapic ··· 892 890 */ 893 891 __setup_APIC_LVTT(0xffffffff, 0, 0); 894 892 895 - /* Let the interrupts run */ 893 + /* 894 + * Methods to terminate the calibration loop: 895 + * 1) Global clockevent if available (jiffies) 896 + * 2) TSC if available and frequency is known 897 + */ 898 + jif_start = READ_ONCE(jiffies); 899 + 900 + if (tsc_khz) { 901 + tsc_start = rdtsc(); 902 + tsc_perj = div_u64((u64)tsc_khz * 1000, HZ); 903 + } 904 + 905 + /* 906 + * Enable interrupts so the tick can fire, if a global 907 + * clockevent device is available 908 + */ 896 909 local_irq_enable(); 897 910 898 - while (lapic_cal_loops <= LAPIC_CAL_LOOPS) 899 - cpu_relax(); 911 + while (lapic_cal_loops <= LAPIC_CAL_LOOPS) { 912 + /* Wait for a tick to elapse */ 913 + while (1) { 914 + if (tsc_khz) { 915 + u64 tsc_now = rdtsc(); 916 + if ((tsc_now - tsc_start) >= tsc_perj) { 917 + tsc_start += tsc_perj; 918 + break; 919 + } 920 + } else { 921 + unsigned long jif_now = READ_ONCE(jiffies); 922 + 923 + if (time_after(jif_now, jif_start)) { 924 + jif_start = jif_now; 925 + break; 926 + } 927 + } 928 + cpu_relax(); 929 + } 930 + 931 + /* Invoke the calibration routine */ 932 + local_irq_disable(); 933 + lapic_cal_handler(NULL); 934 + local_irq_enable(); 935 + } 900 936 901 937 local_irq_disable(); 902 - 903 - /* Restore the real event handler */ 904 - global_clock_event->event_handler = real_handler; 905 938 906 939 /* Build delta t1-t2 as apic timer counts down */ 907 940 delta = lapic_cal_t1 - lapic_cal_t2; ··· 980 943 levt->features &= ~CLOCK_EVT_FEAT_DUMMY; 981 944 982 945 /* 983 - * PM timer calibration failed or not turned on 984 - * so lets try APIC timer based calibration 946 + * PM timer calibration failed or not turned on so lets try APIC 947 + * timer based calibration, if a global clockevent device is 948 + * available. 985 949 */ 986 - if (!pm_referenced) { 950 + if (!pm_referenced && global_clock_event) { 987 951 apic_printk(APIC_VERBOSE, "... verify APIC timer\n"); 988 952 989 953 /*
+66
arch/x86/kernel/cpu/amd.c
··· 804 804 msr_set_bit(MSR_AMD64_DE_CFG, 31); 805 805 } 806 806 807 + static bool rdrand_force; 808 + 809 + static int __init rdrand_cmdline(char *str) 810 + { 811 + if (!str) 812 + return -EINVAL; 813 + 814 + if (!strcmp(str, "force")) 815 + rdrand_force = true; 816 + else 817 + return -EINVAL; 818 + 819 + return 0; 820 + } 821 + early_param("rdrand", rdrand_cmdline); 822 + 823 + static void clear_rdrand_cpuid_bit(struct cpuinfo_x86 *c) 824 + { 825 + /* 826 + * Saving of the MSR used to hide the RDRAND support during 827 + * suspend/resume is done by arch/x86/power/cpu.c, which is 828 + * dependent on CONFIG_PM_SLEEP. 829 + */ 830 + if (!IS_ENABLED(CONFIG_PM_SLEEP)) 831 + return; 832 + 833 + /* 834 + * The nordrand option can clear X86_FEATURE_RDRAND, so check for 835 + * RDRAND support using the CPUID function directly. 836 + */ 837 + if (!(cpuid_ecx(1) & BIT(30)) || rdrand_force) 838 + return; 839 + 840 + msr_clear_bit(MSR_AMD64_CPUID_FN_1, 62); 841 + 842 + /* 843 + * Verify that the CPUID change has occurred in case the kernel is 844 + * running virtualized and the hypervisor doesn't support the MSR. 845 + */ 846 + if (cpuid_ecx(1) & BIT(30)) { 847 + pr_info_once("BIOS may not properly restore RDRAND after suspend, but hypervisor does not support hiding RDRAND via CPUID.\n"); 848 + return; 849 + } 850 + 851 + clear_cpu_cap(c, X86_FEATURE_RDRAND); 852 + pr_info_once("BIOS may not properly restore RDRAND after suspend, hiding RDRAND via CPUID. Use rdrand=force to reenable.\n"); 853 + } 854 + 855 + static void init_amd_jg(struct cpuinfo_x86 *c) 856 + { 857 + /* 858 + * Some BIOS implementations do not restore proper RDRAND support 859 + * across suspend and resume. Check on whether to hide the RDRAND 860 + * instruction support via CPUID. 861 + */ 862 + clear_rdrand_cpuid_bit(c); 863 + } 864 + 807 865 static void init_amd_bd(struct cpuinfo_x86 *c) 808 866 { 809 867 u64 value; ··· 876 818 wrmsrl_safe(MSR_F15H_IC_CFG, value); 877 819 } 878 820 } 821 + 822 + /* 823 + * Some BIOS implementations do not restore proper RDRAND support 824 + * across suspend and resume. Check on whether to hide the RDRAND 825 + * instruction support via CPUID. 826 + */ 827 + clear_rdrand_cpuid_bit(c); 879 828 } 880 829 881 830 static void init_amd_zn(struct cpuinfo_x86 *c) ··· 925 860 case 0x10: init_amd_gh(c); break; 926 861 case 0x12: init_amd_ln(c); break; 927 862 case 0x15: init_amd_bd(c); break; 863 + case 0x16: init_amd_jg(c); break; 928 864 case 0x17: init_amd_zn(c); break; 929 865 } 930 866
+73 -13
arch/x86/power/cpu.c
··· 12 12 #include <linux/smp.h> 13 13 #include <linux/perf_event.h> 14 14 #include <linux/tboot.h> 15 + #include <linux/dmi.h> 15 16 16 17 #include <asm/pgtable.h> 17 18 #include <asm/proto.h> ··· 24 23 #include <asm/debugreg.h> 25 24 #include <asm/cpu.h> 26 25 #include <asm/mmu_context.h> 27 - #include <linux/dmi.h> 26 + #include <asm/cpu_device_id.h> 28 27 29 28 #ifdef CONFIG_X86_32 30 29 __visible unsigned long saved_context_ebx; ··· 398 397 399 398 core_initcall(bsp_pm_check_init); 400 399 401 - static int msr_init_context(const u32 *msr_id, const int total_num) 400 + static int msr_build_context(const u32 *msr_id, const int num) 402 401 { 403 - int i = 0; 402 + struct saved_msrs *saved_msrs = &saved_context.saved_msrs; 404 403 struct saved_msr *msr_array; 404 + int total_num; 405 + int i, j; 405 406 406 - if (saved_context.saved_msrs.array || saved_context.saved_msrs.num > 0) { 407 - pr_err("x86/pm: MSR quirk already applied, please check your DMI match table.\n"); 408 - return -EINVAL; 409 - } 407 + total_num = saved_msrs->num + num; 410 408 411 409 msr_array = kmalloc_array(total_num, sizeof(struct saved_msr), GFP_KERNEL); 412 410 if (!msr_array) { ··· 413 413 return -ENOMEM; 414 414 } 415 415 416 - for (i = 0; i < total_num; i++) { 417 - msr_array[i].info.msr_no = msr_id[i]; 416 + if (saved_msrs->array) { 417 + /* 418 + * Multiple callbacks can invoke this function, so copy any 419 + * MSR save requests from previous invocations. 420 + */ 421 + memcpy(msr_array, saved_msrs->array, 422 + sizeof(struct saved_msr) * saved_msrs->num); 423 + 424 + kfree(saved_msrs->array); 425 + } 426 + 427 + for (i = saved_msrs->num, j = 0; i < total_num; i++, j++) { 428 + msr_array[i].info.msr_no = msr_id[j]; 418 429 msr_array[i].valid = false; 419 430 msr_array[i].info.reg.q = 0; 420 431 } 421 - saved_context.saved_msrs.num = total_num; 422 - saved_context.saved_msrs.array = msr_array; 432 + saved_msrs->num = total_num; 433 + saved_msrs->array = msr_array; 423 434 424 435 return 0; 425 436 } 426 437 427 438 /* 428 - * The following section is a quirk framework for problematic BIOSen: 439 + * The following sections are a quirk framework for problematic BIOSen: 429 440 * Sometimes MSRs are modified by the BIOSen after suspended to 430 441 * RAM, this might cause unexpected behavior after wakeup. 431 442 * Thus we save/restore these specified MSRs across suspend/resume ··· 451 440 u32 bdw_msr_id[] = { MSR_IA32_THERM_CONTROL }; 452 441 453 442 pr_info("x86/pm: %s detected, MSR saving is needed during suspending.\n", d->ident); 454 - return msr_init_context(bdw_msr_id, ARRAY_SIZE(bdw_msr_id)); 443 + return msr_build_context(bdw_msr_id, ARRAY_SIZE(bdw_msr_id)); 455 444 } 456 445 457 446 static const struct dmi_system_id msr_save_dmi_table[] = { ··· 466 455 {} 467 456 }; 468 457 458 + static int msr_save_cpuid_features(const struct x86_cpu_id *c) 459 + { 460 + u32 cpuid_msr_id[] = { 461 + MSR_AMD64_CPUID_FN_1, 462 + }; 463 + 464 + pr_info("x86/pm: family %#hx cpu detected, MSR saving is needed during suspending.\n", 465 + c->family); 466 + 467 + return msr_build_context(cpuid_msr_id, ARRAY_SIZE(cpuid_msr_id)); 468 + } 469 + 470 + static const struct x86_cpu_id msr_save_cpu_table[] = { 471 + { 472 + .vendor = X86_VENDOR_AMD, 473 + .family = 0x15, 474 + .model = X86_MODEL_ANY, 475 + .feature = X86_FEATURE_ANY, 476 + .driver_data = (kernel_ulong_t)msr_save_cpuid_features, 477 + }, 478 + { 479 + .vendor = X86_VENDOR_AMD, 480 + .family = 0x16, 481 + .model = X86_MODEL_ANY, 482 + .feature = X86_FEATURE_ANY, 483 + .driver_data = (kernel_ulong_t)msr_save_cpuid_features, 484 + }, 485 + {} 486 + }; 487 + 488 + typedef int (*pm_cpu_match_t)(const struct x86_cpu_id *); 489 + static int pm_cpu_check(const struct x86_cpu_id *c) 490 + { 491 + const struct x86_cpu_id *m; 492 + int ret = 0; 493 + 494 + m = x86_match_cpu(msr_save_cpu_table); 495 + if (m) { 496 + pm_cpu_match_t fn; 497 + 498 + fn = (pm_cpu_match_t)m->driver_data; 499 + ret = fn(m); 500 + } 501 + 502 + return ret; 503 + } 504 + 469 505 static int pm_check_save_msr(void) 470 506 { 471 507 dmi_check_system(msr_save_dmi_table); 508 + pm_cpu_check(msr_save_cpu_table); 509 + 472 510 return 0; 473 511 } 474 512