Commit 93cd563e authored by Tom Lendacky's avatar Tom Lendacky Committed by Jialin Zhang
Browse files

KVM: x86: Mitigate the cross-thread return address predictions bug

stable inclusion
from stable-v5.15.94
commit 5122e0e44363e3d837592b78bc04222b9d289868
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6FB6C
CVE: CVE-2022-27672

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=5122e0e44363e3d837592b78bc04222b9d289868



--------------------------------

commit 6f0f2d5e upstream.

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: default avatarTom Lendacky <thomas.lendacky@amd.com>
Message-Id: <4019348b5e07148eb4d593380a5f6713b93c9a16.1675956146.git.thomas.lendacky@amd.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarGuo Mengqi <guomengqi3@huawei.com>
Reviewed-by: default avatarWang Weiyang <wangweiyang2@huawei.com>
Reviewed-by: default avatarWeilong Chen <chenweilong@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parent d8f3dbba
Loading
Loading
Loading
Loading
+32 −11
Original line number Diff line number Diff line
@@ -174,6 +174,10 @@ module_param(force_emulation_prefix, bool, S_IRUGO);
int __read_mostly pi_inject_timer = -1;
module_param(pi_inject_timer, bint, S_IRUGO | S_IWUSR);

/* 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
 * usermode, e.g. SYSCALL MSRs and TSC_AUX, can be deferred until the CPU
@@ -3945,10 +3949,15 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
		r = KVM_CLOCK_TSC_STABLE;
		break;
	case KVM_CAP_X86_DISABLE_EXITS:
		r |=  KVM_X86_DISABLE_EXITS_HLT | KVM_X86_DISABLE_EXITS_PAUSE |
		r = KVM_X86_DISABLE_EXITS_PAUSE;

		if (!mitigate_smt_rsb) {
			r |= KVM_X86_DISABLE_EXITS_HLT |
			     KVM_X86_DISABLE_EXITS_CSTATE;

			if (kvm_can_mwait_in_guest())
				r |= KVM_X86_DISABLE_EXITS_MWAIT;
		}
		break;
	case KVM_CAP_X86_SMM:
		/* SMBASE is usually relocated above 1M on modern chipsets,
@@ -5491,15 +5500,26 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
		if (cap->args[0] & ~KVM_X86_DISABLE_VALID_EXITS)
			break;

		if (cap->args[0] & KVM_X86_DISABLE_EXITS_PAUSE)
			kvm->arch.pause_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_PAUSE)
			kvm->arch.pause_in_guest = true;
			if (cap->args[0] & KVM_X86_DISABLE_EXITS_CSTATE)
				kvm->arch.cstate_in_guest = true;
		}

		r = 0;
		break;
	case KVM_CAP_MSR_PLATFORM_INFO:
@@ -11698,6 +11718,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_apicv_update_request);
static int __init kvm_x86_init(void)
{
	kvm_mmu_x86_module_init();
	mitigate_smt_rsb &= boot_cpu_has_bug(X86_BUG_SMT_RSB) && cpu_smt_possible();
	return 0;
}
module_init(kvm_x86_init);