@@ -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);
@@ -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);
@@ -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)
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@gmail.com> --- 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(-)