From: Oliver Upton <oupton@kernel.org>
To: kvmarm@lists.linux.dev
Cc: Marc Zyngier <maz@kernel.org>, Joey Gouly <joey.gouly@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Zenghui Yu <yuzenghui@huawei.com>,
Wei-Lin Chang <weilin.chang@arm.com>,
Steffen Eiden <seiden@linux.ibm.com>,
Oliver Upton <oupton@kernel.org>
Subject: [PATCH 01/22] KVM: arm64: nv: Introduce struct for stage-2 walk step
Date: Tue, 23 Jun 2026 11:41:40 -0700 [thread overview]
Message-ID: <20260623184201.1518871-2-oupton@kernel.org> (raw)
In-Reply-To: <20260623184201.1518871-1-oupton@kernel.org>
Factoring out helpers from walk_nested_s2_pgd() will require passing the
context of the current walk step. Prepare by reorganizing the relvant
information into a struct.
Signed-off-by: Oliver Upton <oupton@kernel.org>
---
arch/arm64/kvm/nested.c | 109 +++++++++++++++++++++-------------------
1 file changed, 57 insertions(+), 52 deletions(-)
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 94df26de6990..9e60c7c822ae 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -134,6 +134,12 @@ struct s2_walk_info {
bool ha;
};
+struct s2_walk_step {
+ u64 desc_pa;
+ u64 desc;
+ int level;
+};
+
static u32 compute_fsc(int level, u32 fsc)
{
return fsc | (level & 0x3);
@@ -199,13 +205,13 @@ static int check_output_size(struct s2_walk_info *wi, phys_addr_t output)
return 0;
}
-static int read_guest_s2_desc(struct kvm_vcpu *vcpu, phys_addr_t pa, u64 *desc,
+static int read_guest_s2_desc(struct kvm_vcpu *vcpu, struct s2_walk_step *ws,
struct s2_walk_info *wi)
{
u64 val;
int r;
- r = kvm_read_guest(vcpu->kvm, pa, &val, sizeof(val));
+ r = kvm_read_guest(vcpu->kvm, ws->desc_pa, &val, sizeof(val));
if (r)
return r;
@@ -214,9 +220,9 @@ static int read_guest_s2_desc(struct kvm_vcpu *vcpu, phys_addr_t pa, u64 *desc,
* host and the guest hypervisor.
*/
if (wi->be)
- *desc = be64_to_cpu((__force __be64)val);
+ ws->desc = be64_to_cpu((__force __be64)val);
else
- *desc = le64_to_cpu((__force __le64)val);
+ ws->desc = le64_to_cpu((__force __le64)val);
return 0;
}
@@ -245,22 +251,22 @@ static int swap_guest_s2_desc(struct kvm_vcpu *vcpu, phys_addr_t pa, u64 old, u6
static int walk_nested_s2_pgd(struct kvm_vcpu *vcpu, phys_addr_t ipa,
struct s2_walk_info *wi, struct kvm_s2_trans *out)
{
- int first_block_level, level, stride, input_size, base_lower_bound;
+ int first_block_level, stride, input_size, base_lower_bound;
+ struct s2_walk_step ws = {};
phys_addr_t base_addr;
unsigned int addr_top, addr_bottom;
- u64 desc, new_desc; /* page table entry */
+ u64 new_desc; /* page table entry */
int ret;
- phys_addr_t paddr;
switch (BIT(wi->pgshift)) {
default:
case SZ_64K:
case SZ_16K:
- level = 3 - wi->sl;
+ ws.level = 3 - wi->sl;
first_block_level = 2;
break;
case SZ_4K:
- level = 2 - wi->sl;
+ ws.level = 2 - wi->sl;
first_block_level = 1;
break;
}
@@ -270,13 +276,13 @@ static int walk_nested_s2_pgd(struct kvm_vcpu *vcpu, phys_addr_t ipa,
if (input_size > 48 || input_size < 25)
return -EFAULT;
- ret = check_base_s2_limits(vcpu, wi, level, input_size, stride);
+ ret = check_base_s2_limits(vcpu, wi, ws.level, input_size, stride);
if (WARN_ON(ret)) {
out->esr = compute_fsc(0, ESR_ELx_FSC_FAULT);
return ret;
}
- base_lower_bound = 3 + input_size - ((3 - level) * stride +
+ base_lower_bound = 3 + input_size - ((3 - ws.level) * stride +
wi->pgshift);
base_addr = wi->baddr & GENMASK_ULL(47, base_lower_bound);
@@ -291,96 +297,95 @@ static int walk_nested_s2_pgd(struct kvm_vcpu *vcpu, phys_addr_t ipa,
while (1) {
phys_addr_t index;
- addr_bottom = (3 - level) * stride + wi->pgshift;
+ addr_bottom = (3 - ws.level) * stride + wi->pgshift;
index = (ipa & GENMASK_ULL(addr_top, addr_bottom))
>> (addr_bottom - 3);
- paddr = base_addr | index;
- ret = read_guest_s2_desc(vcpu, paddr, &desc, wi);
+ ws.desc_pa = base_addr | index;
+ ret = read_guest_s2_desc(vcpu, &ws, wi);
if (ret < 0) {
- out->esr = ESR_ELx_FSC_SEA_TTW(level);
+ out->esr = ESR_ELx_FSC_SEA_TTW(ws.level);
return ret;
}
- new_desc = desc;
+ new_desc = ws.desc;
/* Check for valid descriptor at this point */
- if (!(desc & KVM_PTE_VALID)) {
- out->esr = compute_fsc(level, ESR_ELx_FSC_FAULT);
- out->desc = desc;
+ if (!(ws.desc & KVM_PTE_VALID)) {
+ out->esr = compute_fsc(ws.level, ESR_ELx_FSC_FAULT);
+ out->desc = ws.desc;
return 1;
}
- if (FIELD_GET(KVM_PTE_TYPE, desc) == KVM_PTE_TYPE_BLOCK) {
- if (level < 3)
+ if (FIELD_GET(KVM_PTE_TYPE, ws.desc) == KVM_PTE_TYPE_BLOCK) {
+ if (ws.level < 3)
break;
- out->esr = compute_fsc(level, ESR_ELx_FSC_FAULT);
- out->desc = desc;
+ out->esr = compute_fsc(ws.level, ESR_ELx_FSC_FAULT);
+ out->desc = ws.desc;
return 1;
}
/* We're at the final level */
- if (level == 3)
+ if (ws.level == 3)
break;
- if (check_output_size(wi, desc)) {
- out->esr = compute_fsc(level, ESR_ELx_FSC_ADDRSZ);
- out->desc = desc;
+ if (check_output_size(wi, ws.desc)) {
+ out->esr = compute_fsc(ws.level, ESR_ELx_FSC_ADDRSZ);
+ out->desc = ws.desc;
return 1;
}
- base_addr = desc & GENMASK_ULL(47, wi->pgshift);
+ base_addr = ws.desc & GENMASK_ULL(47, wi->pgshift);
- level += 1;
+ ws.level += 1;
addr_top = addr_bottom - 1;
}
- if (level < first_block_level) {
- out->esr = compute_fsc(level, ESR_ELx_FSC_FAULT);
- out->desc = desc;
+ if (ws.level < first_block_level) {
+ out->esr = compute_fsc(ws.level, ESR_ELx_FSC_FAULT);
+ out->desc = ws.desc;
return 1;
}
- if (check_output_size(wi, desc)) {
- out->esr = compute_fsc(level, ESR_ELx_FSC_ADDRSZ);
- out->desc = desc;
+ if (check_output_size(wi, ws.desc)) {
+ out->esr = compute_fsc(ws.level, ESR_ELx_FSC_ADDRSZ);
+ out->desc = ws.desc;
return 1;
}
if (wi->ha)
new_desc |= KVM_PTE_LEAF_ATTR_LO_S2_AF;
- if (new_desc != desc) {
- ret = swap_guest_s2_desc(vcpu, paddr, desc, new_desc, wi);
+ if (new_desc != ws.desc) {
+ ret = swap_guest_s2_desc(vcpu, ws.desc_pa, ws.desc, new_desc, wi);
if (ret == -EAGAIN)
return ret;
if (ret) {
- out->esr = ESR_ELx_FSC_SEA_TTW(level);
- out->desc = desc;
+ out->esr = ESR_ELx_FSC_SEA_TTW(ws.level);
+ out->desc = ws.desc;
return 1;
}
- desc = new_desc;
+ ws.desc = new_desc;
}
- if (!(desc & KVM_PTE_LEAF_ATTR_LO_S2_AF)) {
- out->esr = compute_fsc(level, ESR_ELx_FSC_ACCESS);
- out->desc = desc;
+ if (!(ws.desc & KVM_PTE_LEAF_ATTR_LO_S2_AF)) {
+ out->esr = compute_fsc(ws.level, ESR_ELx_FSC_ACCESS);
+ out->desc = ws.desc;
return 1;
}
- addr_bottom += contiguous_bit_shift(desc, wi, level);
+ addr_bottom += contiguous_bit_shift(ws.desc, wi, ws.level);
/* Calculate and return the result */
- paddr = (desc & GENMASK_ULL(47, addr_bottom)) |
- (ipa & GENMASK_ULL(addr_bottom - 1, 0));
- out->output = paddr;
- out->block_size = 1UL << ((3 - level) * stride + wi->pgshift);
- out->readable = desc & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R;
- out->writable = desc & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W;
- out->level = level;
- out->desc = desc;
+ out->output = (ws.desc & GENMASK_ULL(47, addr_bottom)) |
+ (ipa & GENMASK_ULL(addr_bottom - 1, 0));
+ out->block_size = 1UL << ((3 - ws.level) * stride + wi->pgshift);
+ out->readable = ws.desc & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R;
+ out->writable = ws.desc & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W;
+ out->level = ws.level;
+ out->desc = ws.desc;
return 0;
}
--
2.47.3
next prev parent reply other threads:[~2026-06-23 18:42 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-23 18:41 [PATCH 00/22] KVM: arm64: nv: Implement FEAT_HAFDBS, FEAT_HAFT Oliver Upton
2026-06-23 18:41 ` Oliver Upton [this message]
2026-06-23 18:41 ` [PATCH 02/22] KVM: arm64: nv: Consolidate computation of stage-2 permissions Oliver Upton
2026-06-23 18:57 ` sashiko-bot
2026-06-23 18:41 ` [PATCH 03/22] KVM: arm64: nv: Get rid of kvm_s2_trans*() accessors Oliver Upton
2026-06-23 18:41 ` [PATCH 04/22] KVM: arm64: nv: Only shadow writable-dirty guest descs as writable Oliver Upton
2026-06-23 18:58 ` sashiko-bot
2026-06-23 20:05 ` Oliver Upton
2026-06-23 18:41 ` [PATCH 05/22] KVM: arm64: nv: Pass an access descriptor for stage-2 walks Oliver Upton
2026-06-23 19:06 ` sashiko-bot
2026-06-23 18:41 ` [PATCH 06/22] KVM: arm64: nv: Use a helper for stage-2 descriptor updates Oliver Upton
2026-06-23 18:41 ` [PATCH 07/22] KVM: arm64: nv: Set dirty state at stage-2 Oliver Upton
2026-06-23 19:03 ` sashiko-bot
2026-06-23 18:41 ` [PATCH 08/22] KVM: arm64: nv: Treat DBM as writable " Oliver Upton
2026-06-23 18:55 ` sashiko-bot
2026-06-23 20:08 ` Oliver Upton
2026-06-23 18:41 ` [PATCH 09/22] KVM: arm64: Compute S1 permissions as part of s1_walk() Oliver Upton
2026-06-23 18:41 ` [PATCH 10/22] KVM: arm64: Plumb through access descriptor for stage-1 Oliver Upton
2026-06-23 18:41 ` [PATCH 11/22] KVM: arm64: Use a struct for stage-1 walk context Oliver Upton
2026-06-23 18:41 ` [PATCH 12/22] KVM: arm64: Create helper for stage-1 descriptor updates Oliver Upton
2026-06-23 18:55 ` sashiko-bot
2026-06-23 18:41 ` [PATCH 13/22] KVM: arm64: Set dirty state at stage-1 Oliver Upton
2026-06-23 18:54 ` sashiko-bot
2026-06-23 18:41 ` [PATCH 14/22] KVM: arm64: Grant write permission when DBM is set at S1 Oliver Upton
2026-06-23 18:57 ` sashiko-bot
2026-06-23 18:41 ` [PATCH 15/22] KVM: arm64: Don't update descriptors for "non-arch" access Oliver Upton
2026-06-23 18:41 ` [PATCH 16/22] KVM: arm64: nv: Expose FEAT_HAFDBS Oliver Upton
2026-06-23 19:01 ` sashiko-bot
2026-06-23 18:41 ` [PATCH 17/22] KVM: arm64: Set Access flag on table descriptors at stage-1 Oliver Upton
2026-06-23 20:56 ` sashiko-bot
2026-06-23 18:41 ` [PATCH 18/22] KVM: arm64: nv: Set access flag on table descriptors at stage-2 Oliver Upton
2026-06-23 19:05 ` sashiko-bot
2026-06-23 20:14 ` Oliver Upton
2026-06-23 18:41 ` [PATCH 19/22] KVM: arm64: nv: Expose FEAT_HAFT Oliver Upton
2026-06-23 19:05 ` sashiko-bot
2026-06-23 18:41 ` [PATCH 20/22] KVM: arm64: selftests: Only test AF behavior for emulated AT insns Oliver Upton
2026-06-23 18:42 ` [PATCH 21/22] KVM: arm64: selftests: Test AT emulation for FEAT_HAFT Oliver Upton
2026-06-23 19:05 ` sashiko-bot
2026-06-23 20:17 ` Oliver Upton
2026-06-23 18:42 ` [PATCH 22/22] HACK: KVM: arm64: nv: Set the dirty state for CMOs that fetch for write Oliver Upton
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=20260623184201.1518871-2-oupton@kernel.org \
--to=oupton@kernel.org \
--cc=joey.gouly@arm.com \
--cc=kvmarm@lists.linux.dev \
--cc=maz@kernel.org \
--cc=seiden@linux.ibm.com \
--cc=suzuki.poulose@arm.com \
--cc=weilin.chang@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.