mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-05-07 15:53:49 +00:00
KVM: x86: emulate RDPID
This is encoded as F3 0F C7 /7 with a register argument. The register argument is the second array in the group9 GroupDual, while F3 is the fourth element of a Prefix. Reviewed-by: Wanpeng Li <wanpeng.li@hotmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
0367f205a3
commit
fb6d4d340e
3 changed files with 42 additions and 2 deletions
|
@ -293,13 +293,18 @@ static int __do_cpuid_ent_emulated(struct kvm_cpuid_entry2 *entry,
|
||||||
{
|
{
|
||||||
switch (func) {
|
switch (func) {
|
||||||
case 0:
|
case 0:
|
||||||
entry->eax = 1; /* only one leaf currently */
|
entry->eax = 7;
|
||||||
++*nent;
|
++*nent;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
entry->ecx = F(MOVBE);
|
entry->ecx = F(MOVBE);
|
||||||
++*nent;
|
++*nent;
|
||||||
break;
|
break;
|
||||||
|
case 7:
|
||||||
|
entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
|
||||||
|
if (index == 0)
|
||||||
|
entry->ecx = F(RDPID);
|
||||||
|
++*nent;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3514,6 +3514,16 @@ static int em_cwd(struct x86_emulate_ctxt *ctxt)
|
||||||
return X86EMUL_CONTINUE;
|
return X86EMUL_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int em_rdpid(struct x86_emulate_ctxt *ctxt)
|
||||||
|
{
|
||||||
|
u64 tsc_aux = 0;
|
||||||
|
|
||||||
|
if (ctxt->ops->get_msr(ctxt, MSR_TSC_AUX, &tsc_aux))
|
||||||
|
return emulate_gp(ctxt, 0);
|
||||||
|
ctxt->dst.val = tsc_aux;
|
||||||
|
return X86EMUL_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
static int em_rdtsc(struct x86_emulate_ctxt *ctxt)
|
static int em_rdtsc(struct x86_emulate_ctxt *ctxt)
|
||||||
{
|
{
|
||||||
u64 tsc = 0;
|
u64 tsc = 0;
|
||||||
|
@ -4424,10 +4434,20 @@ static const struct opcode group8[] = {
|
||||||
F(DstMem | SrcImmByte | Lock | PageTable, em_btc),
|
F(DstMem | SrcImmByte | Lock | PageTable, em_btc),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The "memory" destination is actually always a register, since we come
|
||||||
|
* from the register case of group9.
|
||||||
|
*/
|
||||||
|
static const struct gprefix pfx_0f_c7_7 = {
|
||||||
|
N, N, N, II(DstMem | ModRM | Op3264 | EmulateOnUD, em_rdpid, rdtscp),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static const struct group_dual group9 = { {
|
static const struct group_dual group9 = { {
|
||||||
N, I(DstMem64 | 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,
|
N, N, N, N, N, N, N,
|
||||||
|
GP(0, &pfx_0f_c7_7),
|
||||||
} };
|
} };
|
||||||
|
|
||||||
static const struct opcode group11[] = {
|
static const struct opcode group11[] = {
|
||||||
|
|
|
@ -11687,6 +11687,21 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu,
|
||||||
struct x86_instruction_info *info,
|
struct x86_instruction_info *info,
|
||||||
enum x86_intercept_stage stage)
|
enum x86_intercept_stage stage)
|
||||||
{
|
{
|
||||||
|
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
|
||||||
|
struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RDPID causes #UD if disabled through secondary execution controls.
|
||||||
|
* Because it is marked as EmulateOnUD, we need to intercept it here.
|
||||||
|
*/
|
||||||
|
if (info->intercept == x86_intercept_rdtscp &&
|
||||||
|
!nested_cpu_has2(vmcs12, SECONDARY_EXEC_RDTSCP)) {
|
||||||
|
ctxt->exception.vector = UD_VECTOR;
|
||||||
|
ctxt->exception.error_code_valid = false;
|
||||||
|
return X86EMUL_PROPAGATE_FAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: check more intercepts... */
|
||||||
return X86EMUL_CONTINUE;
|
return X86EMUL_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue