From: Fuad Tabba <fuad.tabba@linux.dev>
To: Marc Zyngier <maz@kernel.org>, Oliver Upton <oupton@kernel.org>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>
Cc: James Morse <james.morse@arm.com>,
Ben Horgan <ben.horgan@arm.com>, Xi Ruoyao <xry111@xry111.site>,
Mark Rutland <mark.rutland@arm.com>,
Joey Gouly <joey.gouly@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Zenghui Yu <yuzenghui@huawei.com>,
Steffen Eiden <seiden@linux.ibm.com>,
Gavin Shan <gshan@redhat.com>, Fuad Tabba <tabba@google.com>,
linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
linux-kernel@vger.kernel.org
Subject: [PATCH] KVM: arm64: Trap guest MPAM accesses whenever MPAM is implemented
Date: Thu, 3 Sep 2026 17:08:19 +0100 [thread overview]
Message-ID: <20260903160819.831518-1-fuad.tabba@linux.dev> (raw)
finalise_el2_state() clears the EL2 MPAM traps whenever the ID registers
advertise MPAM, but KVM sets them only when ARM64_MPAM is set, which
also requires MPAMEN. Without EL3 the enable is EL2's own and nothing
sets it, so the cap stays off and a guest reaches the MPAM registers
while ID_AA64PFR0_EL1.MPAM reads 0 for it.
Gate the traps on the ID registers alone. MPAMEN is not a term in any
MPAM accessor, so they take effect without it. finalise_el2_state
already wrote MPAM2_EL2 under the same condition, so MPAM3_EL3.TRAPLOWER
is clear wherever the cap is set, and arm64.nompam still clears it.
Fixes: 31ff96c38ea3 ("KVM: arm64: Fix missing traps of guest accesses to the MPAM registers")
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
---
Found this while working on the other MPAM thread [1].
[1] https://lore.kernel.org/all/CA+EHjTxeWxZiuSmnKLGLxTBXP4oJT7-LuffbPAyCSZZ5TW=5Ew@mail.gmail.com/
arch/arm64/include/asm/cpufeature.h | 5 +++++
arch/arm64/kernel/cpufeature.c | 13 +++++++++++++
arch/arm64/kvm/hyp/include/hyp/switch.h | 4 ++--
arch/arm64/tools/cpucaps | 1 +
4 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 7404a6e83a930..8863ae99596bc 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -873,6 +873,11 @@ static __always_inline bool system_supports_mpam_hcr(void)
return alternative_has_cap_unlikely(ARM64_MPAM_HCR);
}
+static __always_inline bool system_supports_mpam_sysregs(void)
+{
+ return alternative_has_cap_unlikely(ARM64_MPAM_SYSREGS);
+}
+
static inline bool system_supports_pmuv3(void)
{
return cpus_have_final_cap(ARM64_HAS_PMUV3);
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 17b83a2518a8f..36a27692e5cf7 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2501,6 +2501,13 @@ test_has_mpam(const struct arm64_cpu_capabilities *entry, int scope)
return (read_sysreg_s(SYS_MPAM1_EL1) & MPAM1_EL1_MPAMEN);
}
+static bool
+test_has_mpam_sysregs(const struct arm64_cpu_capabilities *entry, int __unused)
+{
+ /* The registers exist whether or not firmware enabled MPAM. */
+ return detect_ftr_has_mpam();
+}
+
static void
cpu_enable_mpam(const struct arm64_cpu_capabilities *entry)
{
@@ -3116,6 +3123,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = test_has_mpam,
.cpu_enable = cpu_enable_mpam,
},
+ {
+ .desc = "Memory Partitioning And Monitoring system registers",
+ .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+ .capability = ARM64_MPAM_SYSREGS,
+ .matches = test_has_mpam_sysregs,
+ },
{
.desc = "Memory Partitioning And Monitoring Virtualisation",
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 1ce7130e25490..8941335724f6b 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -298,7 +298,7 @@ static inline void __activate_traps_mpam(struct kvm_vcpu *vcpu)
u64 clr = MPAM2_EL2_EnMPAMSM;
u64 set = MPAM2_EL2_TRAPMPAM0EL1 | MPAM2_EL2_TRAPMPAM1EL1;
- if (!system_supports_mpam())
+ if (!system_supports_mpam_sysregs())
return;
/* trap guest access to MPAMIDR_EL1 */
@@ -317,7 +317,7 @@ static inline void __deactivate_traps_mpam(void)
u64 clr = MPAM2_EL2_TRAPMPAM0EL1 | MPAM2_EL2_TRAPMPAM1EL1 | MPAM2_EL2_TIDR;
u64 set = MPAM2_EL2_EnMPAMSM;
- if (!system_supports_mpam())
+ if (!system_supports_mpam_sysregs())
return;
sysreg_clear_set_s(SYS_MPAM2_EL2, clr, set);
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 2775ba3359cfe..aa5be51385f68 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -78,6 +78,7 @@ KVM_PROTECTED_MODE
MISMATCHED_CACHE_TYPE
MPAM
MPAM_HCR
+MPAM_SYSREGS
MTE
MTE_ASYMM
MTE_FAR
base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
--
2.39.5
next reply other threads:[~2026-09-03 16:08 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-03 16:08 Fuad Tabba [this message]
2026-09-03 16:25 ` [PATCH] KVM: arm64: Trap guest MPAM accesses whenever MPAM is implemented sashiko-bot
2026-09-03 16:28 ` Fuad Tabba
2026-09-04 9:58 ` Yao Yuan
2026-09-04 11:18 ` Fuad Tabba
2026-09-04 23:07 ` Yao Yuan
2026-09-07 9:12 ` Ben Horgan
2026-09-07 10:28 ` Fuad Tabba
2026-09-07 15:00 ` Fuad Tabba
2026-09-08 13:15 ` Ben Horgan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260903160819.831518-1-fuad.tabba@linux.dev \
--to=fuad.tabba@linux.dev \
--cc=ben.horgan@arm.com \
--cc=catalin.marinas@arm.com \
--cc=gshan@redhat.com \
--cc=james.morse@arm.com \
--cc=joey.gouly@arm.com \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=maz@kernel.org \
--cc=oupton@kernel.org \
--cc=seiden@linux.ibm.com \
--cc=suzuki.poulose@arm.com \
--cc=tabba@google.com \
--cc=will@kernel.org \
--cc=xry111@xry111.site \
--cc=yuzenghui@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.