aboutsummaryrefslogtreecommitdiffstats
path: root/target-i386/kvm.c
diff options
context:
space:
mode:
authorJun Nakajima <jun.nakajima@intel.com>2011-05-27 18:24:21 -0700
committerJun Nakajima <jun.nakajima@intel.com>2011-05-27 18:24:21 -0700
commitbb0140b925cb2adce03ebc0885067ea3bfd19a20 (patch)
tree1e5cb53ab8a3cf8da339498754e1a7eda80cb039 /target-i386/kvm.c
parentbd03068d5d287ec638bc834d04f85b4e49404db5 (diff)
downloadexternal_qemu-bb0140b925cb2adce03ebc0885067ea3bfd19a20.zip
external_qemu-bb0140b925cb2adce03ebc0885067ea3bfd19a20.tar.gz
external_qemu-bb0140b925cb2adce03ebc0885067ea3bfd19a20.tar.bz2
x86: Workaorund for the KVM GS_BASE MSR save/restore issue.
In some versions of the kvm module in Ubuntu, the host's GS_BASE MSR is not save/restored correctly when running guests on 64-bit hosts if the qemu/emulator is 32-bit. This patch implements a workaround in the emulator code. Change-Id: If3ebe3cb49f377c5d0547c75f6ac3a3ceacdc375 Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com> Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
Diffstat (limited to 'target-i386/kvm.c')
-rw-r--r--target-i386/kvm.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 4b135b1..07efac0 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -26,6 +26,10 @@
#include "cpu.h"
#include "gdbstub.h"
+#ifdef CONFIG_KVM_GS_RESTORE
+#include "kvm-gs-restore.h"
+#endif
+
//#define DEBUG_KVM
#ifdef DEBUG_KVM
@@ -690,6 +694,16 @@ int kvm_arch_get_registers(CPUState *env)
return 0;
}
+int kvm_arch_vcpu_run(CPUState *env)
+{
+#ifdef CONFIG_KVM_GS_RESTORE
+ if (gs_need_restore != KVM_GS_RESTORE_NO)
+ return no_gs_ioctl(env->kvm_fd, KVM_RUN, 0);
+ else
+#endif
+ return kvm_vcpu_ioctl(env, KVM_RUN, 0);
+}
+
int kvm_arch_pre_run(CPUState *env, struct kvm_run *run)
{
/* Try to inject an interrupt if the guest can accept it */
@@ -721,11 +735,18 @@ int kvm_arch_pre_run(CPUState *env, struct kvm_run *run)
dprintf("setting tpr\n");
run->cr8 = cpu_get_apic_tpr(env);
+#ifdef CONFIG_KVM_GS_RESTORE
+ gs_base_pre_run();
+#endif
+
return 0;
}
int kvm_arch_post_run(CPUState *env, struct kvm_run *run)
{
+#ifdef CONFIG_KVM_GS_RESTORE
+ gs_base_post_run();
+#endif
if (run->if_flag)
env->eflags |= IF_MASK;
else