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

KVM: SVM: Don't change target vCPU state on AP Creation VMGEXIT error



If KVM rejects an AP Creation event, leave the target vCPU state as-is.
Nothing in the GHCB suggests the hypervisor is *allowed* to muck with vCPU
state on failure, let alone required to do so.  Furthermore, kicking only
in the !ON_INIT case leads to divergent behavior, and even the "kick" case
is non-deterministic.

E.g. if an ON_INIT request fails, the guest can successfully retry if the
fixed AP Creation request is made prior to sending INIT.  And if a !ON_INIT
fails, the guest can successfully retry if the fixed AP Creation request is
handled before the target vCPU processes KVM's
KVM_REQ_UPDATE_PROTECTED_GUEST_STATE.

Fixes: e366f92e ("KVM: SEV: Support SEV-SNP AP Creation NAE event")
Cc: stable@vger.kernel.org
Reviewed-by: default avatarTom Lendacky <thomas.lendacky@amd.com>
Reviewed-by: default avatarPankaj Gupta <pankaj.gupta@amd.com>
Link: https://lore.kernel.org/r/20250227012541.3234589-5-seanjc@google.com


Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
parent 72d12715
Loading
Loading
Loading
Loading
+6 −7
Original line number Diff line number Diff line
@@ -3963,16 +3963,12 @@ static int sev_snp_ap_creation(struct vcpu_svm *svm)

	/*
	 * The target vCPU is valid, so the vCPU will be kicked unless the
	 * request is for CREATE_ON_INIT. For any errors at this stage, the
	 * kick will place the vCPU in an non-runnable state.
	 * request is for CREATE_ON_INIT.
	 */
	kick = true;

	mutex_lock(&target_svm->sev_es.snp_vmsa_mutex);

	target_svm->sev_es.snp_vmsa_gpa = INVALID_PAGE;
	target_svm->sev_es.snp_ap_waiting_for_reset = true;

	/* Interrupt injection mode shouldn't change for AP creation */
	if (request < SVM_VMGEXIT_AP_DESTROY) {
		u64 sev_features;
@@ -4018,20 +4014,23 @@ static int sev_snp_ap_creation(struct vcpu_svm *svm)
		target_svm->sev_es.snp_vmsa_gpa = svm->vmcb->control.exit_info_2;
		break;
	case SVM_VMGEXIT_AP_DESTROY:
		target_svm->sev_es.snp_vmsa_gpa = INVALID_PAGE;
		break;
	default:
		vcpu_unimpl(vcpu, "vmgexit: invalid AP creation request [%#x] from guest\n",
			    request);
		ret = -EINVAL;
		break;
		goto out;
	}

out:
	target_svm->sev_es.snp_ap_waiting_for_reset = true;

	if (kick) {
		kvm_make_request(KVM_REQ_UPDATE_PROTECTED_GUEST_STATE, target_vcpu);
		kvm_vcpu_kick(target_vcpu);
	}

out:
	mutex_unlock(&target_svm->sev_es.snp_vmsa_mutex);

	return ret;