From: Marc Zyngier <maz@kernel.org>
To: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
kvm@vger.kernel.org
Cc: Joey Gouly <joey.gouly@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Oliver Upton <oliver.upton@linux.dev>,
Zenghui Yu <yuzenghui@huawei.com>,
Alexandru Elisei <alexandru.elisei@arm.com>,
Mark Brown <broonie@kernel.org>
Subject: [PATCH v4 19/36] KVM: arm64: Split S1 permission evaluation into direct and hierarchical parts
Date: Wed, 9 Oct 2024 20:00:02 +0100 [thread overview]
Message-ID: <20241009190019.3222687-20-maz@kernel.org> (raw)
In-Reply-To: <20241009190019.3222687-1-maz@kernel.org>
The AArch64.S1DirectBasePermissions() pseudocode deals with both
direct and hierarchical S1 permission evaluation. While this is
probably convenient in the pseudocode, we would like a bit more
flexibility to slot things like indirect permissions.
To that effect, split the two permission check parts out of
handle_at_slow() and into their own functions. The permissions
are passed around as part of the walk_result structure.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kvm/at.c | 162 +++++++++++++++++++++++++++-----------------
1 file changed, 98 insertions(+), 64 deletions(-)
diff --git a/arch/arm64/kvm/at.c b/arch/arm64/kvm/at.c
index b9d0992e91972..adcfce3f67f03 100644
--- a/arch/arm64/kvm/at.c
+++ b/arch/arm64/kvm/at.c
@@ -37,6 +37,12 @@ struct s1_walk_result {
u8 APTable;
bool UXNTable;
bool PXNTable;
+ bool ur;
+ bool uw;
+ bool ux;
+ bool pr;
+ bool pw;
+ bool px;
};
struct {
u8 fst;
@@ -764,111 +770,139 @@ static bool pan3_enabled(struct kvm_vcpu *vcpu, enum trans_regime regime)
return sctlr & SCTLR_EL1_EPAN;
}
-static u64 handle_at_slow(struct kvm_vcpu *vcpu, u32 op, u64 vaddr)
+static void compute_s1_direct_permissions(struct kvm_vcpu *vcpu,
+ struct s1_walk_info *wi,
+ struct s1_walk_result *wr)
{
- bool perm_fail, ur, uw, ux, pr, pw, px;
- struct s1_walk_result wr = {};
- struct s1_walk_info wi = {};
- int ret, idx;
-
- ret = setup_s1_walk(vcpu, op, &wi, &wr, vaddr);
- if (ret)
- goto compute_par;
-
- if (wr.level == S1_MMU_DISABLED)
- goto compute_par;
-
- idx = srcu_read_lock(&vcpu->kvm->srcu);
-
- ret = walk_s1(vcpu, &wi, &wr, vaddr);
-
- srcu_read_unlock(&vcpu->kvm->srcu, idx);
-
- if (ret)
- goto compute_par;
-
- /* FIXME: revisit when adding indirect permission support */
- /* AArch64.S1DirectBasePermissions() */
- if (wi.regime != TR_EL2) {
- switch (FIELD_GET(PTE_USER | PTE_RDONLY, wr.desc)) {
+ /* Non-hierarchical part of AArch64.S1DirectBasePermissions() */
+ if (wi->regime != TR_EL2) {
+ switch (FIELD_GET(PTE_USER | PTE_RDONLY, wr->desc)) {
case 0b00:
- pr = pw = true;
- ur = uw = false;
+ wr->pr = wr->pw = true;
+ wr->ur = wr->uw = false;
break;
case 0b01:
- pr = pw = ur = uw = true;
+ wr->pr = wr->pw = wr->ur = wr->uw = true;
break;
case 0b10:
- pr = true;
- pw = ur = uw = false;
+ wr->pr = true;
+ wr->pw = wr->ur = wr->uw = false;
break;
case 0b11:
- pr = ur = true;
- pw = uw = false;
+ wr->pr = wr->ur = true;
+ wr->pw = wr->uw = false;
break;
}
- switch (wr.APTable) {
+ /* We don't use px for anything yet, but hey... */
+ wr->px = !((wr->desc & PTE_PXN) || wr->uw);
+ wr->ux = !(wr->desc & PTE_UXN);
+ } else {
+ wr->ur = wr->uw = wr->ux = false;
+
+ if (!(wr->desc & PTE_RDONLY)) {
+ wr->pr = wr->pw = true;
+ } else {
+ wr->pr = true;
+ wr->pw = false;
+ }
+
+ /* XN maps to UXN */
+ wr->px = !(wr->desc & PTE_UXN);
+ }
+}
+
+static void compute_s1_hierarchical_permissions(struct kvm_vcpu *vcpu,
+ struct s1_walk_info *wi,
+ struct s1_walk_result *wr)
+{
+ /* Hierarchical part of AArch64.S1DirectBasePermissions() */
+ if (wi->regime != TR_EL2) {
+ switch (wr->APTable) {
case 0b00:
break;
case 0b01:
- ur = uw = false;
+ wr->ur = wr->uw = false;
break;
case 0b10:
- pw = uw = false;
+ wr->pw = wr->uw = false;
break;
case 0b11:
- pw = ur = uw = false;
+ wr->pw = wr->ur = wr->uw = false;
break;
}
- /* We don't use px for anything yet, but hey... */
- px = !((wr.desc & PTE_PXN) || wr.PXNTable || uw);
- ux = !((wr.desc & PTE_UXN) || wr.UXNTable);
+ wr->px &= !wr->PXNTable;
+ wr->ux &= !wr->UXNTable;
+ } else {
+ if (wr->APTable & BIT(1))
+ wr->pw = false;
- if (op == OP_AT_S1E1RP || op == OP_AT_S1E1WP) {
- bool pan;
+ /* XN maps to UXN */
+ wr->px &= !wr->UXNTable;
+ }
+}
- pan = *vcpu_cpsr(vcpu) & PSR_PAN_BIT;
- pan &= ur || uw || (pan3_enabled(vcpu, wi.regime) && ux);
- pw &= !pan;
- pr &= !pan;
- }
- } else {
- ur = uw = ux = false;
+static void compute_s1_permissions(struct kvm_vcpu *vcpu, u32 op,
+ struct s1_walk_info *wi,
+ struct s1_walk_result *wr)
+{
+ compute_s1_direct_permissions(vcpu, wi, wr);
- if (!(wr.desc & PTE_RDONLY)) {
- pr = pw = true;
- } else {
- pr = true;
- pw = false;
- }
+ if (!wi->hpd)
+ compute_s1_hierarchical_permissions(vcpu, wi, wr);
- if (wr.APTable & BIT(1))
- pw = false;
+ if (op == OP_AT_S1E1RP || op == OP_AT_S1E1WP) {
+ bool pan;
- /* XN maps to UXN */
- px = !((wr.desc & PTE_UXN) || wr.UXNTable);
+ pan = *vcpu_cpsr(vcpu) & PSR_PAN_BIT;
+ pan &= wr->ur || wr->uw || (pan3_enabled(vcpu, wi->regime) && wr->ux);
+ wr->pw &= !pan;
+ wr->pr &= !pan;
}
+}
+
+static u64 handle_at_slow(struct kvm_vcpu *vcpu, u32 op, u64 vaddr)
+{
+ struct s1_walk_result wr = {};
+ struct s1_walk_info wi = {};
+ bool perm_fail = false;
+ int ret, idx;
+
+ ret = setup_s1_walk(vcpu, op, &wi, &wr, vaddr);
+ if (ret)
+ goto compute_par;
+
+ if (wr.level == S1_MMU_DISABLED)
+ goto compute_par;
+
+ idx = srcu_read_lock(&vcpu->kvm->srcu);
+
+ ret = walk_s1(vcpu, &wi, &wr, vaddr);
+
+ srcu_read_unlock(&vcpu->kvm->srcu, idx);
+
+ if (ret)
+ goto compute_par;
- perm_fail = false;
+ compute_s1_permissions(vcpu, op, &wi, &wr);
switch (op) {
case OP_AT_S1E1RP:
case OP_AT_S1E1R:
case OP_AT_S1E2R:
- perm_fail = !pr;
+ perm_fail = !wr.pr;
break;
case OP_AT_S1E1WP:
case OP_AT_S1E1W:
case OP_AT_S1E2W:
- perm_fail = !pw;
+ perm_fail = !wr.pw;
break;
case OP_AT_S1E0R:
- perm_fail = !ur;
+ perm_fail = !wr.ur;
break;
case OP_AT_S1E0W:
- perm_fail = !uw;
+ perm_fail = !wr.uw;
break;
case OP_AT_S1E1A:
case OP_AT_S1E2A:
--
2.39.2
next prev parent reply other threads:[~2024-10-09 19:00 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-09 18:59 [PATCH v4 00/36] KVM: arm64: Add EL2 support to FEAT_S1PIE/S1POE Marc Zyngier
2024-10-09 18:59 ` [PATCH v4 01/36] arm64: Drop SKL0/SKL1 from TCR2_EL2 Marc Zyngier
2024-10-09 18:59 ` [PATCH v4 02/36] arm64: Remove VNCR definition for PIRE0_EL2 Marc Zyngier
2024-10-09 18:59 ` [PATCH v4 03/36] arm64: Add encoding " Marc Zyngier
2024-10-10 10:46 ` Mark Brown
2024-10-09 18:59 ` [PATCH v4 04/36] KVM: arm64: Drop useless struct s2_mmu in __kvm_at_s1e2() Marc Zyngier
2024-10-09 18:59 ` [PATCH v4 05/36] KVM: arm64: nv: Add missing EL2->EL1 mappings in get_el2_to_el1_mapping() Marc Zyngier
2024-10-09 18:59 ` [PATCH v4 06/36] KVM: arm64: nv: Handle CNTHCTL_EL2 specially Marc Zyngier
2024-10-16 9:37 ` Alexandru Elisei
2024-10-16 11:29 ` Marc Zyngier
2024-10-16 13:19 ` Alexandru Elisei
2024-10-16 13:41 ` Marc Zyngier
2024-10-09 18:59 ` [PATCH v4 07/36] KVM: arm64: nv: Save/Restore vEL2 sysregs Marc Zyngier
2024-10-09 19:55 ` Oliver Upton
2024-10-16 13:12 ` Alexandru Elisei
2024-10-16 13:57 ` Marc Zyngier
2024-10-09 18:59 ` [PATCH v4 08/36] KVM: arm64: Correctly access TCR2_EL1, PIR_EL1, PIRE0_EL1 with VHE Marc Zyngier
2024-10-09 18:59 ` [PATCH v4 09/36] KVM: arm64: Extend masking facility to arbitrary registers Marc Zyngier
2024-10-09 18:59 ` [PATCH v4 10/36] arm64: Define ID_AA64MMFR1_EL1.HAFDBS advertising FEAT_HAFT Marc Zyngier
2024-10-10 16:20 ` Mark Brown
2024-10-09 18:59 ` [PATCH v4 11/36] KVM: arm64: Add TCR2_EL2 to the sysreg arrays Marc Zyngier
2024-10-09 18:59 ` [PATCH v4 12/36] KVM: arm64: Sanitise TCR2_EL2 Marc Zyngier
2024-10-09 18:59 ` [PATCH v4 13/36] KVM: arm64: Add save/restore for TCR2_EL2 Marc Zyngier
2024-10-09 18:59 ` [PATCH v4 14/36] KVM: arm64: Add PIR{,E0}_EL2 to the sysreg arrays Marc Zyngier
2024-10-09 18:59 ` [PATCH v4 15/36] KVM: arm64: Add save/restore for PIR{,E0}_EL2 Marc Zyngier
2024-10-09 18:59 ` [PATCH v4 16/36] KVM: arm64: Handle PIR{,E0}_EL2 traps Marc Zyngier
2024-10-09 19:00 ` [PATCH v4 17/36] KVM: arm64: Sanitise ID_AA64MMFR3_EL1 Marc Zyngier
2024-10-09 19:00 ` [PATCH v4 18/36] KVM: arm64: Add AT fast-path support for S1PIE Marc Zyngier
2024-10-09 19:00 ` Marc Zyngier [this message]
2024-10-09 19:00 ` [PATCH v4 20/36] KVM: arm64: Disable hierarchical permissions when S1PIE is enabled Marc Zyngier
2024-10-10 7:33 ` Oliver Upton
2024-10-10 8:04 ` Marc Zyngier
2024-10-09 19:00 ` [PATCH v4 21/36] KVM: arm64: Implement AT S1PIE support Marc Zyngier
2024-10-09 19:00 ` [PATCH v4 22/36] KVM: arm64: Define helper for EL2 registers with custom visibility Marc Zyngier
2024-10-09 19:00 ` [PATCH v4 23/36] KVM: arm64: Hide TCR2_EL1 from userspace when disabled for guests Marc Zyngier
2024-10-10 7:50 ` Oliver Upton
2024-10-09 19:00 ` [PATCH v4 24/36] KVM: arm64: Hide S1PIE registers " Marc Zyngier
2024-10-09 19:00 ` [PATCH v4 25/36] KVM: arm64: Rely on visibility to let PIR*_ELx/TCR2_ELx UNDEF Marc Zyngier
2024-10-09 19:00 ` [PATCH v4 26/36] arm64: Add encoding for POR_EL2 Marc Zyngier
2024-10-09 19:00 ` [PATCH v4 27/36] KVM: arm64: Add a composite EL2 visibility helper Marc Zyngier
2024-10-10 7:52 ` Oliver Upton
2024-10-09 19:00 ` [PATCH v4 28/36] KVM: arm64: Drop bogus CPTR_EL2.E0POE trap routing Marc Zyngier
2024-10-09 19:00 ` [PATCH v4 29/36] KVM: arm64: Subject S1PIE/S1POE registers to HCR_EL2.{TVM,TRVM} Marc Zyngier
2024-10-10 7:53 ` Oliver Upton
2024-10-09 19:00 ` [PATCH v4 30/36] KVM: arm64: Add basic support for POR_EL2 Marc Zyngier
2024-10-09 19:00 ` [PATCH v4 31/36] KVM: arm64: Add save/retore " Marc Zyngier
2024-10-09 19:00 ` [PATCH v4 32/36] KVM: arm64: Add POE save/restore for AT emulation fast-path Marc Zyngier
2024-10-09 19:00 ` [PATCH v4 33/36] KVM: arm64: Disable hierarchical permissions when POE is enabled Marc Zyngier
2024-10-10 8:08 ` Oliver Upton
2024-10-13 14:27 ` Marc Zyngier
2024-10-09 19:00 ` [PATCH v4 34/36] KVM: arm64: Make PAN conditions part of the S1 walk context Marc Zyngier
2024-10-09 19:00 ` [PATCH v4 35/36] KVM: arm64: Handle stage-1 permission overlays Marc Zyngier
2024-10-09 19:00 ` [PATCH v4 36/36] KVM: arm64: Handle WXN attribute Marc Zyngier
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=20241009190019.3222687-20-maz@kernel.org \
--to=maz@kernel.org \
--cc=alexandru.elisei@arm.com \
--cc=broonie@kernel.org \
--cc=joey.gouly@arm.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=oliver.upton@linux.dev \
--cc=suzuki.poulose@arm.com \
--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.