From nobody Thu Dec 18 18:47:16 2025 Received: from out-189.mta0.migadu.com (out-189.mta0.migadu.com [91.218.175.189]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 789B11D54E2 for ; Mon, 3 Feb 2025 18:31:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.189 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738607506; cv=none; b=FCg+e1RPlbJ5b5Wlth0nx6ev5ahlIN2Omn5irrqI3jsSyq/I//DDPG9qW3FbxIl2Fa49SwPdxSku5U40K/Hhpg4Tnb/EOZBl6XTOJIyMgCtXuQlBwE4UFvFisbAasFCd8Z5goTQvuqw+RwHU+1Ew6BidZOFUXlQ/3mnYoLngbjo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738607506; c=relaxed/simple; bh=hGXtgTxlVOSEkZPZl6Q3pgWkOgOaE72a0yYctig5aeE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=fl8ETc0PcFwyd5B+WOwusdQWxc7HH/Ez9gK+kIQk9Yw22jhhRXUHJwxKD/Pp0ooo0VsQU8SaEzRa+cKpj1+gcDP0YP8iplZJg395PczioUDy5aS1RgGQsWH/641ZrdNFgIMDCdjxquqgm/DQ0vHi9XmmxnCzsJTDTVKNWpExikY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=OXs9h+Cx; arc=none smtp.client-ip=91.218.175.189 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="OXs9h+Cx" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1738607501; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HVdhPRPhu/oRpEuf2KXzS/cqoEesNVF//Q5fOtfKKRU=; b=OXs9h+CxohMA1hGtuk0TWjCwiDvzQLQdQEdksVxrQurPDD1Nh2a+w5HYxt/FzTeauxNXew 049151b7alpgPMOmOIahGzTBdn7wkkvaUyqAtndsG44k+IzawmzGO9Mlh7mZ2RjYMOON1c MgcMZLlG4qI0shD4d4SpQdcd5eVEuNo= From: Oliver Upton To: kvmarm@lists.linux.dev Cc: Marc Zyngier , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Mingwei Zhang , Colton Lewis , Raghavendra Rao Ananta , Catalin Marinas , Will Deacon , Mark Rutland , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Oliver Upton , Janne Grunau Subject: [PATCH v2 02/14] drivers/perf: apple_m1: Support host/guest event filtering Date: Mon, 3 Feb 2025 10:30:59 -0800 Message-Id: <20250203183111.191519-3-oliver.upton@linux.dev> In-Reply-To: <20250203183111.191519-1-oliver.upton@linux.dev> References: <20250203183111.191519-1-oliver.upton@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" The PMU appears to have a separate register for filtering 'guest' exception levels (i.e. EL1 and !ELIsInHost(EL0)) which has the same layout as PMCR1_EL1. Conveniently, there exists a VHE register alias (PMCR1_EL12) that can be used to configure it. Support guest events by programming the EL12 register with the intended guest kernel/userspace filters. Limit support for guest events to VHE (i.e. kernel running at EL2), as it avoids involving KVM to context switch PMU registers. VHE is the only supported mode on M* parts anyway, so this isn't an actual feature limitation. Tested-by: Janne Grunau Signed-off-by: Oliver Upton --- drivers/perf/apple_m1_cpu_pmu.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pm= u.c index cea80afd1253..d6d4ff6da862 100644 --- a/drivers/perf/apple_m1_cpu_pmu.c +++ b/drivers/perf/apple_m1_cpu_pmu.c @@ -120,6 +120,8 @@ enum m1_pmu_events { */ M1_PMU_CFG_COUNT_USER =3D BIT(8), M1_PMU_CFG_COUNT_KERNEL =3D BIT(9), + M1_PMU_CFG_COUNT_HOST =3D BIT(10), + M1_PMU_CFG_COUNT_GUEST =3D BIT(11), }; =20 /* @@ -328,7 +330,7 @@ static void m1_pmu_disable_counter_interrupt(unsigned i= nt index) } =20 static void __m1_pmu_configure_event_filter(unsigned int index, bool user, - bool kernel) + bool kernel, bool host) { u64 clear, set, user_bit, kernel_bit; =20 @@ -356,7 +358,10 @@ static void __m1_pmu_configure_event_filter(unsigned i= nt index, bool user, else clear |=3D kernel_bit; =20 - sysreg_clear_set_s(SYS_IMP_APL_PMCR1_EL1, clear, set); + if (host) + sysreg_clear_set_s(SYS_IMP_APL_PMCR1_EL1, clear, set); + else if (is_kernel_in_hyp_mode()) + sysreg_clear_set_s(SYS_IMP_APL_PMCR1_EL12, clear, set); } =20 static void __m1_pmu_configure_eventsel(unsigned int index, u8 event) @@ -391,10 +396,13 @@ static void __m1_pmu_configure_eventsel(unsigned int = index, u8 event) static void m1_pmu_configure_counter(unsigned int index, unsigned long con= fig_base) { bool kernel =3D config_base & M1_PMU_CFG_COUNT_KERNEL; + bool guest =3D config_base & M1_PMU_CFG_COUNT_GUEST; + bool host =3D config_base & M1_PMU_CFG_COUNT_HOST; bool user =3D config_base & M1_PMU_CFG_COUNT_USER; u8 evt =3D config_base & M1_PMU_CFG_EVENT; =20 - __m1_pmu_configure_event_filter(index, user, kernel); + __m1_pmu_configure_event_filter(index, user && host, kernel && host, true= ); + __m1_pmu_configure_event_filter(index, user && guest, kernel && guest, fa= lse); __m1_pmu_configure_eventsel(index, evt); } =20 @@ -570,7 +578,7 @@ static int m1_pmu_set_event_filter(struct hw_perf_event= *event, { unsigned long config_base =3D 0; =20 - if (!attr->exclude_guest) { + if (!attr->exclude_guest && !is_kernel_in_hyp_mode()) { pr_debug("ARM performance counters do not support mode exclusion\n"); return -EOPNOTSUPP; } @@ -578,6 +586,10 @@ static int m1_pmu_set_event_filter(struct hw_perf_even= t *event, config_base |=3D M1_PMU_CFG_COUNT_KERNEL; if (!attr->exclude_user) config_base |=3D M1_PMU_CFG_COUNT_USER; + if (!attr->exclude_host) + config_base |=3D M1_PMU_CFG_COUNT_HOST; + if (!attr->exclude_guest) + config_base |=3D M1_PMU_CFG_COUNT_GUEST; =20 event->config_base =3D config_base; =20 --=20 2.39.5