git: f5858d5551b4 - stable/13 - arm64 hwpmc: Support restricting counters to user or kernel mode.

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Thu, 10 Nov 2022 21:25:00 UTC
The branch stable/13 has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=f5858d5551b4559c603c2f3dba512c76b7eea3fb

commit f5858d5551b4559c603c2f3dba512c76b7eea3fb
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2022-03-11 19:29:45 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2022-11-10 21:04:56 +0000

    arm64 hwpmc: Support restricting counters to user or kernel mode.
    
    Support the "usr" and "os" qualifiers on arm64 events to restrict
    event counting to either usermode or the kernel, respectively.  If
    neither qualifier is given, events are counted in both.
    
    Reviewed by:    emaste
    Sponsored by:   University of Cambridge, Google, Inc.
    Differential Revision:  https://reviews.freebsd.org/D34527
    
    (cherry picked from commit 6bb7ba4aa180f667c1b558de1fc364f41bab57ce)
---
 lib/libpmc/libpmc.c         | 17 ++++++++++++-----
 sys/dev/hwpmc/hwpmc_arm64.c | 17 +++++++++++++++++
 2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c
index d36648ee6b89..0ccefad5ca7d 100644
--- a/lib/libpmc/libpmc.c
+++ b/lib/libpmc/libpmc.c
@@ -779,13 +779,20 @@ static struct pmc_event_alias cortex_a57_aliases[] = {
 static struct pmc_event_alias cortex_a76_aliases[] = {
 	EV_ALIAS(NULL, NULL)
 };
+
 static int
-arm64_allocate_pmc(enum pmc_event pe, char *ctrspec __unused,
-    struct pmc_op_pmcallocate *pmc_config __unused)
+arm64_allocate_pmc(enum pmc_event pe, char *ctrspec,
+    struct pmc_op_pmcallocate *pmc_config)
 {
-	switch (pe) {
-	default:
-		break;
+	char *p;
+
+	while ((p = strsep(&ctrspec, ",")) != NULL) {
+		if (KWMATCH(p, "os"))
+			pmc_config->pm_caps |= PMC_CAP_SYSTEM;
+		else if (KWMATCH(p, "usr"))
+			pmc_config->pm_caps |= PMC_CAP_USER;
+		else
+			return (-1);
 	}
 
 	return (0);
diff --git a/sys/dev/hwpmc/hwpmc_arm64.c b/sys/dev/hwpmc/hwpmc_arm64.c
index 17d383133bf3..80d97070b913 100644
--- a/sys/dev/hwpmc/hwpmc_arm64.c
+++ b/sys/dev/hwpmc/hwpmc_arm64.c
@@ -187,6 +187,23 @@ arm64_allocate_pmc(int cpu, int ri, struct pmc *pm,
 		if (config > (PMC_EV_ARMV8_LAST - PMC_EV_ARMV8_FIRST))
 			return (EINVAL);
 	}
+
+	switch (a->pm_caps & (PMC_CAP_SYSTEM | PMC_CAP_USER)) {
+	case PMC_CAP_SYSTEM:
+		config |= PMEVTYPER_U;
+		break;
+	case PMC_CAP_USER:
+		config |= PMEVTYPER_P;
+		break;
+	default:
+		/*
+		 * Trace both USER and SYSTEM if none are specified
+		 * (default setting) or if both flags are specified
+		 * (user explicitly requested both qualifiers).
+		 */
+		break;
+	}
+
 	pm->pm_md.pm_arm64.pm_arm64_evsel = config;
 	PMCDBG2(MDP, ALL, 2, "arm64-allocate ri=%d -> config=0x%x", ri, config);