On Wed, 23 Sept 2026 at 16:17, Lorenzo Stoakes (ARM) <[email protected]> wrote: > > kvm_handle_guest_abort() establishes a kvm_s2_fault_desc data structure, > s2fd, to store and propagate state to either pkvm_mem_abort(), gmem_abort() > or user_mem_abort() handlers. > > Each of these, however, examines the state of the stage 2 MMU via > vcpu->arch.hw_mmu. > > Introduce an s2fd->mmu field to abstract this and propagate it to callers. > > Similar to adding the esr field, this allows injection of synthetic faults > with the ultimate intention of implementing stage 2 page table > pre-faulting. > > No functional change intended. > > Reviewed-by: Oliver Upton <[email protected]> > Signed-off-by: Lorenzo Stoakes (ARM) <[email protected]>
Reviewed-by: Fuad Tabba <[email protected]> Cheers, /fuad > --- > arch/arm64/kvm/mmu.c | 19 +++++++++++-------- > 1 file changed, 11 insertions(+), 8 deletions(-) > > diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c > index cb677ab76484..9d799f7c1e62 100644 > --- a/arch/arm64/kvm/mmu.c > +++ b/arch/arm64/kvm/mmu.c > @@ -1656,6 +1656,7 @@ struct kvm_s2_fault_desc { > struct kvm_memory_slot *memslot; > unsigned long hva; > unsigned long esr; > + struct kvm_s2_mmu *mmu; > }; > > static bool kvm_s2_fault_is_perm(const struct kvm_s2_fault_desc *s2fd) > @@ -1689,7 +1690,7 @@ static int gmem_abort(const struct kvm_s2_fault_desc > *s2fd) > bool perm_fault = kvm_s2_fault_is_perm(s2fd); > enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_SHARED; > enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R; > - struct kvm_pgtable *pgt = s2fd->vcpu->arch.hw_mmu->pgt; > + struct kvm_pgtable *pgt = s2fd->mmu->pgt; > struct kvm_guest_s2_mapping *mapping = NULL; > unsigned long mmu_seq; > struct page *page; > @@ -1805,7 +1806,7 @@ static int pkvm_mem_abort(const struct > kvm_s2_fault_desc *s2fd) > { > unsigned int flags = FOLL_HWPOISON | FOLL_LONGTERM | FOLL_WRITE; > struct kvm_vcpu *vcpu = s2fd->vcpu; > - struct kvm_pgtable *pgt = vcpu->arch.hw_mmu->pgt; > + struct kvm_pgtable *pgt = s2fd->mmu->pgt; > struct mm_struct *mm = current->mm; > struct kvm *kvm = vcpu->kvm; > void *hyp_memcache; > @@ -2121,7 +2122,7 @@ static int kvm_s2_fault_map(const struct > kvm_s2_fault_desc *s2fd, > gfn_t gfn; > int ret; > > - if (kvm_is_nested_s2_mmu(kvm, s2fd->vcpu->arch.hw_mmu)) { > + if (kvm_is_nested_s2_mmu(kvm, s2fd->mmu)) { > mapping = kmalloc_obj(struct kvm_guest_s2_mapping, > GFP_KERNEL_ACCOUNT); > if (!mapping) { > @@ -2131,7 +2132,7 @@ static int kvm_s2_fault_map(const struct > kvm_s2_fault_desc *s2fd, > } > > kvm_fault_lock(kvm); > - pgt = s2fd->vcpu->arch.hw_mmu->pgt; > + pgt = s2fd->mmu->pgt; > ret = -EAGAIN; > if (mmu_invalidate_retry(kvm, s2vi->mmu_seq)) > goto out_unlock; > @@ -2363,6 +2364,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) > { > struct kvm_s2_trans nested_trans, *nested = NULL; > unsigned long esr = kvm_vcpu_get_esr(vcpu); > + struct kvm_s2_mmu *mmu = vcpu->arch.hw_mmu; > phys_addr_t fault_ipa; /* The address we faulted on */ > phys_addr_t ipa; /* Always the IPA in the L1 guest phys space */ > struct kvm_memory_slot *memslot; > @@ -2392,7 +2394,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) > } > > /* Falls between the IPA range and the PARange? */ > - if (fault_ipa >= > BIT_ULL(VTCR_EL2_IPA(vcpu->arch.hw_mmu->vtcr))) { > + if (fault_ipa >= BIT_ULL(VTCR_EL2_IPA(mmu->vtcr))) { > fault_ipa |= > FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(vcpu)); > > return kvm_inject_sea(vcpu, is_iabt, fault_ipa); > @@ -2429,8 +2431,8 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) > * nothing to walk and we treat it as a 1:1 before going through the > * canonical translation. > */ > - if (kvm_is_nested_s2_mmu(vcpu->kvm,vcpu->arch.hw_mmu) && > - vcpu->arch.hw_mmu->nested_stage2_enabled) { > + if (kvm_is_nested_s2_mmu(vcpu->kvm, mmu) && > + mmu->nested_stage2_enabled) { > u32 esr; > > ret = kvm_walk_nested_s2(vcpu, fault_ipa, &nested_trans); > @@ -2505,7 +2507,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) > } > > /* Userspace should not be able to register out-of-bounds IPAs */ > - VM_BUG_ON(ipa >= kvm_phys_size(vcpu->arch.hw_mmu)); > + VM_BUG_ON(ipa >= kvm_phys_size(mmu)); > > if (esr_fsc_is_access_flag_fault(esr)) { > handle_access_fault(vcpu, fault_ipa); > @@ -2520,6 +2522,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) > .memslot = memslot, > .hva = hva, > .esr = esr, > + .mmu = mmu, > }; > > if (kvm_vm_is_protected(vcpu->kvm)) { > > -- > 2.55.0 >

