diff options
author | James Hogan <james.hogan@imgtec.com> | 2016-10-08 02:16:21 +0200 |
---|---|---|
committer | James Hogan <james.hogan@imgtec.com> | 2017-02-03 16:20:59 +0100 |
commit | 4c86460cbc03f32c3649f7aaf9104e6e65c88a61 (patch) | |
tree | d94bd09b1a0271c6442bfe9fe4cb97a7abcef7c5 /arch/mips/kvm/mmu.c | |
parent | KVM: MIPS/MMU: Convert TLB mapped faults to page tables (diff) | |
download | linux-4c86460cbc03f32c3649f7aaf9104e6e65c88a61.tar.xz linux-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.c | 21 |
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) { |