x86: add sanity check and comments for vMCE injection
authorLiu, Jinsong <jinsong.liu@intel.com>
Fri, 5 Oct 2012 12:30:21 +0000 (14:30 +0200)
committerLiu, Jinsong <jinsong.liu@intel.com>
Fri, 5 Oct 2012 12:30:21 +0000 (14:30 +0200)
Add sanity check for input vcpu so that malicious value would not
return 0. Add comments since vcpu=-1 (broadcast) is some implicit to
code reader.

Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>
Suggested-by: Christoph Egger <Christoph.Egger@amd.com>
Acked-by: Christoph Egger <Christoph.Egger@amd.com>
Committed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/cpu/mcheck/mce_intel.c
xen/arch/x86/cpu/mcheck/vmce.c
xen/arch/x86/cpu/mcheck/vmce.h

index 254cbc910019485b753cc486142e908726b3872e..a717dfd660eeb090474b25bcaf7fcf07adb60759 100644 (file)
@@ -360,7 +360,7 @@ static void intel_memerr_dhandler(
                 }
 
                 /* We will inject vMCE to DOMU*/
-                if ( inject_vmce(d, -1) < 0 )
+                if ( inject_vmce(d, VMCE_INJECT_BROADCAST) < 0 )
                 {
                     mce_printk(MCE_QUIET, "inject vMCE to DOM%d"
                       " failed\n", d->domain_id);
index a486af5c9bc7ace786ad15e8e47c7bc8cb28de0d..7d3fac7c0d2a3eccb951e69dede6b6a5f326554e 100644 (file)
@@ -341,14 +341,20 @@ HVM_REGISTER_SAVE_RESTORE(VMCE_VCPU, vmce_save_vcpu_ctxt,
 /*
  * for Intel MCE, broadcast vMCE to all vcpus
  * for AMD MCE, only inject vMCE to vcpu0
+ *
+ * @ d, domain to which would inject vmce
+ * @ vcpu,
+ *   -1 (VMCE_INJECT_BROADCAST), broadcast vMCE to all vcpus
+ *   >= 0, vcpu, the vMCE is injected to
  */
 int inject_vmce(struct domain *d, int vcpu)
 {
     struct vcpu *v;
+    int ret = -ESRCH;
 
     for_each_vcpu ( d, v )
     {
-        if ( vcpu >= 0 && v->vcpu_id != vcpu )
+        if ( vcpu != VMCE_INJECT_BROADCAST && vcpu != v->vcpu_id )
             continue;
 
         if ( (is_hvm_domain(d) ||
@@ -358,19 +364,21 @@ int inject_vmce(struct domain *d, int vcpu)
             mce_printk(MCE_VERBOSE, "MCE: inject vMCE to d%d:v%d\n",
                        d->domain_id, v->vcpu_id);
             vcpu_kick(v);
+            ret = 0;
         }
         else
         {
             mce_printk(MCE_QUIET, "Failed to inject vMCE to d%d:v%d\n",
                        d->domain_id, v->vcpu_id);
-            return -EBUSY;
+            ret = -EBUSY;
+            break;
         }
 
-        if ( vcpu >= 0 )
-            return 0;
+        if ( vcpu != VMCE_INJECT_BROADCAST )
+            break;
     }
 
-    return v ? -ESRCH : 0;
+    return ret;
 }
 
 int fill_vmsr_data(struct mcinfo_bank *mc_bank, struct domain *d,
index a83db4ac04617c5f558b3f8a048de410a91d2ce3..7263deb98fac6b5a7b21c602cadb52a4e4d2e361 100644 (file)
@@ -18,6 +18,8 @@ int vmce_amd_wrmsr(struct vcpu *, uint32_t msr, uint64_t val);
 
 int fill_vmsr_data(struct mcinfo_bank *mc_bank, struct domain *d,
     uint64_t gstatus);
+
+#define VMCE_INJECT_BROADCAST (-1)
 int inject_vmce(struct domain *d, int vcpu);
 
 #endif