All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Manali Shukla <manali.shukla@amd.com>
Cc: kvm@vger.kernel.org, linux-kselftest@vger.kernel.org,
	pbonzini@redhat.com,  shuah@kernel.org, nikunj@amd.com,
	thomas.lendacky@amd.com,  vkuznets@redhat.com, bp@alien8.de,
	babu.moger@amd.com,  Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
Subject: Re: [PATCH v3 2/4] KVM: SVM: Enable Bus lock threshold exit
Date: Mon, 4 Nov 2024 18:22:38 -0800	[thread overview]
Message-ID: <ZymBbk829lGCY8dp@google.com> (raw)
In-Reply-To: <74089281-3208-435d-93b3-22f1d794dfae@amd.com>

On Sun, Nov 03, 2024, Manali Shukla wrote:
> On 10/15/2024 11:19 PM, Sean Christopherson wrote:
> > On Fri, Oct 04, 2024, Manali Shukla wrote:
> ...
> >>  
> >> +static int bus_lock_exit(struct kvm_vcpu *vcpu)
> >> +{
> >> +	struct vcpu_svm *svm = to_svm(vcpu);
> >> +
> >> +	vcpu->run->exit_reason = KVM_EXIT_X86_BUS_LOCK;
> >> +	vcpu->run->flags |= KVM_RUN_X86_BUS_LOCK;
> >> +
> >> +	/*
> >> +	 * Reload the counter with value greater than '0'.
> > 
> > The value quite obviously must be exactly '1', not simply greater than '0.  I also
> > think this is the wrong place to set the counter.  Rather than set the counter at
> > the time of exit, KVM should implement a vcpu->arch.complete_userspace_io callback
> > and set the counter to '1' if and only if RIP (or LIP, but I have no objection to
> > keeping things simple) is unchanged.  It's a bit of extra complexity, but it will
> > make it super obvious why KVM is setting the counter to '1'.  And, if userspace
> > wants to stuff state and move past the instruction, e.g. by emulating the guilty
> > instruction, then KVM won't unnecessarily allow a bus lock in the guest.
> > 
> > And then the comment can be:
> > 
> > 	/*
> > 	 * If userspace has NOT change RIP, then KVM's ABI is to let the guest
> > 	 * execute the bus-locking instruction.  Set the bus lock counter to '1'
> > 	 * to effectively step past the bus lock.
> > 	 */
> > 
> 
> The bus lock threshold intercept feature is available for SEV-ES and SEV-SNP
> guests too. The rip where the bus lock exit occurred, is not available in
> bus_lock_exit handler for SEV-ES and SEV-SNP guests, so the above-mentioned
> solution won't work with SEV-ES and SEV-SNP guests.
> 
> I would propose to add the above-mentioned solution only for normal and SEV guests
> and unconditionally reloading of bus_lock_counter to 1 in complete_userspace_io
> for SEV-ES and SEV-SNP guests.

Yeah, that works.  Though I would condition the check on guest_state_protected.
Actually, and this is going to seem really stupid, but everything will Just Work
if you use kvm_get_linear_rip() and kvm_is_linear_rip(), because kvm_get_linear_rip()
returns '0' for vCPUs with protected state.  I.e. KVM will do a rather superfluous
cui() callback, but otherwise it's fine.  Silly, but in many ways preferable to
special casing ES and SNP guests.

On a related topic, can you add a refacotring prep patch to move linear_rip out
of kvm_pio_request and place it next to complete_userspace_io?  There's nothing
port I/O specific about that field, it just so happens to that port I/O is the
only case where KVM's ABI is to let userspace stuff state (to emulate RESET)
without first completing the I/O instruction.

I.e.

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 8e8ca6dab2b2..8617b15096a6 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -406,7 +406,6 @@ struct kvm_rmap_head {
 };
 
 struct kvm_pio_request {
-       unsigned long linear_rip;
        unsigned long count;
        int in;
        int port;
@@ -884,6 +883,7 @@ struct kvm_vcpu_arch {
        bool emulate_regs_need_sync_to_vcpu;
        bool emulate_regs_need_sync_from_vcpu;
        int (*complete_userspace_io)(struct kvm_vcpu *vcpu);
+       unsigned long cui_linear_rip;
 
        gpa_t time;
        struct pvclock_vcpu_time_info hv_clock;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 425a301911a6..7704d3901481 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -9308,7 +9308,7 @@ static int complete_fast_pio_out(struct kvm_vcpu *vcpu)
 {
        vcpu->arch.pio.count = 0;
 
-       if (unlikely(!kvm_is_linear_rip(vcpu, vcpu->arch.pio.linear_rip)))
+       if (unlikely(!kvm_is_linear_rip(vcpu, vcpu->arch.cui_linear_rip)))
                return 1;
 
        return kvm_skip_emulated_instruction(vcpu);
@@ -9333,7 +9333,7 @@ static int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size,
                        complete_fast_pio_out_port_0x7e;
                kvm_skip_emulated_instruction(vcpu);
        } else {
-               vcpu->arch.pio.linear_rip = kvm_get_linear_rip(vcpu);
+               vcpu->arch.cui_linear_rip = kvm_get_linear_rip(vcpu);
                vcpu->arch.complete_userspace_io = complete_fast_pio_out;
        }
        return 0;
@@ -9346,7 +9346,7 @@ static int complete_fast_pio_in(struct kvm_vcpu *vcpu)
        /* We should only ever be called with arch.pio.count equal to 1 */
        BUG_ON(vcpu->arch.pio.count != 1);
 
-       if (unlikely(!kvm_is_linear_rip(vcpu, vcpu->arch.pio.linear_rip))) {
+       if (unlikely(!kvm_is_linear_rip(vcpu, vcpu->arch.cui_linear_rip))) {
                vcpu->arch.pio.count = 0;
                return 1;
        }
@@ -9375,7 +9375,7 @@ static int kvm_fast_pio_in(struct kvm_vcpu *vcpu, int size,
                return ret;
        }
 
-       vcpu->arch.pio.linear_rip = kvm_get_linear_rip(vcpu);
+       vcpu->arch.cui_linear_rip = kvm_get_linear_rip(vcpu);
        vcpu->arch.complete_userspace_io = complete_fast_pio_in;
 
        return 0;

  reply	other threads:[~2024-11-05  2:22 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-04  5:33 [PATCH v3 0/4] Add support for the Bus Lock Threshold Manali Shukla
2024-10-04  5:33 ` [PATCH v3 1/4] x86/cpufeatures: Add CPUID feature bit " Manali Shukla
2024-10-06  6:26   ` Borislav Petkov
2024-10-07  4:39     ` Manali Shukla
2024-10-04  5:33 ` [PATCH v3 2/4] KVM: SVM: Enable Bus lock threshold exit Manali Shukla
2024-10-15 17:49   ` Sean Christopherson
2024-10-18 11:35     ` Manali Shukla
2024-11-03 14:23     ` Manali Shukla
2024-11-05  2:22       ` Sean Christopherson [this message]
2024-11-05 15:41         ` Manali Shukla
2024-10-04  5:33 ` [PATCH v3 3/4] KVM: X86: Add documentation about behavioral difference for KVM_EXIT_BUS_LOCK Manali Shukla
2024-10-15 18:15   ` Sean Christopherson
2024-10-04  5:33 ` [PATCH v3 4/4] KVM: selftests: Add bus lock exit test Manali Shukla
2024-10-06  3:34   ` kernel test robot

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=ZymBbk829lGCY8dp@google.com \
    --to=seanjc@google.com \
    --cc=Neeraj.Upadhyay@amd.com \
    --cc=babu.moger@amd.com \
    --cc=bp@alien8.de \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=manali.shukla@amd.com \
    --cc=nikunj@amd.com \
    --cc=pbonzini@redhat.com \
    --cc=shuah@kernel.org \
    --cc=thomas.lendacky@amd.com \
    --cc=vkuznets@redhat.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.