Commit c4db4f20 authored by Sean Christopherson's avatar Sean Christopherson
Browse files

KVM: SVM: Check that the current CPU supports SVM in kvm_is_svm_supported()

Check "this" CPU instead of the boot CPU when querying SVM support so that
the per-CPU checks done during hardware enabling actually function as
intended, i.e. will detect issues where SVM isn't support on all CPUs.

Disable migration for the use from svm_init() mostly so that the standard
accessors for the per-CPU data can be used without getting yelled at by
CONFIG_DEBUG_PREEMPT=y sanity checks.  Preventing the "disabled by BIOS"
error message from reporting the wrong CPU is largely a bonus, as ensuring
a stable CPU during module load is a non-goal for KVM.

Link: https://lore.kernel.org/all/ZAdxNgv0M6P63odE@google.com


Cc: Kai Huang <kai.huang@intel.com>
Cc: Chao Gao <chao.gao@intel.com>
Reviewed-by: default avatarKai Huang <kai.huang@intel.com>
Link: https://lore.kernel.org/r/20230721201859.2307736-15-seanjc@google.com


Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
parent 85fd29dd
Loading
Loading
Loading
Loading
+19 −6
Original line number Diff line number Diff line
@@ -518,18 +518,20 @@ static void svm_init_osvw(struct kvm_vcpu *vcpu)
		vcpu->arch.osvw.status |= 1;
}

static bool kvm_is_svm_supported(void)
static bool __kvm_is_svm_supported(void)
{
	int cpu = raw_smp_processor_id();
	int cpu = smp_processor_id();
	struct cpuinfo_x86 *c = &cpu_data(cpu);

	u64 vm_cr;

	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
	    boot_cpu_data.x86_vendor != X86_VENDOR_HYGON) {
	if (c->x86_vendor != X86_VENDOR_AMD &&
	    c->x86_vendor != X86_VENDOR_HYGON) {
		pr_err("CPU %d isn't AMD or Hygon\n", cpu);
		return false;
	}

	if (!boot_cpu_has(X86_FEATURE_SVM)) {
	if (!cpu_has(c, X86_FEATURE_SVM)) {
		pr_err("SVM not supported by CPU %d\n", cpu);
		return false;
	}
@@ -548,9 +550,20 @@ static bool kvm_is_svm_supported(void)
	return true;
}

static bool kvm_is_svm_supported(void)
{
	bool supported;

	migrate_disable();
	supported = __kvm_is_svm_supported();
	migrate_enable();

	return supported;
}

static int svm_check_processor_compat(void)
{
	if (!kvm_is_svm_supported())
	if (!__kvm_is_svm_supported())
		return -EIO;

	return 0;