]> xenbits.xensource.com Git - people/iwj/xen.git/commitdiff
SVM: correct CPUID event processing
authorJan Beulich <jbeulich@suse.com>
Wed, 25 Sep 2019 13:51:52 +0000 (15:51 +0200)
committerJan Beulich <jbeulich@suse.com>
Wed, 25 Sep 2019 13:51:52 +0000 (15:51 +0200)
hvm_monitor_cpuid() expects the input registers, not two of the outputs
(it was this way right from its introduction by commit d05f1eb374
["hvm/svm: implement CPUID events"]).

However, once having made the necessary adjustment, the SVM and VMX
functions are so similar that they should be folded (thus avoiding
further similar asymmetries to get introduced). Use the best of both
worlds by e.g. using "curr" consistently. This then being the only
caller of hvm_check_cpuid_faulting(), fold in that function as well.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Acked-by: Razvan Cojocaru <rcojocaru@bitdefender.com>
Reviewed-by: Alexandru Isaila <aisaila@bitdefender.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Release-acked-by: Juergen Gross <jgross@suse.com>
xen/arch/x86/hvm/hvm.c
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/vmx/vmx.c
xen/include/asm-x86/hvm/hvm.h

index c82e7b2cd39b6ba3cbbd12ee516921ab01f33fec..c22cb39cf392ebf8e69d1e6af9737d3bb52d3f1d 100644 (file)
@@ -3358,14 +3358,28 @@ unsigned long copy_from_user_hvm(void *to, const void *from, unsigned len)
     return rc ? len : 0; /* fake a copy_from_user() return code */
 }
 
-bool hvm_check_cpuid_faulting(struct vcpu *v)
+int hvm_vmexit_cpuid(struct cpu_user_regs *regs, unsigned int inst_len)
 {
-    const struct vcpu_msrs *msrs = v->arch.msrs;
+    struct vcpu *curr = current;
+    unsigned int leaf = regs->eax, subleaf = regs->ecx;
+    struct cpuid_leaf res;
 
-    if ( !msrs->misc_features_enables.cpuid_faulting )
-        return false;
+    if ( curr->arch.msrs->misc_features_enables.cpuid_faulting &&
+         hvm_get_cpl(curr) > 0 )
+    {
+        hvm_inject_hw_exception(TRAP_gp_fault, 0);
+        return 1; /* Don't advance the guest IP! */
+    }
+
+    guest_cpuid(curr, leaf, subleaf, &res);
+    HVMTRACE_6D(CPUID, leaf, subleaf, res.a, res.b, res.c, res.d);
+
+    regs->rax = res.a;
+    regs->rbx = res.b;
+    regs->rcx = res.c;
+    regs->rdx = res.d;
 
-    return hvm_get_cpl(v) > 0;
+    return hvm_monitor_cpuid(inst_len, leaf, subleaf);
 }
 
 static uint64_t _hvm_rdtsc_intercept(void)
index cf83ce9a1976cfe1be44c69d39ba5c2bc097d6e4..4eb6b0e4c747536480053b053726b2e25caabeb3 100644 (file)
@@ -1784,28 +1784,6 @@ static void svm_fpu_dirty_intercept(void)
         vmcb_set_cr0(vmcb, vmcb_get_cr0(vmcb) & ~X86_CR0_TS);
 }
 
-static int svm_vmexit_do_cpuid(struct cpu_user_regs *regs, unsigned int inst_len)
-{
-    struct vcpu *curr = current;
-    struct cpuid_leaf res;
-
-    if ( hvm_check_cpuid_faulting(curr) )
-    {
-        hvm_inject_hw_exception(TRAP_gp_fault, 0);
-        return 1; /* Don't advance the guest IP! */
-    }
-
-    guest_cpuid(curr, regs->eax, regs->ecx, &res);
-    HVMTRACE_5D(CPUID, regs->eax, res.a, res.b, res.c, res.d);
-
-    regs->rax = res.a;
-    regs->rbx = res.b;
-    regs->rcx = res.c;
-    regs->rdx = res.d;
-
-    return hvm_monitor_cpuid(inst_len, regs->eax, regs->ecx);
-}
-
 static void svm_vmexit_do_cr_access(
     struct vmcb_struct *vmcb, struct cpu_user_regs *regs)
 {
@@ -2828,7 +2806,7 @@ void svm_vmexit_handler(struct cpu_user_regs *regs)
         if ( inst_len == 0 )
             break;
 
-        rc = svm_vmexit_do_cpuid(regs, inst_len);
+        rc = hvm_vmexit_cpuid(regs, inst_len);
 
         if ( rc < 0 )
             goto unexpected_exit_type;
index 3b3d5b625079f0cb20e0be2069bf28f53b817fc1..535e0384fe170450fe82442a500fab3b088e31cf 100644 (file)
@@ -2489,29 +2489,6 @@ static void vmx_fpu_dirty_intercept(void)
     }
 }
 
-static int vmx_do_cpuid(struct cpu_user_regs *regs)
-{
-    struct vcpu *curr = current;
-    uint32_t leaf = regs->eax, subleaf = regs->ecx;
-    struct cpuid_leaf res;
-
-    if ( hvm_check_cpuid_faulting(current) )
-    {
-        hvm_inject_hw_exception(TRAP_gp_fault, 0);
-        return 1;  /* Don't advance the guest IP! */
-    }
-
-    guest_cpuid(curr, leaf, subleaf, &res);
-    HVMTRACE_5D(CPUID, leaf, res.a, res.b, res.c, res.d);
-
-    regs->rax = res.a;
-    regs->rbx = res.b;
-    regs->rcx = res.c;
-    regs->rdx = res.d;
-
-    return hvm_monitor_cpuid(get_instruction_length(), leaf, subleaf);
-}
-
 static void vmx_dr_access(unsigned long exit_qualification,
                           struct cpu_user_regs *regs)
 {
@@ -3862,7 +3839,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
     }
     case EXIT_REASON_CPUID:
     {
-        int rc = vmx_do_cpuid(regs);
+        int rc = hvm_vmexit_cpuid(regs, get_instruction_length());
 
         /*
          * rc < 0 error in monitor/vm_event, crash
index 4e72d0732e2912eafd4264fed2b45e73903476cb..f86af0989837694a9638fea62566e8367bad0150 100644 (file)
@@ -280,7 +280,7 @@ void hvm_set_segment_register(struct vcpu *v, enum x86_segment seg,
 
 bool hvm_set_guest_bndcfgs(struct vcpu *v, u64 val);
 
-bool hvm_check_cpuid_faulting(struct vcpu *v);
+int hvm_vmexit_cpuid(struct cpu_user_regs *regs, unsigned int inst_len);
 void hvm_migrate_timers(struct vcpu *v);
 void hvm_do_resume(struct vcpu *v);
 void hvm_migrate_pirq(struct hvm_pirq_dpci *pirq_dpci, const struct vcpu *v);