aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2008-07-16 12:27:23 +0300
committerAvi Kivity <avi@qumranet.com>2008-07-16 12:27:23 +0300
commit617f95c72437a8a928de2a672d4c839274e173b1 (patch)
tree9f2435ff2d5b82e981c5021654f5b768a4630fab /kvm-tpr-opt.c
parentRegenerate bios for 'push tpr' instruction (diff)
downloadqemu-kvm-617f95c72437a8a928de2a672d4c839274e173b1.tar.gz
qemu-kvm-617f95c72437a8a928de2a672d4c839274e173b1.tar.bz2
qemu-kvm-617f95c72437a8a928de2a672d4c839274e173b1.zip
Patch 'push tpr' instruction
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 ab8a0e4b4..e960df090 100644
--- a/kvm-tpr-opt.c
+++ b/kvm-tpr-opt.c
@@ -96,6 +96,7 @@ struct vapic_bios {
uint32_t set_tpr;
uint32_t set_tpr_eax;
uint32_t get_tpr[8];
+ uint32_t get_tpr_stack;
} __attribute__((packed)) up, mp;
} __attribute__((packed));
@@ -151,6 +152,10 @@ static int instruction_is_ok(CPUState *env, uint64_t rip, int is_write)
case 0xa3: /* mov eax to abs */
addr_offset = 1;
break;
+ case 0xff: /* push r/m32 */
+ if (modrm_reg(b2) != 6 || !is_abs_modrm(b2))
+ return 0;
+ addr_offset = 2;
default:
return 0;
}
@@ -266,6 +271,11 @@ static void patch_instruction(CPUState *env, uint64_t rip)
write_byte_virt(env, rip + 4, read_byte_virt(env, rip+9));
patch_call(env, rip + 5, vp->set_tpr);
break;
+ case 0xff: /* push r/m32 */
+ printf("patching push\n");
+ write_byte_virt(env, rip, 0x50); /* push eax */
+ patch_call(env, rip + 1, vp->get_tpr_stack);
+ break;
default:
printf("funny insn %02x %02x\n", b1, b2);
}