KVM: PPC: Book3S HV: Enable guests to use large decrementer mode on POWER9
authorPaul Mackerras <paulus@ozlabs.org>
Mon, 22 May 2017 06:55:16 +0000 (16:55 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Mon, 19 Jun 2017 04:02:04 +0000 (14:02 +1000)
This allows userspace (e.g. QEMU) to enable large decrementer mode for
the guest when running on a POWER9 host, by setting the LPCR_LD bit in
the guest LPCR value.  With this, the guest exit code saves 64 bits of
the guest DEC value on exit.  Other places that use the guest DEC
value check the LPCR_LD bit in the guest LPCR value, and if it is set,
omit the 32-bit sign extension that would otherwise be done.

This doesn't change the DEC emulation used by PR KVM because PR KVM
is not supported on POWER9 yet.

This is partly based on an earlier patch by Oliver O'Halloran.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/kvm/emulate.c

index 9c51ac4b8f3699d256b4a33bd75e2466b856fc3f..3f879c802feb30b4578eda6a2c9b4469b533b070 100644 (file)
@@ -579,7 +579,7 @@ struct kvm_vcpu_arch {
        ulong mcsrr0;
        ulong mcsrr1;
        ulong mcsr;
-       u32 dec;
+       ulong dec;
 #ifdef CONFIG_BOOKE
        u32 decar;
 #endif
index 8d1a365b8edc45fa9f655b77789a0d8602b462fd..ffbb1b35974882c69e909a3d15325715401e6143 100644 (file)
@@ -1143,6 +1143,12 @@ static void kvmppc_set_lpcr(struct kvm_vcpu *vcpu, u64 new_lpcr,
        mask = LPCR_DPFD | LPCR_ILE | LPCR_TC;
        if (cpu_has_feature(CPU_FTR_ARCH_207S))
                mask |= LPCR_AIL;
+       /*
+        * On POWER9, allow userspace to enable large decrementer for the
+        * guest, whether or not the host has it enabled.
+        */
+       if (cpu_has_feature(CPU_FTR_ARCH_300))
+               mask |= LPCR_LD;
 
        /* Broken 32-bit version of LPCR must not clear top bits */
        if (preserve_top32)
index 4888dd494604f101a194a51ff168c44d85c4354d..cc2a86bf09887a4b2625c099183b2fc9e4af3428 100644 (file)
@@ -936,7 +936,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
        mftb    r7
        subf    r3,r7,r8
        mtspr   SPRN_DEC,r3
-       stw     r3,VCPU_DEC(r4)
+       std     r3,VCPU_DEC(r4)
 
        ld      r5, VCPU_SPRG0(r4)
        ld      r6, VCPU_SPRG1(r4)
@@ -1048,7 +1048,13 @@ kvmppc_cede_reentry:             /* r4 = vcpu, r13 = paca */
        li      r0, BOOK3S_INTERRUPT_EXTERNAL
        bne     cr1, 12f
        mfspr   r0, SPRN_DEC
-       cmpwi   r0, 0
+BEGIN_FTR_SECTION
+       /* On POWER9 check whether the guest has large decrementer enabled */
+       andis.  r8, r8, LPCR_LD@h
+       bne     15f
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
+       extsw   r0, r0
+15:    cmpdi   r0, 0
        li      r0, BOOK3S_INTERRUPT_DECREMENTER
        bge     5f
 
@@ -1475,12 +1481,18 @@ mc_cont:
        mtspr   SPRN_SPURR,r4
 
        /* Save DEC */
+       ld      r3, HSTATE_KVM_VCORE(r13)
        mfspr   r5,SPRN_DEC
        mftb    r6
+       /* On P9, if the guest has large decr enabled, don't sign extend */
+BEGIN_FTR_SECTION
+       ld      r4, VCORE_LPCR(r3)
+       andis.  r4, r4, LPCR_LD@h
+       bne     16f
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
        extsw   r5,r5
-       add     r5,r5,r6
+16:    add     r5,r5,r6
        /* r5 is a guest timebase value here, convert to host TB */
-       ld      r3,HSTATE_KVM_VCORE(r13)
        ld      r4,VCORE_TB_OFFSET(r3)
        subf    r5,r4,r5
        std     r5,VCPU_DEC_EXPIRES(r9)
@@ -2402,8 +2414,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
        mfspr   r3, SPRN_DEC
        mfspr   r4, SPRN_HDEC
        mftb    r5
+BEGIN_FTR_SECTION
+       /* On P9 check whether the guest has large decrementer mode enabled */
+       ld      r6, HSTATE_KVM_VCORE(r13)
+       ld      r6, VCORE_LPCR(r6)
+       andis.  r6, r6, LPCR_LD@h
+       bne     68f
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
        extsw   r3, r3
-       EXTEND_HDEC(r4)
+68:    EXTEND_HDEC(r4)
        cmpd    r3, r4
        ble     67f
        mtspr   SPRN_DEC, r4
index c873ffe553624f32ec8e5619981cd12e68fcb61c..4d8b4d6cebff24390c3921857771c34f57014a8f 100644 (file)
@@ -39,7 +39,7 @@ void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
        unsigned long dec_nsec;
        unsigned long long dec_time;
 
-       pr_debug("mtDEC: %x\n", vcpu->arch.dec);
+       pr_debug("mtDEC: %lx\n", vcpu->arch.dec);
        hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
 
 #ifdef CONFIG_PPC_BOOK3S
@@ -109,7 +109,7 @@ static int kvmppc_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
        case SPRN_TBWU: break;
 
        case SPRN_DEC:
-               vcpu->arch.dec = spr_val;
+               vcpu->arch.dec = (u32) spr_val;
                kvmppc_emulate_dec(vcpu);
                break;