summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/reg.h12
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S59
2 files changed, 64 insertions, 7 deletions
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index e5d2e0bc7e03..4852bcf270f3 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -670,18 +670,20 @@
670#define MMCR0_PROBLEM_DISABLE MMCR0_FCP 670#define MMCR0_PROBLEM_DISABLE MMCR0_FCP
671#define MMCR0_FCM1 0x10000000UL /* freeze counters while MSR mark = 1 */ 671#define MMCR0_FCM1 0x10000000UL /* freeze counters while MSR mark = 1 */
672#define MMCR0_FCM0 0x08000000UL /* freeze counters while MSR mark = 0 */ 672#define MMCR0_FCM0 0x08000000UL /* freeze counters while MSR mark = 0 */
673#define MMCR0_PMXE 0x04000000UL /* performance monitor exception enable */ 673#define MMCR0_PMXE ASM_CONST(0x04000000) /* perf mon exception enable */
674#define MMCR0_FCECE 0x02000000UL /* freeze ctrs on enabled cond or event */ 674#define MMCR0_FCECE ASM_CONST(0x02000000) /* freeze ctrs on enabled cond or event */
675#define MMCR0_TBEE 0x00400000UL /* time base exception enable */ 675#define MMCR0_TBEE 0x00400000UL /* time base exception enable */
676#define MMCR0_BHRBA 0x00200000UL /* BHRB Access allowed in userspace */ 676#define MMCR0_BHRBA 0x00200000UL /* BHRB Access allowed in userspace */
677#define MMCR0_EBE 0x00100000UL /* Event based branch enable */ 677#define MMCR0_EBE 0x00100000UL /* Event based branch enable */
678#define MMCR0_PMCC 0x000c0000UL /* PMC control */ 678#define MMCR0_PMCC 0x000c0000UL /* PMC control */
679#define MMCR0_PMCC_U6 0x00080000UL /* PMC1-6 are R/W by user (PR) */ 679#define MMCR0_PMCC_U6 0x00080000UL /* PMC1-6 are R/W by user (PR) */
680#define MMCR0_PMC1CE 0x00008000UL /* PMC1 count enable*/ 680#define MMCR0_PMC1CE 0x00008000UL /* PMC1 count enable*/
681#define MMCR0_PMCjCE 0x00004000UL /* PMCj count enable*/ 681#define MMCR0_PMCjCE ASM_CONST(0x00004000) /* PMCj count enable*/
682#define MMCR0_TRIGGER 0x00002000UL /* TRIGGER enable */ 682#define MMCR0_TRIGGER 0x00002000UL /* TRIGGER enable */
683#define MMCR0_PMAO_SYNC 0x00000800UL /* PMU interrupt is synchronous */ 683#define MMCR0_PMAO_SYNC ASM_CONST(0x00000800) /* PMU intr is synchronous */
684#define MMCR0_PMAO 0x00000080UL /* performance monitor alert has occurred, set to 0 after handling exception */ 684#define MMCR0_C56RUN ASM_CONST(0x00000100) /* PMC5/6 count when RUN=0 */
685/* performance monitor alert has occurred, set to 0 after handling exception */
686#define MMCR0_PMAO ASM_CONST(0x00000080)
685#define MMCR0_SHRFC 0x00000040UL /* SHRre freeze conditions between threads */ 687#define MMCR0_SHRFC 0x00000040UL /* SHRre freeze conditions between threads */
686#define MMCR0_FC56 0x00000010UL /* freeze counters 5 and 6 */ 688#define MMCR0_FC56 0x00000010UL /* freeze counters 5 and 6 */
687#define MMCR0_FCTI 0x00000008UL /* freeze counters in tags inactive mode */ 689#define MMCR0_FCTI 0x00000008UL /* freeze counters in tags inactive mode */
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index ffbb871c2bd8..60fe8ba318cf 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -86,6 +86,12 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
86 lbz r4, LPPACA_PMCINUSE(r3) 86 lbz r4, LPPACA_PMCINUSE(r3)
87 cmpwi r4, 0 87 cmpwi r4, 0
88 beq 23f /* skip if not */ 88 beq 23f /* skip if not */
89BEGIN_FTR_SECTION
90 ld r3, HSTATE_MMCR(r13)
91 andi. r4, r3, MMCR0_PMAO_SYNC | MMCR0_PMAO
92 cmpwi r4, MMCR0_PMAO
93 beql kvmppc_fix_pmao
94END_FTR_SECTION_IFSET(CPU_FTR_PMAO_BUG)
89 lwz r3, HSTATE_PMC(r13) 95 lwz r3, HSTATE_PMC(r13)
90 lwz r4, HSTATE_PMC + 4(r13) 96 lwz r4, HSTATE_PMC + 4(r13)
91 lwz r5, HSTATE_PMC + 8(r13) 97 lwz r5, HSTATE_PMC + 8(r13)
@@ -726,6 +732,12 @@ skip_tm:
726 sldi r3, r3, 31 /* MMCR0_FC (freeze counters) bit */ 732 sldi r3, r3, 31 /* MMCR0_FC (freeze counters) bit */
727 mtspr SPRN_MMCR0, r3 /* freeze all counters, disable ints */ 733 mtspr SPRN_MMCR0, r3 /* freeze all counters, disable ints */
728 isync 734 isync
735BEGIN_FTR_SECTION
736 ld r3, VCPU_MMCR(r4)
737 andi. r5, r3, MMCR0_PMAO_SYNC | MMCR0_PMAO
738 cmpwi r5, MMCR0_PMAO
739 beql kvmppc_fix_pmao
740END_FTR_SECTION_IFSET(CPU_FTR_PMAO_BUG)
729 lwz r3, VCPU_PMC(r4) /* always load up guest PMU registers */ 741 lwz r3, VCPU_PMC(r4) /* always load up guest PMU registers */
730 lwz r5, VCPU_PMC + 4(r4) /* to prevent information leak */ 742 lwz r5, VCPU_PMC + 4(r4) /* to prevent information leak */
731 lwz r6, VCPU_PMC + 8(r4) 743 lwz r6, VCPU_PMC + 8(r4)
@@ -1324,6 +1336,30 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
132425: 133625:
1325 /* Save PMU registers if requested */ 1337 /* Save PMU registers if requested */
1326 /* r8 and cr0.eq are live here */ 1338 /* r8 and cr0.eq are live here */
1339BEGIN_FTR_SECTION
1340 /*
1341 * POWER8 seems to have a hardware bug where setting
1342 * MMCR0[PMAE] along with MMCR0[PMC1CE] and/or MMCR0[PMCjCE]
1343 * when some counters are already negative doesn't seem
1344 * to cause a performance monitor alert (and hence interrupt).
1345 * The effect of this is that when saving the PMU state,
1346 * if there is no PMU alert pending when we read MMCR0
1347 * before freezing the counters, but one becomes pending
1348 * before we read the counters, we lose it.
1349 * To work around this, we need a way to freeze the counters
1350 * before reading MMCR0. Normally, freezing the counters
1351 * is done by writing MMCR0 (to set MMCR0[FC]) which
1352 * unavoidably writes MMCR0[PMA0] as well. On POWER8,
1353 * we can also freeze the counters using MMCR2, by writing
1354 * 1s to all the counter freeze condition bits (there are
1355 * 9 bits each for 6 counters).
1356 */
1357 li r3, -1 /* set all freeze bits */
1358 clrrdi r3, r3, 10
1359 mfspr r10, SPRN_MMCR2
1360 mtspr SPRN_MMCR2, r3
1361 isync
1362END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
1327 li r3, 1 1363 li r3, 1
1328 sldi r3, r3, 31 /* MMCR0_FC (freeze counters) bit */ 1364 sldi r3, r3, 31 /* MMCR0_FC (freeze counters) bit */
1329 mfspr r4, SPRN_MMCR0 /* save MMCR0 */ 1365 mfspr r4, SPRN_MMCR0 /* save MMCR0 */
@@ -1347,6 +1383,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
1347 std r4, VCPU_MMCR(r9) 1383 std r4, VCPU_MMCR(r9)
1348 std r5, VCPU_MMCR + 8(r9) 1384 std r5, VCPU_MMCR + 8(r9)
1349 std r6, VCPU_MMCR + 16(r9) 1385 std r6, VCPU_MMCR + 16(r9)
1386BEGIN_FTR_SECTION
1387 std r10, VCPU_MMCR + 24(r9)
1388END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
1350 std r7, VCPU_SIAR(r9) 1389 std r7, VCPU_SIAR(r9)
1351 std r8, VCPU_SDAR(r9) 1390 std r8, VCPU_SDAR(r9)
1352 mfspr r3, SPRN_PMC1 1391 mfspr r3, SPRN_PMC1
@@ -1370,12 +1409,10 @@ BEGIN_FTR_SECTION
1370 stw r11, VCPU_PMC + 28(r9) 1409 stw r11, VCPU_PMC + 28(r9)
1371END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) 1410END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
1372BEGIN_FTR_SECTION 1411BEGIN_FTR_SECTION
1373 mfspr r4, SPRN_MMCR2
1374 mfspr r5, SPRN_SIER 1412 mfspr r5, SPRN_SIER
1375 mfspr r6, SPRN_SPMC1 1413 mfspr r6, SPRN_SPMC1
1376 mfspr r7, SPRN_SPMC2 1414 mfspr r7, SPRN_SPMC2
1377 mfspr r8, SPRN_MMCRS 1415 mfspr r8, SPRN_MMCRS
1378 std r4, VCPU_MMCR + 24(r9)
1379 std r5, VCPU_SIER(r9) 1416 std r5, VCPU_SIER(r9)
1380 stw r6, VCPU_PMC + 24(r9) 1417 stw r6, VCPU_PMC + 24(r9)
1381 stw r7, VCPU_PMC + 28(r9) 1418 stw r7, VCPU_PMC + 28(r9)
@@ -2311,3 +2348,21 @@ kvmppc_msr_interrupt:
2311 li r0, 1 2348 li r0, 1
23121: rldimi r11, r0, MSR_TS_S_LG, 63 - MSR_TS_T_LG 23491: rldimi r11, r0, MSR_TS_S_LG, 63 - MSR_TS_T_LG
2313 blr 2350 blr
2351
2352/*
2353 * This works around a hardware bug on POWER8E processors, where
2354 * writing a 1 to the MMCR0[PMAO] bit doesn't generate a
2355 * performance monitor interrupt. Instead, when we need to have
2356 * an interrupt pending, we have to arrange for a counter to overflow.
2357 */
2358kvmppc_fix_pmao:
2359 li r3, 0
2360 mtspr SPRN_MMCR2, r3
2361 lis r3, (MMCR0_PMXE | MMCR0_FCECE)@h
2362 ori r3, r3, MMCR0_PMCjCE | MMCR0_C56RUN
2363 mtspr SPRN_MMCR0, r3
2364 lis r3, 0x7fff
2365 ori r3, r3, 0xffff
2366 mtspr SPRN_PMC6, r3
2367 isync
2368 blr