diff options
author | Jun Nakajima <jun.nakajima@intel.com> | 2011-05-27 18:24:21 -0700 |
---|---|---|
committer | Jun Nakajima <jun.nakajima@intel.com> | 2011-05-27 18:24:21 -0700 |
commit | bb0140b925cb2adce03ebc0885067ea3bfd19a20 (patch) | |
tree | 1e5cb53ab8a3cf8da339498754e1a7eda80cb039 /target-i386/kvm.c | |
parent | bd03068d5d287ec638bc834d04f85b4e49404db5 (diff) | |
download | external_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.c | 21 |
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 |