Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b965592a authored by Tom Lendacky's avatar Tom Lendacky Committed by Greg Kroah-Hartman
Browse files

KVM: SVM: Implement VIRT_SPEC_CTRL support for SSBD



commit bc226f07dcd3c9ef0b7f6236fe356ea4a9cb4769 upstream

Expose the new virtualized architectural mechanism, VIRT_SSBD, for using
speculative store bypass disable (SSBD) under SVM.  This will allow guests
to use SSBD on hardware that uses non-architectural mechanisms for enabling
SSBD.

[ tglx: Folded the migration fixup from Paolo Bonzini ]

Signed-off-by: default avatarTom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarDavid Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b0ef8c72
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -864,7 +864,7 @@ struct kvm_x86_ops {
	int (*hardware_setup)(void);               /* __init */
	void (*hardware_unsetup)(void);            /* __exit */
	bool (*cpu_has_accelerated_tpr)(void);
	bool (*cpu_has_high_real_mode_segbase)(void);
	bool (*has_emulated_msr)(int index);
	void (*cpuid_update)(struct kvm_vcpu *vcpu);

	int (*vm_init)(struct kvm *kvm);
+2 −1
Original line number Diff line number Diff line
@@ -735,7 +735,8 @@ static void init_speculation_control(struct cpuinfo_x86 *c)
	if (cpu_has(c, X86_FEATURE_INTEL_STIBP))
		set_cpu_cap(c, X86_FEATURE_STIBP);

	if (cpu_has(c, X86_FEATURE_SPEC_CTRL_SSBD))
	if (cpu_has(c, X86_FEATURE_SPEC_CTRL_SSBD) ||
	    cpu_has(c, X86_FEATURE_VIRT_SSBD))
		set_cpu_cap(c, X86_FEATURE_SSBD);

	if (cpu_has(c, X86_FEATURE_AMD_IBRS)) {
+9 −2
Original line number Diff line number Diff line
@@ -357,7 +357,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,

	/* cpuid 0x80000008.ebx */
	const u32 kvm_cpuid_8000_0008_ebx_x86_features =
		F(AMD_IBPB) | F(AMD_IBRS);
		F(AMD_IBPB) | F(AMD_IBRS) | F(VIRT_SSBD);

	/* cpuid 0xC0000001.edx */
	const u32 kvm_cpuid_C000_0001_edx_x86_features =
@@ -618,13 +618,20 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
			g_phys_as = phys_as;
		entry->eax = g_phys_as | (virt_as << 8);
		entry->edx = 0;
		/* IBRS and IBPB aren't necessarily present in hardware cpuid */
		/*
		 * IBRS, IBPB and VIRT_SSBD aren't necessarily present in
		 * hardware cpuid
		 */
		if (boot_cpu_has(X86_FEATURE_AMD_IBPB))
			entry->ebx |= F(AMD_IBPB);
		if (boot_cpu_has(X86_FEATURE_AMD_IBRS))
			entry->ebx |= F(AMD_IBRS);
		if (boot_cpu_has(X86_FEATURE_VIRT_SSBD))
			entry->ebx |= F(VIRT_SSBD);
		entry->ebx &= kvm_cpuid_8000_0008_ebx_x86_features;
		cpuid_mask(&entry->ebx, CPUID_8000_0008_EBX);
		if (boot_cpu_has(X86_FEATURE_LS_CFG_SSBD))
			entry->ebx |= F(VIRT_SSBD);
		break;
	}
	case 0x80000019:
+9 −0
Original line number Diff line number Diff line
@@ -190,6 +190,15 @@ static inline bool guest_cpuid_has_arch_capabilities(struct kvm_vcpu *vcpu)
	return best && (best->edx & bit(X86_FEATURE_ARCH_CAPABILITIES));
}

static inline bool guest_cpuid_has_virt_ssbd(struct kvm_vcpu *vcpu)
{
	struct kvm_cpuid_entry2 *best;

	best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0);
	return best && (best->ebx & bit(X86_FEATURE_VIRT_SSBD));
}



/*
 * NRIPS is provided through cpuidfn 0x8000000a.edx bit 3
+19 −2
Original line number Diff line number Diff line
@@ -3557,6 +3557,13 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)

		msr_info->data = svm->spec_ctrl;
		break;
	case MSR_AMD64_VIRT_SPEC_CTRL:
		if (!msr_info->host_initiated &&
		    !guest_cpuid_has_virt_ssbd(vcpu))
			return 1;

		msr_info->data = svm->virt_spec_ctrl;
		break;
	case MSR_IA32_UCODE_REV:
		msr_info->data = 0x01000065;
		break;
@@ -3691,6 +3698,16 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
			break;
		set_msr_interception(svm->msrpm, MSR_IA32_PRED_CMD, 0, 1);
		break;
	case MSR_AMD64_VIRT_SPEC_CTRL:
		if (!msr->host_initiated &&
		    !guest_cpuid_has_virt_ssbd(vcpu))
			return 1;

		if (data & ~SPEC_CTRL_SSBD)
			return 1;

		svm->virt_spec_ctrl = data;
		break;
	case MSR_STAR:
		svm->vmcb->save.star = data;
		break;
@@ -5150,7 +5167,7 @@ static bool svm_cpu_has_accelerated_tpr(void)
	return false;
}

static bool svm_has_high_real_mode_segbase(void)
static bool svm_has_emulated_msr(int index)
{
	return true;
}
@@ -5467,7 +5484,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
	.hardware_enable = svm_hardware_enable,
	.hardware_disable = svm_hardware_disable,
	.cpu_has_accelerated_tpr = svm_cpu_has_accelerated_tpr,
	.cpu_has_high_real_mode_segbase = svm_has_high_real_mode_segbase,
	.has_emulated_msr = svm_has_emulated_msr,

	.vcpu_create = svm_create_vcpu,
	.vcpu_free = svm_free_vcpu,
Loading