Skip to content

Commit

Permalink
KVM: x86 emulator: vendor specific instructions
Browse files Browse the repository at this point in the history
Mark some instructions as vendor specific, and allow the caller to request
emulation only of vendor specific instructions.  This is useful in some
circumstances (responding to a #UD fault).

Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
  • Loading branch information
Avi Kivity authored and Marcelo Tosatti committed Mar 17, 2011
1 parent 3e90943 commit d867162
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 3 deletions.
1 change: 1 addition & 0 deletions arch/x86/include/asm/kvm_emulate.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ struct x86_emulate_ctxt {
int interruptibility;

bool perm_ok; /* do not check permissions if true */
bool only_vendor_specific_insn;

bool have_exception;
struct x86_exception exception;
Expand Down
12 changes: 9 additions & 3 deletions arch/x86/kvm/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
#define Group (1<<14) /* Bits 3:5 of modrm byte extend opcode */
#define GroupDual (1<<15) /* Alternate decoding of mod == 3 */
/* Misc flags */
#define VendorSpecific (1<<22) /* Vendor specific instruction */
#define NoAccess (1<<23) /* Don't access memory (lea/invlpg/verr etc) */
#define Op3264 (1<<24) /* Operand is 64b in long mode, 32b otherwise */
#define Undefined (1<<25) /* No Such Instruction */
Expand Down Expand Up @@ -2365,7 +2366,8 @@ static struct group_dual group7 = { {
D(SrcMem16 | ModRM | Mov | Priv),
D(SrcMem | ModRM | ByteOp | Priv | NoAccess),
}, {
D(SrcNone | ModRM | Priv), N, N, D(SrcNone | ModRM | Priv),
D(SrcNone | ModRM | Priv | VendorSpecific), N,
N, D(SrcNone | ModRM | Priv | VendorSpecific),
D(SrcNone | ModRM | DstMem | Mov), N,
D(SrcMem16 | ModRM | Mov | Priv), N,
} };
Expand Down Expand Up @@ -2489,7 +2491,7 @@ static struct opcode opcode_table[256] = {
static struct opcode twobyte_table[256] = {
/* 0x00 - 0x0F */
N, GD(0, &group7), N, N,
N, D(ImplicitOps), D(ImplicitOps | Priv), N,
N, D(ImplicitOps | VendorSpecific), D(ImplicitOps | Priv), N,
D(ImplicitOps | Priv), D(ImplicitOps | Priv), N, N,
N, D(ImplicitOps | ModRM), N, N,
/* 0x10 - 0x1F */
Expand All @@ -2502,7 +2504,8 @@ static struct opcode twobyte_table[256] = {
/* 0x30 - 0x3F */
D(ImplicitOps | Priv), I(ImplicitOps, em_rdtsc),
D(ImplicitOps | Priv), N,
D(ImplicitOps), D(ImplicitOps | Priv), N, N,
D(ImplicitOps | VendorSpecific), D(ImplicitOps | Priv | VendorSpecific),
N, N,
N, N, N, N, N, N, N, N,
/* 0x40 - 0x4F */
X16(D(DstReg | SrcMem | ModRM | Mov)),
Expand Down Expand Up @@ -2741,6 +2744,9 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
if (c->d == 0 || (c->d & Undefined))
return -1;

if (!(c->d & VendorSpecific) && ctxt->only_vendor_specific_insn)
return -1;

if (mode == X86EMUL_MODE_PROT64 && (c->d & Stack))
c->op_bytes = 8;

Expand Down

0 comments on commit d867162

Please sign in to comment.