Skip to content

Commit

Permalink
KVM: PPC: Book3S HV: Save/restore new PMU registers
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Athira Rajeev authored and Michael Ellerman committed Jul 22, 2020
1 parent c718547 commit 5752fe0
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 5 deletions.
3 changes: 3 additions & 0 deletions Documentation/virt/kvm/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/include/asm/kvm_book3s_asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions arch/powerpc/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions arch/powerpc/include/uapi/asm/kvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
3 changes: 3 additions & 0 deletions arch/powerpc/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down
22 changes: 20 additions & 2 deletions arch/powerpc/kvm/book3s_hv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
8 changes: 8 additions & 0 deletions arch/powerpc/kvm/book3s_hv_interrupts.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 24 additions & 0 deletions arch/powerpc/kvm/book3s_hv_rmhandlers.S
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions tools/arch/powerpc/include/uapi/asm/kvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down

0 comments on commit 5752fe0

Please sign in to comment.