Skip to content

Commit

Permalink
powerpc/perf: Add support for ISA3.1 PMU SPRs
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Madhavan Srinivasan authored and Michael Ellerman committed Jul 22, 2020
1 parent 9d4fc86 commit c718547
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 0 deletions.
2 changes: 2 additions & 0 deletions arch/powerpc/include/asm/perf_event_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down
4 changes: 4 additions & 0 deletions arch/powerpc/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,10 @@ struct thread_struct {
unsigned mmcr0;

unsigned used_ebb;
unsigned long mmcr3;
unsigned long sier2;
unsigned long sier3;

#endif
};

Expand Down
6 changes: 6 additions & 0 deletions arch/powerpc/include/asm/reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions arch/powerpc/kernel/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */


Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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)) {
Expand Down
29 changes: 29 additions & 0 deletions arch/powerpc/perf/core-book3s.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit c718547

Please sign in to comment.