summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2016-11-18 13:25:24 +0000
committerJames Hogan <james.hogan@imgtec.com>2017-02-03 15:20:47 +0000
commit91cdee5710d5fe8f81915307b5ff38d364fbde33 (patch)
treed53768eb9f21961659e0909bcf3b868d4ef85049 /arch
parenta2c046e40ff16ef6c20d534b0d77d526bc02a684 (diff)
KVM: MIPS/T&E: Restore host asid on return to host
We only need the guest ASID loaded while in guest context, i.e. while running guest code and while handling guest exits. We load the guest ASID when entering the guest, however we restore the host ASID later than necessary, when the VCPU state is saved i.e. vcpu_put() or slightly earlier if preempted after returning to the host. This mismatch is both unpleasant and causes redundant host ASID restores in kvm_trap_emul_vcpu_put(). Lets explicitly restore the host ASID when returning to the host, and don't bother restoring the host ASID on context switch in unless we're already in guest context. 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')
-rw-r--r--arch/mips/kvm/trap_emul.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c
index 92734d095c94..3e1dbcbcea85 100644
--- a/arch/mips/kvm/trap_emul.c
+++ b/arch/mips/kvm/trap_emul.c
@@ -680,14 +680,17 @@ static int kvm_trap_emul_vcpu_put(struct kvm_vcpu *vcpu, int cpu)
{
kvm_lose_fpu(vcpu);
- if (((cpu_context(cpu, current->mm) ^ asid_cache(cpu)) &
- asid_version_mask(cpu))) {
- kvm_debug("%s: Dropping MMU Context: %#lx\n", __func__,
- cpu_context(cpu, current->mm));
- drop_mmu_context(current->mm, cpu);
+ if (current->flags & PF_VCPU) {
+ /* Restore normal Linux process memory map */
+ if (((cpu_context(cpu, current->mm) ^ asid_cache(cpu)) &
+ asid_version_mask(cpu))) {
+ kvm_debug("%s: Dropping MMU Context: %#lx\n", __func__,
+ cpu_context(cpu, current->mm));
+ get_new_mmu_context(current->mm, cpu);
+ }
+ write_c0_entryhi(cpu_asid(cpu, current->mm));
+ ehb();
}
- write_c0_entryhi(cpu_asid(cpu, current->mm));
- ehb();
return 0;
}
@@ -720,6 +723,7 @@ static void kvm_trap_emul_vcpu_reenter(struct kvm_run *run,
static int kvm_trap_emul_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu)
{
+ int cpu;
int r;
/* Check if we have any exceptions/interrupts pending */
@@ -733,6 +737,15 @@ static int kvm_trap_emul_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu)
r = vcpu->arch.vcpu_run(run, vcpu);
+ /* We may have migrated while handling guest exits */
+ cpu = smp_processor_id();
+
+ /* Restore normal Linux process memory map */
+ if (((cpu_context(cpu, current->mm) ^ asid_cache(cpu)) &
+ asid_version_mask(cpu)))
+ get_new_mmu_context(current->mm, cpu);
+ write_c0_entryhi(cpu_asid(cpu, current->mm));
+
htw_start();
return r;