__asm__ __volatile__("int $0x12");
}
+static void x86_cmci_inject(void *data)
+{
+ printk("Simulating CMCI on cpu %d\n", smp_processor_id());
+ __asm__ __volatile__("int $0xf7");
+}
+
#if BITS_PER_LONG == 64
#define ID2COOKIE(id) ((mctelem_cookie_t)(id))
CHECK_FIELD_(struct, mc_physcpuinfo, ncpus);
# define CHECK_compat_mc_physcpuinfo struct mc_physcpuinfo
+#define CHECK_compat_mc_inject_v2 struct mc_inject_v2
CHECK_mc;
# undef CHECK_compat_mc_fetch
# undef CHECK_compat_mc_physcpuinfo
mc_mceinject, 1);
break;
+ case XEN_MC_inject_v2:
+ {
+ cpumask_t cpumap;
+
+ if (nr_mce_banks == 0)
+ return x86_mcerr("do_mca #MC", -ENODEV);
+
+ if ( op->u.mc_inject_v2.flags & XEN_MC_INJECT_CPU_BROADCAST )
+ cpus_copy(cpumap, cpu_online_map);
+ else
+ {
+ int gcw;
+
+ cpus_clear(cpumap);
+ xenctl_cpumap_to_cpumask(&cpumap,
+ &op->u.mc_inject_v2.cpumap);
+ gcw = cpus_weight(cpumap);
+ cpus_and(cpumap, cpu_online_map, cpumap);
+
+ if ( cpus_empty(cpumap) )
+ return x86_mcerr("No online CPU passed\n", -EINVAL);
+ else if ( gcw != cpus_weight(cpumap) )
+ dprintk(XENLOG_INFO,
+ "Not all required CPUs are online\n");
+ }
+
+ switch (op->u.mc_inject_v2.flags & XEN_MC_INJECT_TYPE_MASK)
+ {
+ case XEN_MC_INJECT_TYPE_MCE:
+ if ( mce_broadcast &&
+ !cpus_equal(cpumap, cpu_online_map) )
+ printk("Not trigger MCE on all CPUs, may HANG!\n");
+ on_selected_cpus(&cpumap, x86_mc_mceinject, NULL, 1);
+ break;
+ case XEN_MC_INJECT_TYPE_CMCI:
+ if ( !cmci_support )
+ return x86_mcerr(
+ "No CMCI supported in platform\n", -EINVAL);
+ on_selected_cpus(&cpumap, x86_cmci_inject, NULL, 1);
+ break;
+ default:
+ return x86_mcerr("Wrong mca type\n", -EINVAL);
+ }
+ break;
+ }
+
default:
return x86_mcerr("do_mca: bad command", -EINVAL);
}
unsigned int mceinj_cpunr; /* target processor id */
};
+#if defined(__XEN__) || defined(__XEN_TOOLS__)
+#define XEN_MC_inject_v2 6
+#define XEN_MC_INJECT_TYPE_MASK 0x7
+#define XEN_MC_INJECT_TYPE_MCE 0x0
+#define XEN_MC_INJECT_TYPE_CMCI 0x1
+
+#define XEN_MC_INJECT_CPU_BROADCAST 0x8
+
+struct xen_mc_inject_v2 {
+ uint32_t flags;
+ struct xenctl_cpumap cpumap;
+};
+#endif
+
struct xen_mc {
uint32_t cmd;
uint32_t interface_version; /* XEN_MCA_INTERFACE_VERSION */
struct xen_mc_physcpuinfo mc_physcpuinfo;
struct xen_mc_msrinject mc_msrinject;
struct xen_mc_mceinject mc_mceinject;
+#if defined(__XEN__) || defined(__XEN_TOOLS__)
+ struct xen_mc_inject_v2 mc_inject_v2;
+#endif
} u;
};
typedef struct xen_mc xen_mc_t;
/* Default definitions for macros used by domctl/sysctl. */
#if defined(__XEN__) || defined(__XEN_TOOLS__)
+
#ifndef uint64_aligned_t
#define uint64_aligned_t uint64_t
#endif
#ifndef XEN_GUEST_HANDLE_64
#define XEN_GUEST_HANDLE_64(name) XEN_GUEST_HANDLE(name)
#endif
+
+#ifndef __ASSEMBLY__
+struct xenctl_cpumap {
+ XEN_GUEST_HANDLE_64(uint8) bitmap;
+ uint32_t nr_cpus;
+};
#endif
+#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
+
#endif /* __XEN_PUBLIC_XEN_H__ */
/*