x86: add CMCI software injection interface
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 4 May 2010 11:22:25 +0000 (12:22 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 4 May 2010 11:22:25 +0000 (12:22 +0100)
This small patch now add CMCI software injection interface.
So that CMCI error could be triggered by software on CPUs
which support CMCI.

Signed-off-by: Yunhong Jiang<yunhong.jiang@intel.com>
Signed-off-by: Liping Ke <liping.ke@intel.com>
xen/arch/x86/cpu/mcheck/mce.c
xen/include/public/arch-x86/xen-mca.h

index 33e5bcb4806e3a1add4e043050de32fa6ede23bb..efcd74f9656fe903e610e4d84044debb61482b1d 100644 (file)
@@ -1274,6 +1274,7 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u_xen_mc)
        unsigned int target;
        struct xen_mc_msrinject *mc_msrinject;
        struct xen_mc_mceinject *mc_mceinject;
+       cpumask_t target_map;
 
        if (!IS_PRIV(v->domain) )
                return x86_mcerr(NULL, -EPERM);
@@ -1411,6 +1412,7 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u_xen_mc)
 
                mc_mceinject = &op->u.mc_mceinject;
                target = mc_mceinject->mceinj_cpunr;
+               flags = mc_mceinject->mceinj_flag;
 
                if (target >= NR_CPUS)
                        return x86_mcerr("do_mca #MC: bad target", -EINVAL);
@@ -1419,12 +1421,22 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u_xen_mc)
                        return x86_mcerr("do_mca #MC: target offline", -EINVAL);
 
                add_taint(TAINT_ERROR_INJECT);
-
-        if ( mce_broadcast )
-            on_each_cpu(x86_mc_mceinject, mc_mceinject, 0);
-        else
-            on_selected_cpus(cpumask_of(target), x86_mc_mceinject,
-                  mc_mceinject, 1);
+               if (flags == XEN_MC_UC) {
+                       if ( mce_broadcast )
+                               on_each_cpu(x86_mc_mceinject, mc_mceinject, 0);
+                       else
+                               on_selected_cpus(cpumask_of(target), x86_mc_mceinject,
+                                       mc_mceinject, 1);
+               }
+               else if (flags == XEN_MC_CE) {
+                       if (mce_broadcast)
+                               send_IPI_mask(&cpu_online_map, CMCI_APIC_VECTOR);
+                       else {
+                               cpus_clear(target_map);
+                               cpu_set(target, target_map);
+                               send_IPI_mask(&target_map, CMCI_APIC_VECTOR);
+                       }
+               }
                break;
 
        default:
index 127971468871234cdb3bbb5d7706a15358bc05c2..6458504cd8fa6d02698408da1075cf570cbadc01 100644 (file)
@@ -400,8 +400,11 @@ struct xen_mc_msrinject {
 #define MC_MSRINJ_F_INTERPOSE   0x1
 
 #define XEN_MC_mceinject    5
+#define XEN_MC_UC           0
+#define XEN_MC_CE           1
 struct xen_mc_mceinject {
-       unsigned int mceinj_cpunr;      /* target processor id */
+       uint32_t mceinj_cpunr;      /* target processor id */
+       uint32_t mceinj_flag;       /* UC error or CE error flag */
 };
 
 struct xen_mc {