diff options
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r-- | arch/x86/kvm/emulate.c | 82 |
1 files changed, 47 insertions, 35 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index d6e2477feb18..6df88c7885c0 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -47,38 +47,40 @@ | |||
47 | #define DstDI (5<<1) /* Destination is in ES:(E)DI */ | 47 | #define DstDI (5<<1) /* Destination is in ES:(E)DI */ |
48 | #define DstMem64 (6<<1) /* 64bit memory operand */ | 48 | #define DstMem64 (6<<1) /* 64bit memory operand */ |
49 | #define DstImmUByte (7<<1) /* 8-bit unsigned immediate operand */ | 49 | #define DstImmUByte (7<<1) /* 8-bit unsigned immediate operand */ |
50 | #define DstMask (7<<1) | 50 | #define DstDX (8<<1) /* Destination is in DX register */ |
51 | #define DstMask (0xf<<1) | ||
51 | /* Source operand type. */ | 52 | /* Source operand type. */ |
52 | #define SrcNone (0<<4) /* No source operand. */ | 53 | #define SrcNone (0<<5) /* No source operand. */ |
53 | #define SrcReg (1<<4) /* Register operand. */ | 54 | #define SrcReg (1<<5) /* Register operand. */ |
54 | #define SrcMem (2<<4) /* Memory operand. */ | 55 | #define SrcMem (2<<5) /* Memory operand. */ |
55 | #define SrcMem16 (3<<4) /* Memory operand (16-bit). */ | 56 | #define SrcMem16 (3<<5) /* Memory operand (16-bit). */ |
56 | #define SrcMem32 (4<<4) /* Memory operand (32-bit). */ | 57 | #define SrcMem32 (4<<5) /* Memory operand (32-bit). */ |
57 | #define SrcImm (5<<4) /* Immediate operand. */ | 58 | #define SrcImm (5<<5) /* Immediate operand. */ |
58 | #define SrcImmByte (6<<4) /* 8-bit sign-extended immediate operand. */ | 59 | #define SrcImmByte (6<<5) /* 8-bit sign-extended immediate operand. */ |
59 | #define SrcOne (7<<4) /* Implied '1' */ | 60 | #define SrcOne (7<<5) /* Implied '1' */ |
60 | #define SrcImmUByte (8<<4) /* 8-bit unsigned immediate operand. */ | 61 | #define SrcImmUByte (8<<5) /* 8-bit unsigned immediate operand. */ |
61 | #define SrcImmU (9<<4) /* Immediate operand, unsigned */ | 62 | #define SrcImmU (9<<5) /* Immediate operand, unsigned */ |
62 | #define SrcSI (0xa<<4) /* Source is in the DS:RSI */ | 63 | #define SrcSI (0xa<<5) /* Source is in the DS:RSI */ |
63 | #define SrcImmFAddr (0xb<<4) /* Source is immediate far address */ | 64 | #define SrcImmFAddr (0xb<<5) /* Source is immediate far address */ |
64 | #define SrcMemFAddr (0xc<<4) /* Source is far address in memory */ | 65 | #define SrcMemFAddr (0xc<<5) /* Source is far address in memory */ |
65 | #define SrcAcc (0xd<<4) /* Source Accumulator */ | 66 | #define SrcAcc (0xd<<5) /* Source Accumulator */ |
66 | #define SrcImmU16 (0xe<<4) /* Immediate operand, unsigned, 16 bits */ | 67 | #define SrcImmU16 (0xe<<5) /* Immediate operand, unsigned, 16 bits */ |
67 | #define SrcMask (0xf<<4) | 68 | #define SrcDX (0xf<<5) /* Source is in DX register */ |
69 | #define SrcMask (0xf<<5) | ||
68 | /* Generic ModRM decode. */ | 70 | /* Generic ModRM decode. */ |
69 | #define ModRM (1<<8) | 71 | #define ModRM (1<<9) |
70 | /* Destination is only written; never read. */ | 72 | /* Destination is only written; never read. */ |
71 | #define Mov (1<<9) | 73 | #define Mov (1<<10) |
72 | #define BitOp (1<<10) | 74 | #define BitOp (1<<11) |
73 | #define MemAbs (1<<11) /* Memory operand is absolute displacement */ | 75 | #define MemAbs (1<<12) /* Memory operand is absolute displacement */ |
74 | #define String (1<<12) /* String instruction (rep capable) */ | 76 | #define String (1<<13) /* String instruction (rep capable) */ |
75 | #define Stack (1<<13) /* Stack instruction (push/pop) */ | 77 | #define Stack (1<<14) /* Stack instruction (push/pop) */ |
76 | #define GroupMask (7<<14) /* Opcode uses one of the group mechanisms */ | 78 | #define GroupMask (7<<15) /* Opcode uses one of the group mechanisms */ |
77 | #define Group (1<<14) /* Bits 3:5 of modrm byte extend opcode */ | 79 | #define Group (1<<15) /* Bits 3:5 of modrm byte extend opcode */ |
78 | #define GroupDual (2<<14) /* Alternate decoding of mod == 3 */ | 80 | #define GroupDual (2<<15) /* Alternate decoding of mod == 3 */ |
79 | #define Prefix (3<<14) /* Instruction varies with 66/f2/f3 prefix */ | 81 | #define Prefix (3<<15) /* Instruction varies with 66/f2/f3 prefix */ |
80 | #define RMExt (4<<14) /* Opcode extension in ModRM r/m if mod == 3 */ | 82 | #define RMExt (4<<15) /* Opcode extension in ModRM r/m if mod == 3 */ |
81 | #define Sse (1<<17) /* SSE Vector instruction */ | 83 | #define Sse (1<<18) /* SSE Vector instruction */ |
82 | /* Misc flags */ | 84 | /* Misc flags */ |
83 | #define Prot (1<<21) /* instruction generates #UD if not in prot-mode */ | 85 | #define Prot (1<<21) /* instruction generates #UD if not in prot-mode */ |
84 | #define VendorSpecific (1<<22) /* Vendor specific instruction */ | 86 | #define VendorSpecific (1<<22) /* Vendor specific instruction */ |
@@ -3154,8 +3156,8 @@ static struct opcode opcode_table[256] = { | |||
3154 | I(DstReg | SrcMem | ModRM | Src2Imm, em_imul_3op), | 3156 | I(DstReg | SrcMem | ModRM | Src2Imm, em_imul_3op), |
3155 | I(SrcImmByte | Mov | Stack, em_push), | 3157 | I(SrcImmByte | Mov | Stack, em_push), |
3156 | I(DstReg | SrcMem | ModRM | Src2ImmByte, em_imul_3op), | 3158 | I(DstReg | SrcMem | ModRM | Src2ImmByte, em_imul_3op), |
3157 | D2bvIP(DstDI | Mov | String, ins, check_perm_in), /* insb, insw/insd */ | 3159 | D2bvIP(DstDI | SrcDX | Mov | String, ins, check_perm_in), /* insb, insw/insd */ |
3158 | D2bvIP(SrcSI | ImplicitOps | String, outs, check_perm_out), /* outsb, outsw/outsd */ | 3160 | D2bvIP(SrcSI | DstDX | String, outs, check_perm_out), /* outsb, outsw/outsd */ |
3159 | /* 0x70 - 0x7F */ | 3161 | /* 0x70 - 0x7F */ |
3160 | X16(D(SrcImmByte)), | 3162 | X16(D(SrcImmByte)), |
3161 | /* 0x80 - 0x87 */ | 3163 | /* 0x80 - 0x87 */ |
@@ -3212,8 +3214,8 @@ static struct opcode opcode_table[256] = { | |||
3212 | /* 0xE8 - 0xEF */ | 3214 | /* 0xE8 - 0xEF */ |
3213 | D(SrcImm | Stack), D(SrcImm | ImplicitOps), | 3215 | D(SrcImm | Stack), D(SrcImm | ImplicitOps), |
3214 | D(SrcImmFAddr | No64), D(SrcImmByte | ImplicitOps), | 3216 | D(SrcImmFAddr | No64), D(SrcImmByte | ImplicitOps), |
3215 | D2bvIP(SrcNone | DstAcc, in, check_perm_in), | 3217 | D2bvIP(SrcDX | DstAcc, in, check_perm_in), |
3216 | D2bvIP(SrcAcc | ImplicitOps, out, check_perm_out), | 3218 | D2bvIP(SrcAcc | DstDX, out, check_perm_out), |
3217 | /* 0xF0 - 0xF7 */ | 3219 | /* 0xF0 - 0xF7 */ |
3218 | N, DI(ImplicitOps, icebp), N, N, | 3220 | N, DI(ImplicitOps, icebp), N, N, |
3219 | DI(ImplicitOps | Priv, hlt), D(ImplicitOps), | 3221 | DI(ImplicitOps | Priv, hlt), D(ImplicitOps), |
@@ -3613,6 +3615,12 @@ done_prefixes: | |||
3613 | memop.bytes = c->op_bytes + 2; | 3615 | memop.bytes = c->op_bytes + 2; |
3614 | goto srcmem_common; | 3616 | goto srcmem_common; |
3615 | break; | 3617 | break; |
3618 | case SrcDX: | ||
3619 | c->src.type = OP_REG; | ||
3620 | c->src.bytes = 2; | ||
3621 | c->src.addr.reg = &c->regs[VCPU_REGS_RDX]; | ||
3622 | fetch_register_operand(&c->src); | ||
3623 | break; | ||
3616 | } | 3624 | } |
3617 | 3625 | ||
3618 | if (rc != X86EMUL_CONTINUE) | 3626 | if (rc != X86EMUL_CONTINUE) |
@@ -3682,6 +3690,12 @@ done_prefixes: | |||
3682 | c->dst.addr.mem.seg = VCPU_SREG_ES; | 3690 | c->dst.addr.mem.seg = VCPU_SREG_ES; |
3683 | c->dst.val = 0; | 3691 | c->dst.val = 0; |
3684 | break; | 3692 | break; |
3693 | case DstDX: | ||
3694 | c->dst.type = OP_REG; | ||
3695 | c->dst.bytes = 2; | ||
3696 | c->dst.addr.reg = &c->regs[VCPU_REGS_RDX]; | ||
3697 | fetch_register_operand(&c->dst); | ||
3698 | break; | ||
3685 | case ImplicitOps: | 3699 | case ImplicitOps: |
3686 | /* Special instructions do their own operand decoding. */ | 3700 | /* Special instructions do their own operand decoding. */ |
3687 | default: | 3701 | default: |
@@ -4027,7 +4041,6 @@ special_insn: | |||
4027 | break; | 4041 | break; |
4028 | case 0xec: /* in al,dx */ | 4042 | case 0xec: /* in al,dx */ |
4029 | case 0xed: /* in (e/r)ax,dx */ | 4043 | case 0xed: /* in (e/r)ax,dx */ |
4030 | c->src.val = c->regs[VCPU_REGS_RDX]; | ||
4031 | do_io_in: | 4044 | do_io_in: |
4032 | if (!pio_in_emulated(ctxt, ops, c->dst.bytes, c->src.val, | 4045 | if (!pio_in_emulated(ctxt, ops, c->dst.bytes, c->src.val, |
4033 | &c->dst.val)) | 4046 | &c->dst.val)) |
@@ -4035,7 +4048,6 @@ special_insn: | |||
4035 | break; | 4048 | break; |
4036 | case 0xee: /* out dx,al */ | 4049 | case 0xee: /* out dx,al */ |
4037 | case 0xef: /* out dx,(e/r)ax */ | 4050 | case 0xef: /* out dx,(e/r)ax */ |
4038 | c->dst.val = c->regs[VCPU_REGS_RDX]; | ||
4039 | do_io_out: | 4051 | do_io_out: |
4040 | ops->pio_out_emulated(ctxt, c->src.bytes, c->dst.val, | 4052 | ops->pio_out_emulated(ctxt, c->src.bytes, c->dst.val, |
4041 | &c->src.val, 1); | 4053 | &c->src.val, 1); |