Commit c22ccc4a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'x86_urgent_for_v5.15_rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Borislav Petkov:

 - A FPU fix to properly handle invalid MXCSR values: 32-bit masks them
   out due to historical reasons and 64-bit kernels reject them

 - A fix to clear X86_FEATURE_SMAP when support for is not
   config-enabled

 - Three fixes correcting misspelled Kconfig symbols used in code

 - Two resctrl object cleanup fixes

 - Yet another attempt at fixing the neverending saga of botched x86
   timers, this time because some incredibly smart hardware decides to
   turn off the HPET timer in a low power state - who cares if the OS is
   relying on it...

 - Check the full return value range of an SEV VMGEXIT call to determine
   whether it returned an error

* tag 'x86_urgent_for_v5.15_rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/fpu: Restore the masking out of reserved MXCSR bits
  x86/Kconfig: Correct reference to MWINCHIP3D
  x86/platform/olpc: Correct ifdef symbol to intended CONFIG_OLPC_XO15_SCI
  x86/entry: Clear X86_FEATURE_SMAP when CONFIG_X86_SMAP=n
  x86/entry: Correct reference to intended CONFIG_64_BIT
  x86/resctrl: Fix kfree() of the wrong type in domain_add_cpu()
  x86/resctrl: Free the ctrlval arrays when domain_setup_mon_state() fails
  x86/hpet: Use another crystalball to evaluate HPET usability
  x86/sev: Return an error on a returned non-zero SW_EXITINFO1[31:0]
parents 7fd2bf83 d298b035
...@@ -1405,7 +1405,7 @@ config HIGHMEM4G ...@@ -1405,7 +1405,7 @@ config HIGHMEM4G
config HIGHMEM64G config HIGHMEM64G
bool "64GB" bool "64GB"
depends on !M486SX && !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !WINCHIP3D && !MK6 depends on !M486SX && !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !MWINCHIP3D && !MK6
select X86_PAE select X86_PAE
help help
Select this if you have a 32-bit processor and more than 4 Select this if you have a 32-bit processor and more than 4
......
...@@ -25,7 +25,7 @@ static __always_inline void arch_check_user_regs(struct pt_regs *regs) ...@@ -25,7 +25,7 @@ static __always_inline void arch_check_user_regs(struct pt_regs *regs)
* For !SMAP hardware we patch out CLAC on entry. * For !SMAP hardware we patch out CLAC on entry.
*/ */
if (boot_cpu_has(X86_FEATURE_SMAP) || if (boot_cpu_has(X86_FEATURE_SMAP) ||
(IS_ENABLED(CONFIG_64_BIT) && boot_cpu_has(X86_FEATURE_XENPV))) (IS_ENABLED(CONFIG_64BIT) && boot_cpu_has(X86_FEATURE_XENPV)))
mask |= X86_EFLAGS_AC; mask |= X86_EFLAGS_AC;
WARN_ON_ONCE(flags & mask); WARN_ON_ONCE(flags & mask);
......
...@@ -326,6 +326,7 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c) ...@@ -326,6 +326,7 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c)
#ifdef CONFIG_X86_SMAP #ifdef CONFIG_X86_SMAP
cr4_set_bits(X86_CR4_SMAP); cr4_set_bits(X86_CR4_SMAP);
#else #else
clear_cpu_cap(c, X86_FEATURE_SMAP);
cr4_clear_bits(X86_CR4_SMAP); cr4_clear_bits(X86_CR4_SMAP);
#endif #endif
} }
......
...@@ -527,12 +527,14 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r) ...@@ -527,12 +527,14 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
rdt_domain_reconfigure_cdp(r); rdt_domain_reconfigure_cdp(r);
if (r->alloc_capable && domain_setup_ctrlval(r, d)) { if (r->alloc_capable && domain_setup_ctrlval(r, d)) {
kfree(d); kfree(hw_dom);
return; return;
} }
if (r->mon_capable && domain_setup_mon_state(r, d)) { if (r->mon_capable && domain_setup_mon_state(r, d)) {
kfree(d); kfree(hw_dom->ctrl_val);
kfree(hw_dom->mbps_val);
kfree(hw_dom);
return; return;
} }
......
...@@ -714,12 +714,6 @@ static struct chipset early_qrk[] __initdata = { ...@@ -714,12 +714,6 @@ static struct chipset early_qrk[] __initdata = {
*/ */
{ PCI_VENDOR_ID_INTEL, 0x0f00, { PCI_VENDOR_ID_INTEL, 0x0f00,
PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet}, PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
{ PCI_VENDOR_ID_INTEL, 0x3e20,
PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
{ PCI_VENDOR_ID_INTEL, 0x3ec4,
PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
{ PCI_VENDOR_ID_INTEL, 0x8a12,
PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
{ PCI_VENDOR_ID_BROADCOM, 0x4331, { PCI_VENDOR_ID_BROADCOM, 0x4331,
PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset}, PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset},
{} {}
......
...@@ -379,9 +379,14 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx, ...@@ -379,9 +379,14 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx,
sizeof(fpu->state.fxsave))) sizeof(fpu->state.fxsave)))
return -EFAULT; return -EFAULT;
/* Reject invalid MXCSR values. */ if (IS_ENABLED(CONFIG_X86_64)) {
if (fpu->state.fxsave.mxcsr & ~mxcsr_feature_mask) /* Reject invalid MXCSR values. */
return -EINVAL; if (fpu->state.fxsave.mxcsr & ~mxcsr_feature_mask)
return -EINVAL;
} else {
/* Mask invalid bits out for historical reasons (broken hardware). */
fpu->state.fxsave.mxcsr &= ~mxcsr_feature_mask;
}
/* Enforce XFEATURE_MASK_FPSSE when XSAVE is enabled */ /* Enforce XFEATURE_MASK_FPSSE when XSAVE is enabled */
if (use_xsave()) if (use_xsave())
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <asm/irq_remapping.h> #include <asm/irq_remapping.h>
#include <asm/hpet.h> #include <asm/hpet.h>
#include <asm/time.h> #include <asm/time.h>
#include <asm/mwait.h>
#undef pr_fmt #undef pr_fmt
#define pr_fmt(fmt) "hpet: " fmt #define pr_fmt(fmt) "hpet: " fmt
...@@ -916,6 +917,83 @@ static bool __init hpet_counting(void) ...@@ -916,6 +917,83 @@ static bool __init hpet_counting(void)
return false; return false;
} }
static bool __init mwait_pc10_supported(void)
{
unsigned int eax, ebx, ecx, mwait_substates;
if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
return false;
if (!cpu_feature_enabled(X86_FEATURE_MWAIT))
return false;
if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
return false;
cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates);
return (ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) &&
(ecx & CPUID5_ECX_INTERRUPT_BREAK) &&
(mwait_substates & (0xF << 28));
}
/*
* Check whether the system supports PC10. If so force disable HPET as that
* stops counting in PC10. This check is overbroad as it does not take any
* of the following into account:
*
* - ACPI tables
* - Enablement of intel_idle
* - Command line arguments which limit intel_idle C-state support
*
* That's perfectly fine. HPET is a piece of hardware designed by committee
* and the only reasons why it is still in use on modern systems is the
* fact that it is impossible to reliably query TSC and CPU frequency via
* CPUID or firmware.
*
* If HPET is functional it is useful for calibrating TSC, but this can be
* done via PMTIMER as well which seems to be the last remaining timer on
* X86/INTEL platforms that has not been completely wreckaged by feature
* creep.
*
* In theory HPET support should be removed altogether, but there are older
* systems out there which depend on it because TSC and APIC timer are
* dysfunctional in deeper C-states.
*
* It's only 20 years now that hardware people have been asked to provide
* reliable and discoverable facilities which can be used for timekeeping
* and per CPU timer interrupts.
*
* The probability that this problem is going to be solved in the
* forseeable future is close to zero, so the kernel has to be cluttered
* with heuristics to keep up with the ever growing amount of hardware and
* firmware trainwrecks. Hopefully some day hardware people will understand
* that the approach of "This can be fixed in software" is not sustainable.
* Hope dies last...
*/
static bool __init hpet_is_pc10_damaged(void)
{
unsigned long long pcfg;
/* Check whether PC10 substates are supported */
if (!mwait_pc10_supported())
return false;
/* Check whether PC10 is enabled in PKG C-state limit */
rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, pcfg);
if ((pcfg & 0xF) < 8)
return false;
if (hpet_force_user) {
pr_warn("HPET force enabled via command line, but dysfunctional in PC10.\n");
return false;
}
pr_info("HPET dysfunctional in PC10. Force disabled.\n");
boot_hpet_disable = true;
return true;
}
/** /**
* hpet_enable - Try to setup the HPET timer. Returns 1 on success. * hpet_enable - Try to setup the HPET timer. Returns 1 on success.
*/ */
...@@ -929,6 +1007,9 @@ int __init hpet_enable(void) ...@@ -929,6 +1007,9 @@ int __init hpet_enable(void)
if (!is_hpet_capable()) if (!is_hpet_capable())
return 0; return 0;
if (hpet_is_pc10_damaged())
return 0;
hpet_set_mapping(); hpet_set_mapping();
if (!hpet_virt_address) if (!hpet_virt_address)
return 0; return 0;
......
...@@ -130,6 +130,8 @@ static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb, ...@@ -130,6 +130,8 @@ static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
} else { } else {
ret = ES_VMM_ERROR; ret = ES_VMM_ERROR;
} }
} else if (ghcb->save.sw_exit_info_1 & 0xffffffff) {
ret = ES_VMM_ERROR;
} else { } else {
ret = ES_OK; ret = ES_OK;
} }
......
...@@ -274,7 +274,7 @@ static struct olpc_ec_driver ec_xo1_driver = { ...@@ -274,7 +274,7 @@ static struct olpc_ec_driver ec_xo1_driver = {
static struct olpc_ec_driver ec_xo1_5_driver = { static struct olpc_ec_driver ec_xo1_5_driver = {
.ec_cmd = olpc_xo1_ec_cmd, .ec_cmd = olpc_xo1_ec_cmd,
#ifdef CONFIG_OLPC_XO1_5_SCI #ifdef CONFIG_OLPC_XO15_SCI
/* /*
* XO-1.5 EC wakeups are available when olpc-xo15-sci driver is * XO-1.5 EC wakeups are available when olpc-xo15-sci driver is
* compiled in * compiled in
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment