git: 6bb7ba4aa180 - main - arm64 hwpmc: Support restricting counters to user or kernel mode.

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Fri, 11 Mar 2022 19:29:59 UTC
The branch main has been updated by jhb:

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

commit 6bb7ba4aa180f667c1b558de1fc364f41bab57ce
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2022-03-11 19:29:45 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2022-03-11 19:29:45 +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
---
 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 ea0539d2225a..d01f88bdaff7 100644
--- a/lib/libpmc/libpmc.c
+++ b/lib/libpmc/libpmc.c
@@ -763,13 +763,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 988cd1744a07..9cdb2bfc06cb 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);