Re: [PATCH v2 3/3] KVM: arm64: Use generic KVM xfer to guest work function

2021-07-31 Thread Sean Christopherson
On Fri, Jul 30, 2021, Oliver Upton wrote:
> 
> On Fri, Jul 30, 2021 at 2:41 AM Marc Zyngier  wrote:
> >
> > On Thu, 29 Jul 2021 23:09:16 +0100, Oliver Upton  wrote:
> > > @@ -714,6 +715,13 @@ static bool vcpu_mode_is_bad_32bit(struct kvm_vcpu 
> > > *vcpu)
> > >   static_branch_unlikely(_mismatched_32bit_el0);
> > >  }
> > >
> > > +static bool kvm_vcpu_exit_request(struct kvm_vcpu *vcpu)
> > > +{
> > > + return kvm_request_pending(vcpu) ||
> > > + need_new_vmid_gen(>arch.hw_mmu->vmid) ||
> > > + xfer_to_guest_mode_work_pending();
> >
> > Here's what xfer_to_guest_mode_work_pending() says:
> >
> > 
> >  * Has to be invoked with interrupts disabled before the transition to
> >  * guest mode.
> > 
> >
> > At the point where you call this, we already are in guest mode, at
> > least in the KVM sense.
> 
> I believe the comment is suggestive of guest mode in the hardware
> sense, not KVM's vcpu->mode designation. I got this from
> arch/x86/kvm/x86.c:vcpu_enter_guest() to infer the author's
> intentions.

Yeah, the comment is referring to hardware guest mode.  The intent is to verify
there is no work to be done before making the expensive world switch.  There's
no meaningful interaction with vcpu->mode, on x86 it's simply more convenient
from a code perspective to throw it into kvm_vcpu_exit_request().
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v2 3/3] KVM: arm64: Use generic KVM xfer to guest work function

2021-07-30 Thread Oliver Upton
On Fri, Jul 30, 2021 at 9:56 AM Sean Christopherson  wrote:
>
> On Fri, Jul 30, 2021, Oliver Upton wrote:
> >
> > On Fri, Jul 30, 2021 at 2:41 AM Marc Zyngier  wrote:
> > >
> > > On Thu, 29 Jul 2021 23:09:16 +0100, Oliver Upton  
> > > wrote:
> > > > @@ -714,6 +715,13 @@ static bool vcpu_mode_is_bad_32bit(struct kvm_vcpu 
> > > > *vcpu)
> > > >   static_branch_unlikely(_mismatched_32bit_el0);
> > > >  }
> > > >
> > > > +static bool kvm_vcpu_exit_request(struct kvm_vcpu *vcpu)
> > > > +{
> > > > + return kvm_request_pending(vcpu) ||
> > > > + need_new_vmid_gen(>arch.hw_mmu->vmid) ||
> > > > + xfer_to_guest_mode_work_pending();
> > >
> > > Here's what xfer_to_guest_mode_work_pending() says:
> > >
> > > 
> > >  * Has to be invoked with interrupts disabled before the transition to
> > >  * guest mode.
> > > 
> > >
> > > At the point where you call this, we already are in guest mode, at
> > > least in the KVM sense.
> >
> > I believe the comment is suggestive of guest mode in the hardware
> > sense, not KVM's vcpu->mode designation. I got this from
> > arch/x86/kvm/x86.c:vcpu_enter_guest() to infer the author's
> > intentions.
>
> Yeah, the comment is referring to hardware guest mode.  The intent is to 
> verify
> there is no work to be done before making the expensive world switch.  There's
> no meaningful interaction with vcpu->mode, on x86 it's simply more convenient
> from a code perspective to throw it into kvm_vcpu_exit_request().

Yep, the same is true for ARM as well, doing it the way it appears in
this patch allows for the recycling of the block to enable irqs and
preemption.

--
Thanks,
Oliver
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v2 3/3] KVM: arm64: Use generic KVM xfer to guest work function

2021-07-30 Thread Oliver Upton
Marc,

On Fri, Jul 30, 2021 at 2:41 AM Marc Zyngier  wrote:
>
> Hi Oliver,
>
> On Thu, 29 Jul 2021 23:09:16 +0100,
> Oliver Upton  wrote:
> >
> > Clean up handling of checks for pending work by switching to the generic
> > infrastructure to do so.
> >
> > We pick up handling for TIF_NOTIFY_RESUME from this switch, meaning that
> > task work will be correctly handled.
> >
> > Signed-off-by: Oliver Upton 
> > ---
> >  arch/arm64/kvm/Kconfig |  1 +
> >  arch/arm64/kvm/arm.c   | 27 ++-
> >  2 files changed, 15 insertions(+), 13 deletions(-)
> >
> > diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
> > index a4eba0908bfa..8bc1fac5fa26 100644
> > --- a/arch/arm64/kvm/Kconfig
> > +++ b/arch/arm64/kvm/Kconfig
> > @@ -26,6 +26,7 @@ menuconfig KVM
> >   select HAVE_KVM_ARCH_TLB_FLUSH_ALL
> >   select KVM_MMIO
> >   select KVM_GENERIC_DIRTYLOG_READ_PROTECT
> > + select KVM_XFER_TO_GUEST_WORK
> >   select SRCU
> >   select KVM_VFIO
> >   select HAVE_KVM_EVENTFD
> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index 60d0a546d7fd..9762e2129813 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -6,6 +6,7 @@
> >
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -714,6 +715,13 @@ static bool vcpu_mode_is_bad_32bit(struct kvm_vcpu 
> > *vcpu)
> >   static_branch_unlikely(_mismatched_32bit_el0);
> >  }
> >
> > +static bool kvm_vcpu_exit_request(struct kvm_vcpu *vcpu)
> > +{
> > + return kvm_request_pending(vcpu) ||
> > + need_new_vmid_gen(>arch.hw_mmu->vmid) ||
> > + xfer_to_guest_mode_work_pending();
>
> Here's what xfer_to_guest_mode_work_pending() says:
>
> 
>  * Has to be invoked with interrupts disabled before the transition to
>  * guest mode.
> 
>
> At the point where you call this, we already are in guest mode, at
> least in the KVM sense.

I believe the comment is suggestive of guest mode in the hardware
sense, not KVM's vcpu->mode designation. I got this from
arch/x86/kvm/x86.c:vcpu_enter_guest() to infer the author's
intentions.

>
> > +}
> > +
> >  /**
> >   * kvm_arch_vcpu_ioctl_run - the main VCPU run function to execute guest 
> > code
> >   * @vcpu:The VCPU pointer
> > @@ -757,7 +765,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
> >   /*
> >* Check conditions before entering the guest
> >*/
> > - cond_resched();
> > + if (__xfer_to_guest_mode_work_pending()) {
> > + ret = xfer_to_guest_mode_handle_work(vcpu);
>
> xfer_to_guest_mode_handle_work() already does the exact equivalent of
> __xfer_to_guest_mode_work_pending(). Why do we need to do it twice?

Right, there's no need to do the check twice.

>
> > + if (!ret)
> > + ret = 1;
> > + }
> >
> >   update_vmid(>arch.hw_mmu->vmid);
> >
> > @@ -776,16 +788,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
> >
> >   kvm_vgic_flush_hwstate(vcpu);
> >
> > - /*
> > -  * Exit if we have a signal pending so that we can deliver the
> > -  * signal to user space.
> > -  */
> > - if (signal_pending(current)) {
> > - ret = -EINTR;
> > - run->exit_reason = KVM_EXIT_INTR;
> > - ++vcpu->stat.signal_exits;
> > - }
> > -
> >   /*
> >* If we're using a userspace irqchip, then check if we need
> >* to tell a userspace irqchip about timer or PMU level
> > @@ -809,8 +811,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
> >*/
> >   smp_store_mb(vcpu->mode, IN_GUEST_MODE);
> >
> > - if (ret <= 0 || need_new_vmid_gen(>arch.hw_mmu->vmid) ||
> > - kvm_request_pending(vcpu)) {
> > + if (ret <= 0 || kvm_vcpu_exit_request(vcpu)) {
>
> If you are doing this, please move the userspace irqchip handling into
> the helper as well, so that we have a single function dealing with
> collecting exit reasons.

Sure thing.

Thanks for the quick review, Marc!

--
Best,
Oliver
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v2 3/3] KVM: arm64: Use generic KVM xfer to guest work function

2021-07-30 Thread Marc Zyngier
Hi Oliver,

On Thu, 29 Jul 2021 23:09:16 +0100,
Oliver Upton  wrote:
> 
> Clean up handling of checks for pending work by switching to the generic
> infrastructure to do so.
> 
> We pick up handling for TIF_NOTIFY_RESUME from this switch, meaning that
> task work will be correctly handled.
> 
> Signed-off-by: Oliver Upton 
> ---
>  arch/arm64/kvm/Kconfig |  1 +
>  arch/arm64/kvm/arm.c   | 27 ++-
>  2 files changed, 15 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
> index a4eba0908bfa..8bc1fac5fa26 100644
> --- a/arch/arm64/kvm/Kconfig
> +++ b/arch/arm64/kvm/Kconfig
> @@ -26,6 +26,7 @@ menuconfig KVM
>   select HAVE_KVM_ARCH_TLB_FLUSH_ALL
>   select KVM_MMIO
>   select KVM_GENERIC_DIRTYLOG_READ_PROTECT
> + select KVM_XFER_TO_GUEST_WORK
>   select SRCU
>   select KVM_VFIO
>   select HAVE_KVM_EVENTFD
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 60d0a546d7fd..9762e2129813 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -6,6 +6,7 @@
>  
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -714,6 +715,13 @@ static bool vcpu_mode_is_bad_32bit(struct kvm_vcpu *vcpu)
>   static_branch_unlikely(_mismatched_32bit_el0);
>  }
>  
> +static bool kvm_vcpu_exit_request(struct kvm_vcpu *vcpu)
> +{
> + return kvm_request_pending(vcpu) ||
> + need_new_vmid_gen(>arch.hw_mmu->vmid) ||
> + xfer_to_guest_mode_work_pending();

Here's what xfer_to_guest_mode_work_pending() says:


 * Has to be invoked with interrupts disabled before the transition to
 * guest mode.


At the point where you call this, we already are in guest mode, at
least in the KVM sense.

> +}
> +
>  /**
>   * kvm_arch_vcpu_ioctl_run - the main VCPU run function to execute guest code
>   * @vcpu:The VCPU pointer
> @@ -757,7 +765,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
>   /*
>* Check conditions before entering the guest
>*/
> - cond_resched();
> + if (__xfer_to_guest_mode_work_pending()) {
> + ret = xfer_to_guest_mode_handle_work(vcpu);

xfer_to_guest_mode_handle_work() already does the exact equivalent of
__xfer_to_guest_mode_work_pending(). Why do we need to do it twice?

> + if (!ret)
> + ret = 1;
> + }
>  
>   update_vmid(>arch.hw_mmu->vmid);
>  
> @@ -776,16 +788,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
>  
>   kvm_vgic_flush_hwstate(vcpu);
>  
> - /*
> -  * Exit if we have a signal pending so that we can deliver the
> -  * signal to user space.
> -  */
> - if (signal_pending(current)) {
> - ret = -EINTR;
> - run->exit_reason = KVM_EXIT_INTR;
> - ++vcpu->stat.signal_exits;
> - }
> -
>   /*
>* If we're using a userspace irqchip, then check if we need
>* to tell a userspace irqchip about timer or PMU level
> @@ -809,8 +811,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
>*/
>   smp_store_mb(vcpu->mode, IN_GUEST_MODE);
>  
> - if (ret <= 0 || need_new_vmid_gen(>arch.hw_mmu->vmid) ||
> - kvm_request_pending(vcpu)) {
> + if (ret <= 0 || kvm_vcpu_exit_request(vcpu)) {

If you are doing this, please move the userspace irqchip handling into
the helper as well, so that we have a single function dealing with
collecting exit reasons.

>   vcpu->mode = OUTSIDE_GUEST_MODE;
>   isb(); /* Ensure work in x_flush_hwstate is committed */
>   kvm_pmu_sync_hwstate(vcpu);

Thanks,

M.

-- 
Without deviation from the norm, progress is not possible.
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


[PATCH v2 3/3] KVM: arm64: Use generic KVM xfer to guest work function

2021-07-29 Thread Oliver Upton
Clean up handling of checks for pending work by switching to the generic
infrastructure to do so.

We pick up handling for TIF_NOTIFY_RESUME from this switch, meaning that
task work will be correctly handled.

Signed-off-by: Oliver Upton 
---
 arch/arm64/kvm/Kconfig |  1 +
 arch/arm64/kvm/arm.c   | 27 ++-
 2 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index a4eba0908bfa..8bc1fac5fa26 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -26,6 +26,7 @@ menuconfig KVM
select HAVE_KVM_ARCH_TLB_FLUSH_ALL
select KVM_MMIO
select KVM_GENERIC_DIRTYLOG_READ_PROTECT
+   select KVM_XFER_TO_GUEST_WORK
select SRCU
select KVM_VFIO
select HAVE_KVM_EVENTFD
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 60d0a546d7fd..9762e2129813 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -6,6 +6,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -714,6 +715,13 @@ static bool vcpu_mode_is_bad_32bit(struct kvm_vcpu *vcpu)
static_branch_unlikely(_mismatched_32bit_el0);
 }
 
+static bool kvm_vcpu_exit_request(struct kvm_vcpu *vcpu)
+{
+   return kvm_request_pending(vcpu) ||
+   need_new_vmid_gen(>arch.hw_mmu->vmid) ||
+   xfer_to_guest_mode_work_pending();
+}
+
 /**
  * kvm_arch_vcpu_ioctl_run - the main VCPU run function to execute guest code
  * @vcpu:  The VCPU pointer
@@ -757,7 +765,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
/*
 * Check conditions before entering the guest
 */
-   cond_resched();
+   if (__xfer_to_guest_mode_work_pending()) {
+   ret = xfer_to_guest_mode_handle_work(vcpu);
+   if (!ret)
+   ret = 1;
+   }
 
update_vmid(>arch.hw_mmu->vmid);
 
@@ -776,16 +788,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 
kvm_vgic_flush_hwstate(vcpu);
 
-   /*
-* Exit if we have a signal pending so that we can deliver the
-* signal to user space.
-*/
-   if (signal_pending(current)) {
-   ret = -EINTR;
-   run->exit_reason = KVM_EXIT_INTR;
-   ++vcpu->stat.signal_exits;
-   }
-
/*
 * If we're using a userspace irqchip, then check if we need
 * to tell a userspace irqchip about timer or PMU level
@@ -809,8 +811,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 */
smp_store_mb(vcpu->mode, IN_GUEST_MODE);
 
-   if (ret <= 0 || need_new_vmid_gen(>arch.hw_mmu->vmid) ||
-   kvm_request_pending(vcpu)) {
+   if (ret <= 0 || kvm_vcpu_exit_request(vcpu)) {
vcpu->mode = OUTSIDE_GUEST_MODE;
isb(); /* Ensure work in x_flush_hwstate is committed */
kvm_pmu_sync_hwstate(vcpu);
-- 
2.32.0.554.ge1b32706d8-goog

___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm