diff options
author | Mohammed Gamal <m.gamal005@gmail.com> | 2008-09-06 10:22:29 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-10-15 04:15:25 -0400 |
commit | a6a3034cb979b1fa3948d8e1e91b2387fc66b89b (patch) | |
tree | 4f7c5f7d86a8bc135dd852c7927de7417ccd1375 /arch | |
parent | fa89a81766e33343fa8f0fe0e371819bf94a17a1 (diff) |
KVM: x86 emulator: Add in/out instructions (opcodes 0xe4-0xe7, 0xec-0xef)
The patch adds in/out instructions to the x86 emulator.
The instruction was encountered while running the BIOS while using
the invalid guest state emulation patch.
Signed-off-by: Mohammed Gamal <m.gamal005@gmail.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kvm/x86_emulate.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 944f1f4d4be4..3ac2f1485223 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c | |||
@@ -177,11 +177,14 @@ static u16 opcode_table[256] = { | |||
177 | /* 0xD8 - 0xDF */ | 177 | /* 0xD8 - 0xDF */ |
178 | 0, 0, 0, 0, 0, 0, 0, 0, | 178 | 0, 0, 0, 0, 0, 0, 0, 0, |
179 | /* 0xE0 - 0xE7 */ | 179 | /* 0xE0 - 0xE7 */ |
180 | 0, 0, 0, 0, 0, 0, 0, 0, | 180 | 0, 0, 0, 0, |
181 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, | ||
182 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, | ||
181 | /* 0xE8 - 0xEF */ | 183 | /* 0xE8 - 0xEF */ |
182 | ImplicitOps | Stack, SrcImm | ImplicitOps, | 184 | ImplicitOps | Stack, SrcImm | ImplicitOps, |
183 | ImplicitOps, SrcImmByte | ImplicitOps, | 185 | ImplicitOps, SrcImmByte | ImplicitOps, |
184 | 0, 0, 0, 0, | 186 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, |
187 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, | ||
185 | /* 0xF0 - 0xF7 */ | 188 | /* 0xF0 - 0xF7 */ |
186 | 0, 0, 0, 0, | 189 | 0, 0, 0, 0, |
187 | ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3, | 190 | ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3, |
@@ -1259,6 +1262,8 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1259 | u64 msr_data; | 1262 | u64 msr_data; |
1260 | unsigned long saved_eip = 0; | 1263 | unsigned long saved_eip = 0; |
1261 | struct decode_cache *c = &ctxt->decode; | 1264 | struct decode_cache *c = &ctxt->decode; |
1265 | unsigned int port; | ||
1266 | int io_dir_in; | ||
1262 | int rc = 0; | 1267 | int rc = 0; |
1263 | 1268 | ||
1264 | /* Shadow copy of register state. Committed on successful emulation. | 1269 | /* Shadow copy of register state. Committed on successful emulation. |
@@ -1687,6 +1692,16 @@ special_insn: | |||
1687 | c->src.val = c->regs[VCPU_REGS_RCX]; | 1692 | c->src.val = c->regs[VCPU_REGS_RCX]; |
1688 | emulate_grp2(ctxt); | 1693 | emulate_grp2(ctxt); |
1689 | break; | 1694 | break; |
1695 | case 0xe4: /* inb */ | ||
1696 | case 0xe5: /* in */ | ||
1697 | port = insn_fetch(u8, 1, c->eip); | ||
1698 | io_dir_in = 1; | ||
1699 | goto do_io; | ||
1700 | case 0xe6: /* outb */ | ||
1701 | case 0xe7: /* out */ | ||
1702 | port = insn_fetch(u8, 1, c->eip); | ||
1703 | io_dir_in = 0; | ||
1704 | goto do_io; | ||
1690 | case 0xe8: /* call (near) */ { | 1705 | case 0xe8: /* call (near) */ { |
1691 | long int rel; | 1706 | long int rel; |
1692 | switch (c->op_bytes) { | 1707 | switch (c->op_bytes) { |
@@ -1737,6 +1752,22 @@ special_insn: | |||
1737 | jmp_rel(c, c->src.val); | 1752 | jmp_rel(c, c->src.val); |
1738 | c->dst.type = OP_NONE; /* Disable writeback. */ | 1753 | c->dst.type = OP_NONE; /* Disable writeback. */ |
1739 | break; | 1754 | break; |
1755 | case 0xec: /* in al,dx */ | ||
1756 | case 0xed: /* in (e/r)ax,dx */ | ||
1757 | port = c->regs[VCPU_REGS_RDX]; | ||
1758 | io_dir_in = 1; | ||
1759 | goto do_io; | ||
1760 | case 0xee: /* out al,dx */ | ||
1761 | case 0xef: /* out (e/r)ax,dx */ | ||
1762 | port = c->regs[VCPU_REGS_RDX]; | ||
1763 | io_dir_in = 0; | ||
1764 | do_io: if (kvm_emulate_pio(ctxt->vcpu, NULL, io_dir_in, | ||
1765 | (c->d & ByteOp) ? 1 : c->op_bytes, | ||
1766 | port) != 0) { | ||
1767 | c->eip = saved_eip; | ||
1768 | goto cannot_emulate; | ||
1769 | } | ||
1770 | return 0; | ||
1740 | case 0xf4: /* hlt */ | 1771 | case 0xf4: /* hlt */ |
1741 | ctxt->vcpu->arch.halt_request = 1; | 1772 | ctxt->vcpu->arch.halt_request = 1; |
1742 | break; | 1773 | break; |