diff options
author | Paul Mackerras <paulus@samba.org> | 2013-09-05 23:11:18 -0400 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2013-10-17 08:44:59 -0400 |
commit | 14941789f2a13cd89e2dd567c4f708e571ab714e (patch) | |
tree | 71149df5b0ab4e2790c368d7addf90fb920b0caa /arch/powerpc | |
parent | 3b7834743f9492e3509930feb4ca47135905e640 (diff) |
KVM: PPC: Book3S HV: Save/restore SIAR and SDAR along with other PMU registers
Currently we are not saving and restoring the SIAR and SDAR registers in
the PMU (performance monitor unit) on guest entry and exit. The result
is that performance monitoring tools in the guest could get false
information about where a program was executing and what data it was
accessing at the time of a performance monitor interrupt. This fixes
it by saving and restoring these registers along with the other PMU
registers on guest entry/exit.
This also provides a way for userspace to access these values for a
vcpu via the one_reg interface.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/include/asm/kvm_host.h | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_hv.c | 12 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_hv_rmhandlers.S | 8 |
4 files changed, 24 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 0866230b7c2d..d9b21af62610 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h | |||
@@ -493,6 +493,8 @@ struct kvm_vcpu_arch { | |||
493 | 493 | ||
494 | u64 mmcr[3]; | 494 | u64 mmcr[3]; |
495 | u32 pmc[8]; | 495 | u32 pmc[8]; |
496 | u64 siar; | ||
497 | u64 sdar; | ||
496 | 498 | ||
497 | #ifdef CONFIG_KVM_EXIT_TIMING | 499 | #ifdef CONFIG_KVM_EXIT_TIMING |
498 | struct mutex exit_timing_lock; | 500 | struct mutex exit_timing_lock; |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index d8958be5f31a..19e699d747b7 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -508,6 +508,8 @@ int main(void) | |||
508 | DEFINE(VCPU_PRODDED, offsetof(struct kvm_vcpu, arch.prodded)); | 508 | DEFINE(VCPU_PRODDED, offsetof(struct kvm_vcpu, arch.prodded)); |
509 | DEFINE(VCPU_MMCR, offsetof(struct kvm_vcpu, arch.mmcr)); | 509 | DEFINE(VCPU_MMCR, offsetof(struct kvm_vcpu, arch.mmcr)); |
510 | DEFINE(VCPU_PMC, offsetof(struct kvm_vcpu, arch.pmc)); | 510 | DEFINE(VCPU_PMC, offsetof(struct kvm_vcpu, arch.pmc)); |
511 | DEFINE(VCPU_SIAR, offsetof(struct kvm_vcpu, arch.siar)); | ||
512 | DEFINE(VCPU_SDAR, offsetof(struct kvm_vcpu, arch.sdar)); | ||
511 | DEFINE(VCPU_SLB, offsetof(struct kvm_vcpu, arch.slb)); | 513 | DEFINE(VCPU_SLB, offsetof(struct kvm_vcpu, arch.slb)); |
512 | DEFINE(VCPU_SLB_MAX, offsetof(struct kvm_vcpu, arch.slb_max)); | 514 | DEFINE(VCPU_SLB_MAX, offsetof(struct kvm_vcpu, arch.slb_max)); |
513 | DEFINE(VCPU_SLB_NR, offsetof(struct kvm_vcpu, arch.slb_nr)); | 515 | DEFINE(VCPU_SLB_NR, offsetof(struct kvm_vcpu, arch.slb_nr)); |
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 62a2b5ab08ed..45a9b876b0a0 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c | |||
@@ -749,6 +749,12 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val) | |||
749 | i = id - KVM_REG_PPC_PMC1; | 749 | i = id - KVM_REG_PPC_PMC1; |
750 | *val = get_reg_val(id, vcpu->arch.pmc[i]); | 750 | *val = get_reg_val(id, vcpu->arch.pmc[i]); |
751 | break; | 751 | break; |
752 | case KVM_REG_PPC_SIAR: | ||
753 | *val = get_reg_val(id, vcpu->arch.siar); | ||
754 | break; | ||
755 | case KVM_REG_PPC_SDAR: | ||
756 | *val = get_reg_val(id, vcpu->arch.sdar); | ||
757 | break; | ||
752 | #ifdef CONFIG_VSX | 758 | #ifdef CONFIG_VSX |
753 | case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31: | 759 | case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31: |
754 | if (cpu_has_feature(CPU_FTR_VSX)) { | 760 | if (cpu_has_feature(CPU_FTR_VSX)) { |
@@ -833,6 +839,12 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val) | |||
833 | i = id - KVM_REG_PPC_PMC1; | 839 | i = id - KVM_REG_PPC_PMC1; |
834 | vcpu->arch.pmc[i] = set_reg_val(id, *val); | 840 | vcpu->arch.pmc[i] = set_reg_val(id, *val); |
835 | break; | 841 | break; |
842 | case KVM_REG_PPC_SIAR: | ||
843 | vcpu->arch.siar = set_reg_val(id, *val); | ||
844 | break; | ||
845 | case KVM_REG_PPC_SDAR: | ||
846 | vcpu->arch.sdar = set_reg_val(id, *val); | ||
847 | break; | ||
836 | #ifdef CONFIG_VSX | 848 | #ifdef CONFIG_VSX |
837 | case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31: | 849 | case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31: |
838 | if (cpu_has_feature(CPU_FTR_VSX)) { | 850 | if (cpu_has_feature(CPU_FTR_VSX)) { |
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 294b7af28cdd..541aea0ce91a 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S | |||
@@ -200,8 +200,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) | |||
200 | ld r3, VCPU_MMCR(r4) | 200 | ld r3, VCPU_MMCR(r4) |
201 | ld r5, VCPU_MMCR + 8(r4) | 201 | ld r5, VCPU_MMCR + 8(r4) |
202 | ld r6, VCPU_MMCR + 16(r4) | 202 | ld r6, VCPU_MMCR + 16(r4) |
203 | ld r7, VCPU_SIAR(r4) | ||
204 | ld r8, VCPU_SDAR(r4) | ||
203 | mtspr SPRN_MMCR1, r5 | 205 | mtspr SPRN_MMCR1, r5 |
204 | mtspr SPRN_MMCRA, r6 | 206 | mtspr SPRN_MMCRA, r6 |
207 | mtspr SPRN_SIAR, r7 | ||
208 | mtspr SPRN_SDAR, r8 | ||
205 | mtspr SPRN_MMCR0, r3 | 209 | mtspr SPRN_MMCR0, r3 |
206 | isync | 210 | isync |
207 | 211 | ||
@@ -1134,9 +1138,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) | |||
1134 | std r3, VCPU_MMCR(r9) /* if not, set saved MMCR0 to FC */ | 1138 | std r3, VCPU_MMCR(r9) /* if not, set saved MMCR0 to FC */ |
1135 | b 22f | 1139 | b 22f |
1136 | 21: mfspr r5, SPRN_MMCR1 | 1140 | 21: mfspr r5, SPRN_MMCR1 |
1141 | mfspr r7, SPRN_SIAR | ||
1142 | mfspr r8, SPRN_SDAR | ||
1137 | std r4, VCPU_MMCR(r9) | 1143 | std r4, VCPU_MMCR(r9) |
1138 | std r5, VCPU_MMCR + 8(r9) | 1144 | std r5, VCPU_MMCR + 8(r9) |
1139 | std r6, VCPU_MMCR + 16(r9) | 1145 | std r6, VCPU_MMCR + 16(r9) |
1146 | std r7, VCPU_SIAR(r9) | ||
1147 | std r8, VCPU_SDAR(r9) | ||
1140 | mfspr r3, SPRN_PMC1 | 1148 | mfspr r3, SPRN_PMC1 |
1141 | mfspr r4, SPRN_PMC2 | 1149 | mfspr r4, SPRN_PMC2 |
1142 | mfspr r5, SPRN_PMC3 | 1150 | mfspr r5, SPRN_PMC3 |