diff options
author | Gleb Natapov <gleb@redhat.com> | 2013-04-11 04:59:55 -0400 |
---|---|---|
committer | Gleb Natapov <gleb@redhat.com> | 2013-04-14 02:44:16 -0400 |
commit | 0b789eee2c0204da83278f181428560faf6efefb (patch) | |
tree | 033042a99893a21f21425bc7c6af8f2686cf200c /arch/x86 | |
parent | f8da94e9e44b237fa5cc8521faeb714dc2e83b54 (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')
-rw-r--r-- | arch/x86/kvm/emulate.c | 7 |
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) |