* [PATCH 0/2] KVM: arm64: Fixes and clarifications for FEAT_S1POE
@ 2025-07-01 15:16 Marc Zyngier
2025-07-01 15:16 ` [PATCH 1/2] KVM: arm64: Remove the wi->{e0,}poe vs wr->{p,u}ov confusion Marc Zyngier
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Marc Zyngier @ 2025-07-01 15:16 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel
Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu
I (almost accidentally) spotted a couple of issues with the current NV
support for S1POE:
- wi->{e0,}poe and wr->{p,u}ov are used interchangeably, and sometimes
in conjunction -- none of that makes much sense
- The two rules describing WXN are not exactly been applied to the
correct state
These two patches address these issues (not that it matters much yet,
there is no S1POE HW out there).
Marc Zyngier (2):
KVM: arm64: Remove the wi->{e0,}poe vs wr->{p,u}ov confusion
KVM: arm64: Follow specification when implementing WXN
arch/arm64/kvm/at.c | 80 +++++++++++++++++++++++++--------------------
1 file changed, 44 insertions(+), 36 deletions(-)
--
2.39.2
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] KVM: arm64: Remove the wi->{e0,}poe vs wr->{p,u}ov confusion
2025-07-01 15:16 [PATCH 0/2] KVM: arm64: Fixes and clarifications for FEAT_S1POE Marc Zyngier
@ 2025-07-01 15:16 ` Marc Zyngier
2025-07-01 15:16 ` [PATCH 2/2] KVM: arm64: Follow specification when implementing WXN Marc Zyngier
2025-07-24 6:49 ` [PATCH 0/2] KVM: arm64: Fixes and clarifications for FEAT_S1POE Oliver Upton
2 siblings, 0 replies; 4+ messages in thread
From: Marc Zyngier @ 2025-07-01 15:16 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel
Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu
Some of the POE computation is a bit confused. Specifically, there
is an element of confusion between what wi->{e0,}poe an wr->{p,u}ov
actually represent.
- wi->{e0,}poe is an *input* to the walk, and indicates whether
POE is enabled at EL0 or EL{1,2}
- wr->{p,u}ov is a *result* of the walk, and indicates whether
overlays are enabled. Crutially, it is possible to have POE
enabled, and yet overlays disabled, while the converse isn't
true
What this all means is that once the base permissions have been
established, checking for wi->{e0,}poe makes little sense, because
the truth about overlays resides in wr->{p,u}ov. So constructs
checking for (wi->poe && wr->pov) only add perplexity.
Refactor compute_s1_overlay_permissions() and the way it is
called according to the above principles. Take the opportunity
to avoid reading registers that are not strictly required.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kvm/at.c | 52 ++++++++++++++++++++++++++-------------------
1 file changed, 30 insertions(+), 22 deletions(-)
diff --git a/arch/arm64/kvm/at.c b/arch/arm64/kvm/at.c
index a25be111cd8f8..a26e377a36171 100644
--- a/arch/arm64/kvm/at.c
+++ b/arch/arm64/kvm/at.c
@@ -1047,34 +1047,43 @@ static void compute_s1_overlay_permissions(struct kvm_vcpu *vcpu,
idx = FIELD_GET(PTE_PO_IDX_MASK, wr->desc);
- switch (wi->regime) {
- case TR_EL10:
- pov_perms = perm_idx(vcpu, POR_EL1, idx);
- uov_perms = perm_idx(vcpu, POR_EL0, idx);
- break;
- case TR_EL20:
- pov_perms = perm_idx(vcpu, POR_EL2, idx);
- uov_perms = perm_idx(vcpu, POR_EL0, idx);
- break;
- case TR_EL2:
- pov_perms = perm_idx(vcpu, POR_EL2, idx);
- uov_perms = 0;
- break;
- }
+ if (wr->pov) {
+ switch (wi->regime) {
+ case TR_EL10:
+ pov_perms = perm_idx(vcpu, POR_EL1, idx);
+ break;
+ case TR_EL20:
+ pov_perms = perm_idx(vcpu, POR_EL2, idx);
+ break;
+ case TR_EL2:
+ pov_perms = perm_idx(vcpu, POR_EL2, idx);
+ break;
+ }
- if (pov_perms & ~POE_RWX)
- pov_perms = POE_NONE;
+ if (pov_perms & ~POE_RWX)
+ pov_perms = POE_NONE;
- if (wi->poe && wr->pov) {
wr->pr &= pov_perms & POE_R;
wr->pw &= pov_perms & POE_W;
wr->px &= pov_perms & POE_X;
}
- if (uov_perms & ~POE_RWX)
- uov_perms = POE_NONE;
+ if (wr->uov) {
+ switch (wi->regime) {
+ case TR_EL10:
+ uov_perms = perm_idx(vcpu, POR_EL0, idx);
+ break;
+ case TR_EL20:
+ uov_perms = perm_idx(vcpu, POR_EL0, idx);
+ break;
+ case TR_EL2:
+ uov_perms = 0;
+ break;
+ }
+
+ if (uov_perms & ~POE_RWX)
+ uov_perms = POE_NONE;
- if (wi->e0poe && wr->uov) {
wr->ur &= uov_perms & POE_R;
wr->uw &= uov_perms & POE_W;
wr->ux &= uov_perms & POE_X;
@@ -1095,8 +1104,7 @@ static void compute_s1_permissions(struct kvm_vcpu *vcpu,
if (!wi->hpd)
compute_s1_hierarchical_permissions(vcpu, wi, wr);
- if (wi->poe || wi->e0poe)
- compute_s1_overlay_permissions(vcpu, wi, wr);
+ compute_s1_overlay_permissions(vcpu, wi, wr);
/* R_QXXPC */
if (wr->pwxn) {
--
2.39.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] KVM: arm64: Follow specification when implementing WXN
2025-07-01 15:16 [PATCH 0/2] KVM: arm64: Fixes and clarifications for FEAT_S1POE Marc Zyngier
2025-07-01 15:16 ` [PATCH 1/2] KVM: arm64: Remove the wi->{e0,}poe vs wr->{p,u}ov confusion Marc Zyngier
@ 2025-07-01 15:16 ` Marc Zyngier
2025-07-24 6:49 ` [PATCH 0/2] KVM: arm64: Fixes and clarifications for FEAT_S1POE Oliver Upton
2 siblings, 0 replies; 4+ messages in thread
From: Marc Zyngier @ 2025-07-01 15:16 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel
Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu
The R_QXXPC and R_NPBXC rules have some interesting (and pretty
sharp) corners when defining the behaviour of of WXN at S1:
- when S1 overlay is enabled, WXN applies to the overlay and
will remove W
- when S1 overlay is disabled, WXN applies to the base permissions
and will remove X.
Today, we lumb the two together in a way that doesn't really match
the rules, making things awkward to follow what is happening, in
particular when overlays are enabled.
Split these two rules over two distinct paths, which makes things
a lot easier to read and validate against the architecture rules.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kvm/at.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/arch/arm64/kvm/at.c b/arch/arm64/kvm/at.c
index a26e377a36171..0e56105339493 100644
--- a/arch/arm64/kvm/at.c
+++ b/arch/arm64/kvm/at.c
@@ -1063,6 +1063,10 @@ static void compute_s1_overlay_permissions(struct kvm_vcpu *vcpu,
if (pov_perms & ~POE_RWX)
pov_perms = POE_NONE;
+ /* R_QXXPC, S1PrivOverflow enabled */
+ if (wr->pwxn && (pov_perms & POE_X))
+ pov_perms &= ~POE_W;
+
wr->pr &= pov_perms & POE_R;
wr->pw &= pov_perms & POE_W;
wr->px &= pov_perms & POE_X;
@@ -1084,6 +1088,10 @@ static void compute_s1_overlay_permissions(struct kvm_vcpu *vcpu,
if (uov_perms & ~POE_RWX)
uov_perms = POE_NONE;
+ /* R_NPBXC, S1UnprivOverlay enabled */
+ if (wr->uwxn && (uov_perms & POE_X))
+ uov_perms &= ~POE_W;
+
wr->ur &= uov_perms & POE_R;
wr->uw &= uov_perms & POE_W;
wr->ux &= uov_perms & POE_X;
@@ -1106,21 +1114,13 @@ static void compute_s1_permissions(struct kvm_vcpu *vcpu,
compute_s1_overlay_permissions(vcpu, wi, wr);
- /* R_QXXPC */
- if (wr->pwxn) {
- if (!wr->pov && wr->pw)
- wr->px = false;
- if (wr->pov && wr->px)
- wr->pw = false;
- }
+ /* R_QXXPC, S1PrivOverlay disabled */
+ if (!wr->pov)
+ wr->px &= !(wr->pwxn && wr->pw);
- /* R_NPBXC */
- if (wr->uwxn) {
- if (!wr->uov && wr->uw)
- wr->ux = false;
- if (wr->uov && wr->ux)
- wr->uw = false;
- }
+ /* R_NPBXC, S1UnprivOverlay disabled */
+ if (!wr->uov)
+ wr->ux &= !(wr->uwxn && wr->uw);
pan = wi->pan && (wr->ur || wr->uw ||
(pan3_enabled(vcpu, wi->regime) && wr->ux));
--
2.39.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 0/2] KVM: arm64: Fixes and clarifications for FEAT_S1POE
2025-07-01 15:16 [PATCH 0/2] KVM: arm64: Fixes and clarifications for FEAT_S1POE Marc Zyngier
2025-07-01 15:16 ` [PATCH 1/2] KVM: arm64: Remove the wi->{e0,}poe vs wr->{p,u}ov confusion Marc Zyngier
2025-07-01 15:16 ` [PATCH 2/2] KVM: arm64: Follow specification when implementing WXN Marc Zyngier
@ 2025-07-24 6:49 ` Oliver Upton
2 siblings, 0 replies; 4+ messages in thread
From: Oliver Upton @ 2025-07-24 6:49 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, Marc Zyngier
Cc: Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu
On Tue, 01 Jul 2025 16:16:46 +0100, Marc Zyngier wrote:
> I (almost accidentally) spotted a couple of issues with the current NV
> support for S1POE:
>
> - wi->{e0,}poe and wr->{p,u}ov are used interchangeably, and sometimes
> in conjunction -- none of that makes much sense
>
> - The two rules describing WXN are not exactly been applied to the
> correct state
>
> [...]
Applied to next, thanks!
[1/2] KVM: arm64: Remove the wi->{e0,}poe vs wr->{p,u}ov confusion
https://git.kernel.org/kvmarm/kvmarm/c/a508d5afb708
[2/2] KVM: arm64: Follow specification when implementing WXN
https://git.kernel.org/kvmarm/kvmarm/c/5152977340b6
--
Best,
Oliver
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-07-24 6:59 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-01 15:16 [PATCH 0/2] KVM: arm64: Fixes and clarifications for FEAT_S1POE Marc Zyngier
2025-07-01 15:16 ` [PATCH 1/2] KVM: arm64: Remove the wi->{e0,}poe vs wr->{p,u}ov confusion Marc Zyngier
2025-07-01 15:16 ` [PATCH 2/2] KVM: arm64: Follow specification when implementing WXN Marc Zyngier
2025-07-24 6:49 ` [PATCH 0/2] KVM: arm64: Fixes and clarifications for FEAT_S1POE Oliver Upton
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).