The function kvmppc_hpte_hv_fault() is used to search a hpt (hash page table) for an existing entry given a slb entry, a fault code and a fault address. Currently this function is only called in real mode. Modify this function so that it can be called in virtual mode and add a function parameter used to specify if the function is being called from real mode or not. Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@xxxxxxxxx> --- arch/powerpc/include/asm/kvm_ppc.h | 3 ++- arch/powerpc/kvm/book3s_hv_rm_mmu.c | 9 +++++++-- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 2 ++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 2484e6a8f5ca..2c4d659cf8bb 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -688,7 +688,8 @@ long kvmppc_h_clear_mod(struct kvm_vcpu *vcpu, unsigned long flags, long kvmppc_rm_h_page_init(struct kvm_vcpu *vcpu, unsigned long flags, unsigned long dest, unsigned long src); long kvmppc_hpte_hv_fault(struct kvm_vcpu *vcpu, unsigned long addr, - unsigned long slb_v, unsigned int status, bool data); + unsigned long slb_v, unsigned int status, + bool data, bool is_realmode); unsigned long kvmppc_rm_h_xirr(struct kvm_vcpu *vcpu); unsigned long kvmppc_rm_h_xirr_x(struct kvm_vcpu *vcpu); unsigned long kvmppc_rm_h_ipoll(struct kvm_vcpu *vcpu, unsigned long server); diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index 63e0ce91e29d..9f7ad4eaa528 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c @@ -1182,9 +1182,12 @@ EXPORT_SYMBOL(kvmppc_hv_find_lock_hpte); * -1 to pass the fault up to host kernel mode code, -2 to do that * and also load the instruction word (for MMIO emulation), * or 0 if we should make the guest retry the access. + * For a nested hypervisor, this will be called in virtual mode + * (is_realmode == false) and should be called with preemption disabled. */ long kvmppc_hpte_hv_fault(struct kvm_vcpu *vcpu, unsigned long addr, - unsigned long slb_v, unsigned int status, bool data) + unsigned long slb_v, unsigned int status, + bool data, bool is_realmode) { struct kvm *kvm = vcpu->kvm; long int index; @@ -1222,7 +1225,9 @@ long kvmppc_hpte_hv_fault(struct kvm_vcpu *vcpu, unsigned long addr, v = hpte_new_to_old_v(v, r); r = hpte_new_to_old_r(r); } - rev = real_vmalloc_addr(&kvm->arch.hpt.rev[index]); + rev = &kvm->arch.hpt.rev[index]; + if (is_realmode) + rev = real_vmalloc_addr(rev); gr = rev->guest_rpte; unlock_hpte(hpte, orig_v); diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 337e64468d78..54e1864d4702 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -2066,6 +2066,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) /* Search the hash table. */ mr r3, r9 /* vcpu pointer */ li r7, 1 /* data fault */ + li r8, 1 /* is real mode */ bl kvmppc_hpte_hv_fault ld r9, HSTATE_KVM_VCPU(r13) ld r10, VCPU_PC(r9) @@ -2158,6 +2159,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) mr r4, r10 mr r6, r11 li r7, 0 /* instruction fault */ + li r8, 1 /* is real mode */ bl kvmppc_hpte_hv_fault ld r9, HSTATE_KVM_VCPU(r13) ld r10, VCPU_PC(r9) -- 2.13.6