summaryrefslogtreecommitdiff
path: root/kvm-tpr-opt.c
diff options
context:
space:
mode:
authorMarcelo Tosatti <mtosatti@redhat.com>2008-07-20 14:52:43 -0300
committerAvi Kivity <avi@qumranet.com>2008-07-21 16:23:51 +0300
commitc7dcb4d975bcf764b42c7cf48fa4037a0939b000 (patch)
tree29e24ece75c1c3fdc401f8bc141890c47c4d31db /kvm-tpr-opt.c
parent4012052f01aeb5b54a9a1e26602f0e418c07ad9f (diff)
Avoid tpr patching when rsp == 0
Early Windows 2003 SMP initialization contains a mov imm32, r/m32 instruction that is patched by tpr optimization. Problem is rsp, used by the patched instruction, is zero, so the guest gets a double fault and dies. Avoid any patching at all if rsp is zero. Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'kvm-tpr-opt.c')
-rw-r--r--kvm-tpr-opt.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/kvm-tpr-opt.c b/kvm-tpr-opt.c
index e960df090..8f6c4c8d6 100644
--- a/kvm-tpr-opt.c
+++ b/kvm-tpr-opt.c
@@ -83,6 +83,14 @@ static void write_byte_virt(CPUState *env, target_ulong virt, uint8_t b)
stb_phys(map_addr(&sregs, virt, NULL), b);
}
+static __u64 kvm_rsp_read(CPUState *env)
+{
+ struct kvm_regs regs;
+
+ kvm_get_regs(kvm_context, env->cpu_index, &regs);
+ return regs.rsp;
+}
+
struct vapic_bios {
char signature[8];
uint32_t virt_base;
@@ -135,6 +143,8 @@ static int instruction_is_ok(CPUState *env, uint64_t rip, int is_write)
if ((rip & 0xf0000000) != 0x80000000 && (rip & 0xf0000000) != 0xe0000000)
return 0;
+ if (kvm_rsp_read(env) == 0)
+ return 0;
b1 = read_byte_virt(env, rip);
b2 = read_byte_virt(env, rip + 1);
switch (b1) {