KVM: PPC: Book3S HV: Save/restore new PMU registers
authorAthira Rajeev <atrajeev@linux.vnet.ibm.com>
Fri, 17 Jul 2020 14:38:17 +0000 (10:38 -0400)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 22 Jul 2020 11:56:41 +0000 (21:56 +1000)
Power ISA v3.1 has added new performance monitoring unit (PMU) special
purpose registers (SPRs). They are:

Monitor Mode Control Register 3 (MMCR3)
Sampled Instruction Event Register A (SIER2)
Sampled Instruction Event Register B (SIER3)

Add support to save/restore these new SPRs while entering/exiting
guest. Also include changes to support KVM_REG_PPC_MMCR3/SIER2/SIER3.
Add new SPRs to KVM API documentation.

Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/1594996707-3727-6-git-send-email-atrajeev@linux.vnet.ibm.com
Documentation/virt/kvm/api.rst
arch/powerpc/include/asm/kvm_book3s_asm.h
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/include/uapi/asm/kvm.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_hv_interrupts.S
arch/powerpc/kvm/book3s_hv_rmhandlers.S
tools/arch/powerpc/include/uapi/asm/kvm.h

index 426f94582b7a1a58a21e7e703beb3bc052440f90..8cb6eb76c1292a65fa7ae9ca462e7cb81c52c614 100644 (file)
@@ -2156,9 +2156,12 @@ registers, find a list below:
   PPC     KVM_REG_PPC_MMCRA               64
   PPC     KVM_REG_PPC_MMCR2               64
   PPC     KVM_REG_PPC_MMCRS               64
+  PPC     KVM_REG_PPC_MMCR3               64
   PPC     KVM_REG_PPC_SIAR                64
   PPC     KVM_REG_PPC_SDAR                64
   PPC     KVM_REG_PPC_SIER                64
+  PPC     KVM_REG_PPC_SIER2               64
+  PPC     KVM_REG_PPC_SIER3               64
   PPC     KVM_REG_PPC_PMC1                32
   PPC     KVM_REG_PPC_PMC2                32
   PPC     KVM_REG_PPC_PMC3                32
index 45704f2716e2d95cf0f898196d745acdf941369f..078f4648ea27ff431ffa657523356af71990e130 100644 (file)
@@ -119,7 +119,7 @@ struct kvmppc_host_state {
        void __iomem *xive_tima_virt;
        u32 saved_xirr;
        u64 dabr;
-       u64 host_mmcr[7];       /* MMCR 0,1,A, SIAR, SDAR, MMCR2, SIER */
+       u64 host_mmcr[10];      /* MMCR 0,1,A, SIAR, SDAR, MMCR2, SIER, MMCR3, SIER2/3 */
        u32 host_pmc[8];
        u64 host_purr;
        u64 host_spurr;
index 80b0005a722436c8b0c4480d891e637280476251..e020d269416d633f45b3fb19e8670f3728dbd4dd 100644 (file)
@@ -637,14 +637,14 @@ struct kvm_vcpu_arch {
        u32 ccr1;
        u32 dbsr;
 
-       u64 mmcr[3];    /* MMCR0, MMCR1, MMCR2 */
+       u64 mmcr[4];    /* MMCR0, MMCR1, MMCR2, MMCR3 */
        u64 mmcra;
        u64 mmcrs;
        u32 pmc[8];
        u32 spmc[2];
        u64 siar;
        u64 sdar;
-       u64 sier;
+       u64 sier[3];
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
        u64 tfhar;
        u64 texasr;
index 264e266a85bf6a99c5b27b47733ad5f11b5e02d5..c3af3f324c5ad14625baf14fa488b2aa104240c3 100644 (file)
@@ -640,6 +640,11 @@ struct kvm_ppc_cpu_char {
 #define KVM_REG_PPC_ONLINE     (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbf)
 #define KVM_REG_PPC_PTCR       (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc0)
 
+/* POWER10 registers */
+#define KVM_REG_PPC_MMCR3      (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc1)
+#define KVM_REG_PPC_SIER2      (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc2)
+#define KVM_REG_PPC_SIER3      (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc3)
+
 /* Transactional Memory checkpointed state:
  * This is all GPRs, all VSX regs and a subset of SPRs
  */
index 6fa4853691dec7387ef740963bb110a3e8c71b64..8711c2164b45af553d1c097ba26bad90cf65f2f3 100644 (file)
@@ -698,6 +698,9 @@ int main(void)
        HSTATE_FIELD(HSTATE_SDAR, host_mmcr[4]);
        HSTATE_FIELD(HSTATE_MMCR2, host_mmcr[5]);
        HSTATE_FIELD(HSTATE_SIER, host_mmcr[6]);
+       HSTATE_FIELD(HSTATE_MMCR3, host_mmcr[7]);
+       HSTATE_FIELD(HSTATE_SIER2, host_mmcr[8]);
+       HSTATE_FIELD(HSTATE_SIER3, host_mmcr[9]);
        HSTATE_FIELD(HSTATE_PMC1, host_pmc[0]);
        HSTATE_FIELD(HSTATE_PMC2, host_pmc[1]);
        HSTATE_FIELD(HSTATE_PMC3, host_pmc[2]);
index b10bb404f0d54573d94c1d21531861114c18f27a..0a0df31987f75d3802239c51d2e1f61c11ea443a 100644 (file)
@@ -1692,6 +1692,9 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
        case KVM_REG_PPC_MMCRS:
                *val = get_reg_val(id, vcpu->arch.mmcrs);
                break;
+       case KVM_REG_PPC_MMCR3:
+               *val = get_reg_val(id, vcpu->arch.mmcr[3]);
+               break;
        case KVM_REG_PPC_PMC1 ... KVM_REG_PPC_PMC8:
                i = id - KVM_REG_PPC_PMC1;
                *val = get_reg_val(id, vcpu->arch.pmc[i]);
@@ -1707,7 +1710,13 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
                *val = get_reg_val(id, vcpu->arch.sdar);
                break;
        case KVM_REG_PPC_SIER:
-               *val = get_reg_val(id, vcpu->arch.sier);
+               *val = get_reg_val(id, vcpu->arch.sier[0]);
+               break;
+       case KVM_REG_PPC_SIER2:
+               *val = get_reg_val(id, vcpu->arch.sier[1]);
+               break;
+       case KVM_REG_PPC_SIER3:
+               *val = get_reg_val(id, vcpu->arch.sier[2]);
                break;
        case KVM_REG_PPC_IAMR:
                *val = get_reg_val(id, vcpu->arch.iamr);
@@ -1922,6 +1931,9 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
        case KVM_REG_PPC_MMCRS:
                vcpu->arch.mmcrs = set_reg_val(id, *val);
                break;
+       case KVM_REG_PPC_MMCR3:
+               *val = get_reg_val(id, vcpu->arch.mmcr[3]);
+               break;
        case KVM_REG_PPC_PMC1 ... KVM_REG_PPC_PMC8:
                i = id - KVM_REG_PPC_PMC1;
                vcpu->arch.pmc[i] = set_reg_val(id, *val);
@@ -1937,7 +1949,13 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
                vcpu->arch.sdar = set_reg_val(id, *val);
                break;
        case KVM_REG_PPC_SIER:
-               vcpu->arch.sier = set_reg_val(id, *val);
+               vcpu->arch.sier[0] = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_SIER2:
+               vcpu->arch.sier[1] = set_reg_val(id, *val);
+               break;
+       case KVM_REG_PPC_SIER3:
+               vcpu->arch.sier[2] = set_reg_val(id, *val);
                break;
        case KVM_REG_PPC_IAMR:
                vcpu->arch.iamr = set_reg_val(id, *val);
index 63fd81f3039dd32c3e43503633a57c1a738463df..59822cba454d203427057722fb064e670bc91d6c 100644 (file)
@@ -140,6 +140,14 @@ BEGIN_FTR_SECTION
        std     r8, HSTATE_MMCR2(r13)
        std     r9, HSTATE_SIER(r13)
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
+BEGIN_FTR_SECTION
+       mfspr   r5, SPRN_MMCR3
+       mfspr   r6, SPRN_SIER2
+       mfspr   r7, SPRN_SIER3
+       std     r5, HSTATE_MMCR3(r13)
+       std     r6, HSTATE_SIER2(r13)
+       std     r7, HSTATE_SIER3(r13)
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_31)
        mfspr   r3, SPRN_PMC1
        mfspr   r5, SPRN_PMC2
        mfspr   r6, SPRN_PMC3
index 702eaa253042151fde26586f83dbc89bb418e05f..799d6d0f4eadee541e016eeb0aec1c92e75c0b33 100644 (file)
@@ -3435,6 +3435,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_PMAO_BUG)
        mtspr   SPRN_MMCRA, r6
        mtspr   SPRN_SIAR, r7
        mtspr   SPRN_SDAR, r8
+BEGIN_FTR_SECTION
+       ld      r5, VCPU_MMCR + 24(r4)
+       ld      r6, VCPU_SIER + 8(r4)
+       ld      r7, VCPU_SIER + 16(r4)
+       mtspr   SPRN_MMCR3, r5
+       mtspr   SPRN_SIER2, r6
+       mtspr   SPRN_SIER3, r7
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_31)
 BEGIN_FTR_SECTION
        ld      r5, VCPU_MMCR + 16(r4)
        ld      r6, VCPU_SIER(r4)
@@ -3496,6 +3504,14 @@ BEGIN_FTR_SECTION
        mtspr   SPRN_MMCR2, r8
        mtspr   SPRN_SIER, r9
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
+BEGIN_FTR_SECTION
+       ld      r5, HSTATE_MMCR3(r13)
+       ld      r6, HSTATE_SIER2(r13)
+       ld      r7, HSTATE_SIER3(r13)
+       mtspr   SPRN_MMCR3, r5
+       mtspr   SPRN_SIER2, r6
+       mtspr   SPRN_SIER3, r7
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_31)
        mtspr   SPRN_MMCR0, r3
        isync
        mtlr    r0
@@ -3555,6 +3571,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 BEGIN_FTR_SECTION
        std     r10, VCPU_MMCR + 16(r9)
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
+BEGIN_FTR_SECTION
+       mfspr   r5, SPRN_MMCR3
+       mfspr   r6, SPRN_SIER2
+       mfspr   r7, SPRN_SIER3
+       std     r5, VCPU_MMCR + 24(r9)
+       std     r6, VCPU_SIER + 8(r9)
+       std     r7, VCPU_SIER + 16(r9)
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_31)
        std     r7, VCPU_SIAR(r9)
        std     r8, VCPU_SDAR(r9)
        mfspr   r3, SPRN_PMC1
index 264e266a85bf6a99c5b27b47733ad5f11b5e02d5..c3af3f324c5ad14625baf14fa488b2aa104240c3 100644 (file)
@@ -640,6 +640,11 @@ struct kvm_ppc_cpu_char {
 #define KVM_REG_PPC_ONLINE     (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbf)
 #define KVM_REG_PPC_PTCR       (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc0)
 
+/* POWER10 registers */
+#define KVM_REG_PPC_MMCR3      (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc1)
+#define KVM_REG_PPC_SIER2      (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc2)
+#define KVM_REG_PPC_SIER3      (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc3)
+
 /* Transactional Memory checkpointed state:
  * This is all GPRs, all VSX regs and a subset of SPRs
  */