aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/emulate.c
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2013-04-11 04:59:55 -0400
committerGleb Natapov <gleb@redhat.com>2013-04-14 02:44:16 -0400
commit0b789eee2c0204da83278f181428560faf6efefb (patch)
tree033042a99893a21f21425bc7c6af8f2686cf200c /arch/x86/kvm/emulate.c
parentf8da94e9e44b237fa5cc8521faeb714dc2e83b54 (diff)
KVM: emulator: fix unimplemented instruction detection
Unimplemented instruction detection is broken for group instructions since it relies on "flags" field of opcode to be zero, but all instructions in a group inherit flags from a group encoding. Fix that by having a separate flag for unimplemented instructions. Signed-off-by: Gleb Natapov <gleb@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r--arch/x86/kvm/emulate.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 069d79926e2b..ab6fda4eb98f 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -132,8 +132,9 @@
132#define Priv (1<<27) /* instruction generates #GP if current CPL != 0 */ 132#define Priv (1<<27) /* instruction generates #GP if current CPL != 0 */
133#define No64 (1<<28) 133#define No64 (1<<28)
134#define PageTable (1 << 29) /* instruction used to write page table */ 134#define PageTable (1 << 29) /* instruction used to write page table */
135#define NotImpl (1 << 30) /* instruction is not implemented */
135/* Source 2 operand type */ 136/* Source 2 operand type */
136#define Src2Shift (30) 137#define Src2Shift (31)
137#define Src2None (OpNone << Src2Shift) 138#define Src2None (OpNone << Src2Shift)
138#define Src2CL (OpCL << Src2Shift) 139#define Src2CL (OpCL << Src2Shift)
139#define Src2ImmByte (OpImmByte << Src2Shift) 140#define Src2ImmByte (OpImmByte << Src2Shift)
@@ -3624,7 +3625,7 @@ static int check_perm_out(struct x86_emulate_ctxt *ctxt)
3624#define DI(_y, _i) { .flags = (_y), .intercept = x86_intercept_##_i } 3625#define DI(_y, _i) { .flags = (_y), .intercept = x86_intercept_##_i }
3625#define DIP(_y, _i, _p) { .flags = (_y), .intercept = x86_intercept_##_i, \ 3626#define DIP(_y, _i, _p) { .flags = (_y), .intercept = x86_intercept_##_i, \
3626 .check_perm = (_p) } 3627 .check_perm = (_p) }
3627#define N D(0) 3628#define N D(NotImpl)
3628#define EXT(_f, _e) { .flags = ((_f) | RMExt), .u.group = (_e) } 3629#define EXT(_f, _e) { .flags = ((_f) | RMExt), .u.group = (_e) }
3629#define G(_f, _g) { .flags = ((_f) | Group | ModRM), .u.group = (_g) } 3630#define G(_f, _g) { .flags = ((_f) | Group | ModRM), .u.group = (_g) }
3630#define GD(_f, _g) { .flags = ((_f) | GroupDual | ModRM), .u.gdual = (_g) } 3631#define GD(_f, _g) { .flags = ((_f) | GroupDual | ModRM), .u.gdual = (_g) }
@@ -4382,7 +4383,7 @@ done_prefixes:
4382 ctxt->intercept = opcode.intercept; 4383 ctxt->intercept = opcode.intercept;
4383 4384
4384 /* Unrecognised? */ 4385 /* Unrecognised? */
4385 if (ctxt->d == 0 || (ctxt->d & Undefined)) 4386 if (ctxt->d == 0 || (ctxt->d & NotImpl) || (ctxt->d & Undefined))
4386 return EMULATION_FAILED; 4387 return EMULATION_FAILED;
4387 4388
4388 if (!(ctxt->d & VendorSpecific) && ctxt->only_vendor_specific_insn) 4389 if (!(ctxt->d & VendorSpecific) && ctxt->only_vendor_specific_insn)