public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	 Naveen N Rao <naveen@kernel.org>,
	Kim Phillips <kim.phillips@amd.com>,
	 Alexey Kardashevskiy <aik@amd.com>
Subject: Re: [PATCH 03/10] KVM: SVM: Terminate the VM if a SEV-ES+ guest is run with an invalid VMSA
Date: Mon, 24 Feb 2025 16:54:08 -0800	[thread overview]
Message-ID: <Z70UsI0kgcZu844d@google.com> (raw)
In-Reply-To: <f9050ee1-3f82-7ae0-68b0-eccae6059fde@amd.com>

On Mon, Feb 24, 2025, Tom Lendacky wrote:
> On 2/24/25 16:55, Sean Christopherson wrote:
> > On Mon, Feb 24, 2025, Tom Lendacky wrote:
> >> On 2/18/25 19:26, Sean Christopherson wrote:
> >>> -void pre_sev_run(struct vcpu_svm *svm, int cpu)
> >>> +int pre_sev_run(struct vcpu_svm *svm, int cpu)
> >>>  {
> >>>  	struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu);
> >>> -	unsigned int asid = sev_get_asid(svm->vcpu.kvm);
> >>> +	struct kvm *kvm = svm->vcpu.kvm;
> >>> +	unsigned int asid = sev_get_asid(kvm);
> >>> +
> >>> +	/*
> >>> +	 * Terminate the VM if userspace attempts to run the vCPU with an
> >>> +	 * invalid VMSA, e.g. if userspace forces the vCPU to be RUNNABLE after
> >>> +	 * an SNP AP Destroy event.
> >>> +	 */
> >>> +	if (sev_es_guest(kvm) && !VALID_PAGE(svm->vmcb->control.vmsa_pa)) {
> >>> +		kvm_vm_dead(kvm);
> >>> +		return -EIO;
> >>> +	}
> >>
> >> If a VMRUN is performed with the vmsa_pa value set to INVALID_PAGE, the
> >> VMRUN will fail and KVM will dump the VMCB and exit back to userspace
> > 
> > I haven't tested, but based on what the APM says, I'm pretty sure this would crash
> > the host due to a #GP on VMRUN, i.e. due to the resulting kvm_spurious_fault().
> > 
> >   IF (rAX contains an unsupported physical address)
> >     EXCEPTION [#GP]
> 
> Well that's for the VMCB, the VMSA is pointed to by the VMCB and results
> in a VMEXIT code of -1 if you don't supply a proper page-aligned,
> physical address.

Ah, good to know (and somewhat of a relief :-) ).

> >>>  static void svm_inject_nmi(struct kvm_vcpu *vcpu)
> >>> @@ -4231,7 +4233,8 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu,
> >>>  	if (force_immediate_exit)
> >>>  		smp_send_reschedule(vcpu->cpu);
> >>>  
> >>> -	pre_svm_run(vcpu);
> >>> +	if (pre_svm_run(vcpu))
> >>> +		return EXIT_FASTPATH_EXIT_USERSPACE;
> 
> In testing this out, I think userspace continues on because I eventually
> get:
> 
> KVM_GET_PIT2 failed: Input/output error
> /tmp/cmdline.98112: line 1: 98163 Aborted (core dumped) ...
> 
> Haven't looked too close, but maybe an exit_reason needs to be set to
> get qemu to quit sooner?

Oh, the irony.  In trying to do the right thing (exit to userspace), I managed to
do the wrong thing.

If KVM tried to re-enter the guest, vcpu_enter_guest() would have encountered
the KVM_REQ_DEAD and exited with -EIO.

		if (kvm_check_request(KVM_REQ_VM_DEAD, vcpu)) {
			r = -EIO;
			goto out;
		}

By returning EXIT_FASTPATH_EXIT_USERSPACE, KVM exited to userspace more directly
and returned '0' instead of -EIO.

Getting KVM to return -EIO is easy, but doing so feels wrong, especially if we
take the quick-and-dirty route like so:

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 454fd6b8f3db..9c8b400e04f2 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -11102,7 +11102,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
                kvm_lapic_sync_from_vapic(vcpu);
 
        if (unlikely(exit_fastpath == EXIT_FASTPATH_EXIT_USERSPACE))
-               return 0;
+               return kvm_test_request(KVM_REQ_VM_DEAD, vcpu) ? -EIO : 0;
 
        r = kvm_x86_call(handle_exit)(vcpu, exit_fastpath);
        return r;

Given that, IIUC, KVM would eventually return KVM_EXIT_FAIL_ENTRY, I like your
idea of returning meaningful information.  And unless I'm missing something, that
would obviate any need to terminate the VM, which would address your earlier point
of whether terminating the VM is truly better than returning than returning a
familiar error code.

So this? (completely untested)

diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 7345cac6f93a..71b340cbe561 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -3463,10 +3463,8 @@ int pre_sev_run(struct vcpu_svm *svm, int cpu)
         * invalid VMSA, e.g. if userspace forces the vCPU to be RUNNABLE after
         * an SNP AP Destroy event.
         */
-       if (sev_es_guest(kvm) && !VALID_PAGE(svm->vmcb->control.vmsa_pa)) {
-               kvm_vm_dead(kvm);
-               return -EIO;
-       }
+       if (sev_es_guest(kvm) && !VALID_PAGE(svm->vmcb->control.vmsa_pa))
+               return -EINVAL;
 
        /* Assign the asid allocated with this SEV guest */
        svm->asid = asid;
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 46e0b65a9fec..f72bcf2e590e 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -4233,8 +4233,12 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu,
        if (force_immediate_exit)
                smp_send_reschedule(vcpu->cpu);
 
-       if (pre_svm_run(vcpu))
+       if (pre_svm_run(vcpu)) {
+               vcpu->run->exit_reason = KVM_EXIT_FAIL_ENTRY;
+               vcpu->run->fail_entry.hardware_entry_failure_reason = SVM_EXIT_ERR;
+               vcpu->run->fail_entry.cpu = vcpu->cpu;
                return EXIT_FASTPATH_EXIT_USERSPACE;
+       }
 
        sync_lapic_to_cr8(vcpu);

  reply	other threads:[~2025-02-25  0:54 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-19  1:26 [PATCH 00/10] KVM: SVM: Attempt to cleanup SEV_FEATURES Sean Christopherson
2025-02-19  1:26 ` [PATCH 01/10] KVM: SVM: Save host DR masks but NOT DRs on CPUs with DebugSwap Sean Christopherson
2025-02-24 19:38   ` Tom Lendacky
2025-02-25  2:22   ` Kim Phillips
2025-02-25 14:12     ` Tom Lendacky
2025-02-19  1:26 ` [PATCH 02/10] KVM: SVM: Don't rely on DebugSwap to restore host DR0..DR3 Sean Christopherson
2025-02-24 20:32   ` Tom Lendacky
2025-02-24 22:32     ` Sean Christopherson
2025-02-19  1:26 ` [PATCH 03/10] KVM: SVM: Terminate the VM if a SEV-ES+ guest is run with an invalid VMSA Sean Christopherson
2025-02-24 21:03   ` Tom Lendacky
2025-02-24 22:55     ` Sean Christopherson
2025-02-24 23:55       ` Tom Lendacky
2025-02-25  0:54         ` Sean Christopherson [this message]
2025-02-25  1:20           ` Sean Christopherson
2025-02-25 14:42           ` Tom Lendacky
2025-02-19  1:26 ` [PATCH 04/10] KVM: SVM: Don't change target vCPU state on AP Creation VMGEXIT error Sean Christopherson
2025-02-24 21:31   ` Tom Lendacky
2025-02-19  1:27 ` [PATCH 05/10] KVM: SVM: Require AP's "requested" SEV_FEATURES to match KVM's view Sean Christopherson
2025-02-24 21:46   ` Tom Lendacky
2025-02-19  1:27 ` [PATCH 06/10] KVM: SVM: Simplify request+kick logic in SNP AP Creation handling Sean Christopherson
2025-02-19  6:19   ` Gupta, Pankaj
2025-02-24 21:48   ` Tom Lendacky
2025-02-19  1:27 ` [PATCH 07/10] KVM: SVM: Use guard(mutex) to simplify SNP AP Creation error handling Sean Christopherson
2025-02-24 21:49   ` Tom Lendacky
2025-02-19  1:27 ` [PATCH 08/10] KVM: SVM: Mark VMCB dirty before processing incoming snp_vmsa_gpa Sean Christopherson
2025-02-24 21:58   ` Tom Lendacky
2025-02-19  1:27 ` [PATCH 09/10] KVM: SVM: Use guard(mutex) to simplify SNP vCPU state updates Sean Christopherson
2025-02-24 22:57   ` Tom Lendacky
2025-02-19  1:27 ` [PATCH 10/10] KVM: SVM: Invalidate "next" SNP VMSA GPA even on failure Sean Christopherson
2025-02-25  0:00   ` Tom Lendacky
2025-02-20 22:51 ` [PATCH 00/10] KVM: SVM: Attempt to cleanup SEV_FEATURES Tom Lendacky
2025-02-25  0:02   ` Tom Lendacky
2025-02-25  2:21     ` Kim Phillips

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Z70UsI0kgcZu844d@google.com \
    --to=seanjc@google.com \
    --cc=aik@amd.com \
    --cc=kim.phillips@amd.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=naveen@kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=thomas.lendacky@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox