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.

Signed-off-by: Lorenzo Stoakes (ARM) <[email protected]>
---
 arch/arm64/kvm/mmu.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 30d605e87b01..80cb520e25b9 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1604,6 +1604,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)
@@ -1637,7 +1638,7 @@ static int gmem_abort(const struct kvm_s2_fault_desc 
*s2fd)
        const 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;
        unsigned long mmu_seq;
        struct page *page;
        struct kvm *kvm = s2fd->vcpu->kvm;
@@ -1735,7 +1736,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;
@@ -2050,7 +2051,7 @@ static int kvm_s2_fault_map(const struct 
kvm_s2_fault_desc *s2fd,
        int ret;
 
        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;
@@ -2271,6 +2272,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 {
        struct kvm_s2_trans nested_trans, *nested = NULL;
        const 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;
@@ -2300,7 +2302,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);
@@ -2337,8 +2339,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);
@@ -2413,7 +2415,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);
@@ -2428,6 +2430,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


Reply via email to