aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMohammed Gamal <m.gamal005@gmail.com>2008-09-06 10:22:29 -0400
committerAvi Kivity <avi@qumranet.com>2008-10-15 04:15:25 -0400
commita6a3034cb979b1fa3948d8e1e91b2387fc66b89b (patch)
tree4f7c5f7d86a8bc135dd852c7927de7417ccd1375 /arch
parentfa89a81766e33343fa8f0fe0e371819bf94a17a1 (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.c35
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;