Nicholas Piggin <npig...@gmail.com> writes:

> LPCR[HDICE]=0 suppresses hypervisor decrementer exceptions on some
> processors, so it must be enabled before HDEC is set.
>
> Rather than set it in the host LPCR then setting HDEC, move the HDEC
> update to after the guest MMU context (including LPCR) is loaded.
> There shouldn't be much concern with delaying HDEC by some 10s or 100s
> of nanoseconds by setting it a bit later.
>
> Signed-off-by: Nicholas Piggin <npig...@gmail.com>
> ---
>  arch/powerpc/kvm/book3s_hv.c | 24 ++++++++++--------------
>  1 file changed, 10 insertions(+), 14 deletions(-)
>
> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
> index d4770b222d7e..63cc92c45c5d 100644
> --- a/arch/powerpc/kvm/book3s_hv.c
> +++ b/arch/powerpc/kvm/book3s_hv.c
> @@ -3490,23 +3490,13 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu 
> *vcpu, u64 time_limit,
>               host_dawrx1 = mfspr(SPRN_DAWRX1);
>       }
>
> -     /*
> -      * P8 and P9 suppress the HDEC exception when LPCR[HDICE] = 0,
> -      * so set HDICE before writing HDEC.
> -      */
> -     mtspr(SPRN_LPCR, kvm->arch.host_lpcr | LPCR_HDICE);
> -     isync();
> -
> -     hdec = time_limit - mftb();

Would it be possible to leave the mftb() in this patch and then replace
them all at once in patch 20/37 - "KVM: PPC: Book3S HV P9: Reduce mftb
per guest entry/exit"?

> -     if (hdec < 0) {
> -             mtspr(SPRN_LPCR, kvm->arch.host_lpcr);
> -             isync();
> +     tb = mftb();
> +     hdec = time_limit - tb;
> +     if (hdec < 0)
>               return BOOK3S_INTERRUPT_HV_DECREMENTER;
> -     }
> -     mtspr(SPRN_HDEC, hdec);
>
>       if (vc->tb_offset) {
> -             u64 new_tb = mftb() + vc->tb_offset;
> +             u64 new_tb = tb + vc->tb_offset;
>               mtspr(SPRN_TBU40, new_tb);
>               tb = mftb();
>               if ((tb & 0xffffff) < (new_tb & 0xffffff))
> @@ -3549,6 +3539,12 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu 
> *vcpu, u64 time_limit,
>
>       switch_mmu_to_guest_radix(kvm, vcpu, lpcr);
>
> +     /*
> +      * P9 suppresses the HDEC exception when LPCR[HDICE] = 0,
> +      * so set guest LPCR (with HDICE) before writing HDEC.
> +      */
> +     mtspr(SPRN_HDEC, hdec);
> +
>       mtspr(SPRN_SRR0, vcpu->arch.shregs.srr0);
>       mtspr(SPRN_SRR1, vcpu->arch.shregs.srr1);

Reply via email to