]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
KVM: x86: emulate RDPID
authorPaolo Bonzini <pbonzini@redhat.com>
Tue, 12 Jul 2016 09:04:26 +0000 (11:04 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Thu, 14 Dec 2017 08:26:40 +0000 (09:26 +0100)
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>
arch/x86/kvm/cpuid.c
arch/x86/kvm/emulate.c
arch/x86/kvm/vmx.c

index 2b3b06458f6f67dd693cafc2c2dc202cfe94956a..b94371146533ff357c139687286465006d461189 100644 (file)
@@ -293,13 +293,18 @@ static int __do_cpuid_ent_emulated(struct kvm_cpuid_entry2 *entry,
 {
        switch (func) {
        case 0:
-               entry->eax = 1;         /* only one leaf currently */
+               entry->eax = 7;
                ++*nent;
                break;
        case 1:
                entry->ecx = F(MOVBE);
                ++*nent;
                break;
+       case 7:
+               entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
+               if (index == 0)
+                       entry->ecx = F(RDPID);
+               ++*nent;
        default:
                break;
        }
index fa703e3baa4bb8919d2dcd0beae355d3f1b1ceca..cb929d0bb1bd115270b3577c77de6cfccaf51274 100644 (file)
@@ -3514,6 +3514,16 @@ static int em_cwd(struct x86_emulate_ctxt *ctxt)
        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)
 {
        u64 tsc = 0;
@@ -4424,10 +4434,20 @@ static const struct opcode group8[] = {
        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 = { {
        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[] = {
index ebd50de981ee67105b937b2b7c1324d8d9579911..8dafc5d7d4d666bf821ade463a2a6136647204de 100644 (file)
@@ -11687,6 +11687,21 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu,
                               struct x86_instruction_info *info,
                               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;
 }