Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 307902
b: refs/heads/master
c: f256905
h: refs/heads/master
v: v3
  • Loading branch information
Avi Kivity committed May 8, 2012
1 parent 8cc0023 commit 4b985bd
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 71 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 54771e6217ce05a474827d9b23ff03de9d2ef2a0
refs/heads/master: f2569053e0b3ae092e2f35514f8d108647baa01f
6 changes: 5 additions & 1 deletion trunk/Documentation/virtual/kvm/cpuid.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ a guest.
KVM cpuid functions are:

function: KVM_CPUID_SIGNATURE (0x40000000)
returns : eax = 0,
returns : eax = 0x40000001,
ebx = 0x4b4d564b,
ecx = 0x564b4d56,
edx = 0x4d.
Note that this value in ebx, ecx and edx corresponds to the string "KVMKVMKVM".
The value in eax corresponds to the maximum cpuid function present in this leaf,
and will be updated if more functions are added in the future.
Note also that old hosts set eax value to 0x0. This should
be interpreted as if the value was 0x40000001.
This function queries the presence of KVM cpuid leafs.


Expand Down
18 changes: 10 additions & 8 deletions trunk/arch/x86/include/asm/kvm_para.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,14 +178,16 @@ static inline int kvm_para_available(void)
unsigned int eax, ebx, ecx, edx;
char signature[13];

cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx);
memcpy(signature + 0, &ebx, 4);
memcpy(signature + 4, &ecx, 4);
memcpy(signature + 8, &edx, 4);
signature[12] = 0;

if (strcmp(signature, "KVMKVMKVM") == 0)
return 1;
if (cpu_has_hypervisor) {
cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx);
memcpy(signature + 0, &ebx, 4);
memcpy(signature + 4, &ecx, 4);
memcpy(signature + 8, &edx, 4);
signature[12] = 0;

if (strcmp(signature, "KVMKVMKVM") == 0)
return 1;
}

return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/x86/kvm/cpuid.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
case KVM_CPUID_SIGNATURE: {
char signature[12] = "KVMKVMKVM\0\0";
u32 *sigptr = (u32 *)signature;
entry->eax = 0;
entry->eax = KVM_CPUID_FEATURES;
entry->ebx = sigptr[0];
entry->ecx = sigptr[1];
entry->edx = sigptr[2];
Expand Down
119 changes: 59 additions & 60 deletions trunk/arch/x86/kvm/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -972,7 +972,6 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
ctxt->modrm_rm = base_reg = (ctxt->rex_prefix & 1) << 3; /* REG.B */
}

ctxt->modrm = insn_fetch(u8, ctxt);
ctxt->modrm_mod |= (ctxt->modrm & 0xc0) >> 6;
ctxt->modrm_reg |= (ctxt->modrm & 0x38) >> 3;
ctxt->modrm_rm |= (ctxt->modrm & 0x07);
Expand Down Expand Up @@ -3359,8 +3358,8 @@ static int check_perm_out(struct x86_emulate_ctxt *ctxt)
.check_perm = (_p) }
#define N D(0)
#define EXT(_f, _e) { .flags = ((_f) | RMExt), .u.group = (_e) }
#define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
#define GD(_f, _g) { .flags = ((_f) | GroupDual), .u.gdual = (_g) }
#define G(_f, _g) { .flags = ((_f) | Group | ModRM), .u.group = (_g) }
#define GD(_f, _g) { .flags = ((_f) | GroupDual | ModRM), .u.gdual = (_g) }
#define I(_f, _e) { .flags = (_f), .u.execute = (_e) }
#define II(_f, _e, _i) \
{ .flags = (_f), .u.execute = (_e), .intercept = x86_intercept_##_i }
Expand All @@ -3380,25 +3379,25 @@ static int check_perm_out(struct x86_emulate_ctxt *ctxt)
I2bv(((_f) & ~Lock) | DstAcc | SrcImm, _e)

static struct opcode group7_rm1[] = {
DI(SrcNone | ModRM | Priv, monitor),
DI(SrcNone | ModRM | Priv, mwait),
DI(SrcNone | Priv, monitor),
DI(SrcNone | Priv, mwait),
N, N, N, N, N, N,
};

static struct opcode group7_rm3[] = {
DIP(SrcNone | ModRM | Prot | Priv, vmrun, check_svme_pa),
II(SrcNone | ModRM | Prot | VendorSpecific, em_vmmcall, vmmcall),
DIP(SrcNone | ModRM | Prot | Priv, vmload, check_svme_pa),
DIP(SrcNone | ModRM | Prot | Priv, vmsave, check_svme_pa),
DIP(SrcNone | ModRM | Prot | Priv, stgi, check_svme),
DIP(SrcNone | ModRM | Prot | Priv, clgi, check_svme),
DIP(SrcNone | ModRM | Prot | Priv, skinit, check_svme),
DIP(SrcNone | ModRM | Prot | Priv, invlpga, check_svme),
DIP(SrcNone | Prot | Priv, vmrun, check_svme_pa),
II(SrcNone | Prot | VendorSpecific, em_vmmcall, vmmcall),
DIP(SrcNone | Prot | Priv, vmload, check_svme_pa),
DIP(SrcNone | Prot | Priv, vmsave, check_svme_pa),
DIP(SrcNone | Prot | Priv, stgi, check_svme),
DIP(SrcNone | Prot | Priv, clgi, check_svme),
DIP(SrcNone | Prot | Priv, skinit, check_svme),
DIP(SrcNone | Prot | Priv, invlpga, check_svme),
};

static struct opcode group7_rm7[] = {
N,
DIP(SrcNone | ModRM, rdtscp, check_rdtsc),
DIP(SrcNone, rdtscp, check_rdtsc),
N, N, N, N, N, N,
};

Expand All @@ -3414,76 +3413,77 @@ static struct opcode group1[] = {
};

static struct opcode group1A[] = {
I(DstMem | SrcNone | ModRM | Mov | Stack, em_pop), N, N, N, N, N, N, N,
I(DstMem | SrcNone | Mov | Stack, em_pop), N, N, N, N, N, N, N,
};

static struct opcode group3[] = {
I(DstMem | SrcImm | ModRM, em_test),
I(DstMem | SrcImm | ModRM, em_test),
I(DstMem | SrcNone | ModRM | Lock, em_not),
I(DstMem | SrcNone | ModRM | Lock, em_neg),
I(SrcMem | ModRM, em_mul_ex),
I(SrcMem | ModRM, em_imul_ex),
I(SrcMem | ModRM, em_div_ex),
I(SrcMem | ModRM, em_idiv_ex),
I(DstMem | SrcImm, em_test),
I(DstMem | SrcImm, em_test),
I(DstMem | SrcNone | Lock, em_not),
I(DstMem | SrcNone | Lock, em_neg),
I(SrcMem, em_mul_ex),
I(SrcMem, em_imul_ex),
I(SrcMem, em_div_ex),
I(SrcMem, em_idiv_ex),
};

static struct opcode group4[] = {
I(ByteOp | DstMem | SrcNone | ModRM | Lock, em_grp45),
I(ByteOp | DstMem | SrcNone | ModRM | Lock, em_grp45),
I(ByteOp | DstMem | SrcNone | Lock, em_grp45),
I(ByteOp | DstMem | SrcNone | Lock, em_grp45),
N, N, N, N, N, N,
};

static struct opcode group5[] = {
I(DstMem | SrcNone | ModRM | Lock, em_grp45),
I(DstMem | SrcNone | ModRM | Lock, em_grp45),
I(SrcMem | ModRM | Stack, em_grp45),
I(SrcMemFAddr | ModRM | ImplicitOps | Stack, em_call_far),
I(SrcMem | ModRM | Stack, em_grp45),
I(SrcMemFAddr | ModRM | ImplicitOps, em_grp45),
I(SrcMem | ModRM | Stack, em_grp45), N,
I(DstMem | SrcNone | Lock, em_grp45),
I(DstMem | SrcNone | Lock, em_grp45),
I(SrcMem | Stack, em_grp45),
I(SrcMemFAddr | ImplicitOps | Stack, em_call_far),
I(SrcMem | Stack, em_grp45),
I(SrcMemFAddr | ImplicitOps, em_grp45),
I(SrcMem | Stack, em_grp45), N,
};

static struct opcode group6[] = {
DI(ModRM | Prot, sldt),
DI(ModRM | Prot, str),
DI(ModRM | Prot | Priv, lldt),
DI(ModRM | Prot | Priv, ltr),
DI(Prot, sldt),
DI(Prot, str),
DI(Prot | Priv, lldt),
DI(Prot | Priv, ltr),
N, N, N, N,
};

static struct group_dual group7 = { {
DI(ModRM | Mov | DstMem | Priv, sgdt),
DI(ModRM | Mov | DstMem | Priv, sidt),
II(ModRM | SrcMem | Priv, em_lgdt, lgdt),
II(ModRM | SrcMem | Priv, em_lidt, lidt),
II(SrcNone | ModRM | DstMem | Mov, em_smsw, smsw), N,
II(SrcMem16 | ModRM | Mov | Priv, em_lmsw, lmsw),
II(SrcMem | ModRM | ByteOp | Priv | NoAccess, em_invlpg, invlpg),
DI(Mov | DstMem | Priv, sgdt),
DI(Mov | DstMem | Priv, sidt),
II(SrcMem | Priv, em_lgdt, lgdt),
II(SrcMem | Priv, em_lidt, lidt),
II(SrcNone | DstMem | Mov, em_smsw, smsw), N,
II(SrcMem16 | Mov | Priv, em_lmsw, lmsw),
II(SrcMem | ByteOp | Priv | NoAccess, em_invlpg, invlpg),
}, {
I(SrcNone | ModRM | Priv | VendorSpecific, em_vmcall),
I(SrcNone | Priv | VendorSpecific, em_vmcall),
EXT(0, group7_rm1),
N, EXT(0, group7_rm3),
II(SrcNone | ModRM | DstMem | Mov, em_smsw, smsw), N,
II(SrcMem16 | ModRM | Mov | Priv, em_lmsw, lmsw), EXT(0, group7_rm7),
II(SrcNone | DstMem | Mov, em_smsw, smsw), N,
II(SrcMem16 | Mov | Priv, em_lmsw, lmsw),
EXT(0, group7_rm7),
} };

static struct opcode group8[] = {
N, N, N, N,
I(DstMem | SrcImmByte | ModRM, em_bt),
I(DstMem | SrcImmByte | ModRM | Lock | PageTable, em_bts),
I(DstMem | SrcImmByte | ModRM | Lock, em_btr),
I(DstMem | SrcImmByte | ModRM | Lock | PageTable, em_btc),
I(DstMem | SrcImmByte, em_bt),
I(DstMem | SrcImmByte | Lock | PageTable, em_bts),
I(DstMem | SrcImmByte | Lock, em_btr),
I(DstMem | SrcImmByte | Lock | PageTable, em_btc),
};

static struct group_dual group9 = { {
N, I(DstMem64 | ModRM | Lock | PageTable, em_cmpxchg8b), N, N, N, N, N, N,
N, I(DstMem64 | Lock | PageTable, em_cmpxchg8b), N, N, N, N, N, N,
}, {
N, N, N, N, N, N, N, N,
} };

static struct opcode group11[] = {
I(DstMem | SrcImm | ModRM | Mov | PageTable, em_mov),
I(DstMem | SrcImm | Mov | PageTable, em_mov),
X7(D(Undefined)),
};

Expand Down Expand Up @@ -3541,10 +3541,10 @@ static struct opcode opcode_table[256] = {
/* 0x70 - 0x7F */
X16(D(SrcImmByte)),
/* 0x80 - 0x87 */
G(ByteOp | DstMem | SrcImm | ModRM | Group, group1),
G(DstMem | SrcImm | ModRM | Group, group1),
G(ByteOp | DstMem | SrcImm | ModRM | No64 | Group, group1),
G(DstMem | SrcImmByte | ModRM | Group, group1),
G(ByteOp | DstMem | SrcImm, group1),
G(DstMem | SrcImm, group1),
G(ByteOp | DstMem | SrcImm | No64, group1),
G(DstMem | SrcImmByte, group1),
I2bv(DstMem | SrcReg | ModRM, em_test),
I2bv(DstMem | SrcReg | ModRM | Lock | PageTable, em_xchg),
/* 0x88 - 0x8F */
Expand Down Expand Up @@ -3975,17 +3975,16 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
}
ctxt->d = opcode.flags;

if (ctxt->d & ModRM)
ctxt->modrm = insn_fetch(u8, ctxt);

while (ctxt->d & GroupMask) {
switch (ctxt->d & GroupMask) {
case Group:
ctxt->modrm = insn_fetch(u8, ctxt);
--ctxt->_eip;
goffset = (ctxt->modrm >> 3) & 7;
opcode = opcode.u.group[goffset];
break;
case GroupDual:
ctxt->modrm = insn_fetch(u8, ctxt);
--ctxt->_eip;
goffset = (ctxt->modrm >> 3) & 7;
if ((ctxt->modrm >> 6) == 3)
opcode = opcode.u.gdual->mod3[goffset];
Expand Down

0 comments on commit 4b985bd

Please sign in to comment.