aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kvm
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2015-02-04 05:52:03 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2015-02-04 10:23:33 -0500
commitc4c6f2cad9e1d4cc076bc183c3689cc9e7019c75 (patch)
treee7afc343303e4e6a048fd67156ff6fa7a68885cd /arch/mips/kvm
parent705699a139948a671cd66b915e8095c95fdf44d9 (diff)
KVM: MIPS: Disable HTW while in guest
Ensure any hardware page table walker (HTW) is disabled while in KVM guest mode, as KVM doesn't yet set up hardware page table walking for guest mappings so the wrong mappings would get loaded, resulting in the guest hanging or crashing once it reaches userland. The HTW is disabled and re-enabled around the call to __kvm_mips_vcpu_run() which does the initial switch into guest mode and the final switch out of guest context. Additionally it is enabled for the duration of guest exits (i.e. kvm_mips_handle_exit()), getting disabled again before returning back to guest or host. In all cases the HTW is only disabled in normal kernel mode while interrupts are disabled, so that the HTW doesn't get left disabled if the process is preempted. Signed-off-by: James Hogan <james.hogan@imgtec.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Markos Chandras <markos.chandras@imgtec.com> Cc: Gleb Natapov <gleb@kernel.org> Cc: kvm@vger.kernel.org Cc: linux-mips@linux-mips.org Cc: <stable@vger.kernel.org> # v3.17+ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/mips/kvm')
-rw-r--r--arch/mips/kvm/mips.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index 7082481cd108..9a28ea4f54f3 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -18,6 +18,7 @@
18#include <asm/page.h> 18#include <asm/page.h>
19#include <asm/cacheflush.h> 19#include <asm/cacheflush.h>
20#include <asm/mmu_context.h> 20#include <asm/mmu_context.h>
21#include <asm/pgtable.h>
21 22
22#include <linux/kvm_host.h> 23#include <linux/kvm_host.h>
23 24
@@ -385,8 +386,14 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
385 386
386 kvm_guest_enter(); 387 kvm_guest_enter();
387 388
389 /* Disable hardware page table walking while in guest */
390 htw_stop();
391
388 r = __kvm_mips_vcpu_run(run, vcpu); 392 r = __kvm_mips_vcpu_run(run, vcpu);
389 393
394 /* Re-enable HTW before enabling interrupts */
395 htw_start();
396
390 kvm_guest_exit(); 397 kvm_guest_exit();
391 local_irq_enable(); 398 local_irq_enable();
392 399
@@ -1001,6 +1008,9 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
1001 enum emulation_result er = EMULATE_DONE; 1008 enum emulation_result er = EMULATE_DONE;
1002 int ret = RESUME_GUEST; 1009 int ret = RESUME_GUEST;
1003 1010
1011 /* re-enable HTW before enabling interrupts */
1012 htw_start();
1013
1004 /* Set a default exit reason */ 1014 /* Set a default exit reason */
1005 run->exit_reason = KVM_EXIT_UNKNOWN; 1015 run->exit_reason = KVM_EXIT_UNKNOWN;
1006 run->ready_for_interrupt_injection = 1; 1016 run->ready_for_interrupt_injection = 1;
@@ -1135,6 +1145,9 @@ skip_emul:
1135 } 1145 }
1136 } 1146 }
1137 1147
1148 /* Disable HTW before returning to guest or host */
1149 htw_stop();
1150
1138 return ret; 1151 return ret;
1139} 1152}
1140 1153