summaryrefslogtreecommitdiff
path: root/arch/mips/kvm/emulate.c
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2016-09-15 23:06:43 (GMT)
committerJames Hogan <james.hogan@imgtec.com>2016-09-29 11:40:12 (GMT)
commit25b08c7fb0e410bdf7c42ea1faff816eb0451bbc (patch)
treef2be0c2e8c95086fbfb6f79d7ca890eadd0895d2 /arch/mips/kvm/emulate.c
parentf3124cc551c8575c30e3736faf2d0bca54ee07cb (diff)
downloadlinux-25b08c7fb0e410bdf7c42ea1faff816eb0451bbc.tar.xz
KVM: MIPS: Invalidate TLB by regenerating ASIDs
Invalidate host TLB mappings when the guest ASID is changed by regenerating ASIDs, rather than flushing the entire host TLB except entries in the guest KSeg0 range. For the guest kernel mode ASID we regenerate on the spot when the guest ASID is changed, as that will always take place while the guest is in kernel mode. However when the guest invalidates TLB entries the ASID will often by changed temporarily as part of writing EntryHi without the guest returning to user mode in between. We therefore regenerate the user mode ASID lazily before entering the guest in user mode, if and only if the guest ASID has actually changed since the last guest user mode entry. 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/emulate.c')
-rw-r--r--arch/mips/kvm/emulate.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index 43853ec..8dc9e64 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -1170,15 +1170,23 @@ enum emulation_result kvm_mips_emulate_CP0(union mips_instruction inst,
& KVM_ENTRYHI_ASID,
nasid);
+ /*
+ * Regenerate/invalidate kernel MMU
+ * context.
+ * The user MMU context will be
+ * regenerated lazily on re-entry to
+ * guest user if the guest ASID actually
+ * changes.
+ */
preempt_disable();
- /* Blow away the shadow host TLBs */
- kvm_mips_flush_host_tlb(1);
cpu = smp_processor_id();
+ kvm_get_new_mmu_context(&vcpu->arch.guest_kernel_mm,
+ cpu, vcpu);
+ vcpu->arch.guest_kernel_asid[cpu] =
+ vcpu->arch.guest_kernel_mm.context.asid[cpu];
for_each_possible_cpu(i)
- if (i != cpu) {
- vcpu->arch.guest_user_asid[i] = 0;
+ if (i != cpu)
vcpu->arch.guest_kernel_asid[i] = 0;
- }
preempt_enable();
}
kvm_write_c0_guest_entryhi(cop0,