aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/emulate.c
diff options
context:
space:
mode:
authorNadav Amit <namit@cs.technion.ac.il>2014-10-24 04:35:09 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-11-03 06:07:20 -0500
commit58b7075d059f7d37ca86c76fb1446fa3447b9f4f (patch)
tree57b978e405103e5bfd274655aaf569b782b6156a /arch/x86/kvm/emulate.c
parentf7784046ab7cfc1645f4110b6ed14fbdffc2abee (diff)
KVM: x86: Distinguish between stack operation and near branches
In 64-bit, stack operations default to 64-bits, but can be overriden (to 16-bit) using opsize override prefix. In contrast, near-branches are always 64-bit. This patch distinguish between the different behaviors. Signed-off-by: Nadav Amit <namit@cs.technion.ac.il> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r--arch/x86/kvm/emulate.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 147f3fdfb5ce..a90fa188aeea 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -166,6 +166,7 @@
166#define CheckPerm ((u64)1 << 49) /* Has valid check_perm field */ 166#define CheckPerm ((u64)1 << 49) /* Has valid check_perm field */
167#define NoBigReal ((u64)1 << 50) /* No big real mode */ 167#define NoBigReal ((u64)1 << 50) /* No big real mode */
168#define PrivUD ((u64)1 << 51) /* #UD instead of #GP on CPL > 0 */ 168#define PrivUD ((u64)1 << 51) /* #UD instead of #GP on CPL > 0 */
169#define NearBranch ((u64)1 << 52) /* Near branches */
169 170
170#define DstXacc (DstAccLo | SrcAccHi | SrcWrite) 171#define DstXacc (DstAccLo | SrcAccHi | SrcWrite)
171 172
@@ -3771,9 +3772,9 @@ static const struct opcode group4[] = {
3771static const struct opcode group5[] = { 3772static const struct opcode group5[] = {
3772 F(DstMem | SrcNone | Lock, em_inc), 3773 F(DstMem | SrcNone | Lock, em_inc),
3773 F(DstMem | SrcNone | Lock, em_dec), 3774 F(DstMem | SrcNone | Lock, em_dec),
3774 I(SrcMem | Stack, em_call_near_abs), 3775 I(SrcMem | NearBranch, em_call_near_abs),
3775 I(SrcMemFAddr | ImplicitOps | Stack, em_call_far), 3776 I(SrcMemFAddr | ImplicitOps | Stack, em_call_far),
3776 I(SrcMem | Stack, em_jmp_abs), 3777 I(SrcMem | NearBranch, em_jmp_abs),
3777 I(SrcMemFAddr | ImplicitOps, em_jmp_far), 3778 I(SrcMemFAddr | ImplicitOps, em_jmp_far),
3778 I(SrcMem | Stack, em_push), D(Undefined), 3779 I(SrcMem | Stack, em_push), D(Undefined),
3779}; 3780};
@@ -3955,7 +3956,7 @@ static const struct opcode opcode_table[256] = {
3955 I2bvIP(DstDI | SrcDX | Mov | String | Unaligned, em_in, ins, check_perm_in), /* insb, insw/insd */ 3956 I2bvIP(DstDI | SrcDX | Mov | String | Unaligned, em_in, ins, check_perm_in), /* insb, insw/insd */
3956 I2bvIP(SrcSI | DstDX | String, em_out, outs, check_perm_out), /* outsb, outsw/outsd */ 3957 I2bvIP(SrcSI | DstDX | String, em_out, outs, check_perm_out), /* outsb, outsw/outsd */
3957 /* 0x70 - 0x7F */ 3958 /* 0x70 - 0x7F */
3958 X16(D(SrcImmByte)), 3959 X16(D(SrcImmByte | NearBranch)),
3959 /* 0x80 - 0x87 */ 3960 /* 0x80 - 0x87 */
3960 G(ByteOp | DstMem | SrcImm, group1), 3961 G(ByteOp | DstMem | SrcImm, group1),
3961 G(DstMem | SrcImm, group1), 3962 G(DstMem | SrcImm, group1),
@@ -3994,8 +3995,8 @@ static const struct opcode opcode_table[256] = {
3994 X8(I(DstReg | SrcImm64 | Mov, em_mov)), 3995 X8(I(DstReg | SrcImm64 | Mov, em_mov)),
3995 /* 0xC0 - 0xC7 */ 3996 /* 0xC0 - 0xC7 */
3996 G(ByteOp | Src2ImmByte, group2), G(Src2ImmByte, group2), 3997 G(ByteOp | Src2ImmByte, group2), G(Src2ImmByte, group2),
3997 I(ImplicitOps | Stack | SrcImmU16, em_ret_near_imm), 3998 I(ImplicitOps | NearBranch | SrcImmU16, em_ret_near_imm),
3998 I(ImplicitOps | Stack, em_ret), 3999 I(ImplicitOps | NearBranch, em_ret),
3999 I(DstReg | SrcMemFAddr | ModRM | No64 | Src2ES, em_lseg), 4000 I(DstReg | SrcMemFAddr | ModRM | No64 | Src2ES, em_lseg),
4000 I(DstReg | SrcMemFAddr | ModRM | No64 | Src2DS, em_lseg), 4001 I(DstReg | SrcMemFAddr | ModRM | No64 | Src2DS, em_lseg),
4001 G(ByteOp, group11), G(0, group11), 4002 G(ByteOp, group11), G(0, group11),
@@ -4015,13 +4016,14 @@ static const struct opcode opcode_table[256] = {
4015 /* 0xD8 - 0xDF */ 4016 /* 0xD8 - 0xDF */
4016 N, E(0, &escape_d9), N, E(0, &escape_db), N, E(0, &escape_dd), N, N, 4017 N, E(0, &escape_d9), N, E(0, &escape_db), N, E(0, &escape_dd), N, N,
4017 /* 0xE0 - 0xE7 */ 4018 /* 0xE0 - 0xE7 */
4018 X3(I(SrcImmByte, em_loop)), 4019 X3(I(SrcImmByte | NearBranch, em_loop)),
4019 I(SrcImmByte, em_jcxz), 4020 I(SrcImmByte | NearBranch, em_jcxz),
4020 I2bvIP(SrcImmUByte | DstAcc, em_in, in, check_perm_in), 4021 I2bvIP(SrcImmUByte | DstAcc, em_in, in, check_perm_in),
4021 I2bvIP(SrcAcc | DstImmUByte, em_out, out, check_perm_out), 4022 I2bvIP(SrcAcc | DstImmUByte, em_out, out, check_perm_out),
4022 /* 0xE8 - 0xEF */ 4023 /* 0xE8 - 0xEF */
4023 I(SrcImm | Stack, em_call), D(SrcImm | ImplicitOps), 4024 I(SrcImm | NearBranch, em_call), D(SrcImm | ImplicitOps | NearBranch),
4024 I(SrcImmFAddr | No64, em_jmp_far), D(SrcImmByte | ImplicitOps), 4025 I(SrcImmFAddr | No64, em_jmp_far),
4026 D(SrcImmByte | ImplicitOps | NearBranch),
4025 I2bvIP(SrcDX | DstAcc, em_in, in, check_perm_in), 4027 I2bvIP(SrcDX | DstAcc, em_in, in, check_perm_in),
4026 I2bvIP(SrcAcc | DstDX, em_out, out, check_perm_out), 4028 I2bvIP(SrcAcc | DstDX, em_out, out, check_perm_out),
4027 /* 0xF0 - 0xF7 */ 4029 /* 0xF0 - 0xF7 */
@@ -4081,7 +4083,7 @@ static const struct opcode twobyte_table[256] = {
4081 N, N, N, N, 4083 N, N, N, N,
4082 N, N, N, GP(SrcReg | DstMem | ModRM | Mov, &pfx_0f_6f_0f_7f), 4084 N, N, N, GP(SrcReg | DstMem | ModRM | Mov, &pfx_0f_6f_0f_7f),
4083 /* 0x80 - 0x8F */ 4085 /* 0x80 - 0x8F */
4084 X16(D(SrcImm)), 4086 X16(D(SrcImm | NearBranch)),
4085 /* 0x90 - 0x9F */ 4087 /* 0x90 - 0x9F */
4086 X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)), 4088 X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)),
4087 /* 0xA0 - 0xA7 */ 4089 /* 0xA0 - 0xA7 */
@@ -4550,7 +4552,7 @@ done_prefixes:
4550 return EMULATION_FAILED; 4552 return EMULATION_FAILED;
4551 4553
4552 if (unlikely(ctxt->d & 4554 if (unlikely(ctxt->d &
4553 (NotImpl|Stack|Op3264|Sse|Mmx|Intercept|CheckPerm))) { 4555 (NotImpl|Stack|Op3264|Sse|Mmx|Intercept|CheckPerm|NearBranch))) {
4554 /* 4556 /*
4555 * These are copied unconditionally here, and checked unconditionally 4557 * These are copied unconditionally here, and checked unconditionally
4556 * in x86_emulate_insn. 4558 * in x86_emulate_insn.
@@ -4561,8 +4563,12 @@ done_prefixes:
4561 if (ctxt->d & NotImpl) 4563 if (ctxt->d & NotImpl)
4562 return EMULATION_FAILED; 4564 return EMULATION_FAILED;
4563 4565
4564 if (mode == X86EMUL_MODE_PROT64 && (ctxt->d & Stack)) 4566 if (mode == X86EMUL_MODE_PROT64) {
4565 ctxt->op_bytes = 8; 4567 if (ctxt->op_bytes == 4 && (ctxt->d & Stack))
4568 ctxt->op_bytes = 8;
4569 else if (ctxt->d & NearBranch)
4570 ctxt->op_bytes = 8;
4571 }
4566 4572
4567 if (ctxt->d & Op3264) { 4573 if (ctxt->d & Op3264) {
4568 if (mode == X86EMUL_MODE_PROT64) 4574 if (mode == X86EMUL_MODE_PROT64)