mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
synced 2025-09-01 23:46:45 +00:00
KVM: x86: Mitigate the cross-thread return address predictions bug
By default, KVM/SVM will intercept attempts by the guest to transition out of C0. However, the KVM_CAP_X86_DISABLE_EXITS capability can be used by a VMM to change this behavior. To mitigate the cross-thread return address predictions bug (X86_BUG_SMT_RSB), a VMM must not be allowed to override the default behavior to intercept C0 transitions. Use a module parameter to control the mitigation on processors that are vulnerable to X86_BUG_SMT_RSB. If the processor is vulnerable to the X86_BUG_SMT_RSB bug and the module parameter is set to mitigate the bug, KVM will not allow the disabling of the HLT, MWAIT and CSTATE exits. Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Message-Id: <4019348b5e07148eb4d593380a5f6713b93c9a16.1675956146.git.thomas.lendacky@amd.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
be8de49bea
commit
6f0f2d5ef8
@ -191,6 +191,10 @@ module_param(enable_pmu, bool, 0444);
|
|||||||
bool __read_mostly eager_page_split = true;
|
bool __read_mostly eager_page_split = true;
|
||||||
module_param(eager_page_split, bool, 0644);
|
module_param(eager_page_split, bool, 0644);
|
||||||
|
|
||||||
|
/* Enable/disable SMT_RSB bug mitigation */
|
||||||
|
bool __read_mostly mitigate_smt_rsb;
|
||||||
|
module_param(mitigate_smt_rsb, bool, 0444);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Restoring the host value for MSRs that are only consumed when running in
|
* Restoring the host value for MSRs that are only consumed when running in
|
||||||
* usermode, e.g. SYSCALL MSRs and TSC_AUX, can be deferred until the CPU
|
* usermode, e.g. SYSCALL MSRs and TSC_AUX, can be deferred until the CPU
|
||||||
@ -4448,10 +4452,15 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
|
|||||||
r = KVM_CLOCK_VALID_FLAGS;
|
r = KVM_CLOCK_VALID_FLAGS;
|
||||||
break;
|
break;
|
||||||
case KVM_CAP_X86_DISABLE_EXITS:
|
case KVM_CAP_X86_DISABLE_EXITS:
|
||||||
r |= KVM_X86_DISABLE_EXITS_HLT | KVM_X86_DISABLE_EXITS_PAUSE |
|
r = KVM_X86_DISABLE_EXITS_PAUSE;
|
||||||
KVM_X86_DISABLE_EXITS_CSTATE;
|
|
||||||
if(kvm_can_mwait_in_guest())
|
if (!mitigate_smt_rsb) {
|
||||||
r |= KVM_X86_DISABLE_EXITS_MWAIT;
|
r |= KVM_X86_DISABLE_EXITS_HLT |
|
||||||
|
KVM_X86_DISABLE_EXITS_CSTATE;
|
||||||
|
|
||||||
|
if (kvm_can_mwait_in_guest())
|
||||||
|
r |= KVM_X86_DISABLE_EXITS_MWAIT;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case KVM_CAP_X86_SMM:
|
case KVM_CAP_X86_SMM:
|
||||||
if (!IS_ENABLED(CONFIG_KVM_SMM))
|
if (!IS_ENABLED(CONFIG_KVM_SMM))
|
||||||
@ -6227,15 +6236,26 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
|
|||||||
if (cap->args[0] & ~KVM_X86_DISABLE_VALID_EXITS)
|
if (cap->args[0] & ~KVM_X86_DISABLE_VALID_EXITS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ((cap->args[0] & KVM_X86_DISABLE_EXITS_MWAIT) &&
|
|
||||||
kvm_can_mwait_in_guest())
|
|
||||||
kvm->arch.mwait_in_guest = true;
|
|
||||||
if (cap->args[0] & KVM_X86_DISABLE_EXITS_HLT)
|
|
||||||
kvm->arch.hlt_in_guest = true;
|
|
||||||
if (cap->args[0] & KVM_X86_DISABLE_EXITS_PAUSE)
|
if (cap->args[0] & KVM_X86_DISABLE_EXITS_PAUSE)
|
||||||
kvm->arch.pause_in_guest = true;
|
kvm->arch.pause_in_guest = true;
|
||||||
if (cap->args[0] & KVM_X86_DISABLE_EXITS_CSTATE)
|
|
||||||
kvm->arch.cstate_in_guest = true;
|
#define SMT_RSB_MSG "This processor is affected by the Cross-Thread Return Predictions vulnerability. " \
|
||||||
|
"KVM_CAP_X86_DISABLE_EXITS should only be used with SMT disabled or trusted guests."
|
||||||
|
|
||||||
|
if (!mitigate_smt_rsb) {
|
||||||
|
if (boot_cpu_has_bug(X86_BUG_SMT_RSB) && cpu_smt_possible() &&
|
||||||
|
(cap->args[0] & ~KVM_X86_DISABLE_EXITS_PAUSE))
|
||||||
|
pr_warn_once(SMT_RSB_MSG);
|
||||||
|
|
||||||
|
if ((cap->args[0] & KVM_X86_DISABLE_EXITS_MWAIT) &&
|
||||||
|
kvm_can_mwait_in_guest())
|
||||||
|
kvm->arch.mwait_in_guest = true;
|
||||||
|
if (cap->args[0] & KVM_X86_DISABLE_EXITS_HLT)
|
||||||
|
kvm->arch.hlt_in_guest = true;
|
||||||
|
if (cap->args[0] & KVM_X86_DISABLE_EXITS_CSTATE)
|
||||||
|
kvm->arch.cstate_in_guest = true;
|
||||||
|
}
|
||||||
|
|
||||||
r = 0;
|
r = 0;
|
||||||
break;
|
break;
|
||||||
case KVM_CAP_MSR_PLATFORM_INFO:
|
case KVM_CAP_MSR_PLATFORM_INFO:
|
||||||
@ -13456,6 +13476,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_msr_protocol_exit);
|
|||||||
static int __init kvm_x86_init(void)
|
static int __init kvm_x86_init(void)
|
||||||
{
|
{
|
||||||
kvm_mmu_x86_module_init();
|
kvm_mmu_x86_module_init();
|
||||||
|
mitigate_smt_rsb &= boot_cpu_has_bug(X86_BUG_SMT_RSB) && cpu_smt_possible();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
module_init(kvm_x86_init);
|
module_init(kvm_x86_init);
|
||||||
|
Loading…
Reference in New Issue
Block a user