diff options
author | James Hogan <james.hogan@imgtec.com> | 2016-12-16 18:57:00 +0300 |
---|---|---|
committer | James Hogan <james.hogan@imgtec.com> | 2017-02-03 18:20:55 +0300 |
commit | a31b50d741bd85a127d5ef2c21c0788041bc41a9 (patch) | |
tree | e67fc587b0eb2d038b20f3b9b67be6a5bdf868b5 /arch/mips/kvm/trap_emul.c | |
parent | 57e3869cfaaec712f6ea1855ab7ba868f6f306ed (diff) | |
download | linux-a31b50d741bd85a127d5ef2c21c0788041bc41a9.tar.xz |
KVM: MIPS/MMU: Invalidate GVA PTs on ASID changes
Implement invalidation of large ranges of virtual addresses from GVA
page tables in response to a guest ASID change (immediately for guest
kernel page table, lazily for guest user page table).
We iterate through a range of page tables invalidating entries and
freeing fully invalidated tables. To minimise overhead the exact ranges
invalidated depends on the flags argument to kvm_mips_flush_gva_pt(),
which also allows it to be used in future KVM_CAP_SYNC_MMU patches in
response to GPA changes, which unlike guest TLB mapping changes affects
guest KSeg0 mappings.
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/trap_emul.c')
-rw-r--r-- | arch/mips/kvm/trap_emul.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c index f39d427649dc..6a56e48f4bfa 100644 --- a/arch/mips/kvm/trap_emul.c +++ b/arch/mips/kvm/trap_emul.c @@ -774,14 +774,15 @@ static void kvm_trap_emul_vcpu_reenter(struct kvm_run *run, unsigned int gasid; /* - * Lazy host ASID regeneration for guest user mode. + * Lazy host ASID regeneration / PT flush for guest user mode. * If the guest ASID has changed since the last guest usermode * execution, regenerate the host ASID so as to invalidate stale TLB - * entries. + * entries and flush GVA PT entries too. */ if (!KVM_GUEST_KERNEL_MODE(vcpu)) { gasid = kvm_read_c0_guest_entryhi(cop0) & KVM_ENTRYHI_ASID; if (gasid != vcpu->arch.last_user_gasid) { + kvm_mips_flush_gva_pt(user_mm->pgd, KMF_USER); kvm_get_new_mmu_context(user_mm, cpu, vcpu); for_each_possible_cpu(i) if (i != cpu) |