All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/12] Add LMCE support
@ 2017-03-17  6:46 Haozhong Zhang
  2017-03-17  6:46 ` [PATCH v2 01/12] xen/mce: switch bool_t/1/0 to bool/true/false Haozhong Zhang
                   ` (11 more replies)
  0 siblings, 12 replies; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-17  6:46 UTC (permalink / raw)
  To: xen-devel
  Cc: Haozhong Zhang, Kevin Tian, Wei Liu, Jan Beulich, Andrew Cooper,
	Ian Jackson, Jun Nakajima

v1 and test instructions can be found at
https://lists.xenproject.org/archives/html/xen-devel/2017-02/msg02084.html

Note: the xl config for LMCE is changed from "lmce=1" to "mca_caps=[ "lmce" ]".

Other changes are logged in each patch separately.

This patch series is organized as below:
 * Patch 1 - 3 are new in this series and for code cleanup.
 * Patch 4 & 5 correspond to v1 patch 12 & 13, which add host-side
   LMCE support, including detecting, enabling and handling LMCE.
 * Patch 6 - 9 correspond to v1 patch 14 - 17, which add guest-side
   LMCE support (only HVM domain so far), including emulating LMCE
   feature and injecting LMCE to HVM domain.
 * Patch 10 - 12 correspond to v1 patch 18 & 19, which add xen-mceinj
   support to inject LMCE for test purpose.

Haozhong Zhang (12):
  01/12 xen/mce: switch bool_t/1/0 to bool/true/false
  02/12 x86/mce_intel: refine messages of MCA capabilities
  03/12 xen/mce: add blank lines between non-fall-through switch case blocks
  04/12 x86/mce: handle LMCE locally
  05/12 x86/mce_intel: detect and enable LMCE on Intel host
  06/12 x86/vmx: expose LMCE feature via guest MSR_IA32_FEATURE_CONTROL
  07/12 x86/vmce: emulate MSR_IA32_MCG_EXT_CTL
  08/12 x86/vmce: enable injecting LMCE to guest on Intel host
  09/12 x86/vmce, tools/libxl: expose LMCE capability in guest MSR_IA32_MCG_CAP
  10/12 xen/mce: add support of vLMCE injection to XEN_MC_inject_v2
  11/12 tools/libxc: add support of injecting MC# to specified CPUs
  12/12 tools/xen-mceinj: add support of injecting LMCE

 docs/man/xl.cfg.pod.5.in                |  24 ++++++
 tools/libxc/include/xenctrl.h           |   2 +
 tools/libxc/xc_misc.c                   |  52 +++++++++++-
 tools/libxl/libxl_dom.c                 |  30 +++++++
 tools/libxl/libxl_types.idl             |   1 +
 tools/tests/mce-test/tools/xen-mceinj.c |  50 ++++++++++-
 tools/xl/xl_parse.c                     |   4 +
 xen/arch/x86/acpi/power.c               |   2 +-
 xen/arch/x86/cpu/common.c               |   4 +-
 xen/arch/x86/cpu/mcheck/barrier.c       |  14 ++--
 xen/arch/x86/cpu/mcheck/barrier.h       |  14 +++-
 xen/arch/x86/cpu/mcheck/mcaction.c      |  26 ++++--
 xen/arch/x86/cpu/mcheck/mcaction.h      |   2 +-
 xen/arch/x86/cpu/mcheck/mce-apei.c      |   2 +-
 xen/arch/x86/cpu/mcheck/mce.c           | 100 +++++++++++++++-------
 xen/arch/x86/cpu/mcheck/mce.h           |  26 +++---
 xen/arch/x86/cpu/mcheck/mce_amd.c       |  24 +++---
 xen/arch/x86/cpu/mcheck/mce_amd.h       |   4 +-
 xen/arch/x86/cpu/mcheck/mce_intel.c     | 143 ++++++++++++++++++++++----------
 xen/arch/x86/cpu/mcheck/mctelem.c       |   6 +-
 xen/arch/x86/cpu/mcheck/mctelem.h       |   2 +-
 xen/arch/x86/cpu/mcheck/vmce.c          |  82 +++++++++++++++++-
 xen/arch/x86/cpu/mcheck/vmce.h          |   2 +-
 xen/arch/x86/cpu/mcheck/x86_mca.h       |  13 ++-
 xen/arch/x86/hvm/hvm.c                  |   5 ++
 xen/arch/x86/hvm/vmx/vmx.c              |   9 ++
 xen/arch/x86/hvm/vmx/vvmx.c             |   4 -
 xen/include/asm-x86/mce.h               |   3 +
 xen/include/asm-x86/msr-index.h         |   2 +
 xen/include/public/arch-x86/hvm/save.h  |   2 +
 xen/include/public/arch-x86/xen-mca.h   |   1 +
 xen/include/public/domctl.h             |   2 +-
 xen/include/public/hvm/params.h         |   7 +-
 33 files changed, 526 insertions(+), 138 deletions(-)

-- 
2.10.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v2 01/12] xen/mce: switch bool_t/1/0 to bool/true/false
  2017-03-17  6:46 [PATCH v2 00/12] Add LMCE support Haozhong Zhang
@ 2017-03-17  6:46 ` Haozhong Zhang
  2017-03-20 13:04   ` Jan Beulich
  2017-03-17  6:46 ` [PATCH v2 02/12] x86/mce_intel: refine messages of MCA capabilities Haozhong Zhang
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-17  6:46 UTC (permalink / raw)
  To: xen-devel; +Cc: Haozhong Zhang, Jan Beulich, Andrew Cooper

Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/acpi/power.c           |  2 +-
 xen/arch/x86/cpu/common.c           |  4 +-
 xen/arch/x86/cpu/mcheck/mcaction.h  |  2 +-
 xen/arch/x86/cpu/mcheck/mce-apei.c  |  2 +-
 xen/arch/x86/cpu/mcheck/mce.c       | 32 ++++++++--------
 xen/arch/x86/cpu/mcheck/mce.h       | 22 +++++------
 xen/arch/x86/cpu/mcheck/mce_amd.c   | 20 +++++-----
 xen/arch/x86/cpu/mcheck/mce_amd.h   |  4 +-
 xen/arch/x86/cpu/mcheck/mce_intel.c | 76 ++++++++++++++++++-------------------
 xen/arch/x86/cpu/mcheck/mctelem.c   |  6 +--
 xen/arch/x86/cpu/mcheck/mctelem.h   |  2 +-
 xen/arch/x86/cpu/mcheck/x86_mca.h   |  4 +-
 12 files changed, 88 insertions(+), 88 deletions(-)

diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c
index 506f54d..1e4e568 100644
--- a/xen/arch/x86/acpi/power.c
+++ b/xen/arch/x86/acpi/power.c
@@ -235,7 +235,7 @@ static int enter_state(u32 state)
 
     device_power_up(SAVED_ALL);
 
-    mcheck_init(&boot_cpu_data, 0);
+    mcheck_init(&boot_cpu_data, false);
     write_cr4(cr4);
 
     printk(XENLOG_INFO "Finishing wakeup from ACPI S%d state.\n", state);
diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index 0040fa3..9c44bbd 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -406,9 +406,9 @@ void identify_cpu(struct cpuinfo_x86 *c)
 		for ( i = 0 ; i < NCAPINTS ; i++ )
 			boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
 
-		mcheck_init(c, 0);
+		mcheck_init(c, false);
 	} else {
-		mcheck_init(c, 1);
+		mcheck_init(c, true);
 
 		mtrr_bp_init();
 	}
diff --git a/xen/arch/x86/cpu/mcheck/mcaction.h b/xen/arch/x86/cpu/mcheck/mcaction.h
index c6044d5..5cbe558 100644
--- a/xen/arch/x86/cpu/mcheck/mcaction.h
+++ b/xen/arch/x86/cpu/mcheck/mcaction.h
@@ -12,7 +12,7 @@ mc_memerr_dhandler(struct mca_binfo *binfo,
 #define MC_ADDR_PHYSICAL  0
 #define MC_ADDR_VIRTUAL   1
 
-typedef int (*mce_check_addr_t)(uint64_t status, uint64_t misc, int addr_type);
+typedef bool (*mce_check_addr_t)(uint64_t status, uint64_t misc, int addr_type);
 extern void mce_register_addrcheck(mce_check_addr_t);
 
 extern mce_check_addr_t mc_check_addr;
diff --git a/xen/arch/x86/cpu/mcheck/mce-apei.c b/xen/arch/x86/cpu/mcheck/mce-apei.c
index 3933c19..53b6735 100644
--- a/xen/arch/x86/cpu/mcheck/mce-apei.c
+++ b/xen/arch/x86/cpu/mcheck/mce-apei.c
@@ -116,7 +116,7 @@ ssize_t apei_read_mce(struct mce *m, u64 *record_id)
 }
 
 /* Check whether there is record in ERST */
-bool_t apei_check_mce(void)
+bool apei_check_mce(void)
 {
 	return erst_get_record_count() > 0;
 }
diff --git a/xen/arch/x86/cpu/mcheck/mce.c b/xen/arch/x86/cpu/mcheck/mce.c
index cd4f0ee..df2e3a4 100644
--- a/xen/arch/x86/cpu/mcheck/mce.c
+++ b/xen/arch/x86/cpu/mcheck/mce.c
@@ -30,10 +30,10 @@
 #include "util.h"
 #include "vmce.h"
 
-bool_t __read_mostly opt_mce = 1;
+bool __read_mostly opt_mce = true;
 boolean_param("mce", opt_mce);
-bool_t __read_mostly mce_broadcast = 0;
-bool_t is_mc_panic;
+bool __read_mostly mce_broadcast;
+bool is_mc_panic;
 unsigned int __read_mostly nr_mce_banks;
 unsigned int __read_mostly firstbank;
 uint8_t __read_mostly cmci_apic_vector;
@@ -285,7 +285,7 @@ mcheck_mca_logout(enum mca_source who, struct mca_banks *bankmask,
     uint64_t gstatus, status;
     struct mcinfo_global *mig = NULL; /* on stack */
     mctelem_cookie_t mctc = NULL;
-    bool_t uc = 0, pcc = 0, recover = 1, need_clear = 1;
+    bool uc = false, pcc = false, recover = true, need_clear = true;
     uint32_t mc_flags = 0;
     struct mc_info *mci = NULL;
     mctelem_class_t which = MC_URGENT; /* XXXgcc */
@@ -356,14 +356,14 @@ mcheck_mca_logout(enum mca_source who, struct mca_banks *bankmask,
 
         /* flag for uncorrected errors */
         if (!uc && ((status & MCi_STATUS_UC) != 0))
-            uc = 1;
+            uc = true;
 
         /* flag processor context corrupt */
         if (!pcc && ((status & MCi_STATUS_PCC) != 0))
-            pcc = 1;
+            pcc = true;
 
         if (recover && uc)
-            /* uc = 1, recover = 1, we need not panic.
+            /* uc = true, recover = true, we need not panic.
              */
             recover = mc_recoverable_scan(status);
 
@@ -372,7 +372,7 @@ mcheck_mca_logout(enum mca_source who, struct mca_banks *bankmask,
         if (mc_callback_bank_extended)
             mc_callback_bank_extended(mci, i, status);
 
-        /* By default, need_clear = 1 */
+        /* By default, need_clear = true */
         if (who != MCA_MCE_SCAN && need_clear)
             /* Clear bank */
             mcabank_clear(i);
@@ -554,7 +554,7 @@ void mcheck_mca_clearbanks(struct mca_banks *bankmask)
 }
 
 /*check the existence of Machine Check*/
-int mce_available(struct cpuinfo_x86 *c)
+bool mce_available(struct cpuinfo_x86 *c)
 {
     return cpu_has(c, X86_FEATURE_MCE) && cpu_has(c, X86_FEATURE_MCA);
 }
@@ -719,7 +719,7 @@ static struct notifier_block cpu_nfb = {
 };
 
 /* This has to be run for each processor */
-void mcheck_init(struct cpuinfo_x86 *c, bool_t bsp)
+void mcheck_init(struct cpuinfo_x86 *c, bool bsp)
 {
     enum mcheck_type inited = mcheck_none;
 
@@ -1059,15 +1059,15 @@ static void intpose_add(unsigned int cpu_nr, uint64_t msr, uint64_t val)
     printk("intpose_add: interpose array full - request dropped\n");
 }
 
-bool_t intpose_inval(unsigned int cpu_nr, uint64_t msr)
+bool intpose_inval(unsigned int cpu_nr, uint64_t msr)
 {
     struct intpose_ent *ent = intpose_lookup(cpu_nr, msr, NULL);
 
     if ( !ent )
-        return 0;
+        return false;
 
     ent->cpu_nr = -1;
-    return 1;
+    return true;
 }
 
 #define IS_MCA_BANKREG(r) \
@@ -1075,7 +1075,7 @@ bool_t intpose_inval(unsigned int cpu_nr, uint64_t msr)
     (r) <= MSR_IA32_MCx_MISC(nr_mce_banks - 1) && \
     ((r) - MSR_IA32_MC0_CTL) % 4 != 0) /* excludes MCi_CTL */
 
-static int x86_mc_msrinject_verify(struct xen_mc_msrinject *mci)
+static bool x86_mc_msrinject_verify(struct xen_mc_msrinject *mci)
 {
     struct cpuinfo_x86 *c;
     int i, errs = 0;
@@ -1569,7 +1569,7 @@ static void mc_panic_dump(void)
 
 void mc_panic(char *s)
 {
-    is_mc_panic = 1;
+    is_mc_panic = true;
     console_force_unlock();
 
     printk("Fatal machine check: %s\n", s);
@@ -1669,7 +1669,7 @@ static int mce_delayed_action(mctelem_cookie_t mctc)
     {
     case MCER_RESET:
         dprintk(XENLOG_ERR, "MCE delayed action failed\n");
-        is_mc_panic = 1;
+        is_mc_panic = true;
         x86_mcinfo_dump(mctelem_dataptr(mctc));
         panic("MCE: Software recovery failed for the UCR");
         break;
diff --git a/xen/arch/x86/cpu/mcheck/mce.h b/xen/arch/x86/cpu/mcheck/mce.h
index 4129a99..7611789 100644
--- a/xen/arch/x86/cpu/mcheck/mce.h
+++ b/xen/arch/x86/cpu/mcheck/mce.h
@@ -41,7 +41,7 @@ extern uint8_t cmci_apic_vector;
 
 /* Init functions */
 enum mcheck_type amd_mcheck_init(struct cpuinfo_x86 *c);
-enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c, bool_t bsp);
+enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c, bool bsp);
 
 void amd_nonfatal_mcheck_init(struct cpuinfo_x86 *c);
 
@@ -50,7 +50,7 @@ extern unsigned int firstbank;
 struct mcinfo_extended *intel_get_extended_msrs(
     struct mcinfo_global *mig, struct mc_info *mi);
 
-int mce_available(struct cpuinfo_x86 *c);
+bool mce_available(struct cpuinfo_x86 *c);
 unsigned int mce_firstbank(struct cpuinfo_x86 *c);
 /* Helper functions used for collecting error telemetry */
 void noreturn mc_panic(char *s);
@@ -66,13 +66,13 @@ extern void x86_mce_vector_register(x86_mce_vector_t);
 extern void mcheck_cmn_handler(const struct cpu_user_regs *regs);
 
 /* Register a handler for judging whether mce is recoverable. */
-typedef int (*mce_recoverable_t)(uint64_t status);
+typedef bool (*mce_recoverable_t)(uint64_t status);
 extern void mce_recoverable_register(mce_recoverable_t);
 
 /* Read an MSR, checking for an interposed value first */
 extern struct intpose_ent *intpose_lookup(unsigned int, uint64_t,
     uint64_t *);
-extern bool_t intpose_inval(unsigned int, uint64_t);
+extern bool intpose_inval(unsigned int, uint64_t);
 
 static inline uint64_t mca_rdmsr(unsigned int msr)
 {
@@ -107,18 +107,18 @@ struct mca_summary {
     uint32_t    errcnt; /* number of banks with valid errors */
     int         ripv;   /* meaningful on #MC */
     int         eipv;   /* meaningful on #MC */
-    bool_t      uc;     /* UC flag */
-    bool_t      pcc;    /* PCC flag */
-    bool_t      recoverable; /* software error recoverable flag */
+    bool        uc;     /* UC flag */
+    bool        pcc;    /* PCC flag */
+    bool        recoverable; /* software error recoverable flag */
 };
 
 DECLARE_PER_CPU(struct mca_banks *, poll_bankmask);
 DECLARE_PER_CPU(struct mca_banks *, no_cmci_banks);
 DECLARE_PER_CPU(struct mca_banks *, mce_clear_banks);
 
-extern bool_t cmci_support;
-extern bool_t is_mc_panic;
-extern bool_t mce_broadcast;
+extern bool cmci_support;
+extern bool is_mc_panic;
+extern bool mce_broadcast;
 extern void mcheck_mca_clearbanks(struct mca_banks *);
 
 extern mctelem_cookie_t mcheck_mca_logout(enum mca_source, struct mca_banks *,
@@ -131,7 +131,7 @@ extern mctelem_cookie_t mcheck_mca_logout(enum mca_source, struct mca_banks *,
  */
 
 /* Register a handler for judging whether the bank need to be cleared */
-typedef int (*mce_need_clearbank_t)(enum mca_source who, u64 status);
+typedef bool (*mce_need_clearbank_t)(enum mca_source who, u64 status);
 extern void mce_need_clearbank_register(mce_need_clearbank_t);
 
 /* Register a callback to collect additional information (typically non-
diff --git a/xen/arch/x86/cpu/mcheck/mce_amd.c b/xen/arch/x86/cpu/mcheck/mce_amd.c
index fe51be9..c580a91 100644
--- a/xen/arch/x86/cpu/mcheck/mce_amd.c
+++ b/xen/arch/x86/cpu/mcheck/mce_amd.c
@@ -103,15 +103,15 @@ mc_ec2type(uint16_t errorcode)
     return 0;
 }
 
-int
+bool
 mc_amd_recoverable_scan(uint64_t status)
 {
-    int ret = 0;
+    bool ret = false;
     enum mc_ec_type ectype;
     uint16_t errorcode;
 
     if ( !(status & MCi_STATUS_UC) )
-        return 1;
+        return true;
 
     errorcode = status & (MCi_STATUS_MCA | MCi_STATUS_MSEC);
     ectype = mc_ec2type(errorcode);
@@ -122,7 +122,7 @@ mc_amd_recoverable_scan(uint64_t status)
         /* should run cpu offline action */
         break;
     case MC_EC_MEM_TYPE: /* value in addr MSR is physical */
-        ret = 1; /* run memory page offline action */
+        ret = true; /* run memory page offline action */
         break;
     case MC_EC_TLB_TYPE: /* value in addr MSR is virtual */
         /* should run tlb flush action and retry */
@@ -132,7 +132,7 @@ mc_amd_recoverable_scan(uint64_t status)
     return ret;
 }
 
-int
+bool
 mc_amd_addrcheck(uint64_t status, uint64_t misc, int addrtype)
 {
     enum mc_ec_type ectype;
@@ -152,7 +152,7 @@ mc_amd_addrcheck(uint64_t status, uint64_t misc, int addrtype)
 
     /* unreached */
     BUG();
-    return 0;
+    return false;
 }
 
 /* MC quirks */
@@ -238,19 +238,19 @@ amd_f10_handler(struct mc_info *mi, uint16_t bank, uint64_t status)
     return mc_ext;
 }
 
-static int amd_need_clearbank_scan(enum mca_source who, uint64_t status)
+static bool amd_need_clearbank_scan(enum mca_source who, uint64_t status)
 {
     if ( who != MCA_MCE_SCAN )
-        return 1;
+        return true;
 
     /*
      * For fatal error, it shouldn't be cleared so that sticky bank
      * have a chance to be handled after reboot by polling.
      */
     if ( (status & MCi_STATUS_UC) && (status & MCi_STATUS_PCC) )
-        return 0;
+        return false;
 
-    return 1;
+    return true;
 }
 
 /* AMD specific MCA MSR */
diff --git a/xen/arch/x86/cpu/mcheck/mce_amd.h b/xen/arch/x86/cpu/mcheck/mce_amd.h
index de5fc48..67c4545 100644
--- a/xen/arch/x86/cpu/mcheck/mce_amd.h
+++ b/xen/arch/x86/cpu/mcheck/mce_amd.h
@@ -1,7 +1,7 @@
 #ifndef _MCHECK_AMD_H
 #define _MCHECK_AMD_H
 
-int mc_amd_recoverable_scan(uint64_t status);
-int mc_amd_addrcheck(uint64_t status, uint64_t misc, int addrtype);
+bool mc_amd_recoverable_scan(uint64_t status);
+bool mc_amd_addrcheck(uint64_t status, uint64_t misc, int addrtype);
 
 #endif
diff --git a/xen/arch/x86/cpu/mcheck/mce_intel.c b/xen/arch/x86/cpu/mcheck/mce_intel.c
index 189c1ed..b0d8280 100644
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c
@@ -22,9 +22,9 @@
 #include "mcaction.h"
 
 static DEFINE_PER_CPU_READ_MOSTLY(struct mca_banks *, mce_banks_owned);
-bool_t __read_mostly cmci_support = 0;
-static bool_t __read_mostly ser_support = 0;
-static bool_t __read_mostly mce_force_broadcast;
+bool __read_mostly cmci_support;
+static bool __read_mostly ser_support;
+static bool __read_mostly mce_force_broadcast;
 boolean_param("mce_fb", mce_force_broadcast);
 
 static int __read_mostly nr_intel_ext_msrs;
@@ -81,13 +81,13 @@ static void intel_thermal_interrupt(struct cpu_user_regs *regs)
 }
 
 /* Thermal monitoring depends on APIC, ACPI and clock modulation */
-static int intel_thermal_supported(struct cpuinfo_x86 *c)
+static bool intel_thermal_supported(struct cpuinfo_x86 *c)
 {
     if (!cpu_has_apic)
-        return 0;
+        return false;
     if (!cpu_has(c, X86_FEATURE_ACPI) || !cpu_has(c, X86_FEATURE_TM1))
-        return 0;
-    return 1;
+        return false;
+    return true;
 }
 
 static u32 __read_mostly lvtthmr_init;
@@ -268,12 +268,12 @@ static void intel_memerr_dhandler(
     mc_memerr_dhandler(binfo, result, regs);
 }
 
-static int intel_srar_check(uint64_t status)
+static bool intel_srar_check(uint64_t status)
 {
     return ( intel_check_mce_type(status) == intel_mce_ucr_srar );
 }
 
-static int intel_checkaddr(uint64_t status, uint64_t misc, int addrtype)
+static bool intel_checkaddr(uint64_t status, uint64_t misc, int addrtype)
 {
     if (!(status & MCi_STATUS_ADDRV) ||
         !(status & MCi_STATUS_MISCV) ||
@@ -307,7 +307,7 @@ static void intel_srar_dhandler(
     }
 }
 
-static int intel_srao_check(uint64_t status)
+static bool intel_srao_check(uint64_t status)
 {
     return ( intel_check_mce_type(status) == intel_mce_ucr_srao );
 }
@@ -336,7 +336,7 @@ static void intel_srao_dhandler(
     }
 }
 
-static int intel_default_check(uint64_t status)
+static bool intel_default_check(uint64_t status)
 {
     return 1;
 }
@@ -398,51 +398,51 @@ static const struct mca_error_handler intel_mce_uhandlers[] = {
  * 3) ser_support = 1, SRAO, UC = 1, S = 1, AR = 0, [EN = 1]
 */
 
-static int intel_need_clearbank_scan(enum mca_source who, u64 status)
+static bool intel_need_clearbank_scan(enum mca_source who, u64 status)
 {
     if ( who == MCA_CMCI_HANDLER) {
         /* CMCI need clear bank */
         if ( !(status & MCi_STATUS_UC) )
-            return 1;
+            return true;
         /* Spurious need clear bank */
         else if ( ser_support && !(status & MCi_STATUS_OVER)
                     && !(status & MCi_STATUS_EN) )
-            return 1;
+            return true;
         /* UCNA OVER = 0 need clear bank */
         else if ( ser_support && !(status & MCi_STATUS_OVER) 
                     && !(status & MCi_STATUS_PCC) && !(status & MCi_STATUS_S) 
                     && !(status & MCi_STATUS_AR))
-            return 1;
+            return true;
         /* Only Log, no clear */
-        else return 0;
+        else return false;
     }
     else if ( who == MCA_MCE_SCAN) {
         if ( !ser_support )
-            return 0;
+            return false;
         /* 
          * For fatal error, it shouldn't be cleared so that sticky bank
          * have chance to be handled after reboot by polling
          */
         if ( (status & MCi_STATUS_UC) && (status & MCi_STATUS_PCC) )
-            return 0;
+            return false;
         /* Spurious need clear bank */
         else if ( !(status & MCi_STATUS_OVER)
                     && (status & MCi_STATUS_UC) && !(status & MCi_STATUS_EN))
-            return 1;
+            return true;
         /* SRAR OVER=0 clear bank. OVER = 1 have caused reset */
         else if ( (status & MCi_STATUS_UC)
                     && (status & MCi_STATUS_S) && (status & MCi_STATUS_AR )
                     && !(status & MCi_STATUS_OVER) )
-            return 1;
+            return true;
         /* SRAO need clear bank */
         else if ( !(status & MCi_STATUS_AR) 
                     && (status & MCi_STATUS_S) && (status & MCi_STATUS_UC))
-            return 1; 
+            return true;
         else
-            return 0;
+            return false;
     }
 
-    return 1;
+    return true;
 }
 
 /* MCE continues/is recoverable when 
@@ -452,30 +452,30 @@ static int intel_need_clearbank_scan(enum mca_source who, u64 status)
  * 4) SRAO ser_support = 1, PCC = 0, S = 1, AR = 0, EN = 1 [UC = 1]
  * 5) UCNA ser_support = 1, OVER = 0, EN = 1, PCC = 0, S = 0, AR = 0, [UC = 1]
  */
-static int intel_recoverable_scan(uint64_t status)
+static bool intel_recoverable_scan(uint64_t status)
 {
 
     if ( !(status & MCi_STATUS_UC ) )
-        return 1;
+        return true;
     else if ( ser_support && !(status & MCi_STATUS_EN) 
                 && !(status & MCi_STATUS_OVER) )
-        return 1;
+        return true;
     /* SRAR error */
     else if ( ser_support && !(status & MCi_STATUS_OVER) 
                 && !(status & MCi_STATUS_PCC) && (status & MCi_STATUS_S)
                 && (status & MCi_STATUS_AR) && (status & MCi_STATUS_EN) )
-        return 1;
+        return true;
     /* SRAO error */
     else if (ser_support && !(status & MCi_STATUS_PCC)
                 && (status & MCi_STATUS_S) && !(status & MCi_STATUS_AR)
                 && (status & MCi_STATUS_EN))
-        return 1;
+        return true;
     /* UCNA error */
     else if (ser_support && !(status & MCi_STATUS_OVER)
                 && (status & MCi_STATUS_EN) && !(status & MCi_STATUS_PCC)
                 && !(status & MCi_STATUS_S) && !(status & MCi_STATUS_AR))
-        return 1;
-    return 0;
+        return true;
+    return false;
 }
 
 /* CMCI */
@@ -686,10 +686,10 @@ static void intel_init_cmci(struct cpuinfo_x86 *c)
 
 /* MCA */
 
-static int mce_is_broadcast(struct cpuinfo_x86 *c)
+static bool mce_is_broadcast(struct cpuinfo_x86 *c)
 {
     if (mce_force_broadcast)
-        return 1;
+        return true;
 
     /* According to Intel SDM Dec, 2009, 15.10.4.1, For processors with
      * DisplayFamily_DisplayModel encoding of 06H_EH and above,
@@ -697,14 +697,14 @@ static int mce_is_broadcast(struct cpuinfo_x86 *c)
      */
     if (c->x86_vendor == X86_VENDOR_INTEL && c->x86 == 6 &&
         c->x86_model >= 0xe)
-            return 1;
-    return 0;
+            return true;
+    return false;
 }
 
 /* Check and init MCA */
 static void intel_init_mca(struct cpuinfo_x86 *c)
 {
-    bool_t broadcast, cmci = 0, ser = 0;
+    bool broadcast, cmci = false, ser = false;
     int ext_num = 0, first;
     uint64_t msr_content;
 
@@ -713,11 +713,11 @@ static void intel_init_mca(struct cpuinfo_x86 *c)
     rdmsrl(MSR_IA32_MCG_CAP, msr_content);
 
     if ((msr_content & MCG_CMCI_P) && cpu_has_apic)
-        cmci = 1;
+        cmci = true;
 
     /* Support Software Error Recovery */
     if (msr_content & MCG_SER_P)
-        ser = 1;
+        ser = true;
 
     if (msr_content & MCG_EXT_P)
         ext_num = (msr_content >> MCG_EXT_CNT) & 0xff;
@@ -856,7 +856,7 @@ static struct notifier_block cpu_nfb = {
 };
 
 /* p4/p6 family have similar MCA initialization process */
-enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c, bool_t bsp)
+enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c, bool bsp)
 {
     if ( bsp )
     {
diff --git a/xen/arch/x86/cpu/mcheck/mctelem.c b/xen/arch/x86/cpu/mcheck/mctelem.c
index f26f13d..96048eb 100644
--- a/xen/arch/x86/cpu/mcheck/mctelem.c
+++ b/xen/arch/x86/cpu/mcheck/mctelem.c
@@ -189,11 +189,11 @@ void mctelem_process_deferred(unsigned int cpu,
 	}
 }
 
-int mctelem_has_deferred(unsigned int cpu)
+bool mctelem_has_deferred(unsigned int cpu)
 {
 	if (per_cpu(mctctl.pending, cpu) != NULL)
-		return 1;
-	return 0;
+		return true;
+	return false;
 }
 
 /* Free an entry to its native free list; the entry must not be linked on
diff --git a/xen/arch/x86/cpu/mcheck/mctelem.h b/xen/arch/x86/cpu/mcheck/mctelem.h
index 4947b57..9fcde4f 100644
--- a/xen/arch/x86/cpu/mcheck/mctelem.h
+++ b/xen/arch/x86/cpu/mcheck/mctelem.h
@@ -70,6 +70,6 @@ extern void mctelem_ack(mctelem_class_t, mctelem_cookie_t);
 extern void mctelem_defer(mctelem_cookie_t);
 extern void mctelem_process_deferred(unsigned int,
     int (*)(mctelem_cookie_t));
-int mctelem_has_deferred(unsigned int);
+bool mctelem_has_deferred(unsigned int);
 
 #endif
diff --git a/xen/arch/x86/cpu/mcheck/x86_mca.h b/xen/arch/x86/cpu/mcheck/x86_mca.h
index e25d619..34d1921 100644
--- a/xen/arch/x86/cpu/mcheck/x86_mca.h
+++ b/xen/arch/x86/cpu/mcheck/x86_mca.h
@@ -147,12 +147,12 @@ struct mca_error_handler
      * a seperate function to decode the corresponding actions
      * for the particular mca error later.
      */
-    int (*owned_error)(uint64_t status);
+    bool (*owned_error)(uint64_t status);
     void (*recovery_handler)(struct mca_binfo *binfo,
                     enum mce_result *result, const struct cpu_user_regs *regs);
 };
 
 /* Global variables */
-extern bool_t opt_mce;
+extern bool opt_mce;
 
 #endif /* X86_MCA_H */
-- 
2.10.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 02/12] x86/mce_intel: refine messages of MCA capabilities
  2017-03-17  6:46 [PATCH v2 00/12] Add LMCE support Haozhong Zhang
  2017-03-17  6:46 ` [PATCH v2 01/12] xen/mce: switch bool_t/1/0 to bool/true/false Haozhong Zhang
@ 2017-03-17  6:46 ` Haozhong Zhang
  2017-03-20 13:10   ` Jan Beulich
  2017-03-17  6:46 ` [PATCH v2 03/12] xen/mce: add blank lines between non-fall-through switch case blocks Haozhong Zhang
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-17  6:46 UTC (permalink / raw)
  To: xen-devel; +Cc: Haozhong Zhang, Jan Beulich, Andrew Cooper

... to only print available ones.

Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/cpu/mcheck/mce_intel.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/xen/arch/x86/cpu/mcheck/mce_intel.c b/xen/arch/x86/cpu/mcheck/mce_intel.c
index b0d8280..48f41d6 100644
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c
@@ -724,11 +724,15 @@ static void intel_init_mca(struct cpuinfo_x86 *c)
 
     first = mce_firstbank(c);
 
+#define CAP(enabled, name) ((enabled) ? ", "name : "")
     if (smp_processor_id() == 0)
     {
-        dprintk(XENLOG_INFO, "MCA Capability: BCAST %x SER %x"
-                " CMCI %x firstbank %x extended MCE MSR %x\n",
-                broadcast, ser, cmci, first, ext_num);
+        dprintk(XENLOG_INFO,
+                "MCA Capability: firstbank %d, extended MCE MSR %d%s%s%s\n",
+                first, ext_num,
+                CAP(broadcast, "BCAST"),
+                CAP(ser, "SER"),
+                CAP(cmci, "CMCI"));
 
         mce_broadcast = broadcast;
         cmci_support = cmci;
@@ -739,12 +743,15 @@ static void intel_init_mca(struct cpuinfo_x86 *c)
     else if (cmci != cmci_support || ser != ser_support ||
              broadcast != mce_broadcast ||
              first != firstbank || ext_num != nr_intel_ext_msrs)
-    {
         dprintk(XENLOG_WARNING,
-                "CPU %u has different MCA capability (%x,%x,%x,%x,%x)"
+                "CPU %u has different MCA capability "
+                "(firstbank %d, extended MCE MSR %d%s%s%s)"
                 " than BSP, may cause undetermined result!!!\n",
-                smp_processor_id(), broadcast, ser, cmci, first, ext_num);
-    }
+                smp_processor_id(), first, ext_num,
+                CAP(broadcast, "BCAST"),
+                CAP(ser, "SER"),
+                CAP(cmci, "CMCI"));
+#undef CAP
 }
 
 static void intel_mce_post_reset(void)
-- 
2.10.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 03/12] xen/mce: add blank lines between non-fall-through switch case blocks
  2017-03-17  6:46 [PATCH v2 00/12] Add LMCE support Haozhong Zhang
  2017-03-17  6:46 ` [PATCH v2 01/12] xen/mce: switch bool_t/1/0 to bool/true/false Haozhong Zhang
  2017-03-17  6:46 ` [PATCH v2 02/12] x86/mce_intel: refine messages of MCA capabilities Haozhong Zhang
@ 2017-03-17  6:46 ` Haozhong Zhang
  2017-03-20 13:12   ` Jan Beulich
  2017-03-17  6:46 ` [PATCH v2 04/12] x86/mce: handle LMCE locally Haozhong Zhang
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-17  6:46 UTC (permalink / raw)
  To: xen-devel; +Cc: Haozhong Zhang, Jan Beulich, Andrew Cooper

Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/cpu/mcheck/mce.c       |  9 +++++++++
 xen/arch/x86/cpu/mcheck/mce.h       |  1 +
 xen/arch/x86/cpu/mcheck/mce_amd.c   |  4 ++++
 xen/arch/x86/cpu/mcheck/mce_intel.c |  6 ++++++
 xen/arch/x86/cpu/mcheck/vmce.c      | 18 ++++++++++++++++++
 5 files changed, 38 insertions(+)

diff --git a/xen/arch/x86/cpu/mcheck/mce.c b/xen/arch/x86/cpu/mcheck/mce.c
index df2e3a4..52b5e29 100644
--- a/xen/arch/x86/cpu/mcheck/mce.c
+++ b/xen/arch/x86/cpu/mcheck/mce.c
@@ -594,10 +594,12 @@ int show_mca_info(int inited, struct cpuinfo_x86 *c)
             printk("%s%s machine check reporting enabled\n",
                    prefix, type_str[inited]);
             break;
+
         case mcheck_amd_famXX:
             printk("%s%s Fam%xh machine check reporting enabled\n",
                    prefix, type_str[inited], c->x86);
             break;
+
         case mcheck_none:
             printk("%sNo machine check initialization\n", prefix);
             break;
@@ -703,10 +705,12 @@ static int cpu_callback(
     case CPU_UP_PREPARE:
         rc = cpu_bank_alloc(cpu);
         break;
+
     case CPU_UP_CANCELED:
     case CPU_DEAD:
         cpu_bank_free(cpu);
         break;
+
     default:
         break;
     }
@@ -1516,6 +1520,7 @@ long do_mca(XEN_GUEST_HANDLE_PARAM(xen_mc_t) u_xen_mc)
                 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_apic_vector )
                 ret = x86_mcerr(
@@ -1527,6 +1532,7 @@ long do_mca(XEN_GUEST_HANDLE_PARAM(xen_mc_t) u_xen_mc)
                 send_IPI_mask(cpumap, cmci_apic_vector);
             }
             break;
+
         default:
             ret = x86_mcerr("Wrong mca type\n", -EINVAL);
             break;
@@ -1673,16 +1679,19 @@ static int mce_delayed_action(mctelem_cookie_t mctc)
         x86_mcinfo_dump(mctelem_dataptr(mctc));
         panic("MCE: Software recovery failed for the UCR");
         break;
+
     case MCER_RECOVERED:
         dprintk(XENLOG_INFO, "MCE: Error is successfully recovered\n");
         ret  = 1;
         break;
+
     case MCER_CONTINUE:
         dprintk(XENLOG_INFO, "MCE: Error can't be recovered, "
             "system is tainted\n");
         x86_mcinfo_dump(mctelem_dataptr(mctc));
         ret = 1;
         break;
+
     default:
         ret = 0;
         break;
diff --git a/xen/arch/x86/cpu/mcheck/mce.h b/xen/arch/x86/cpu/mcheck/mce.h
index 7611789..32f85c7 100644
--- a/xen/arch/x86/cpu/mcheck/mce.h
+++ b/xen/arch/x86/cpu/mcheck/mce.h
@@ -158,6 +158,7 @@ static inline int mce_vendor_bank_msr(const struct vcpu *v, uint32_t msr)
             msr < MSR_IA32_MCx_CTL2(v->arch.vmce.mcg_cap & MCG_CAP_COUNT) )
             return 1;
         break;
+
     case X86_VENDOR_AMD:
         switch (msr) {
         case MSR_F10_MC4_MISC1:
diff --git a/xen/arch/x86/cpu/mcheck/mce_amd.c b/xen/arch/x86/cpu/mcheck/mce_amd.c
index c580a91..74e3473 100644
--- a/xen/arch/x86/cpu/mcheck/mce_amd.c
+++ b/xen/arch/x86/cpu/mcheck/mce_amd.c
@@ -121,9 +121,11 @@ mc_amd_recoverable_scan(uint64_t status)
     case MC_EC_BUS_TYPE: /* value in addr MSR is physical */
         /* should run cpu offline action */
         break;
+
     case MC_EC_MEM_TYPE: /* value in addr MSR is physical */
         ret = true; /* run memory page offline action */
         break;
+
     case MC_EC_TLB_TYPE: /* value in addr MSR is virtual */
         /* should run tlb flush action and retry */
         break;
@@ -146,6 +148,7 @@ mc_amd_addrcheck(uint64_t status, uint64_t misc, int addrtype)
     case MC_EC_BUS_TYPE: /* value in addr MSR is physical */
     case MC_EC_MEM_TYPE: /* value in addr MSR is physical */
         return (addrtype == MC_ADDR_PHYSICAL);
+
     case MC_EC_TLB_TYPE: /* value in addr MSR is virtual */
         return (addrtype == MC_ADDR_VIRTUAL);
     }
@@ -193,6 +196,7 @@ int mcequirk_amd_apply(enum mcequirk_amd_flags flags)
         wrmsrl(MSR_IA32_MCx_CTL(4), ~(1ULL << 10));
         wrmsrl(MSR_IA32_MCx_STATUS(4), 0ULL);
         break;
+
     case MCEQUIRK_F10_GART:
         if ( rdmsr_safe(MSR_AMD64_MCx_MASK(4), val) == 0 )
                 wrmsr_safe(MSR_AMD64_MCx_MASK(4), val | (1 << 10));
diff --git a/xen/arch/x86/cpu/mcheck/mce_intel.c b/xen/arch/x86/cpu/mcheck/mce_intel.c
index 48f41d6..fe927f6 100644
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c
@@ -302,6 +302,7 @@ static void intel_srar_dhandler(
     case INTEL_SRAR_INSTR_FETCH:
         intel_memerr_dhandler(binfo, result, regs);
         break;
+
     default:
         break;
     }
@@ -330,6 +331,7 @@ static void intel_srao_dhandler(
         case INTEL_SRAO_L3_EWB:
             intel_memerr_dhandler(binfo, result, regs);
             break;
+
         default:
             break;
         }
@@ -378,6 +380,7 @@ static void intel_default_mce_uhandler(
     case intel_mce_fatal:
         *result = MCER_RESET;
         break;
+
     default:
         *result = MCER_CONTINUE;
         break;
@@ -843,14 +846,17 @@ static int cpu_callback(
     case CPU_UP_PREPARE:
         rc = cpu_mcabank_alloc(cpu);
         break;
+
     case CPU_DYING:
         cpu_mcheck_disable();
         break;
+
     case CPU_UP_CANCELED:
     case CPU_DEAD:
         cpu_mcheck_distribute_cmci();
         cpu_mcabank_free(cpu);
         break;
+
     default:
         break;
     }
diff --git a/xen/arch/x86/cpu/mcheck/vmce.c b/xen/arch/x86/cpu/mcheck/vmce.c
index 01a5826..058bb91 100644
--- a/xen/arch/x86/cpu/mcheck/vmce.c
+++ b/xen/arch/x86/cpu/mcheck/vmce.c
@@ -113,6 +113,7 @@ static int bank_mce_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val)
         mce_printk(MCE_VERBOSE, "MCE: %pv: rd MC%u_CTL %#"PRIx64"\n",
                    v, bank, *val);
         break;
+
     case MSR_IA32_MC0_STATUS:
         if ( bank < GUEST_MC_BANK_NUM )
         {
@@ -122,6 +123,7 @@ static int bank_mce_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val)
                            v, bank, *val);
         }
         break;
+
     case MSR_IA32_MC0_ADDR:
         if ( bank < GUEST_MC_BANK_NUM )
         {
@@ -131,6 +133,7 @@ static int bank_mce_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val)
                            v, bank, *val);
         }
         break;
+
     case MSR_IA32_MC0_MISC:
         if ( bank < GUEST_MC_BANK_NUM )
         {
@@ -140,15 +143,18 @@ static int bank_mce_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val)
                            v, bank, *val);
         }
         break;
+
     default:
         switch ( boot_cpu_data.x86_vendor )
         {
         case X86_VENDOR_INTEL:
             ret = vmce_intel_rdmsr(v, msr, val);
             break;
+
         case X86_VENDOR_AMD:
             ret = vmce_amd_rdmsr(v, msr, val);
             break;
+
         default:
             ret = 0;
             break;
@@ -181,15 +187,18 @@ int vmce_rdmsr(uint32_t msr, uint64_t *val)
             mce_printk(MCE_VERBOSE,
                        "MCE: %pv: rd MCG_STATUS %#"PRIx64"\n", cur, *val);
         break;
+
     case MSR_IA32_MCG_CAP:
         *val = cur->arch.vmce.mcg_cap;
         mce_printk(MCE_VERBOSE, "MCE: %pv: rd MCG_CAP %#"PRIx64"\n", cur, *val);
         break;
+
     case MSR_IA32_MCG_CTL:
         if ( cur->arch.vmce.mcg_cap & MCG_CTL_P )
             *val = ~0ULL;
         mce_printk(MCE_VERBOSE, "MCE: %pv: rd MCG_CTL %#"PRIx64"\n", cur, *val);
         break;
+
     default:
         ret = mce_bank_msr(cur, msr) ? bank_mce_rdmsr(cur, msr, val) : 0;
         break;
@@ -217,6 +226,7 @@ static int bank_mce_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
          * treat it as not implement and ignore write change it.
          */
         break;
+
     case MSR_IA32_MC0_STATUS:
         mce_printk(MCE_VERBOSE, "MCE: %pv: wr MC%u_STATUS %#"PRIx64"\n",
                    v, bank, val);
@@ -225,6 +235,7 @@ static int bank_mce_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
         else if ( bank < GUEST_MC_BANK_NUM )
             v->arch.vmce.bank[bank].mci_status = val;
         break;
+
     case MSR_IA32_MC0_ADDR:
         mce_printk(MCE_VERBOSE, "MCE: %pv: wr MC%u_ADDR %#"PRIx64"\n",
                    v, bank, val);
@@ -233,6 +244,7 @@ static int bank_mce_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
         else if ( bank < GUEST_MC_BANK_NUM )
             v->arch.vmce.bank[bank].mci_addr = val;
         break;
+
     case MSR_IA32_MC0_MISC:
         mce_printk(MCE_VERBOSE, "MCE: %pv: wr MC%u_MISC %#"PRIx64"\n",
                    v, bank, val);
@@ -241,15 +253,18 @@ static int bank_mce_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
         else if ( bank < GUEST_MC_BANK_NUM )
             v->arch.vmce.bank[bank].mci_misc = val;
         break;
+
     default:
         switch ( boot_cpu_data.x86_vendor )
         {
         case X86_VENDOR_INTEL:
             ret = vmce_intel_wrmsr(v, msr, val);
             break;
+
         case X86_VENDOR_AMD:
             ret = vmce_amd_wrmsr(v, msr, val);
             break;
+
         default:
             ret = 0;
             break;
@@ -277,11 +292,13 @@ int vmce_wrmsr(uint32_t msr, uint64_t val)
     case MSR_IA32_MCG_CTL:
         /* If MCG_CTL exists then stick to all 1's, else ignore. */
         break;
+
     case MSR_IA32_MCG_STATUS:
         cur->arch.vmce.mcg_status = val;
         mce_printk(MCE_VERBOSE, "MCE: %pv: wr MCG_STATUS %"PRIx64"\n",
                    cur, val);
         break;
+
     case MSR_IA32_MCG_CAP:
         /*
          * According to Intel SDM, IA32_MCG_CAP is a read-only register,
@@ -290,6 +307,7 @@ int vmce_wrmsr(uint32_t msr, uint64_t val)
          */
         mce_printk(MCE_VERBOSE, "MCE: %pv: MCG_CAP is r/o\n", cur);
         break;
+
     default:
         ret = mce_bank_msr(cur, msr) ? bank_mce_wrmsr(cur, msr, val) : 0;
         break;
-- 
2.10.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 04/12] x86/mce: handle LMCE locally
  2017-03-17  6:46 [PATCH v2 00/12] Add LMCE support Haozhong Zhang
                   ` (2 preceding siblings ...)
  2017-03-17  6:46 ` [PATCH v2 03/12] xen/mce: add blank lines between non-fall-through switch case blocks Haozhong Zhang
@ 2017-03-17  6:46 ` Haozhong Zhang
  2017-03-20 14:24   ` Jan Beulich
  2017-03-17  6:46 ` [PATCH v2 05/12] x86/mce_intel: detect and enable LMCE on Intel host Haozhong Zhang
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-17  6:46 UTC (permalink / raw)
  To: xen-devel; +Cc: Haozhong Zhang, Jan Beulich, Andrew Cooper

LMCE is sent to only one CPU thread, so MCE handler, barriers and
softirq handler should go without waiting for other CPUs, when
handling LMCE. Note LMCE is still broadcast to all vcpus as regular
MCE on Intel CPU right now.

Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>

Changes in v2:
 * Use this_cpu() rather than __get_cpu_var().
 * Drop the per-cpu flag lmce_in_process.
 * Add parameter "bool nowait" to mce_barrier_enter/exit to let callers
   control mce_barrier_enter/exit needs to wait for barrier operations
   on other CPU's.
 * Introduce a new per-cpu flag mce_in_process to indicate whether a
   non-local MCE have not been processed completely. mce_softirq() uses
   this flag to decide whether it needs to synchronize with mce_softirq()
   on other CPU's.
---
 xen/arch/x86/cpu/mcheck/barrier.c  | 14 ++++++------
 xen/arch/x86/cpu/mcheck/barrier.h  | 14 +++++++++---
 xen/arch/x86/cpu/mcheck/mcaction.c |  4 +++-
 xen/arch/x86/cpu/mcheck/mce.c      | 44 +++++++++++++++++++++++++++-----------
 xen/arch/x86/cpu/mcheck/mce.h      |  2 ++
 xen/arch/x86/cpu/mcheck/x86_mca.h  |  4 +++-
 6 files changed, 57 insertions(+), 25 deletions(-)

diff --git a/xen/arch/x86/cpu/mcheck/barrier.c b/xen/arch/x86/cpu/mcheck/barrier.c
index 5dce1fb..e6f9ea2 100644
--- a/xen/arch/x86/cpu/mcheck/barrier.c
+++ b/xen/arch/x86/cpu/mcheck/barrier.c
@@ -16,11 +16,11 @@ void mce_barrier_dec(struct mce_softirq_barrier *bar)
     atomic_dec(&bar->val);
 }
 
-void mce_barrier_enter(struct mce_softirq_barrier *bar)
+void mce_barrier_enter(struct mce_softirq_barrier *bar, bool nowait)
 {
     int gen;
 
-    if (!mce_broadcast)
+    if ( !mce_broadcast || nowait )
         return;
     atomic_inc(&bar->ingen);
     gen = atomic_read(&bar->outgen);
@@ -34,11 +34,11 @@ void mce_barrier_enter(struct mce_softirq_barrier *bar)
     }
 }
 
-void mce_barrier_exit(struct mce_softirq_barrier *bar)
+void mce_barrier_exit(struct mce_softirq_barrier *bar, bool nowait)
 {
     int gen;
 
-    if ( !mce_broadcast )
+    if ( !mce_broadcast || nowait )
         return;
     atomic_inc(&bar->outgen);
     gen = atomic_read(&bar->ingen);
@@ -52,8 +52,8 @@ void mce_barrier_exit(struct mce_softirq_barrier *bar)
     }
 }
 
-void mce_barrier(struct mce_softirq_barrier *bar)
+void mce_barrier(struct mce_softirq_barrier *bar, bool nowait)
 {
-    mce_barrier_enter(bar);
-    mce_barrier_exit(bar);
+    mce_barrier_enter(bar, nowait);
+    mce_barrier_exit(bar, nowait);
 }
diff --git a/xen/arch/x86/cpu/mcheck/barrier.h b/xen/arch/x86/cpu/mcheck/barrier.h
index 87f7550..934b627 100644
--- a/xen/arch/x86/cpu/mcheck/barrier.h
+++ b/xen/arch/x86/cpu/mcheck/barrier.h
@@ -25,6 +25,14 @@ void mce_barrier_init(struct mce_softirq_barrier *);
 void mce_barrier_dec(struct mce_softirq_barrier *);
 
 /*
+ * If nowait is true, mce_barrier_enter/exit() will return immediately
+ * without touching the barrier. It's used when handling a LMCE which
+ * is received on only one CPU and thus does not invoke
+ * mce_barrier_enter/exit() calls on all CPUs.
+ *
+ * If nowait is false, mce_barrier_enter/exit() will handle the given
+ * barrier as below.
+ *
  * Increment the generation number and the value. The generation number
  * is incremented when entering a barrier. This way, it can be checked
  * on exit if a CPU is trying to re-enter the barrier. This can happen
@@ -36,9 +44,9 @@ void mce_barrier_dec(struct mce_softirq_barrier *);
  * These barrier functions should always be paired, so that the
  * counter value will reach 0 again after all CPUs have exited.
  */
-void mce_barrier_enter(struct mce_softirq_barrier *);
-void mce_barrier_exit(struct mce_softirq_barrier *);
+void mce_barrier_enter(struct mce_softirq_barrier *, bool nowait);
+void mce_barrier_exit(struct mce_softirq_barrier *, bool nowait);
 
-void mce_barrier(struct mce_softirq_barrier *);
+void mce_barrier(struct mce_softirq_barrier *, bool nowait);
 
 #endif /* _MCHECK_BARRIER_H */
diff --git a/xen/arch/x86/cpu/mcheck/mcaction.c b/xen/arch/x86/cpu/mcheck/mcaction.c
index dab9eac..ca17d22 100644
--- a/xen/arch/x86/cpu/mcheck/mcaction.c
+++ b/xen/arch/x86/cpu/mcheck/mcaction.c
@@ -96,7 +96,9 @@ mc_memerr_dhandler(struct mca_binfo *binfo,
 
                 bank->mc_addr = gfn << PAGE_SHIFT |
                   (bank->mc_addr & (PAGE_SIZE -1 ));
-                if (fill_vmsr_data(bank, d, global->mc_gstatus,
+                /* TODO: support injecting LMCE */
+                if (fill_vmsr_data(bank, d,
+                                   global->mc_gstatus & ~MCG_STATUS_LMCE,
                                    vmce_vcpuid == VMCE_INJECT_BROADCAST))
                 {
                     mce_printk(MCE_QUIET, "Fill vMCE# data for DOM%d "
diff --git a/xen/arch/x86/cpu/mcheck/mce.c b/xen/arch/x86/cpu/mcheck/mce.c
index 52b5e29..20ab678 100644
--- a/xen/arch/x86/cpu/mcheck/mce.c
+++ b/xen/arch/x86/cpu/mcheck/mce.c
@@ -42,6 +42,13 @@ DEFINE_PER_CPU_READ_MOSTLY(struct mca_banks *, poll_bankmask);
 DEFINE_PER_CPU_READ_MOSTLY(struct mca_banks *, no_cmci_banks);
 DEFINE_PER_CPU_READ_MOSTLY(struct mca_banks *, mce_clear_banks);
 
+/*
+ * Flag to indicate that at least one non-local MCE's on this CPU have
+ * not been completed handled. It's set by mcheck_cmn_handler() and
+ * cleared by mce_softirq().
+ */
+DEFINE_PER_CPU(bool, mce_in_process);
+
 static void intpose_init(void);
 static void mcinfo_clear(struct mc_info *);
 struct mca_banks *mca_allbanks;
@@ -396,6 +403,7 @@ mcheck_mca_logout(enum mca_source who, struct mca_banks *bankmask,
         sp->errcnt = errcnt;
         sp->ripv = (gstatus & MCG_STATUS_RIPV) != 0;
         sp->eipv = (gstatus & MCG_STATUS_EIPV) != 0;
+        sp->lmce = (gstatus & MCG_STATUS_LMCE) != 0;
         sp->uc = uc;
         sp->pcc = pcc;
         sp->recoverable = recover;
@@ -459,6 +467,7 @@ void mcheck_cmn_handler(const struct cpu_user_regs *regs)
     uint64_t gstatus;
     mctelem_cookie_t mctc = NULL;
     struct mca_summary bs;
+    bool lmce;
 
     mce_spin_lock(&mce_logout_lock);
 
@@ -502,15 +511,19 @@ void mcheck_cmn_handler(const struct cpu_user_regs *regs)
     }
     mce_spin_unlock(&mce_logout_lock);
 
-    mce_barrier_enter(&mce_trap_bar);
+    lmce = bs.lmce;
+    if ( !lmce )
+        this_cpu(mce_in_process) = true;
+
+    mce_barrier_enter(&mce_trap_bar, lmce);
     if ( mctc != NULL && mce_urgent_action(regs, mctc))
         cpumask_set_cpu(smp_processor_id(), &mce_fatal_cpus);
-    mce_barrier_exit(&mce_trap_bar);
+    mce_barrier_exit(&mce_trap_bar, lmce);
 
     /*
      * Wait until everybody has processed the trap.
      */
-    mce_barrier_enter(&mce_trap_bar);
+    mce_barrier_enter(&mce_trap_bar, lmce);
     if (atomic_read(&severity_cpu) == smp_processor_id())
     {
         /* According to SDM, if no error bank found on any cpus,
@@ -528,16 +541,16 @@ void mcheck_cmn_handler(const struct cpu_user_regs *regs)
         }
         atomic_set(&found_error, 0);
     }
-    mce_barrier_exit(&mce_trap_bar);
+    mce_barrier_exit(&mce_trap_bar, lmce);
 
     /* Clear flags after above fatal check */
-    mce_barrier_enter(&mce_trap_bar);
+    mce_barrier_enter(&mce_trap_bar, lmce);
     gstatus = mca_rdmsr(MSR_IA32_MCG_STATUS);
     if ((gstatus & MCG_STATUS_MCIP) != 0) {
         mce_printk(MCE_CRITICAL, "MCE: Clear MCIP@ last step");
         mca_wrmsr(MSR_IA32_MCG_STATUS, 0);
     }
-    mce_barrier_exit(&mce_trap_bar);
+    mce_barrier_exit(&mce_trap_bar, lmce);
 
     raise_softirq(MACHINE_CHECK_SOFTIRQ);
 }
@@ -1704,10 +1717,11 @@ static void mce_softirq(void)
 {
     int cpu = smp_processor_id();
     unsigned int workcpu;
+    bool nowait = !this_cpu(mce_in_process);
 
     mce_printk(MCE_VERBOSE, "CPU%d enter softirq\n", cpu);
 
-    mce_barrier_enter(&mce_inside_bar);
+    mce_barrier_enter(&mce_inside_bar, nowait);
 
     /*
      * Everybody is here. Now let's see who gets to do the
@@ -1720,10 +1734,10 @@ static void mce_softirq(void)
 
     atomic_set(&severity_cpu, cpu);
 
-    mce_barrier_enter(&mce_severity_bar);
+    mce_barrier_enter(&mce_severity_bar, nowait);
     if (!mctelem_has_deferred(cpu))
         atomic_set(&severity_cpu, cpu);
-    mce_barrier_exit(&mce_severity_bar);
+    mce_barrier_exit(&mce_severity_bar, nowait);
 
     /* We choose severity_cpu for further processing */
     if (atomic_read(&severity_cpu) == cpu) {
@@ -1733,9 +1747,11 @@ static void mce_softirq(void)
         /* Step1: Fill DOM0 LOG buffer, vMCE injection buffer and
          * vMCE MSRs virtualization buffer
          */
-        for_each_online_cpu(workcpu) {
-            mctelem_process_deferred(workcpu, mce_delayed_action);
-        }
+        if (nowait)
+            mctelem_process_deferred(cpu, mce_delayed_action);
+        else
+            for_each_online_cpu(workcpu)
+                mctelem_process_deferred(workcpu, mce_delayed_action);
 
         /* Step2: Send Log to DOM0 through vIRQ */
         if (dom0_vmce_enabled()) {
@@ -1744,7 +1760,9 @@ static void mce_softirq(void)
         }
     }
 
-    mce_barrier_exit(&mce_inside_bar);
+    mce_barrier_exit(&mce_inside_bar, nowait);
+
+    this_cpu(mce_in_process) = false;
 }
 
 /* Machine Check owner judge algorithm:
diff --git a/xen/arch/x86/cpu/mcheck/mce.h b/xen/arch/x86/cpu/mcheck/mce.h
index 32f85c7..9347eb9 100644
--- a/xen/arch/x86/cpu/mcheck/mce.h
+++ b/xen/arch/x86/cpu/mcheck/mce.h
@@ -109,12 +109,14 @@ struct mca_summary {
     int         eipv;   /* meaningful on #MC */
     bool        uc;     /* UC flag */
     bool        pcc;    /* PCC flag */
+    bool        lmce;   /* LMCE flag (Intel only) */
     bool        recoverable; /* software error recoverable flag */
 };
 
 DECLARE_PER_CPU(struct mca_banks *, poll_bankmask);
 DECLARE_PER_CPU(struct mca_banks *, no_cmci_banks);
 DECLARE_PER_CPU(struct mca_banks *, mce_clear_banks);
+DECLARE_PER_CPU(bool, mce_in_process);
 
 extern bool cmci_support;
 extern bool is_mc_panic;
diff --git a/xen/arch/x86/cpu/mcheck/x86_mca.h b/xen/arch/x86/cpu/mcheck/x86_mca.h
index 34d1921..de03f82 100644
--- a/xen/arch/x86/cpu/mcheck/x86_mca.h
+++ b/xen/arch/x86/cpu/mcheck/x86_mca.h
@@ -42,7 +42,9 @@
 #define MCG_STATUS_RIPV         0x0000000000000001ULL
 #define MCG_STATUS_EIPV         0x0000000000000002ULL
 #define MCG_STATUS_MCIP         0x0000000000000004ULL
-/* Bits 3-63 are reserved */
+#define MCG_STATUS_LMCE         0x0000000000000008ULL  /* Intel specific */
+/* Bits 3-63 are reserved on CPU not supporting LMCE */
+/* Bits 4-63 are reserved on CPU supporting LMCE */
 
 /* Bitfield of MSR_K8_MCi_STATUS registers */
 /* MCA error code */
-- 
2.10.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 05/12] x86/mce_intel: detect and enable LMCE on Intel host
  2017-03-17  6:46 [PATCH v2 00/12] Add LMCE support Haozhong Zhang
                   ` (3 preceding siblings ...)
  2017-03-17  6:46 ` [PATCH v2 04/12] x86/mce: handle LMCE locally Haozhong Zhang
@ 2017-03-17  6:46 ` Haozhong Zhang
  2017-03-20 14:30   ` Jan Beulich
  2017-03-17  6:46 ` [PATCH v2 06/12] x86/vmx: expose LMCE feature via guest MSR_IA32_FEATURE_CONTROL Haozhong Zhang
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-17  6:46 UTC (permalink / raw)
  To: xen-devel; +Cc: Haozhong Zhang, Jan Beulich, Andrew Cooper

Enable LMCE if it's supported by the host CPU. If Xen boot parameter
"mce_fb = 1" is present, LMCE will be disabled forcibly.

Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>

Changes in v2:
 * (By patch 1) Convert all bool_t to bool, and use true and false.
 * Fix the check of MSR_IA32_FEATURE_CONTROL in intel_enable_lmce().
 * (By patch 2) Adjust the output messages of MCA capabilities.
 * For additions in existing function, use the coding style around.
   For new added functions, use the coding style of Xen hypervisor.
---
 xen/arch/x86/cpu/mcheck/mce.h       |  1 +
 xen/arch/x86/cpu/mcheck/mce_intel.c | 46 ++++++++++++++++++++++++++++++++-----
 xen/arch/x86/cpu/mcheck/x86_mca.h   |  5 ++++
 xen/include/asm-x86/msr-index.h     |  2 ++
 4 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/xen/arch/x86/cpu/mcheck/mce.h b/xen/arch/x86/cpu/mcheck/mce.h
index 9347eb9..ec58a91 100644
--- a/xen/arch/x86/cpu/mcheck/mce.h
+++ b/xen/arch/x86/cpu/mcheck/mce.h
@@ -38,6 +38,7 @@ enum mcheck_type {
 };
 
 extern uint8_t cmci_apic_vector;
+extern bool lmce_support;
 
 /* Init functions */
 enum mcheck_type amd_mcheck_init(struct cpuinfo_x86 *c);
diff --git a/xen/arch/x86/cpu/mcheck/mce_intel.c b/xen/arch/x86/cpu/mcheck/mce_intel.c
index fe927f6..f8cf5e6 100644
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c
@@ -29,6 +29,9 @@ boolean_param("mce_fb", mce_force_broadcast);
 
 static int __read_mostly nr_intel_ext_msrs;
 
+/* If mce_force_broadcast == 1, lmce_support will be disabled forcibly. */
+bool __read_mostly lmce_support;
+
 /* Intel SDM define bit15~bit0 of IA32_MCi_STATUS as the MC error code */
 #define INTEL_MCCOD_MASK 0xFFFF
 
@@ -704,10 +707,34 @@ static bool mce_is_broadcast(struct cpuinfo_x86 *c)
     return false;
 }
 
+static bool intel_enable_lmce(void)
+{
+    uint64_t msr_content;
+
+    /*
+     * Section "Enabling Local Machine Check" in Intel SDM Vol 3
+     * requires software must ensure the LOCK bit and LMCE_ON bit
+     * of MSR_IA32_FEATURE_CONTROL are set before setting
+     * MSR_IA32_MCG_EXT_CTL.LMCE_EN.
+     */
+
+    if ( rdmsr_safe(MSR_IA32_FEATURE_CONTROL, msr_content) )
+        return false;
+
+    if ( (msr_content & IA32_FEATURE_CONTROL_LOCK) &&
+         (msr_content & IA32_FEATURE_CONTROL_LMCE_ON) )
+    {
+        wrmsrl(MSR_IA32_MCG_EXT_CTL, MCG_EXT_CTL_LMCE_EN);
+        return true;
+    }
+
+    return false;
+}
+
 /* Check and init MCA */
 static void intel_init_mca(struct cpuinfo_x86 *c)
 {
-    bool broadcast, cmci = false, ser = false;
+    bool broadcast, cmci = false, ser = false, lmce = false;
     int ext_num = 0, first;
     uint64_t msr_content;
 
@@ -727,33 +754,40 @@ static void intel_init_mca(struct cpuinfo_x86 *c)
 
     first = mce_firstbank(c);
 
+    if (!mce_force_broadcast && (msr_content & MCG_LMCE_P))
+        lmce = intel_enable_lmce();
+
 #define CAP(enabled, name) ((enabled) ? ", "name : "")
     if (smp_processor_id() == 0)
     {
         dprintk(XENLOG_INFO,
-                "MCA Capability: firstbank %d, extended MCE MSR %d%s%s%s\n",
+                "MCA Capability: firstbank %d, extended MCE MSR %d%s%s%s%s\n",
                 first, ext_num,
                 CAP(broadcast, "BCAST"),
                 CAP(ser, "SER"),
-                CAP(cmci, "CMCI"));
+                CAP(cmci, "CMCI"),
+                CAP(lmce, "LMCE"));
 
         mce_broadcast = broadcast;
         cmci_support = cmci;
         ser_support = ser;
+        lmce_support = lmce;
         nr_intel_ext_msrs = ext_num;
         firstbank = first;
     }
     else if (cmci != cmci_support || ser != ser_support ||
              broadcast != mce_broadcast ||
-             first != firstbank || ext_num != nr_intel_ext_msrs)
+             first != firstbank || ext_num != nr_intel_ext_msrs ||
+             lmce != lmce_support)
         dprintk(XENLOG_WARNING,
                 "CPU %u has different MCA capability "
-                "(firstbank %d, extended MCE MSR %d%s%s%s)"
+                "(firstbank %d, extended MCE MSR %d%s%s%s%s)"
                 " than BSP, may cause undetermined result!!!\n",
                 smp_processor_id(), first, ext_num,
                 CAP(broadcast, "BCAST"),
                 CAP(ser, "SER"),
-                CAP(cmci, "CMCI"));
+                CAP(cmci, "CMCI"),
+                CAP(lmce, "LMCE"));
 #undef CAP
 }
 
diff --git a/xen/arch/x86/cpu/mcheck/x86_mca.h b/xen/arch/x86/cpu/mcheck/x86_mca.h
index de03f82..0f87bcf 100644
--- a/xen/arch/x86/cpu/mcheck/x86_mca.h
+++ b/xen/arch/x86/cpu/mcheck/x86_mca.h
@@ -36,6 +36,7 @@
 #define MCG_TES_P               (1ULL<<11) /* Intel specific */
 #define MCG_EXT_CNT             16         /* Intel specific */
 #define MCG_SER_P               (1ULL<<24) /* Intel specific */
+#define MCG_LMCE_P              (1ULL<<27) /* Intel specific */
 /* Other bits are reserved */
 
 /* Bitfield of the MSR_IA32_MCG_STATUS register */
@@ -46,6 +47,10 @@
 /* Bits 3-63 are reserved on CPU not supporting LMCE */
 /* Bits 4-63 are reserved on CPU supporting LMCE */
 
+/* Bitfield of MSR_IA32_MCG_EXT_CTL register (Intel Specific) */
+#define MCG_EXT_CTL_LMCE_EN     (1ULL<<0)
+/* Other bits are reserved */
+
 /* Bitfield of MSR_K8_MCi_STATUS registers */
 /* MCA error code */
 #define MCi_STATUS_MCA          0x000000000000ffffULL
diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
index 771e750..756b23d 100644
--- a/xen/include/asm-x86/msr-index.h
+++ b/xen/include/asm-x86/msr-index.h
@@ -51,6 +51,7 @@
 #define MSR_IA32_MCG_CAP		0x00000179
 #define MSR_IA32_MCG_STATUS		0x0000017a
 #define MSR_IA32_MCG_CTL		0x0000017b
+#define MSR_IA32_MCG_EXT_CTL	0x000004d0
 
 #define MSR_IA32_PEBS_ENABLE		0x000003f1
 #define MSR_IA32_DS_AREA		0x00000600
@@ -296,6 +297,7 @@
 #define IA32_FEATURE_CONTROL_SENTER_PARAM_CTL         0x7f00
 #define IA32_FEATURE_CONTROL_ENABLE_SENTER            0x8000
 #define IA32_FEATURE_CONTROL_SGX_ENABLE               0x40000
+#define IA32_FEATURE_CONTROL_LMCE_ON                  0x100000
 
 #define MSR_IA32_TSC_ADJUST		0x0000003b
 
-- 
2.10.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 06/12] x86/vmx: expose LMCE feature via guest MSR_IA32_FEATURE_CONTROL
  2017-03-17  6:46 [PATCH v2 00/12] Add LMCE support Haozhong Zhang
                   ` (4 preceding siblings ...)
  2017-03-17  6:46 ` [PATCH v2 05/12] x86/mce_intel: detect and enable LMCE on Intel host Haozhong Zhang
@ 2017-03-17  6:46 ` Haozhong Zhang
  2017-03-20 16:10   ` Jan Beulich
  2017-03-17  6:46 ` [PATCH v2 07/12] x86/vmce: emulate MSR_IA32_MCG_EXT_CTL Haozhong Zhang
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-17  6:46 UTC (permalink / raw)
  To: xen-devel
  Cc: Haozhong Zhang, Kevin Tian, Jun Nakajima, Jan Beulich, Andrew Cooper

If MCG_LMCE_P is present in guest MSR_IA32_MCG_CAP, then set LMCE and
LOCK bits in guest MSR_IA32_FEATURE_CONTROL. Intel SDM requires those
bits are set before SW can enable LMCE.

Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Jun Nakajima <jun.nakajima@intel.com>
Cc: Kevin Tian <kevin.tian@intel.com>

Changes in v2:
 * Remove unnecessary !! in vmce_support_lmce().
 * Rename "struct vcpu *v" to "struct vcpu *curr" in vmx_msr_read_intercept().
 * Remove the duplicated neseted VMX check in vmx_msr_read_intercept().
---
 xen/arch/x86/cpu/mcheck/mce_intel.c | 4 ++++
 xen/arch/x86/hvm/vmx/vmx.c          | 9 +++++++++
 xen/arch/x86/hvm/vmx/vvmx.c         | 4 ----
 xen/include/asm-x86/mce.h           | 1 +
 4 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/cpu/mcheck/mce_intel.c b/xen/arch/x86/cpu/mcheck/mce_intel.c
index f8cf5e6..bf0e8ff 100644
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c
@@ -955,3 +955,7 @@ int vmce_intel_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val)
     return 1;
 }
 
+bool vmce_support_lmce(const struct vcpu *v)
+{
+    return v->arch.vmce.mcg_cap & MCG_LMCE_P;
+}
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 894d7d4..301fda0 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -55,6 +55,7 @@
 #include <asm/hvm/nestedhvm.h>
 #include <asm/altp2m.h>
 #include <asm/event.h>
+#include <asm/mce.h>
 #include <asm/monitor.h>
 #include <public/arch-x86/cpuid.h>
 
@@ -2753,6 +2754,8 @@ static int is_last_branch_msr(u32 ecx)
 
 static int vmx_msr_read_intercept(unsigned int msr, uint64_t *msr_content)
 {
+    struct vcpu *curr = current;
+
     HVM_DBG_LOG(DBG_LEVEL_MSR, "ecx=%#x", msr);
 
     switch ( msr )
@@ -2770,6 +2773,12 @@ static int vmx_msr_read_intercept(unsigned int msr, uint64_t *msr_content)
         __vmread(GUEST_IA32_DEBUGCTL, msr_content);
         break;
     case MSR_IA32_FEATURE_CONTROL:
+        *msr_content = IA32_FEATURE_CONTROL_LOCK;
+        if ( vmce_support_lmce(curr) )
+            *msr_content |= IA32_FEATURE_CONTROL_LMCE_ON;
+        if ( nestedhvm_enabled(curr->domain) )
+            *msr_content |= IA32_FEATURE_CONTROL_ENABLE_VMXON_OUTSIDE_SMX;
+        break;
     case MSR_IA32_VMX_BASIC...MSR_IA32_VMX_VMFUNC:
         if ( !nvmx_msr_read_intercept(msr, msr_content) )
             goto gp_fault;
diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c
index e2c0951..4aa70ef 100644
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -2068,10 +2068,6 @@ int nvmx_msr_read_intercept(unsigned int msr, u64 *msr_content)
         data = gen_vmx_msr(data, VMX_ENTRY_CTLS_DEFAULT1, host_data);
         break;
 
-    case MSR_IA32_FEATURE_CONTROL:
-        data = IA32_FEATURE_CONTROL_LOCK |
-               IA32_FEATURE_CONTROL_ENABLE_VMXON_OUTSIDE_SMX;
-        break;
     case MSR_IA32_VMX_VMCS_ENUM:
         /* The max index of VVMCS encoding is 0x1f. */
         data = 0x1f << 1;
diff --git a/xen/include/asm-x86/mce.h b/xen/include/asm-x86/mce.h
index 549bef3..6b827ef 100644
--- a/xen/include/asm-x86/mce.h
+++ b/xen/include/asm-x86/mce.h
@@ -36,6 +36,7 @@ extern void vmce_init_vcpu(struct vcpu *);
 extern int vmce_restore_vcpu(struct vcpu *, const struct hvm_vmce_vcpu *);
 extern int vmce_wrmsr(uint32_t msr, uint64_t val);
 extern int vmce_rdmsr(uint32_t msr, uint64_t *val);
+extern bool vmce_support_lmce(const struct vcpu *v);
 
 extern unsigned int nr_mce_banks;
 
-- 
2.10.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 07/12] x86/vmce: emulate MSR_IA32_MCG_EXT_CTL
  2017-03-17  6:46 [PATCH v2 00/12] Add LMCE support Haozhong Zhang
                   ` (5 preceding siblings ...)
  2017-03-17  6:46 ` [PATCH v2 06/12] x86/vmx: expose LMCE feature via guest MSR_IA32_FEATURE_CONTROL Haozhong Zhang
@ 2017-03-17  6:46 ` Haozhong Zhang
  2017-03-20 16:17   ` Jan Beulich
  2017-03-17  6:46 ` [PATCH v2 08/12] x86/vmce: enable injecting LMCE to guest on Intel host Haozhong Zhang
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-17  6:46 UTC (permalink / raw)
  To: xen-devel; +Cc: Haozhong Zhang, Jan Beulich, Andrew Cooper

If MCG_LMCE_P is present in guest MSR_IA32_MCG_CAP, then allow guest
to read/write MSR_IA32_MCG_EXT_CTL.

Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>

Changes in v2:
 * Remove stray blank in the code comment.
 * Move the success branch to the front when handling MSR_IA32_MCG_EXT_CTL.
 * Move lmce_enabled before bank[] in struct vmce.
 * Increase XEN_DOMCTL_INTERFACE_VERSION by 1.
---
 xen/arch/x86/cpu/mcheck/vmce.c         | 34 +++++++++++++++++++++++++++++++++-
 xen/include/asm-x86/mce.h              |  1 +
 xen/include/public/arch-x86/hvm/save.h |  2 ++
 xen/include/public/domctl.h            |  2 +-
 4 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/cpu/mcheck/vmce.c b/xen/arch/x86/cpu/mcheck/vmce.c
index 058bb91..c396d07 100644
--- a/xen/arch/x86/cpu/mcheck/vmce.c
+++ b/xen/arch/x86/cpu/mcheck/vmce.c
@@ -90,6 +90,7 @@ int vmce_restore_vcpu(struct vcpu *v, const struct hvm_vmce_vcpu *ctxt)
     v->arch.vmce.mcg_cap = ctxt->caps;
     v->arch.vmce.bank[0].mci_ctl2 = ctxt->mci_ctl2_bank0;
     v->arch.vmce.bank[1].mci_ctl2 = ctxt->mci_ctl2_bank1;
+    v->arch.vmce.lmce_enabled = ctxt->lmce_enabled;
 
     return 0;
 }
@@ -199,6 +200,26 @@ int vmce_rdmsr(uint32_t msr, uint64_t *val)
         mce_printk(MCE_VERBOSE, "MCE: %pv: rd MCG_CTL %#"PRIx64"\n", cur, *val);
         break;
 
+    case MSR_IA32_MCG_EXT_CTL:
+        /*
+         * If MCG_LMCE_P is present in guest MSR_IA32_MCG_CAP, the LMCE and LOCK
+         * bits are always set in guest MSR_IA32_FEATURE_CONTROL by Xen, so it
+         * does not need to check them here.
+         */
+        if ( cur->arch.vmce.mcg_cap & MCG_LMCE_P )
+        {
+            *val = cur->arch.vmce.lmce_enabled ? MCG_EXT_CTL_LMCE_EN : 0;
+            mce_printk(MCE_VERBOSE, "MCE: %pv: rd MCG_EXT_CTL %#"PRIx64"\n",
+                       cur, *val);
+        }
+        else
+        {
+            ret = -1;
+            mce_printk(MCE_VERBOSE, "MCE: %pv: rd MCG_EXT_CTL, not supported\n",
+                       cur);
+        }
+        break;
+
     default:
         ret = mce_bank_msr(cur, msr) ? bank_mce_rdmsr(cur, msr, val) : 0;
         break;
@@ -308,6 +329,16 @@ int vmce_wrmsr(uint32_t msr, uint64_t val)
         mce_printk(MCE_VERBOSE, "MCE: %pv: MCG_CAP is r/o\n", cur);
         break;
 
+    case MSR_IA32_MCG_EXT_CTL:
+        if ( (cur->arch.vmce.mcg_cap & MCG_LMCE_P) &&
+             !(val & ~MCG_EXT_CTL_LMCE_EN) )
+            cur->arch.vmce.lmce_enabled = (val & MCG_EXT_CTL_LMCE_EN);
+        else
+            ret = -1;
+        mce_printk(MCE_VERBOSE, "MCE: %pv: wr MCG_EXT_CTL %"PRIx64"%s\n",
+                   cur, val, (ret == -1) ? ", not supported" : "");
+        break;
+
     default:
         ret = mce_bank_msr(cur, msr) ? bank_mce_wrmsr(cur, msr, val) : 0;
         break;
@@ -326,7 +357,8 @@ static int vmce_save_vcpu_ctxt(struct domain *d, hvm_domain_context_t *h)
         struct hvm_vmce_vcpu ctxt = {
             .caps = v->arch.vmce.mcg_cap,
             .mci_ctl2_bank0 = v->arch.vmce.bank[0].mci_ctl2,
-            .mci_ctl2_bank1 = v->arch.vmce.bank[1].mci_ctl2
+            .mci_ctl2_bank1 = v->arch.vmce.bank[1].mci_ctl2,
+            .lmce_enabled = v->arch.vmce.lmce_enabled,
         };
 
         err = hvm_save_entry(VMCE_VCPU, v->vcpu_id, h, &ctxt);
diff --git a/xen/include/asm-x86/mce.h b/xen/include/asm-x86/mce.h
index 6b827ef..dee66b3 100644
--- a/xen/include/asm-x86/mce.h
+++ b/xen/include/asm-x86/mce.h
@@ -28,6 +28,7 @@ struct vmce {
     uint64_t mcg_cap;
     uint64_t mcg_status;
     spinlock_t lock;
+    bool lmce_enabled; /* guest MSR_IA32_MCG_EXT_CTL.LMCE_EN (bit 0) */
     struct vmce_bank bank[GUEST_MC_BANK_NUM];
 };
 
diff --git a/xen/include/public/arch-x86/hvm/save.h b/xen/include/public/arch-x86/hvm/save.h
index 419a3b2..76374fc 100644
--- a/xen/include/public/arch-x86/hvm/save.h
+++ b/xen/include/public/arch-x86/hvm/save.h
@@ -599,6 +599,8 @@ struct hvm_vmce_vcpu {
     uint64_t caps;
     uint64_t mci_ctl2_bank0;
     uint64_t mci_ctl2_bank1;
+    uint8_t  lmce_enabled;
+    uint8_t  pad[7];
 };
 
 DECLARE_HVM_SAVE_TYPE(VMCE_VCPU, 18, struct hvm_vmce_vcpu);
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 85cbb7c..2842589 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -37,7 +37,7 @@
 #include "hvm/save.h"
 #include "memory.h"
 
-#define XEN_DOMCTL_INTERFACE_VERSION 0x0000000c
+#define XEN_DOMCTL_INTERFACE_VERSION 0x0000000d
 
 /*
  * NB. xen_domctl.domain is an IN/OUT parameter for this operation.
-- 
2.10.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 08/12] x86/vmce: enable injecting LMCE to guest on Intel host
  2017-03-17  6:46 [PATCH v2 00/12] Add LMCE support Haozhong Zhang
                   ` (6 preceding siblings ...)
  2017-03-17  6:46 ` [PATCH v2 07/12] x86/vmce: emulate MSR_IA32_MCG_EXT_CTL Haozhong Zhang
@ 2017-03-17  6:46 ` Haozhong Zhang
  2017-03-20 16:25   ` Jan Beulich
  2017-03-17  6:46 ` [PATCH v2 09/12] x86/vmce, tools/libxl: expose LMCE capability in guest MSR_IA32_MCG_CAP Haozhong Zhang
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-17  6:46 UTC (permalink / raw)
  To: xen-devel; +Cc: Haozhong Zhang, Jan Beulich, Andrew Cooper

Inject LMCE to guest if the host MCE is LMCE and the affected vcpu is
known. Otherwise, broadcast MCE to all vcpus on Intel host.

Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>

Changes in v2:
 * Add comment for a check in mc_memerr_dhandler().
 * Add an ASSERT for vmce_vcpuid in fill_vmsr_data().
 * Combine two if branches about "broadcast".
---
 xen/arch/x86/cpu/mcheck/mcaction.c | 26 ++++++++++++++++++++------
 xen/arch/x86/cpu/mcheck/vmce.c     | 11 ++++++++++-
 xen/arch/x86/cpu/mcheck/vmce.h     |  2 +-
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/xen/arch/x86/cpu/mcheck/mcaction.c b/xen/arch/x86/cpu/mcheck/mcaction.c
index ca17d22..f245356 100644
--- a/xen/arch/x86/cpu/mcheck/mcaction.c
+++ b/xen/arch/x86/cpu/mcheck/mcaction.c
@@ -44,6 +44,7 @@ mc_memerr_dhandler(struct mca_binfo *binfo,
     unsigned long mfn, gfn;
     uint32_t status;
     int vmce_vcpuid;
+    uint16_t mc_vcpuid;
 
     if (!mc_check_addr(bank->mc_status, bank->mc_misc, MC_ADDR_PHYSICAL)) {
         dprintk(XENLOG_WARNING,
@@ -88,18 +89,31 @@ mc_memerr_dhandler(struct mca_binfo *binfo,
                     goto vmce_failed;
                 }
 
-                if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ||
-                    global->mc_vcpuid == XEN_MC_VCPUID_INVALID)
+                mc_vcpuid = global->mc_vcpuid;
+                if (mc_vcpuid == XEN_MC_VCPUID_INVALID ||
+                    (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
+                     (!(global->mc_gstatus & MCG_STATUS_LMCE) ||
+                      !(d->vcpu[mc_vcpuid]->arch.vmce.lmce_enabled) ||
+                      /*
+                       * The following check serves for MCE injection
+                       * test, i.e. xen-mceinj. xen-mceinj may specify
+                       * the target domain (i.e. bank->mc_domid) and
+                       * target CPU, but it's hard for xen-mceinj to
+                       * ensure, when Xen prepares the actual
+                       * injection in this function, vCPU currently
+                       * running on the target CPU belongs to the
+                       * target domain. If such inconsistency does
+                       * happen, fallback to broadcast.
+                       */
+                      global->mc_domid != bank->mc_domid)))
                     vmce_vcpuid = VMCE_INJECT_BROADCAST;
                 else
-                    vmce_vcpuid = global->mc_vcpuid;
+                    vmce_vcpuid = mc_vcpuid;
 
                 bank->mc_addr = gfn << PAGE_SHIFT |
                   (bank->mc_addr & (PAGE_SIZE -1 ));
                 /* TODO: support injecting LMCE */
-                if (fill_vmsr_data(bank, d,
-                                   global->mc_gstatus & ~MCG_STATUS_LMCE,
-                                   vmce_vcpuid == VMCE_INJECT_BROADCAST))
+                if (fill_vmsr_data(bank, d, global->mc_gstatus, vmce_vcpuid))
                 {
                     mce_printk(MCE_QUIET, "Fill vMCE# data for DOM%d "
                       "failed\n", bank->mc_domid);
diff --git a/xen/arch/x86/cpu/mcheck/vmce.c b/xen/arch/x86/cpu/mcheck/vmce.c
index c396d07..994a50e 100644
--- a/xen/arch/x86/cpu/mcheck/vmce.c
+++ b/xen/arch/x86/cpu/mcheck/vmce.c
@@ -464,14 +464,23 @@ static int vcpu_fill_mc_msrs(struct vcpu *v, uint64_t mcg_status,
 }
 
 int fill_vmsr_data(struct mcinfo_bank *mc_bank, struct domain *d,
-                   uint64_t gstatus, bool broadcast)
+                   uint64_t gstatus, int vmce_vcpuid)
 {
     struct vcpu *v = d->vcpu[0];
+    bool broadcast = (vmce_vcpuid == VMCE_INJECT_BROADCAST);
     int ret, err;
 
     if ( mc_bank->mc_domid == DOMID_INVALID )
         return -EINVAL;
 
+    if ( broadcast )
+        gstatus &= ~MCG_STATUS_LMCE;
+    else if ( gstatus & MCG_STATUS_LMCE )
+    {
+        ASSERT(vmce_vcpuid >=0 && vmce_vcpuid < d->max_vcpus);
+        v = d->vcpu[vmce_vcpuid];
+    }
+
     /*
      * vMCE with the actual error information is injected to vCPU0,
      * and, if broadcast is required, we choose to inject less severe
diff --git a/xen/arch/x86/cpu/mcheck/vmce.h b/xen/arch/x86/cpu/mcheck/vmce.h
index 74f6381..2797e00 100644
--- a/xen/arch/x86/cpu/mcheck/vmce.h
+++ b/xen/arch/x86/cpu/mcheck/vmce.h
@@ -17,7 +17,7 @@ int vmce_amd_rdmsr(const struct vcpu *, uint32_t msr, uint64_t *val);
 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, bool broadcast);
+                   uint64_t gstatus, int vmce_vcpuid);
 
 #define VMCE_INJECT_BROADCAST (-1)
 int inject_vmce(struct domain *d, int vcpu);
-- 
2.10.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 09/12] x86/vmce, tools/libxl: expose LMCE capability in guest MSR_IA32_MCG_CAP
  2017-03-17  6:46 [PATCH v2 00/12] Add LMCE support Haozhong Zhang
                   ` (7 preceding siblings ...)
  2017-03-17  6:46 ` [PATCH v2 08/12] x86/vmce: enable injecting LMCE to guest on Intel host Haozhong Zhang
@ 2017-03-17  6:46 ` Haozhong Zhang
  2017-03-20 16:33   ` Jan Beulich
                     ` (2 more replies)
  2017-03-17  6:46 ` [PATCH v2 10/12] xen/mce: add support of vLMCE injection to XEN_MC_inject_v2 Haozhong Zhang
                   ` (2 subsequent siblings)
  11 siblings, 3 replies; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-17  6:46 UTC (permalink / raw)
  To: xen-devel
  Cc: Haozhong Zhang, Ian Jackson, Wei Liu, Jan Beulich, Andrew Cooper

If LMCE is supported by host and ' mca_caps = [ "lmce" ] ' is present
in xl config, the LMCE capability will be exposed in guest MSR_IA32_MCG_CAP.
By default, LMCE is not exposed to guest so as to keep the backwards migration
compatibility.

Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>

Changes in v2:
 * Allow restore an LMCE enabled guest on an LMCE-incapable host.
 * Change xl config to "mca_caps = [ "lmce" ]", which can be extended to
   support other MCA capabilities in the future.
---
 docs/man/xl.cfg.pod.5.in        | 24 ++++++++++++++++++++++++
 tools/libxl/libxl_dom.c         | 30 ++++++++++++++++++++++++++++++
 tools/libxl/libxl_types.idl     |  1 +
 tools/xl/xl_parse.c             |  4 ++++
 xen/arch/x86/cpu/mcheck/vmce.c  | 19 ++++++++++++++++++-
 xen/arch/x86/hvm/hvm.c          |  5 +++++
 xen/include/asm-x86/mce.h       |  1 +
 xen/include/public/hvm/params.h |  7 ++++++-
 8 files changed, 89 insertions(+), 2 deletions(-)

diff --git a/docs/man/xl.cfg.pod.5.in b/docs/man/xl.cfg.pod.5.in
index 505c111..d75dcd2 100644
--- a/docs/man/xl.cfg.pod.5.in
+++ b/docs/man/xl.cfg.pod.5.in
@@ -2021,6 +2021,30 @@ natively or via hardware backwards compatibility support.
 
 =back
 
+=head3 x86
+
+=over 4
+
+=item B<mca_caps=[ "CAP", "CAP", ... ]>
+
+(HVM only) Enable MCA capabilities besides default ones enabled
+by Xen hypervisor for the HVM domain. "CAP" can be one in the
+following list:
+
+=over 4
+
+=item B<"lmce">
+
+Intel local MCE
+
+=item B<default>
+
+No MCA capabilities in above list are enabled.
+
+=back
+
+=back
+
 =head1 SEE ALSO
 
 =over 4
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index d519c8d..91b2f08 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -275,6 +275,32 @@ err:
     libxl_bitmap_dispose(&enlightenments);
     return ERROR_FAIL;
 }
+
+static int hvm_set_mca_capabilities(libxl__gc *gc, uint32_t domid,
+                                    libxl_domain_build_info *const info)
+{
+    int i, rc = 0;
+    const libxl_string_list xl_caps = info->u.hvm.mca_caps;
+    unsigned long caps = 0;
+
+    if (!xl_caps)
+        return 0;
+
+    for (i = 0; xl_caps[i] != NULL; i++) {
+        if (!strcmp(xl_caps[i], "lmce"))
+            caps |= HVMMCA_CAP_LMCE;
+        else {
+            LOG(ERROR, "Unsupported MCA capability %s", xl_caps[i]);
+            rc = ERROR_FAIL;
+            break;
+        }
+    }
+
+    if (!rc)
+        rc = xc_hvm_param_set(CTX->xch, domid, HVM_PARAM_MCA_CAP, caps);
+
+    return rc;
+}
 #endif
 
 static void hvm_set_conf_params(xc_interface *handle, uint32_t domid,
@@ -438,6 +464,10 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
         rc = hvm_set_viridian_features(gc, domid, info);
         if (rc)
             return rc;
+
+        rc = hvm_set_mca_capabilities(gc, domid, info);
+        if (rc)
+            return rc;
 #endif
     }
 
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index a612d1f..71c6c33 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -550,6 +550,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
                                        ("serial_list",      libxl_string_list),
                                        ("rdm", libxl_rdm_reserve),
                                        ("rdm_mem_boundary_memkb", MemKB),
+                                       ("mca_caps",         libxl_string_list),
                                        ])),
                  ("pv", Struct(None, [("kernel", string),
                                       ("slack_memkb", MemKB),
diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
index 1ef0c27..11a9f51 100644
--- a/tools/xl/xl_parse.c
+++ b/tools/xl/xl_parse.c
@@ -1084,6 +1084,10 @@ void parse_config_data(const char *config_source,
 
         if (!xlu_cfg_get_long (config, "rdm_mem_boundary", &l, 0))
             b_info->u.hvm.rdm_mem_boundary_memkb = l * 1024;
+
+        xlu_cfg_get_list_as_string_list(config, "mca_caps",
+                                        &b_info->u.hvm.mca_caps, false);
+
         break;
     case LIBXL_DOMAIN_TYPE_PV:
     {
diff --git a/xen/arch/x86/cpu/mcheck/vmce.c b/xen/arch/x86/cpu/mcheck/vmce.c
index 994a50e..5dc790f 100644
--- a/xen/arch/x86/cpu/mcheck/vmce.c
+++ b/xen/arch/x86/cpu/mcheck/vmce.c
@@ -74,7 +74,7 @@ int vmce_restore_vcpu(struct vcpu *v, const struct hvm_vmce_vcpu *ctxt)
     unsigned long guest_mcg_cap;
 
     if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
-        guest_mcg_cap = INTEL_GUEST_MCG_CAP;
+        guest_mcg_cap = INTEL_GUEST_MCG_CAP | MCG_LMCE_P;
     else
         guest_mcg_cap = AMD_GUEST_MCG_CAP;
 
@@ -546,3 +546,20 @@ int unmmap_broken_page(struct domain *d, mfn_t mfn, unsigned long gfn)
     return rc;
 }
 
+int vmce_enable_mca_cap(struct domain *d, uint64_t cap)
+{
+    struct vcpu *v;
+
+    if ( cap & ~HVMMCA_CAP_MASK )
+        return -EINVAL;
+
+    if ( cap & HVMMCA_CAP_LMCE )
+    {
+        if ( !lmce_support )
+            return -EINVAL;
+        for_each_vcpu(d, v)
+            v->arch.vmce.mcg_cap |= MCG_LMCE_P;
+    }
+
+    return 0;
+}
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index ccfae4f..0007e3d 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -4045,6 +4045,7 @@ static int hvm_allow_set_param(struct domain *d,
     case HVM_PARAM_IOREQ_SERVER_PFN:
     case HVM_PARAM_NR_IOREQ_SERVER_PAGES:
     case HVM_PARAM_ALTP2M:
+    case HVM_PARAM_MCA_CAP:
         if ( value != 0 && a->value != value )
             rc = -EEXIST;
         break;
@@ -4257,6 +4258,10 @@ static int hvmop_set_param(
                                                (0x10000 / 8) + 1) << 32);
         a.value |= VM86_TSS_UPDATED;
         break;
+
+    case HVM_PARAM_MCA_CAP:
+        rc = vmce_enable_mca_cap(d, a.value);
+        break;
     }
 
     if ( rc != 0 )
diff --git a/xen/include/asm-x86/mce.h b/xen/include/asm-x86/mce.h
index dee66b3..70eb50c 100644
--- a/xen/include/asm-x86/mce.h
+++ b/xen/include/asm-x86/mce.h
@@ -38,6 +38,7 @@ extern int vmce_restore_vcpu(struct vcpu *, const struct hvm_vmce_vcpu *);
 extern int vmce_wrmsr(uint32_t msr, uint64_t val);
 extern int vmce_rdmsr(uint32_t msr, uint64_t *val);
 extern bool vmce_support_lmce(const struct vcpu *v);
+extern int vmce_enable_mca_cap(struct domain *d, uint64_t cap);
 
 extern unsigned int nr_mce_banks;
 
diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h
index 58c8478..266c123 100644
--- a/xen/include/public/hvm/params.h
+++ b/xen/include/public/hvm/params.h
@@ -259,6 +259,11 @@
  */
 #define HVM_PARAM_VM86_TSS_SIZED 37
 
-#define HVM_NR_PARAMS 38
+/* Enable MCA capabilities. */
+#define HVM_PARAM_MCA_CAP 38
+#define HVMMCA_CAP_LMCE   (1UL << 27)
+#define HVMMCA_CAP_MASK   HVMMCA_CAP_LMCE
+
+#define HVM_NR_PARAMS 39
 
 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
-- 
2.10.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 10/12] xen/mce: add support of vLMCE injection to XEN_MC_inject_v2
  2017-03-17  6:46 [PATCH v2 00/12] Add LMCE support Haozhong Zhang
                   ` (8 preceding siblings ...)
  2017-03-17  6:46 ` [PATCH v2 09/12] x86/vmce, tools/libxl: expose LMCE capability in guest MSR_IA32_MCG_CAP Haozhong Zhang
@ 2017-03-17  6:46 ` Haozhong Zhang
  2017-03-20 16:37   ` Jan Beulich
  2017-03-17  6:46 ` [PATCH v2 11/12] tools/libxc: add support of injecting MC# to specified CPUs Haozhong Zhang
  2017-03-17  6:46 ` [PATCH v2 12/12] tools/xen-mceinj: add support of injecting LMCE Haozhong Zhang
  11 siblings, 1 reply; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-17  6:46 UTC (permalink / raw)
  To: xen-devel; +Cc: Haozhong Zhang, Jan Beulich, Andrew Cooper

Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>

Changes in v2:
 * Remove the unnecessary local variable "cpu_nr".
---
 xen/arch/x86/cpu/mcheck/mce.c         | 15 +++++++++++++++
 xen/include/public/arch-x86/xen-mca.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/xen/arch/x86/cpu/mcheck/mce.c b/xen/arch/x86/cpu/mcheck/mce.c
index 20ab678..e7c681b 100644
--- a/xen/arch/x86/cpu/mcheck/mce.c
+++ b/xen/arch/x86/cpu/mcheck/mce.c
@@ -1546,6 +1546,21 @@ long do_mca(XEN_GUEST_HANDLE_PARAM(xen_mc_t) u_xen_mc)
             }
             break;
 
+        case XEN_MC_INJECT_TYPE_LMCE:
+            if ( !lmce_support )
+            {
+                ret = x86_mcerr("No LMCE support in platform", -EINVAL);
+                break;
+            }
+            /* Ensure at most one CPU is specified. */
+            if ( nr_cpu_ids > cpumask_next(cpumask_first(cpumap), cpumap) )
+            {
+                ret = x86_mcerr("More than one CPU specified", -EINVAL);
+                break;
+            }
+            on_selected_cpus(cpumap, x86_mc_mceinject, NULL, 1);
+            break;
+
         default:
             ret = x86_mcerr("Wrong mca type\n", -EINVAL);
             break;
diff --git a/xen/include/public/arch-x86/xen-mca.h b/xen/include/public/arch-x86/xen-mca.h
index 7db9907..dc35267 100644
--- a/xen/include/public/arch-x86/xen-mca.h
+++ b/xen/include/public/arch-x86/xen-mca.h
@@ -414,6 +414,7 @@ struct xen_mc_mceinject {
 #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_TYPE_LMCE     0x2
 
 #define XEN_MC_INJECT_CPU_BROADCAST 0x8
 
-- 
2.10.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 11/12] tools/libxc: add support of injecting MC# to specified CPUs
  2017-03-17  6:46 [PATCH v2 00/12] Add LMCE support Haozhong Zhang
                   ` (9 preceding siblings ...)
  2017-03-17  6:46 ` [PATCH v2 10/12] xen/mce: add support of vLMCE injection to XEN_MC_inject_v2 Haozhong Zhang
@ 2017-03-17  6:46 ` Haozhong Zhang
  2017-03-28 14:07   ` Wei Liu
  2017-03-17  6:46 ` [PATCH v2 12/12] tools/xen-mceinj: add support of injecting LMCE Haozhong Zhang
  11 siblings, 1 reply; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-17  6:46 UTC (permalink / raw)
  To: xen-devel; +Cc: Haozhong Zhang, Ian Jackson, Wei Liu

Though XEN_MC_inject_v2 allows injecting MC# to specified CPUs, the
current xc_mca_op() does not use this feature and not provide an
interface to callers. This commit add a new xc_mca_op_inject_v2() that
receives a cpumap providing the set of target CPUs.

Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>

Changes in v2:
 * Separate the libxc changes from v1 patch 19 to this one.
 * Build the bounce buffer completely in one function.
---
 tools/libxc/include/xenctrl.h |  2 ++
 tools/libxc/xc_misc.c         | 52 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index a48981a..d7ecc02 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -1773,6 +1773,8 @@ int xc_cpuid_apply_policy(xc_interface *xch,
 void xc_cpuid_to_str(const unsigned int *regs,
                      char **strs); /* some strs[] may be NULL if ENOMEM */
 int xc_mca_op(xc_interface *xch, struct xen_mc *mc);
+int xc_mca_op_inject_v2(xc_interface *xch, unsigned int flags,
+                        xc_cpumap_t cpumap, unsigned int nr_cpus);
 #endif
 
 struct xc_px_val {
diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
index 88084fd..52ff7b1 100644
--- a/tools/libxc/xc_misc.c
+++ b/tools/libxc/xc_misc.c
@@ -341,7 +341,57 @@ int xc_mca_op(xc_interface *xch, struct xen_mc *mc)
     xc_hypercall_bounce_post(xch, mc);
     return ret;
 }
-#endif
+
+int xc_mca_op_inject_v2(xc_interface *xch, unsigned int flags,
+                        xc_cpumap_t cpumap, unsigned int nr_bits)
+{
+    int ret = -1;
+    struct xen_mc mc_buf, *mc = &mc_buf;
+    struct xen_mc_inject_v2 *inject = &mc->u.mc_inject_v2;
+
+    DECLARE_HYPERCALL_BOUNCE(cpumap, 0, XC_HYPERCALL_BUFFER_BOUNCE_IN);
+    DECLARE_HYPERCALL_BOUNCE(mc, sizeof(*mc), XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
+
+    memset(mc, 0, sizeof(*mc));
+
+    if ( cpumap )
+    {
+        if ( !nr_bits )
+        {
+            errno = EINVAL;
+            return -1;
+        }
+
+        HYPERCALL_BOUNCE_SET_SIZE(cpumap, (nr_bits + 7) / 8);
+        if ( xc_hypercall_bounce_pre(xch, cpumap) )
+        {
+            PERROR("Could not bounce cpumap memory buffer");
+            return -1;
+        }
+        set_xen_guest_handle(inject->cpumap.bitmap, cpumap);
+        inject->cpumap.nr_bits = nr_bits;
+    }
+
+    inject->flags = flags;
+    mc->cmd = XEN_MC_inject_v2;
+    mc->interface_version = XEN_MCA_INTERFACE_VERSION;
+
+    if ( xc_hypercall_bounce_pre(xch, mc) )
+    {
+        PERROR("Could not bounce xen_mc memory buffer");
+        goto out;
+    }
+
+    ret = xencall1(xch->xcall, __HYPERVISOR_mca, HYPERCALL_BUFFER_AS_ARG(mc));
+
+    xc_hypercall_bounce_post(xch, mc);
+out:
+    if ( cpumap )
+        xc_hypercall_bounce_post(xch, cpumap);
+
+    return ret;
+}
+#endif /* __i386__ || __x86_64__ */
 
 int xc_perfc_reset(xc_interface *xch)
 {
-- 
2.10.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 12/12] tools/xen-mceinj: add support of injecting LMCE
  2017-03-17  6:46 [PATCH v2 00/12] Add LMCE support Haozhong Zhang
                   ` (10 preceding siblings ...)
  2017-03-17  6:46 ` [PATCH v2 11/12] tools/libxc: add support of injecting MC# to specified CPUs Haozhong Zhang
@ 2017-03-17  6:46 ` Haozhong Zhang
  2017-03-28 14:08   ` Wei Liu
  11 siblings, 1 reply; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-17  6:46 UTC (permalink / raw)
  To: xen-devel; +Cc: Haozhong Zhang, Ian Jackson, Wei Liu

If option '-l' or '--lmce' is specified and the host supports LMCE,
xen-mceinj will inject LMCE to CPU specified by '-c' (or CPU0 if '-c'
is not present).

Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>

Changes in v2:
 * Separate the xen-mceinj changes from v1 patch 19 to this one.
---
 tools/tests/mce-test/tools/xen-mceinj.c | 50 +++++++++++++++++++++++++++++++--
 1 file changed, 48 insertions(+), 2 deletions(-)

diff --git a/tools/tests/mce-test/tools/xen-mceinj.c b/tools/tests/mce-test/tools/xen-mceinj.c
index bae5a46..380e421 100644
--- a/tools/tests/mce-test/tools/xen-mceinj.c
+++ b/tools/tests/mce-test/tools/xen-mceinj.c
@@ -56,6 +56,8 @@
 #define MSR_IA32_MC0_MISC        0x00000403
 #define MSR_IA32_MC0_CTL2        0x00000280
 
+#define MCG_STATUS_LMCE          0x8
+
 struct mce_info {
     const char *description;
     uint8_t mcg_stat;
@@ -113,6 +115,7 @@ static struct mce_info mce_table[] = {
 #define LOGFILE stdout
 
 int dump;
+int lmce;
 struct xen_mc_msrinject msr_inj;
 
 static void Lprintf(const char *fmt, ...)
@@ -212,6 +215,35 @@ static int inject_mce(xc_interface *xc_handle, int cpu_nr)
     return xc_mca_op(xc_handle, &mc);
 }
 
+static int inject_lmce(xc_interface *xc_handle, unsigned int cpu)
+{
+    uint8_t *cpumap = NULL;
+    size_t cpumap_size, line, shift;
+    unsigned int nr_cpus;
+    int ret;
+
+    nr_cpus = mca_cpuinfo(xc_handle);
+    if ( !nr_cpus )
+        err(xc_handle, "Failed to get mca_cpuinfo");
+    if ( cpu >= nr_cpus )
+        err(xc_handle, "-c %u is larger than %u", cpu, nr_cpus - 1);
+
+    cpumap_size = (nr_cpus + 7) / 8;
+    cpumap = malloc(cpumap_size);
+    if ( !cpumap )
+        err(xc_handle, "Failed to allocate cpumap\n");
+    memset(cpumap, 0, cpumap_size);
+    line = cpu / 8;
+    shift = cpu % 8;
+    memset(cpumap + line, 1 << shift, 1);
+
+    ret = xc_mca_op_inject_v2(xc_handle, XEN_MC_INJECT_TYPE_LMCE,
+                              cpumap, cpumap_size * 8);
+
+    free(cpumap);
+    return ret;
+}
+
 static uint64_t bank_addr(int bank, int type)
 {
     uint64_t addr;
@@ -330,8 +362,15 @@ static int inject(xc_interface *xc_handle, struct mce_info *mce,
                   uint32_t cpu_nr, uint32_t domain, uint64_t gaddr)
 {
     int ret = 0;
+    uint8_t mcg_status = mce->mcg_stat;
 
-    ret = inject_mcg_status(xc_handle, cpu_nr, mce->mcg_stat, domain);
+    if ( lmce )
+    {
+        if ( mce->cmci )
+            err(xc_handle, "No support to inject CMCI as LMCE");
+        mcg_status |= MCG_STATUS_LMCE;
+    }
+    ret = inject_mcg_status(xc_handle, cpu_nr, mcg_status, domain);
     if ( ret )
         err(xc_handle, "Failed to inject MCG_STATUS MSR");
 
@@ -354,6 +393,8 @@ static int inject(xc_interface *xc_handle, struct mce_info *mce,
         err(xc_handle, "Failed to inject MSR");
     if ( mce->cmci )
         ret = inject_cmci(xc_handle, cpu_nr);
+    else if ( lmce )
+        ret = inject_lmce(xc_handle, cpu_nr);
     else
         ret = inject_mce(xc_handle, cpu_nr);
     if ( ret )
@@ -393,6 +434,7 @@ static struct option opts[] = {
     {"dump", 0, 0, 'D'},
     {"help", 0, 0, 'h'},
     {"page", 0, 0, 'p'},
+    {"lmce", 0, 0, 'l'},
     {"", 0, 0, '\0'}
 };
 
@@ -409,6 +451,7 @@ static void help(void)
            "  -d, --domain=DOMID   target domain, the default is Xen itself\n"
            "  -h, --help           print this page\n"
            "  -p, --page=ADDR      physical address to report\n"
+           "  -l, --lmce           inject as LMCE (Intel only)\n"
            "  -t, --type=ERROR     error type\n");
 
     for ( i = 0; i < MCE_TABLE_SIZE; i++ )
@@ -438,7 +481,7 @@ int main(int argc, char *argv[])
     }
 
     while ( 1 ) {
-        c = getopt_long(argc, argv, "c:Dd:t:hp:", opts, &opt_index);
+        c = getopt_long(argc, argv, "c:Dd:t:hp:l", opts, &opt_index);
         if ( c == -1 )
             break;
         switch ( c ) {
@@ -463,6 +506,9 @@ int main(int argc, char *argv[])
         case 't':
             type = strtol(optarg, NULL, 0);
             break;
+        case 'l':
+            lmce = 1;
+            break;
         case 'h':
         default:
             help();
-- 
2.10.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 01/12] xen/mce: switch bool_t/1/0 to bool/true/false
  2017-03-17  6:46 ` [PATCH v2 01/12] xen/mce: switch bool_t/1/0 to bool/true/false Haozhong Zhang
@ 2017-03-20 13:04   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2017-03-20 13:04 UTC (permalink / raw)
  To: Haozhong Zhang; +Cc: Andrew Cooper, xen-devel

>>> On 17.03.17 at 07:46, <haozhong.zhang@intel.com> wrote:
> Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>

Acked-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 02/12] x86/mce_intel: refine messages of MCA capabilities
  2017-03-17  6:46 ` [PATCH v2 02/12] x86/mce_intel: refine messages of MCA capabilities Haozhong Zhang
@ 2017-03-20 13:10   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2017-03-20 13:10 UTC (permalink / raw)
  To: Haozhong Zhang; +Cc: Andrew Cooper, xen-devel

>>> On 17.03.17 at 07:46, <haozhong.zhang@intel.com> wrote:
> ... to only print available ones.

Suggested-by: Jan Beulich <jbeulich@suse.com>

> Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 03/12] xen/mce: add blank lines between non-fall-through switch case blocks
  2017-03-17  6:46 ` [PATCH v2 03/12] xen/mce: add blank lines between non-fall-through switch case blocks Haozhong Zhang
@ 2017-03-20 13:12   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2017-03-20 13:12 UTC (permalink / raw)
  To: Haozhong Zhang; +Cc: Andrew Cooper, xen-devel

>>> On 17.03.17 at 07:46, <haozhong.zhang@intel.com> wrote:
> Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>

Acked-by: Jan Beulich <jbeulich@suse.com>


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 04/12] x86/mce: handle LMCE locally
  2017-03-17  6:46 ` [PATCH v2 04/12] x86/mce: handle LMCE locally Haozhong Zhang
@ 2017-03-20 14:24   ` Jan Beulich
  2017-03-21  7:04     ` Haozhong Zhang
  0 siblings, 1 reply; 35+ messages in thread
From: Jan Beulich @ 2017-03-20 14:24 UTC (permalink / raw)
  To: Haozhong Zhang; +Cc: Andrew Cooper, xen-devel

>>> On 17.03.17 at 07:46, <haozhong.zhang@intel.com> wrote:
> @@ -52,8 +52,8 @@ void mce_barrier_exit(struct mce_softirq_barrier *bar)
>      }
>  }
>  
> -void mce_barrier(struct mce_softirq_barrier *bar)
> +void mce_barrier(struct mce_softirq_barrier *bar, bool nowait)
>  {
> -    mce_barrier_enter(bar);
> -    mce_barrier_exit(bar);
> +    mce_barrier_enter(bar, nowait);
> +    mce_barrier_exit(bar, nowait);
>  }

I don't think this currently unused function needs the extra parameter.
Should a future user find this necessary, it can be done then.

> --- a/xen/arch/x86/cpu/mcheck/mce.c
> +++ b/xen/arch/x86/cpu/mcheck/mce.c
> @@ -42,6 +42,13 @@ DEFINE_PER_CPU_READ_MOSTLY(struct mca_banks *, poll_bankmask);
>  DEFINE_PER_CPU_READ_MOSTLY(struct mca_banks *, no_cmci_banks);
>  DEFINE_PER_CPU_READ_MOSTLY(struct mca_banks *, mce_clear_banks);
>  
> +/*
> + * Flag to indicate that at least one non-local MCE's on this CPU have

... one non-local MCE on this CPU has ...

> + * not been completed handled. It's set by mcheck_cmn_handler() and
> + * cleared by mce_softirq().
> + */
> +DEFINE_PER_CPU(bool, mce_in_process);

static

Also please consider whether mce_in_progress might not be a
better alternative name, and whether the non-local aspect
shouldn't also be expressed by the name chosen.

> @@ -1704,10 +1717,11 @@ static void mce_softirq(void)
>  {
>      int cpu = smp_processor_id();
>      unsigned int workcpu;
> +    bool nowait = !this_cpu(mce_in_process);
>  
>      mce_printk(MCE_VERBOSE, "CPU%d enter softirq\n", cpu);
>  
> -    mce_barrier_enter(&mce_inside_bar);
> +    mce_barrier_enter(&mce_inside_bar, nowait);
>  
>      /*
>       * Everybody is here. Now let's see who gets to do the
> @@ -1720,10 +1734,10 @@ static void mce_softirq(void)
>  
>      atomic_set(&severity_cpu, cpu);
>  
> -    mce_barrier_enter(&mce_severity_bar);
> +    mce_barrier_enter(&mce_severity_bar, nowait);
>      if (!mctelem_has_deferred(cpu))
>          atomic_set(&severity_cpu, cpu);
> -    mce_barrier_exit(&mce_severity_bar);
> +    mce_barrier_exit(&mce_severity_bar, nowait);
>  
>      /* We choose severity_cpu for further processing */
>      if (atomic_read(&severity_cpu) == cpu) {

The logic here looks pretty suspicious even without your changes,
but I think we should try hard to not make it worse. I think you
need to avoid setting severity_cpu in the LMCE case (with,
obviously, further resulting adjustments). And it also needs to be
at least clarified (in the patch description) whether
this_cpu(mce_in_process) changing (namely from 0 to 1) after
you've latched it can't have any bad effect.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 05/12] x86/mce_intel: detect and enable LMCE on Intel host
  2017-03-17  6:46 ` [PATCH v2 05/12] x86/mce_intel: detect and enable LMCE on Intel host Haozhong Zhang
@ 2017-03-20 14:30   ` Jan Beulich
  2017-03-21  7:06     ` Haozhong Zhang
  0 siblings, 1 reply; 35+ messages in thread
From: Jan Beulich @ 2017-03-20 14:30 UTC (permalink / raw)
  To: Haozhong Zhang; +Cc: Andrew Cooper, xen-devel

>>> On 17.03.17 at 07:46, <haozhong.zhang@intel.com> wrote:
> --- a/xen/arch/x86/cpu/mcheck/mce_intel.c
> +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c
> @@ -29,6 +29,9 @@ boolean_param("mce_fb", mce_force_broadcast);
>  
>  static int __read_mostly nr_intel_ext_msrs;
>  
> +/* If mce_force_broadcast == 1, lmce_support will be disabled forcibly. */
> +bool __read_mostly lmce_support;

static

With that adjusted
Reviewed-by: Jan Beulich <jbeulich@suse.com>

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 06/12] x86/vmx: expose LMCE feature via guest MSR_IA32_FEATURE_CONTROL
  2017-03-17  6:46 ` [PATCH v2 06/12] x86/vmx: expose LMCE feature via guest MSR_IA32_FEATURE_CONTROL Haozhong Zhang
@ 2017-03-20 16:10   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2017-03-20 16:10 UTC (permalink / raw)
  To: Haozhong Zhang; +Cc: Andrew Cooper, Kevin Tian, Jun Nakajima, xen-devel

>>> On 17.03.17 at 07:46, <haozhong.zhang@intel.com> wrote:
> --- a/xen/arch/x86/cpu/mcheck/mce_intel.c
> +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c
> @@ -955,3 +955,7 @@ int vmce_intel_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val)
>      return 1;
>  }
>  
> +bool vmce_support_lmce(const struct vcpu *v)

I think you mean vmce_supports_lmce() (or vmce_has_lmce()). I'm
sorry for having overlooked this in v1.

>  static int vmx_msr_read_intercept(unsigned int msr, uint64_t *msr_content)
>  {
> +    struct vcpu *curr = current;

const

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 07/12] x86/vmce: emulate MSR_IA32_MCG_EXT_CTL
  2017-03-17  6:46 ` [PATCH v2 07/12] x86/vmce: emulate MSR_IA32_MCG_EXT_CTL Haozhong Zhang
@ 2017-03-20 16:17   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2017-03-20 16:17 UTC (permalink / raw)
  To: Haozhong Zhang; +Cc: Andrew Cooper, xen-devel

>>> On 17.03.17 at 07:46, <haozhong.zhang@intel.com> wrote:
> --- a/xen/include/public/arch-x86/hvm/save.h
> +++ b/xen/include/public/arch-x86/hvm/save.h
> @@ -599,6 +599,8 @@ struct hvm_vmce_vcpu {
>      uint64_t caps;
>      uint64_t mci_ctl2_bank0;
>      uint64_t mci_ctl2_bank1;
> +    uint8_t  lmce_enabled;
> +    uint8_t  pad[7];

Even if only one bit is used there right now, I think you should migrate
the full MSR.

> --- a/xen/include/public/domctl.h
> +++ b/xen/include/public/domctl.h
> @@ -37,7 +37,7 @@
>  #include "hvm/save.h"
>  #include "memory.h"
>  
> -#define XEN_DOMCTL_INTERFACE_VERSION 0x0000000c
> +#define XEN_DOMCTL_INTERFACE_VERSION 0x0000000d

This seemingly unrelated change needs to be explained in the
description.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 08/12] x86/vmce: enable injecting LMCE to guest on Intel host
  2017-03-17  6:46 ` [PATCH v2 08/12] x86/vmce: enable injecting LMCE to guest on Intel host Haozhong Zhang
@ 2017-03-20 16:25   ` Jan Beulich
  2017-03-22  9:19     ` Haozhong Zhang
  0 siblings, 1 reply; 35+ messages in thread
From: Jan Beulich @ 2017-03-20 16:25 UTC (permalink / raw)
  To: Haozhong Zhang; +Cc: Andrew Cooper, xen-devel

>>> On 17.03.17 at 07:46, <haozhong.zhang@intel.com> wrote:
> @@ -88,18 +89,31 @@ mc_memerr_dhandler(struct mca_binfo *binfo,
>                      goto vmce_failed;
>                  }
>  
> -                if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ||
> -                    global->mc_vcpuid == XEN_MC_VCPUID_INVALID)
> +                mc_vcpuid = global->mc_vcpuid;
> +                if (mc_vcpuid == XEN_MC_VCPUID_INVALID ||
> +                    (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
> +                     (!(global->mc_gstatus & MCG_STATUS_LMCE) ||
> +                      !(d->vcpu[mc_vcpuid]->arch.vmce.lmce_enabled) ||
> +                      /*
> +                       * The following check serves for MCE injection
> +                       * test, i.e. xen-mceinj. xen-mceinj may specify
> +                       * the target domain (i.e. bank->mc_domid) and
> +                       * target CPU, but it's hard for xen-mceinj to
> +                       * ensure, when Xen prepares the actual
> +                       * injection in this function, vCPU currently
> +                       * running on the target CPU belongs to the
> +                       * target domain. If such inconsistency does
> +                       * happen, fallback to broadcast.
> +                       */
> +                      global->mc_domid != bank->mc_domid)))

Thinking about this another time, I don't think we want hackery
like this for a test utility. Instead I think the test utility wants to
pin the vCPU on the pCPU it wants to deliver the LMCE on.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 09/12] x86/vmce, tools/libxl: expose LMCE capability in guest MSR_IA32_MCG_CAP
  2017-03-17  6:46 ` [PATCH v2 09/12] x86/vmce, tools/libxl: expose LMCE capability in guest MSR_IA32_MCG_CAP Haozhong Zhang
@ 2017-03-20 16:33   ` Jan Beulich
  2017-03-21  7:14     ` Haozhong Zhang
  2017-03-20 18:27   ` Ian Jackson
  2017-03-27 15:34   ` Wei Liu
  2 siblings, 1 reply; 35+ messages in thread
From: Jan Beulich @ 2017-03-20 16:33 UTC (permalink / raw)
  To: Haozhong Zhang; +Cc: Andrew Cooper, Wei Liu, Ian Jackson, xen-devel

>>> On 17.03.17 at 07:46, <haozhong.zhang@intel.com> wrote:
> --- a/xen/include/public/hvm/params.h
> +++ b/xen/include/public/hvm/params.h
> @@ -259,6 +259,11 @@
>   */
>  #define HVM_PARAM_VM86_TSS_SIZED 37
>  
> -#define HVM_NR_PARAMS 38
> +/* Enable MCA capabilities. */
> +#define HVM_PARAM_MCA_CAP 38
> +#define HVMMCA_CAP_LMCE   (1UL << 27)

How come this is bit 27 rather than bit 0? Further, to match up with
other, future definitions here, I think you mean 1ULL (or, to be
precise, xen_mk_ullong()).

> +#define HVMMCA_CAP_MASK   HVMMCA_CAP_LMCE

For both of these, please add XEN_ at the front (perhaps replacing
HVM, or if not, add another underscore between HVM and MCA).

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 10/12] xen/mce: add support of vLMCE injection to XEN_MC_inject_v2
  2017-03-17  6:46 ` [PATCH v2 10/12] xen/mce: add support of vLMCE injection to XEN_MC_inject_v2 Haozhong Zhang
@ 2017-03-20 16:37   ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2017-03-20 16:37 UTC (permalink / raw)
  To: Haozhong Zhang; +Cc: Andrew Cooper, xen-devel

>>> On 17.03.17 at 07:46, <haozhong.zhang@intel.com> wrote:
> --- a/xen/arch/x86/cpu/mcheck/mce.c
> +++ b/xen/arch/x86/cpu/mcheck/mce.c
> @@ -1546,6 +1546,21 @@ long do_mca(XEN_GUEST_HANDLE_PARAM(xen_mc_t) u_xen_mc)
>              }
>              break;
>  
> +        case XEN_MC_INJECT_TYPE_LMCE:
> +            if ( !lmce_support )
> +            {
> +                ret = x86_mcerr("No LMCE support in platform", -EINVAL);
> +                break;
> +            }
> +            /* Ensure at most one CPU is specified. */
> +            if ( nr_cpu_ids > cpumask_next(cpumask_first(cpumap), cpumap) )
> +            {
> +                ret = x86_mcerr("More than one CPU specified", -EINVAL);
> +                break;
> +            }
> +            on_selected_cpus(cpumap, x86_mc_mceinject, NULL, 1);
> +            break;

Please reject XEN_MC_INJECT_CPU_BROADCAST being used
together with this new type.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 09/12] x86/vmce, tools/libxl: expose LMCE capability in guest MSR_IA32_MCG_CAP
  2017-03-17  6:46 ` [PATCH v2 09/12] x86/vmce, tools/libxl: expose LMCE capability in guest MSR_IA32_MCG_CAP Haozhong Zhang
  2017-03-20 16:33   ` Jan Beulich
@ 2017-03-20 18:27   ` Ian Jackson
  2017-03-21  7:29     ` Haozhong Zhang
  2017-03-21  9:30     ` Jan Beulich
  2017-03-27 15:34   ` Wei Liu
  2 siblings, 2 replies; 35+ messages in thread
From: Ian Jackson @ 2017-03-20 18:27 UTC (permalink / raw)
  To: Haozhong Zhang; +Cc: Andrew Cooper, Wei Liu, Jan Beulich, xen-devel

Haozhong Zhang writes ("[PATCH v2 09/12] x86/vmce, tools/libxl: expose LMCE capability in guest MSR_IA32_MCG_CAP"):
> If LMCE is supported by host and ' mca_caps = [ "lmce" ] ' is
> present in xl config, the LMCE capability will be exposed in guest
> MSR_IA32_MCG_CAP.  By default, LMCE is not exposed to guest so as to
> keep the backwards migration compatibility.

Excluse my ignorance, but I'm not sure what MCE, MCA and LMCE are.
I'm guessing MC = Machine Check ?

Is MCA "Machine Check Architecture" ?  Is that precisely the machinery
for handling MCEs, or is it something else ?

I think we may need a bit of care in the user-facing interface to try
to make the names and docs comprehensible.

> +=head3 x86
> +
> +=over 4
> +
> +=item B<mca_caps=[ "CAP", "CAP", ... ]>
> +
> +(HVM only) Enable MCA capabilities besides default ones enabled
> +by Xen hypervisor for the HVM domain. "CAP" can be one in the
> +following list:

Would it be incorrect to replace references to "MCA" with "MCE" (eg,
changing "mca_caps" to "mce_caps" here) ?

Ian.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 04/12] x86/mce: handle LMCE locally
  2017-03-20 14:24   ` Jan Beulich
@ 2017-03-21  7:04     ` Haozhong Zhang
  0 siblings, 0 replies; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-21  7:04 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Andrew Cooper, xen-devel

On 03/20/17 08:24 -0600, Jan Beulich wrote:
> >>> On 17.03.17 at 07:46, <haozhong.zhang@intel.com> wrote:
[..]
> > @@ -1704,10 +1717,11 @@ static void mce_softirq(void)
> >  {
> >      int cpu = smp_processor_id();
> >      unsigned int workcpu;
> > +    bool nowait = !this_cpu(mce_in_process);
> >  
> >      mce_printk(MCE_VERBOSE, "CPU%d enter softirq\n", cpu);
> >  
> > -    mce_barrier_enter(&mce_inside_bar);
> > +    mce_barrier_enter(&mce_inside_bar, nowait);
> >  
> >      /*
> >       * Everybody is here. Now let's see who gets to do the
> > @@ -1720,10 +1734,10 @@ static void mce_softirq(void)
> >  
> >      atomic_set(&severity_cpu, cpu);
> >  
> > -    mce_barrier_enter(&mce_severity_bar);
> > +    mce_barrier_enter(&mce_severity_bar, nowait);
> >      if (!mctelem_has_deferred(cpu))
> >          atomic_set(&severity_cpu, cpu);
> > -    mce_barrier_exit(&mce_severity_bar);
> > +    mce_barrier_exit(&mce_severity_bar, nowait);
> >  
> >      /* We choose severity_cpu for further processing */
> >      if (atomic_read(&severity_cpu) == cpu) {
> 
> The logic here looks pretty suspicious even without your changes,
> but I think we should try hard to not make it worse. I think you
> need to avoid setting severity_cpu in the LMCE case (with,
> obviously, further resulting adjustments).

Ah yes, this patch introduces a race condition between
mce_cmn_handler() and mce_softirq() on different CPUs:
mce_cmn_handler() is handling a LMCE on CPUx and mce_softirq() is
handling another LMCE on CPUy, and both are modifying the global
severity_cpu. As both check severity_cpu later, their modifications
will interfere with each other.

I'll not let mce_cmn_handler() and mce_softirq() access severity_cpu
when handling LMCE.

Thanks,
Haozhong

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 05/12] x86/mce_intel: detect and enable LMCE on Intel host
  2017-03-20 14:30   ` Jan Beulich
@ 2017-03-21  7:06     ` Haozhong Zhang
  2017-03-21  8:05       ` Jan Beulich
  0 siblings, 1 reply; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-21  7:06 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Andrew Cooper, xen-devel

On 03/20/17 08:30 -0600, Jan Beulich wrote:
> >>> On 17.03.17 at 07:46, <haozhong.zhang@intel.com> wrote:
> > --- a/xen/arch/x86/cpu/mcheck/mce_intel.c
> > +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c
> > @@ -29,6 +29,9 @@ boolean_param("mce_fb", mce_force_broadcast);
> >  
> >  static int __read_mostly nr_intel_ext_msrs;
> >  
> > +/* If mce_force_broadcast == 1, lmce_support will be disabled forcibly. */
> > +bool __read_mostly lmce_support;
> 
> static

lmce_support is accessed out of mce_intel.c in patch 9 & 10.

Haozhong

> 
> With that adjusted
> Reviewed-by: Jan Beulich <jbeulich@suse.com>
> 
> Jan
> 

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 09/12] x86/vmce, tools/libxl: expose LMCE capability in guest MSR_IA32_MCG_CAP
  2017-03-20 16:33   ` Jan Beulich
@ 2017-03-21  7:14     ` Haozhong Zhang
  0 siblings, 0 replies; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-21  7:14 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Andrew Cooper, Wei Liu, Ian Jackson, xen-devel

On 03/20/17 10:33 -0600, Jan Beulich wrote:
> >>> On 17.03.17 at 07:46, <haozhong.zhang@intel.com> wrote:
> > --- a/xen/include/public/hvm/params.h
> > +++ b/xen/include/public/hvm/params.h
> > @@ -259,6 +259,11 @@
> >   */
> >  #define HVM_PARAM_VM86_TSS_SIZED 37
> >  
> > -#define HVM_NR_PARAMS 38
> > +/* Enable MCA capabilities. */
> > +#define HVM_PARAM_MCA_CAP 38
> > +#define HVMMCA_CAP_LMCE   (1UL << 27)
> 
> How come this is bit 27 rather than bit 0? Further, to match up with
> other, future definitions here, I think you mean 1ULL (or, to be
> precise, xen_mk_ullong()).
>

I intended to use the same bit in MSR_IA32_MCG_CAP to clarify its
semantic, but I realize it's unnecessary as I still need to introduce
HVMMCA_CAP_* for each bit.

Thanks,
Haozhong
 

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 09/12] x86/vmce, tools/libxl: expose LMCE capability in guest MSR_IA32_MCG_CAP
  2017-03-20 18:27   ` Ian Jackson
@ 2017-03-21  7:29     ` Haozhong Zhang
  2017-03-21  7:35       ` Haozhong Zhang
  2017-03-21  9:30     ` Jan Beulich
  1 sibling, 1 reply; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-21  7:29 UTC (permalink / raw)
  To: Ian Jackson; +Cc: Andrew Cooper, Wei Liu, Jan Beulich, xen-devel

On 03/20/17 18:27 +0000, Ian Jackson wrote:
> Haozhong Zhang writes ("[PATCH v2 09/12] x86/vmce, tools/libxl: expose LMCE capability in guest MSR_IA32_MCG_CAP"):
> > If LMCE is supported by host and ' mca_caps = [ "lmce" ] ' is
> > present in xl config, the LMCE capability will be exposed in guest
> > MSR_IA32_MCG_CAP.  By default, LMCE is not exposed to guest so as to
> > keep the backwards migration compatibility.
> 
> Excluse my ignorance, but I'm not sure what MCE, MCA and LMCE are.
> I'm guessing MC = Machine Check ?
>

Yes.

> Is MCA "Machine Check Architecture" ?  Is that precisely the machinery
> for handling MCEs, or is it something else ?

Yes for both.

And LMCE stands for 'Local Machine Check Error', which is only sent to
the affected CPU, in contrast to the current ones on Intel CPU that
are broadcast to all CPUs.

> 
> I think we may need a bit of care in the user-facing interface to try
> to make the names and docs comprehensible.
>

'mca_caps' stands for capabilities of the machine check architecture
present to guest. I choose this name because the existing
intel_init_mca() uses "MCA capability" when it prints supported
capabilities, and ...

> > +=head3 x86
> > +
> > +=over 4
> > +
> > +=item B<mca_caps=[ "CAP", "CAP", ... ]>
> > +
> > +(HVM only) Enable MCA capabilities besides default ones enabled
> > +by Xen hypervisor for the HVM domain. "CAP" can be one in the
> > +following list:
> 
> Would it be incorrect to replace references to "MCA" with "MCE" (eg,
> changing "mca_caps" to "mce_caps" here) ?
>

... besides for consistency with intel_init_mca(), Intel SDM uses "the
information about the machine check architecture" (at the beginning of
section "IA32_MCG_CAP MSR", Vol 3). 'mca_caps' currently is for
capabilities indicated by IA32_MCG_CAP, so I think 'mca' is a better
name than 'mce'.

Thanks,
Haozhong

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 09/12] x86/vmce, tools/libxl: expose LMCE capability in guest MSR_IA32_MCG_CAP
  2017-03-21  7:29     ` Haozhong Zhang
@ 2017-03-21  7:35       ` Haozhong Zhang
  0 siblings, 0 replies; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-21  7:35 UTC (permalink / raw)
  To: Ian Jackson; +Cc: Andrew Cooper, Wei Liu, Jan Beulich, xen-devel

On 03/21/17 15:29 +0800, Haozhong Zhang wrote:
> On 03/20/17 18:27 +0000, Ian Jackson wrote:
> > Haozhong Zhang writes ("[PATCH v2 09/12] x86/vmce, tools/libxl: expose LMCE capability in guest MSR_IA32_MCG_CAP"):
[..]
> > Is MCA "Machine Check Architecture" ?  Is that precisely the machinery
> > for handling MCEs, or is it something else ?

More precisely, MCA is "the mechanism for detecting and reporting
hardware (machine) errors", according to Intel SDM Vol 3, Section
"MACHINE-CHECK ARCHITECTURE".

Haozhong

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 05/12] x86/mce_intel: detect and enable LMCE on Intel host
  2017-03-21  7:06     ` Haozhong Zhang
@ 2017-03-21  8:05       ` Jan Beulich
  0 siblings, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2017-03-21  8:05 UTC (permalink / raw)
  To: Haozhong Zhang; +Cc: Andrew Cooper, xen-devel

>>> On 21.03.17 at 08:06, <haozhong.zhang@intel.com> wrote:
> On 03/20/17 08:30 -0600, Jan Beulich wrote:
>> >>> On 17.03.17 at 07:46, <haozhong.zhang@intel.com> wrote:
>> > --- a/xen/arch/x86/cpu/mcheck/mce_intel.c
>> > +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c
>> > @@ -29,6 +29,9 @@ boolean_param("mce_fb", mce_force_broadcast);
>> >  
>> >  static int __read_mostly nr_intel_ext_msrs;
>> >  
>> > +/* If mce_force_broadcast == 1, lmce_support will be disabled forcibly. */
>> > +bool __read_mostly lmce_support;
>> 
>> static
> 
> lmce_support is accessed out of mce_intel.c in patch 9 & 10.

Well, in that case make it non-static in patch 9. Please remember
that your series may not be committed in one go.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 09/12] x86/vmce, tools/libxl: expose LMCE capability in guest MSR_IA32_MCG_CAP
  2017-03-20 18:27   ` Ian Jackson
  2017-03-21  7:29     ` Haozhong Zhang
@ 2017-03-21  9:30     ` Jan Beulich
  1 sibling, 0 replies; 35+ messages in thread
From: Jan Beulich @ 2017-03-21  9:30 UTC (permalink / raw)
  To: Ian Jackson; +Cc: Andrew Cooper, xen-devel, Wei Liu, Haozhong Zhang

>>> On 20.03.17 at 19:27, <ian.jackson@eu.citrix.com> wrote:
> Haozhong Zhang writes ("[PATCH v2 09/12] x86/vmce, tools/libxl: expose LMCE 
> capability in guest MSR_IA32_MCG_CAP"):
>> +=head3 x86
>> +
>> +=over 4
>> +
>> +=item B<mca_caps=[ "CAP", "CAP", ... ]>
>> +
>> +(HVM only) Enable MCA capabilities besides default ones enabled
>> +by Xen hypervisor for the HVM domain. "CAP" can be one in the
>> +following list:
> 
> Would it be incorrect to replace references to "MCA" with "MCE" (eg,
> changing "mca_caps" to "mce_caps" here) ?

MCE (Machine Check Exception) is only part of MCA, so I don't
think the terms can be used interchangeably. Namely I think
mce_caps would be wrong.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 08/12] x86/vmce: enable injecting LMCE to guest on Intel host
  2017-03-20 16:25   ` Jan Beulich
@ 2017-03-22  9:19     ` Haozhong Zhang
  0 siblings, 0 replies; 35+ messages in thread
From: Haozhong Zhang @ 2017-03-22  9:19 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Andrew Cooper, xen-devel

On 03/20/17 10:25 -0600, Jan Beulich wrote:
> >>> On 17.03.17 at 07:46, <haozhong.zhang@intel.com> wrote:
> > @@ -88,18 +89,31 @@ mc_memerr_dhandler(struct mca_binfo *binfo,
> >                      goto vmce_failed;
> >                  }
> >  
> > -                if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ||
> > -                    global->mc_vcpuid == XEN_MC_VCPUID_INVALID)
> > +                mc_vcpuid = global->mc_vcpuid;
> > +                if (mc_vcpuid == XEN_MC_VCPUID_INVALID ||
> > +                    (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
> > +                     (!(global->mc_gstatus & MCG_STATUS_LMCE) ||
> > +                      !(d->vcpu[mc_vcpuid]->arch.vmce.lmce_enabled) ||
> > +                      /*
> > +                       * The following check serves for MCE injection
> > +                       * test, i.e. xen-mceinj. xen-mceinj may specify
> > +                       * the target domain (i.e. bank->mc_domid) and
> > +                       * target CPU, but it's hard for xen-mceinj to
> > +                       * ensure, when Xen prepares the actual
> > +                       * injection in this function, vCPU currently
> > +                       * running on the target CPU belongs to the
> > +                       * target domain. If such inconsistency does
> > +                       * happen, fallback to broadcast.
> > +                       */
> > +                      global->mc_domid != bank->mc_domid)))
> 
> Thinking about this another time, I don't think we want hackery
> like this for a test utility. Instead I think the test utility wants to
> pin the vCPU on the pCPU it wants to deliver the LMCE on.
> 

I agree we should not introduce hackery only for test purpose.

However, after thinking twice, I think we still need this check, but
it should be lift to the outmost, i.e.
    if (mc_vcpuid == XEN_MC_VCPUID_INVALID ||
        global->mc_domid != bank->mc_domid ||             <== here
        (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
         (!(global->mc_gstatus & MCG_STATUS_LMCE) ||
          !(d->vcpu[mc_vcpuid]->arch.vmce.lmce_enabled))

MC# might not happen immediately at the moment that, e.g., the bad
memory cell is accessed, so the current domain id and vcpu id recorded
in global->mc_{domid, vcpuid} by mca_init_global() are probably not
precise (e.g. the domain accessed the bad memory was scheduled out,
and MC# comes while another domain is running). If such imprecision
does happen when handling Intel LMCE or AMD MCE, we cannot figure out
in mc_memerr_dhandler() (though it's not called in the current AMD MCE
handling, it intended to be the common code) the exact vcpu that
is affected.

To be worse, if the imprecise global->mc_vcpuid (whose value is in
variable mc_vcpuid) is larger than the maximum vcpu id of the affected
domain (indicated by variable 'd'), the check
    !(d->vcpu[mc_vcpuid]->arch.vmce.lmce_enabled)
is definitely wrong.


Haozhong

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 09/12] x86/vmce, tools/libxl: expose LMCE capability in guest MSR_IA32_MCG_CAP
  2017-03-17  6:46 ` [PATCH v2 09/12] x86/vmce, tools/libxl: expose LMCE capability in guest MSR_IA32_MCG_CAP Haozhong Zhang
  2017-03-20 16:33   ` Jan Beulich
  2017-03-20 18:27   ` Ian Jackson
@ 2017-03-27 15:34   ` Wei Liu
  2 siblings, 0 replies; 35+ messages in thread
From: Wei Liu @ 2017-03-27 15:34 UTC (permalink / raw)
  To: Haozhong Zhang
  Cc: Wei Liu, Andrew Cooper, Ian Jackson, Jan Beulich, xen-devel

On Fri, Mar 17, 2017 at 02:46:11PM +0800, Haozhong Zhang wrote:
> If LMCE is supported by host and ' mca_caps = [ "lmce" ] ' is present
> in xl config, the LMCE capability will be exposed in guest MSR_IA32_MCG_CAP.
> By default, LMCE is not exposed to guest so as to keep the backwards migration
> compatibility.
> 
> Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
[...]
> +static int hvm_set_mca_capabilities(libxl__gc *gc, uint32_t domid,
> +                                    libxl_domain_build_info *const info)
> +{
> +    int i, rc = 0;
> +    const libxl_string_list xl_caps = info->u.hvm.mca_caps;
> +    unsigned long caps = 0;
> +
> +    if (!xl_caps)
> +        return 0;
> +
> +    for (i = 0; xl_caps[i] != NULL; i++) {
> +        if (!strcmp(xl_caps[i], "lmce"))
> +            caps |= HVMMCA_CAP_LMCE;
> +        else {
> +            LOG(ERROR, "Unsupported MCA capability %s", xl_caps[i]);
> +            rc = ERROR_FAIL;
> +            break;
> +        }
> +    }
> +

This is not how we normally do this.  Parsing should normally be done in
xl. Is there any particular reason you chose to parse here?

> +    if (!rc)
> +        rc = xc_hvm_param_set(CTX->xch, domid, HVM_PARAM_MCA_CAP, caps);
> +
> +    return rc;
> +}
>  #endif
>  
>  static void hvm_set_conf_params(xc_interface *handle, uint32_t domid,
> @@ -438,6 +464,10 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
>          rc = hvm_set_viridian_features(gc, domid, info);
>          if (rc)
>              return rc;
> +
> +        rc = hvm_set_mca_capabilities(gc, domid, info);
> +        if (rc)
> +            return rc;
>  #endif
>      }
>  
> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> index a612d1f..71c6c33 100644
> --- a/tools/libxl/libxl_types.idl
> +++ b/tools/libxl/libxl_types.idl
> @@ -550,6 +550,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
>                                         ("serial_list",      libxl_string_list),
>                                         ("rdm", libxl_rdm_reserve),
>                                         ("rdm_mem_boundary_memkb", MemKB),
> +                                       ("mca_caps",         libxl_string_list),

You need to add a LIBXL_HAVE_MCA_CAPS to libxl.h

Wei.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 11/12] tools/libxc: add support of injecting MC# to specified CPUs
  2017-03-17  6:46 ` [PATCH v2 11/12] tools/libxc: add support of injecting MC# to specified CPUs Haozhong Zhang
@ 2017-03-28 14:07   ` Wei Liu
  0 siblings, 0 replies; 35+ messages in thread
From: Wei Liu @ 2017-03-28 14:07 UTC (permalink / raw)
  To: Haozhong Zhang; +Cc: Wei Liu, Ian Jackson, xen-devel

On Fri, Mar 17, 2017 at 02:46:13PM +0800, Haozhong Zhang wrote:
> Though XEN_MC_inject_v2 allows injecting MC# to specified CPUs, the
> current xc_mca_op() does not use this feature and not provide an
> interface to callers. This commit add a new xc_mca_op_inject_v2() that
> receives a cpumap providing the set of target CPUs.
> 
> Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
> ---
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> 
> Changes in v2:
>  * Separate the libxc changes from v1 patch 19 to this one.
>  * Build the bounce buffer completely in one function.
> ---
>  tools/libxc/include/xenctrl.h |  2 ++
>  tools/libxc/xc_misc.c         | 52 ++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 53 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
> index a48981a..d7ecc02 100644
> --- a/tools/libxc/include/xenctrl.h
> +++ b/tools/libxc/include/xenctrl.h
> @@ -1773,6 +1773,8 @@ int xc_cpuid_apply_policy(xc_interface *xch,
>  void xc_cpuid_to_str(const unsigned int *regs,
>                       char **strs); /* some strs[] may be NULL if ENOMEM */
>  int xc_mca_op(xc_interface *xch, struct xen_mc *mc);
> +int xc_mca_op_inject_v2(xc_interface *xch, unsigned int flags,
> +                        xc_cpumap_t cpumap, unsigned int nr_cpus);
>  #endif
>  
>  struct xc_px_val {
> diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
> index 88084fd..52ff7b1 100644
> --- a/tools/libxc/xc_misc.c
> +++ b/tools/libxc/xc_misc.c
> @@ -341,7 +341,57 @@ int xc_mca_op(xc_interface *xch, struct xen_mc *mc)
>      xc_hypercall_bounce_post(xch, mc);
>      return ret;
>  }
> -#endif
> +
> +int xc_mca_op_inject_v2(xc_interface *xch, unsigned int flags,
> +                        xc_cpumap_t cpumap, unsigned int nr_bits)
> +{
> +    int ret = -1;
> +    struct xen_mc mc_buf, *mc = &mc_buf;
> +    struct xen_mc_inject_v2 *inject = &mc->u.mc_inject_v2;
> +
> +    DECLARE_HYPERCALL_BOUNCE(cpumap, 0, XC_HYPERCALL_BUFFER_BOUNCE_IN);
> +    DECLARE_HYPERCALL_BOUNCE(mc, sizeof(*mc), XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
> +
> +    memset(mc, 0, sizeof(*mc));
> +
> +    if ( cpumap )
> +    {
> +        if ( !nr_bits )
> +        {
> +            errno = EINVAL;
> +            return -1;

Please use goto out here. I don't want to mix different error handling
styles.

> +        }
> +
> +        HYPERCALL_BOUNCE_SET_SIZE(cpumap, (nr_bits + 7) / 8);
> +        if ( xc_hypercall_bounce_pre(xch, cpumap) )
> +        {
> +            PERROR("Could not bounce cpumap memory buffer");
> +            return -1;

Ditto.

> +        }
> +        set_xen_guest_handle(inject->cpumap.bitmap, cpumap);
> +        inject->cpumap.nr_bits = nr_bits;
> +    }
> +
> +    inject->flags = flags;
> +    mc->cmd = XEN_MC_inject_v2;
> +    mc->interface_version = XEN_MCA_INTERFACE_VERSION;
> +
> +    if ( xc_hypercall_bounce_pre(xch, mc) )
> +    {
> +        PERROR("Could not bounce xen_mc memory buffer");
> +        goto out;
> +    }
> +
> +    ret = xencall1(xch->xcall, __HYPERVISOR_mca, HYPERCALL_BUFFER_AS_ARG(mc));
> +
> +    xc_hypercall_bounce_post(xch, mc);
> +out:
> +    if ( cpumap )
> +        xc_hypercall_bounce_post(xch, cpumap);
> +
> +    return ret;
> +}
> +#endif /* __i386__ || __x86_64__ */
>  
>  int xc_perfc_reset(xc_interface *xch)
>  {
> -- 
> 2.10.1
> 

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 12/12] tools/xen-mceinj: add support of injecting LMCE
  2017-03-17  6:46 ` [PATCH v2 12/12] tools/xen-mceinj: add support of injecting LMCE Haozhong Zhang
@ 2017-03-28 14:08   ` Wei Liu
  0 siblings, 0 replies; 35+ messages in thread
From: Wei Liu @ 2017-03-28 14:08 UTC (permalink / raw)
  To: Haozhong Zhang; +Cc: Wei Liu, Ian Jackson, xen-devel

On Fri, Mar 17, 2017 at 02:46:14PM +0800, Haozhong Zhang wrote:
> If option '-l' or '--lmce' is specified and the host supports LMCE,
> xen-mceinj will inject LMCE to CPU specified by '-c' (or CPU0 if '-c'
> is not present).
> 
> Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>


Acked-by: Wei Liu <wei.liu2@citrix.com>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2017-03-28 14:08 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-17  6:46 [PATCH v2 00/12] Add LMCE support Haozhong Zhang
2017-03-17  6:46 ` [PATCH v2 01/12] xen/mce: switch bool_t/1/0 to bool/true/false Haozhong Zhang
2017-03-20 13:04   ` Jan Beulich
2017-03-17  6:46 ` [PATCH v2 02/12] x86/mce_intel: refine messages of MCA capabilities Haozhong Zhang
2017-03-20 13:10   ` Jan Beulich
2017-03-17  6:46 ` [PATCH v2 03/12] xen/mce: add blank lines between non-fall-through switch case blocks Haozhong Zhang
2017-03-20 13:12   ` Jan Beulich
2017-03-17  6:46 ` [PATCH v2 04/12] x86/mce: handle LMCE locally Haozhong Zhang
2017-03-20 14:24   ` Jan Beulich
2017-03-21  7:04     ` Haozhong Zhang
2017-03-17  6:46 ` [PATCH v2 05/12] x86/mce_intel: detect and enable LMCE on Intel host Haozhong Zhang
2017-03-20 14:30   ` Jan Beulich
2017-03-21  7:06     ` Haozhong Zhang
2017-03-21  8:05       ` Jan Beulich
2017-03-17  6:46 ` [PATCH v2 06/12] x86/vmx: expose LMCE feature via guest MSR_IA32_FEATURE_CONTROL Haozhong Zhang
2017-03-20 16:10   ` Jan Beulich
2017-03-17  6:46 ` [PATCH v2 07/12] x86/vmce: emulate MSR_IA32_MCG_EXT_CTL Haozhong Zhang
2017-03-20 16:17   ` Jan Beulich
2017-03-17  6:46 ` [PATCH v2 08/12] x86/vmce: enable injecting LMCE to guest on Intel host Haozhong Zhang
2017-03-20 16:25   ` Jan Beulich
2017-03-22  9:19     ` Haozhong Zhang
2017-03-17  6:46 ` [PATCH v2 09/12] x86/vmce, tools/libxl: expose LMCE capability in guest MSR_IA32_MCG_CAP Haozhong Zhang
2017-03-20 16:33   ` Jan Beulich
2017-03-21  7:14     ` Haozhong Zhang
2017-03-20 18:27   ` Ian Jackson
2017-03-21  7:29     ` Haozhong Zhang
2017-03-21  7:35       ` Haozhong Zhang
2017-03-21  9:30     ` Jan Beulich
2017-03-27 15:34   ` Wei Liu
2017-03-17  6:46 ` [PATCH v2 10/12] xen/mce: add support of vLMCE injection to XEN_MC_inject_v2 Haozhong Zhang
2017-03-20 16:37   ` Jan Beulich
2017-03-17  6:46 ` [PATCH v2 11/12] tools/libxc: add support of injecting MC# to specified CPUs Haozhong Zhang
2017-03-28 14:07   ` Wei Liu
2017-03-17  6:46 ` [PATCH v2 12/12] tools/xen-mceinj: add support of injecting LMCE Haozhong Zhang
2017-03-28 14:08   ` Wei Liu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.