aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kvm/mmu.c
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2016-10-08 01:16:21 +0100
committerJames Hogan <james.hogan@imgtec.com>2017-02-03 15:20:59 +0000
commit4c86460cbc03f32c3649f7aaf9104e6e65c88a61 (patch)
treed94bd09b1a0271c6442bfe9fe4cb97a7abcef7c5 /arch/mips/kvm/mmu.c
parentKVM: MIPS/MMU: Convert TLB mapped faults to page tables (diff)
downloadlinux-dev-4c86460cbc03f32c3649f7aaf9104e6e65c88a61.tar.xz
linux-dev-4c86460cbc03f32c3649f7aaf9104e6e65c88a61.zip
KVM: MIPS/MMU: Convert commpage fault handling to page tables
Now that we have GVA page tables and an optimised TLB refill handler in place, convert the handling of commpage faults from the guest kernel to fill the GVA page table and invalidate the TLB entry, rather than filling the wired TLB entry directly. For simplicity we no longer use a wired entry for the commpage (refill should be much cheaper with the fast-path handler anyway). Since we don't need to manipulate the TLB directly any longer, move the function from tlb.c to mmu.c. This puts it closer to the similar functions handling KSeg0 and TLB mapped page faults from the guest. Signed-off-by: James Hogan <james.hogan@imgtec.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: "Radim Krčmář" <rkrcmar@redhat.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: linux-mips@linux-mips.org Cc: kvm@vger.kernel.org
Diffstat (limited to 'arch/mips/kvm/mmu.c')
-rw-r--r--arch/mips/kvm/mmu.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/arch/mips/kvm/mmu.c b/arch/mips/kvm/mmu.c
index 62122d297e52..98f1a7715a68 100644
--- a/arch/mips/kvm/mmu.c
+++ b/arch/mips/kvm/mmu.c
@@ -449,6 +449,27 @@ int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
return 0;
}
+int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr,
+ struct kvm_vcpu *vcpu)
+{
+ kvm_pfn_t pfn;
+ pte_t *ptep;
+
+ ptep = kvm_trap_emul_pte_for_gva(vcpu, badvaddr);
+ if (!ptep) {
+ kvm_err("No ptep for commpage %lx\n", badvaddr);
+ return -1;
+ }
+
+ pfn = PFN_DOWN(virt_to_phys(vcpu->arch.kseg0_commpage));
+ /* Also set valid and dirty, so refill handler doesn't have to */
+ *ptep = pte_mkyoung(pte_mkdirty(pfn_pte(pfn, PAGE_SHARED)));
+
+ /* Invalidate this entry in the TLB, guest kernel ASID only */
+ kvm_mips_host_tlb_inv(vcpu, badvaddr, false, true);
+ return 0;
+}
+
void kvm_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu,
struct kvm_vcpu *vcpu)
{