Commit 5752fe0b authored by Athira Rajeev's avatar Athira Rajeev Committed by Michael Ellerman

KVM: PPC: Book3S HV: Save/restore new PMU registers

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: default avatarAthira Rajeev <atrajeev@linux.vnet.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/1594996707-3727-6-git-send-email-atrajeev@linux.vnet.ibm.com
parent c718547e
...@@ -2156,9 +2156,12 @@ registers, find a list below: ...@@ -2156,9 +2156,12 @@ registers, find a list below:
PPC KVM_REG_PPC_MMCRA 64 PPC KVM_REG_PPC_MMCRA 64
PPC KVM_REG_PPC_MMCR2 64 PPC KVM_REG_PPC_MMCR2 64
PPC KVM_REG_PPC_MMCRS 64 PPC KVM_REG_PPC_MMCRS 64
PPC KVM_REG_PPC_MMCR3 64
PPC KVM_REG_PPC_SIAR 64 PPC KVM_REG_PPC_SIAR 64
PPC KVM_REG_PPC_SDAR 64 PPC KVM_REG_PPC_SDAR 64
PPC KVM_REG_PPC_SIER 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_PMC1 32
PPC KVM_REG_PPC_PMC2 32 PPC KVM_REG_PPC_PMC2 32
PPC KVM_REG_PPC_PMC3 32 PPC KVM_REG_PPC_PMC3 32
......
...@@ -119,7 +119,7 @@ struct kvmppc_host_state { ...@@ -119,7 +119,7 @@ struct kvmppc_host_state {
void __iomem *xive_tima_virt; void __iomem *xive_tima_virt;
u32 saved_xirr; u32 saved_xirr;
u64 dabr; 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]; u32 host_pmc[8];
u64 host_purr; u64 host_purr;
u64 host_spurr; u64 host_spurr;
......
...@@ -637,14 +637,14 @@ struct kvm_vcpu_arch { ...@@ -637,14 +637,14 @@ struct kvm_vcpu_arch {
u32 ccr1; u32 ccr1;
u32 dbsr; u32 dbsr;
u64 mmcr[3]; /* MMCR0, MMCR1, MMCR2 */ u64 mmcr[4]; /* MMCR0, MMCR1, MMCR2, MMCR3 */
u64 mmcra; u64 mmcra;
u64 mmcrs; u64 mmcrs;
u32 pmc[8]; u32 pmc[8];
u32 spmc[2]; u32 spmc[2];
u64 siar; u64 siar;
u64 sdar; u64 sdar;
u64 sier; u64 sier[3];
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
u64 tfhar; u64 tfhar;
u64 texasr; u64 texasr;
......
...@@ -640,6 +640,11 @@ struct kvm_ppc_cpu_char { ...@@ -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_ONLINE (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbf)
#define KVM_REG_PPC_PTCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc0) #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: /* Transactional Memory checkpointed state:
* This is all GPRs, all VSX regs and a subset of SPRs * This is all GPRs, all VSX regs and a subset of SPRs
*/ */
......
...@@ -698,6 +698,9 @@ int main(void) ...@@ -698,6 +698,9 @@ int main(void)
HSTATE_FIELD(HSTATE_SDAR, host_mmcr[4]); HSTATE_FIELD(HSTATE_SDAR, host_mmcr[4]);
HSTATE_FIELD(HSTATE_MMCR2, host_mmcr[5]); HSTATE_FIELD(HSTATE_MMCR2, host_mmcr[5]);
HSTATE_FIELD(HSTATE_SIER, host_mmcr[6]); 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_PMC1, host_pmc[0]);
HSTATE_FIELD(HSTATE_PMC2, host_pmc[1]); HSTATE_FIELD(HSTATE_PMC2, host_pmc[1]);
HSTATE_FIELD(HSTATE_PMC3, host_pmc[2]); HSTATE_FIELD(HSTATE_PMC3, host_pmc[2]);
......
...@@ -1692,6 +1692,9 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, ...@@ -1692,6 +1692,9 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
case KVM_REG_PPC_MMCRS: case KVM_REG_PPC_MMCRS:
*val = get_reg_val(id, vcpu->arch.mmcrs); *val = get_reg_val(id, vcpu->arch.mmcrs);
break; 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: case KVM_REG_PPC_PMC1 ... KVM_REG_PPC_PMC8:
i = id - KVM_REG_PPC_PMC1; i = id - KVM_REG_PPC_PMC1;
*val = get_reg_val(id, vcpu->arch.pmc[i]); *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, ...@@ -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); *val = get_reg_val(id, vcpu->arch.sdar);
break; break;
case KVM_REG_PPC_SIER: 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; break;
case KVM_REG_PPC_IAMR: case KVM_REG_PPC_IAMR:
*val = get_reg_val(id, vcpu->arch.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, ...@@ -1922,6 +1931,9 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
case KVM_REG_PPC_MMCRS: case KVM_REG_PPC_MMCRS:
vcpu->arch.mmcrs = set_reg_val(id, *val); vcpu->arch.mmcrs = set_reg_val(id, *val);
break; 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: case KVM_REG_PPC_PMC1 ... KVM_REG_PPC_PMC8:
i = id - KVM_REG_PPC_PMC1; i = id - KVM_REG_PPC_PMC1;
vcpu->arch.pmc[i] = set_reg_val(id, *val); 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, ...@@ -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); vcpu->arch.sdar = set_reg_val(id, *val);
break; break;
case KVM_REG_PPC_SIER: 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; break;
case KVM_REG_PPC_IAMR: case KVM_REG_PPC_IAMR:
vcpu->arch.iamr = set_reg_val(id, *val); vcpu->arch.iamr = set_reg_val(id, *val);
......
...@@ -140,6 +140,14 @@ BEGIN_FTR_SECTION ...@@ -140,6 +140,14 @@ BEGIN_FTR_SECTION
std r8, HSTATE_MMCR2(r13) std r8, HSTATE_MMCR2(r13)
std r9, HSTATE_SIER(r13) std r9, HSTATE_SIER(r13)
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) 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 r3, SPRN_PMC1
mfspr r5, SPRN_PMC2 mfspr r5, SPRN_PMC2
mfspr r6, SPRN_PMC3 mfspr r6, SPRN_PMC3
......
...@@ -3435,6 +3435,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_PMAO_BUG) ...@@ -3435,6 +3435,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_PMAO_BUG)
mtspr SPRN_MMCRA, r6 mtspr SPRN_MMCRA, r6
mtspr SPRN_SIAR, r7 mtspr SPRN_SIAR, r7
mtspr SPRN_SDAR, r8 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 BEGIN_FTR_SECTION
ld r5, VCPU_MMCR + 16(r4) ld r5, VCPU_MMCR + 16(r4)
ld r6, VCPU_SIER(r4) ld r6, VCPU_SIER(r4)
...@@ -3496,6 +3504,14 @@ BEGIN_FTR_SECTION ...@@ -3496,6 +3504,14 @@ BEGIN_FTR_SECTION
mtspr SPRN_MMCR2, r8 mtspr SPRN_MMCR2, r8
mtspr SPRN_SIER, r9 mtspr SPRN_SIER, r9
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) 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 mtspr SPRN_MMCR0, r3
isync isync
mtlr r0 mtlr r0
...@@ -3555,6 +3571,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) ...@@ -3555,6 +3571,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
std r10, VCPU_MMCR + 16(r9) std r10, VCPU_MMCR + 16(r9)
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) 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 r7, VCPU_SIAR(r9)
std r8, VCPU_SDAR(r9) std r8, VCPU_SDAR(r9)
mfspr r3, SPRN_PMC1 mfspr r3, SPRN_PMC1
......
...@@ -640,6 +640,11 @@ struct kvm_ppc_cpu_char { ...@@ -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_ONLINE (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbf)
#define KVM_REG_PPC_PTCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc0) #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: /* Transactional Memory checkpointed state:
* This is all GPRs, all VSX regs and a subset of SPRs * This is all GPRs, all VSX regs and a subset of SPRs
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment