powerpc/perf: Add support for ISA3.1 PMU SPRs
PowerISA v3.1 includes new performance monitoring unit(PMU) special purpose registers (SPRs). They are Monitor Mode Control Register 3 (MMCR3) Sampled Instruction Event Register 2 (SIER2) Sampled Instruction Event Register 3 (SIER3) MMCR3 is added for further sampling related configuration control. SIER2/SIER3 are added to provide additional information about the sampled instruction. Patch adds new PPMU flag called "PPMU_ARCH_31" to support handling of these new SPRs, updates the struct thread_struct to include these new SPRs, include MMCR3 in struct mmcr_regs. This is needed to support programming of MMCR3 SPR during event_enable/disable. Patch also adds the sysfs support for the MMCR3 SPR along with SPRN_ macros for these new pmu SPRs. Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com> [mpe: Rename to PPMU_ARCH_31 as noted by jpn] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/1594996707-3727-5-git-send-email-atrajeev@linux.vnet.ibm.com
This commit is contained in:
parent
9d4fc86dcd
commit
c718547e4a
|
@ -22,6 +22,7 @@ struct mmcr_regs {
|
|||
unsigned long mmcr1;
|
||||
unsigned long mmcr2;
|
||||
unsigned long mmcra;
|
||||
unsigned long mmcr3;
|
||||
};
|
||||
/*
|
||||
* This struct provides the constants and functions needed to
|
||||
|
@ -75,6 +76,7 @@ struct power_pmu {
|
|||
#define PPMU_HAS_SIER 0x00000040 /* Has SIER */
|
||||
#define PPMU_ARCH_207S 0x00000080 /* PMC is architecture v2.07S */
|
||||
#define PPMU_NO_SIAR 0x00000100 /* Do not use SIAR */
|
||||
#define PPMU_ARCH_31 0x00000200 /* Has MMCR3, SIER2 and SIER3 */
|
||||
|
||||
/*
|
||||
* Values for flags to get_alternatives()
|
||||
|
|
|
@ -271,6 +271,10 @@ struct thread_struct {
|
|||
unsigned mmcr0;
|
||||
|
||||
unsigned used_ebb;
|
||||
unsigned long mmcr3;
|
||||
unsigned long sier2;
|
||||
unsigned long sier3;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -876,7 +876,9 @@
|
|||
#define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */
|
||||
#define SPRN_MMCR1 798
|
||||
#define SPRN_MMCR2 785
|
||||
#define SPRN_MMCR3 754
|
||||
#define SPRN_UMMCR2 769
|
||||
#define SPRN_UMMCR3 738
|
||||
#define SPRN_MMCRA 0x312
|
||||
#define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */
|
||||
#define MMCRA_SDAR_DCACHE_MISS 0x40000000UL
|
||||
|
@ -918,6 +920,10 @@
|
|||
#define SIER_SIHV 0x1000000 /* Sampled MSR_HV */
|
||||
#define SIER_SIAR_VALID 0x0400000 /* SIAR contents valid */
|
||||
#define SIER_SDAR_VALID 0x0200000 /* SDAR contents valid */
|
||||
#define SPRN_SIER2 752
|
||||
#define SPRN_SIER3 753
|
||||
#define SPRN_USIER2 736
|
||||
#define SPRN_USIER3 737
|
||||
#define SPRN_SIAR 796
|
||||
#define SPRN_SDAR 797
|
||||
#define SPRN_TACR 888
|
||||
|
|
|
@ -622,8 +622,10 @@ SYSFS_PMCSETUP(pmc7, SPRN_PMC7);
|
|||
SYSFS_PMCSETUP(pmc8, SPRN_PMC8);
|
||||
|
||||
SYSFS_PMCSETUP(mmcra, SPRN_MMCRA);
|
||||
SYSFS_PMCSETUP(mmcr3, SPRN_MMCR3);
|
||||
|
||||
static DEVICE_ATTR(mmcra, 0600, show_mmcra, store_mmcra);
|
||||
static DEVICE_ATTR(mmcr3, 0600, show_mmcr3, store_mmcr3);
|
||||
#endif /* HAS_PPC_PMC56 */
|
||||
|
||||
|
||||
|
@ -886,6 +888,9 @@ static int register_cpu_online(unsigned int cpu)
|
|||
#ifdef CONFIG_PMU_SYSFS
|
||||
if (cpu_has_feature(CPU_FTR_MMCRA))
|
||||
device_create_file(s, &dev_attr_mmcra);
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_ARCH_31))
|
||||
device_create_file(s, &dev_attr_mmcr3);
|
||||
#endif /* CONFIG_PMU_SYSFS */
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_PURR)) {
|
||||
|
@ -980,6 +985,9 @@ static int unregister_cpu_online(unsigned int cpu)
|
|||
#ifdef CONFIG_PMU_SYSFS
|
||||
if (cpu_has_feature(CPU_FTR_MMCRA))
|
||||
device_remove_file(s, &dev_attr_mmcra);
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_ARCH_31))
|
||||
device_remove_file(s, &dev_attr_mmcr3);
|
||||
#endif /* CONFIG_PMU_SYSFS */
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_PURR)) {
|
||||
|
|
|
@ -72,6 +72,11 @@ static unsigned int freeze_events_kernel = MMCR0_FCS;
|
|||
/*
|
||||
* 32-bit doesn't have MMCRA but does have an MMCR2,
|
||||
* and a few other names are different.
|
||||
* Also 32-bit doesn't have MMCR3, SIER2 and SIER3.
|
||||
* Define them as zero knowing that any code path accessing
|
||||
* these registers (via mtspr/mfspr) are done under ppmu flag
|
||||
* check for PPMU_ARCH_31 and we will not enter that code path
|
||||
* for 32-bit.
|
||||
*/
|
||||
#ifdef CONFIG_PPC32
|
||||
|
||||
|
@ -85,6 +90,9 @@ static unsigned int freeze_events_kernel = MMCR0_FCS;
|
|||
#define MMCR0_PMCC_U6 0
|
||||
|
||||
#define SPRN_MMCRA SPRN_MMCR2
|
||||
#define SPRN_MMCR3 0
|
||||
#define SPRN_SIER2 0
|
||||
#define SPRN_SIER3 0
|
||||
#define MMCRA_SAMPLE_ENABLE 0
|
||||
|
||||
static inline unsigned long perf_ip_adjust(struct pt_regs *regs)
|
||||
|
@ -581,6 +589,11 @@ static void ebb_switch_out(unsigned long mmcr0)
|
|||
current->thread.sdar = mfspr(SPRN_SDAR);
|
||||
current->thread.mmcr0 = mmcr0 & MMCR0_USER_MASK;
|
||||
current->thread.mmcr2 = mfspr(SPRN_MMCR2) & MMCR2_USER_MASK;
|
||||
if (ppmu->flags & PPMU_ARCH_31) {
|
||||
current->thread.mmcr3 = mfspr(SPRN_MMCR3);
|
||||
current->thread.sier2 = mfspr(SPRN_SIER2);
|
||||
current->thread.sier3 = mfspr(SPRN_SIER3);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long ebb_switch_in(bool ebb, struct cpu_hw_events *cpuhw)
|
||||
|
@ -620,6 +633,12 @@ static unsigned long ebb_switch_in(bool ebb, struct cpu_hw_events *cpuhw)
|
|||
* instead manage the MMCR2 entirely by itself.
|
||||
*/
|
||||
mtspr(SPRN_MMCR2, cpuhw->mmcr.mmcr2 | current->thread.mmcr2);
|
||||
|
||||
if (ppmu->flags & PPMU_ARCH_31) {
|
||||
mtspr(SPRN_MMCR3, current->thread.mmcr3);
|
||||
mtspr(SPRN_SIER2, current->thread.sier2);
|
||||
mtspr(SPRN_SIER3, current->thread.sier3);
|
||||
}
|
||||
out:
|
||||
return mmcr0;
|
||||
}
|
||||
|
@ -840,6 +859,11 @@ void perf_event_print_debug(void)
|
|||
pr_info("EBBRR: %016lx BESCR: %016lx\n",
|
||||
mfspr(SPRN_EBBRR), mfspr(SPRN_BESCR));
|
||||
}
|
||||
|
||||
if (ppmu->flags & PPMU_ARCH_31) {
|
||||
pr_info("MMCR3: %016lx SIER2: %016lx SIER3: %016lx\n",
|
||||
mfspr(SPRN_MMCR3), mfspr(SPRN_SIER2), mfspr(SPRN_SIER3));
|
||||
}
|
||||
#endif
|
||||
pr_info("SIAR: %016lx SDAR: %016lx SIER: %016lx\n",
|
||||
mfspr(SPRN_SIAR), sdar, sier);
|
||||
|
@ -1305,6 +1329,8 @@ static void power_pmu_enable(struct pmu *pmu)
|
|||
if (!cpuhw->n_added) {
|
||||
mtspr(SPRN_MMCRA, cpuhw->mmcr.mmcra & ~MMCRA_SAMPLE_ENABLE);
|
||||
mtspr(SPRN_MMCR1, cpuhw->mmcr.mmcr1);
|
||||
if (ppmu->flags & PPMU_ARCH_31)
|
||||
mtspr(SPRN_MMCR3, cpuhw->mmcr.mmcr3);
|
||||
goto out_enable;
|
||||
}
|
||||
|
||||
|
@ -1348,6 +1374,9 @@ static void power_pmu_enable(struct pmu *pmu)
|
|||
if (ppmu->flags & PPMU_ARCH_207S)
|
||||
mtspr(SPRN_MMCR2, cpuhw->mmcr.mmcr2);
|
||||
|
||||
if (ppmu->flags & PPMU_ARCH_31)
|
||||
mtspr(SPRN_MMCR3, cpuhw->mmcr.mmcr3);
|
||||
|
||||
/*
|
||||
* Read off any pre-existing events that need to move
|
||||
* to another PMC.
|
||||
|
|
Loading…
Reference in New Issue