diff options
author | Marcelo Tosatti <mtosatti@redhat.com> | 2008-07-20 14:52:43 -0300 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-07-21 16:23:51 +0300 |
commit | c7dcb4d975bcf764b42c7cf48fa4037a0939b000 (patch) | |
tree | 29e24ece75c1c3fdc401f8bc141890c47c4d31db /kvm-tpr-opt.c | |
parent | 4012052f01aeb5b54a9a1e26602f0e418c07ad9f (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.c | 10 |
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, ®s); + 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) { |