On Fri, Sep 24, 2021 at 05:55:24PM -0700, Sean Christopherson wrote:
> Factor out the "block" part of kvm_vcpu_halt() so that x86 can emulate
> non-halt wait/sleep/block conditions that should not be subjected to
> halt-polling.
> 
> No functional change intended.
> 
> Signed-off-by: Sean Christopherson <[email protected]>

Reviewed-by: David Matlack <[email protected]>

> ---
>  include/linux/kvm_host.h |  1 +
>  virt/kvm/kvm_main.c      | 50 ++++++++++++++++++++++++++++------------
>  2 files changed, 36 insertions(+), 15 deletions(-)
> 
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index d2a8be3fb9ba..655c2b24db2d 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -966,6 +966,7 @@ void kvm_sigset_activate(struct kvm_vcpu *vcpu);
>  void kvm_sigset_deactivate(struct kvm_vcpu *vcpu);
>  
>  void kvm_vcpu_halt(struct kvm_vcpu *vcpu);
> +bool kvm_vcpu_block(struct kvm_vcpu *vcpu);
>  void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu);
>  void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu);
>  bool kvm_vcpu_wake_up(struct kvm_vcpu *vcpu);
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 280cf1dca7db..fe34457530c2 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -3199,6 +3199,34 @@ static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
>       return ret;
>  }
>  
> +/*
> + * Block the vCPU until the vCPU is runnable, an event arrives, or a signal 
> is
> + * pending.  This is mostly used when halting a vCPU, but may also be used
> + * directly for other vCPU non-runnable states, e.g. x86's Wait-For-SIPI.
> + */
> +bool kvm_vcpu_block(struct kvm_vcpu *vcpu)
> +{
> +     bool waited = false;
> +
> +     kvm_arch_vcpu_blocking(vcpu);
> +
> +     prepare_to_rcuwait(&vcpu->wait);
> +     for (;;) {
> +             set_current_state(TASK_INTERRUPTIBLE);
> +
> +             if (kvm_vcpu_check_block(vcpu) < 0)
> +                     break;
> +
> +             waited = true;
> +             schedule();
> +     }
> +     finish_rcuwait(&vcpu->wait);
> +
> +     kvm_arch_vcpu_unblocking(vcpu);
> +
> +     return waited;
> +}
> +
>  static inline void update_halt_poll_stats(struct kvm_vcpu *vcpu, ktime_t 
> start,
>                                         ktime_t end, bool success)
>  {
> @@ -3221,6 +3249,12 @@ static inline void update_halt_poll_stats(struct 
> kvm_vcpu *vcpu, ktime_t start,
>       }
>  }
>  
> +/*
> + * Emulate a vCPU halt condition, e.g. HLT on x86, WFI on arm, etc...  If 
> halt
> + * polling is enabled, busy wait for a short time before blocking to avoid 
> the
> + * expensive block+unblock sequence if a wake event arrives soon after the 
> vCPU
> + * is halted.
> + */
>  void kvm_vcpu_halt(struct kvm_vcpu *vcpu)
>  {
>       bool halt_poll_allowed = !kvm_arch_no_poll(vcpu);
> @@ -3245,21 +3279,7 @@ void kvm_vcpu_halt(struct kvm_vcpu *vcpu)
>               } while (kvm_vcpu_can_poll(cur, stop));
>       }
>  
> -     kvm_arch_vcpu_blocking(vcpu);
> -
> -     prepare_to_rcuwait(&vcpu->wait);
> -     for (;;) {
> -             set_current_state(TASK_INTERRUPTIBLE);
> -
> -             if (kvm_vcpu_check_block(vcpu) < 0)
> -                     break;
> -
> -             waited = true;
> -             schedule();
> -     }
> -     finish_rcuwait(&vcpu->wait);
> -
> -     kvm_arch_vcpu_unblocking(vcpu);
> +     waited = kvm_vcpu_block(vcpu);
>  
>       cur = ktime_get();
>       if (waited) {
> -- 
> 2.33.0.685.g46640cef36-goog
> 
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Reply via email to