[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 16/19] x86/vmce: enable injecting LMCE to guest on Intel host



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@xxxxxxxxx>
---
Cc: Christoph Egger <chegger@xxxxxxxxx>
Cc: Liu Jinsong <jinsong.liu@xxxxxxxxxxxxxxx>
Cc: Jan Beulich <jbeulich@xxxxxxxx>
Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 xen/arch/x86/cpu/mcheck/mcaction.c | 14 ++++++++------
 xen/arch/x86/cpu/mcheck/vmce.c     |  9 ++++++++-
 xen/arch/x86/cpu/mcheck/vmce.h     |  2 +-
 3 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/xen/arch/x86/cpu/mcheck/mcaction.c 
b/xen/arch/x86/cpu/mcheck/mcaction.c
index 90c68ff..3410bfd 100644
--- a/xen/arch/x86/cpu/mcheck/mcaction.c
+++ b/xen/arch/x86/cpu/mcheck/mcaction.c
@@ -88,17 +88,19 @@ mc_memerr_dhandler(struct mca_binfo *binfo,
                     goto vmce_failed;
                 }
 
-                if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
+                vmce_vcpuid = global->mc_vcpuid;
+                if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
+                     (vmce_vcpuid == -1 ||
+                      global->mc_domid != bank->mc_domid ||
+                      !(global->mc_gstatus & MCG_STATUS_LMCE) ||
+                      !d->vcpu[vmce_vcpuid]->arch.vmce.lmce_enabled) )
                     vmce_vcpuid = VMCE_INJECT_BROADCAST;
-                else
-                    vmce_vcpuid = global->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) == 
-1 )
+                                    global->mc_gstatus,
+                                    vmce_vcpuid) == -1 )
                 {
                     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 1278839..2a4d3f0 100644
--- a/xen/arch/x86/cpu/mcheck/vmce.c
+++ b/xen/arch/x86/cpu/mcheck/vmce.c
@@ -444,14 +444,21 @@ 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;
 
     if ( mc_bank->mc_domid == (uint16_t)~0 )
         return -EINVAL;
 
+    if ( (gstatus & MCG_STATUS_LMCE) && !broadcast )
+        v = d->vcpu[vmce_vcpuid];
+
+    if ( broadcast )
+        gstatus &= ~MCG_STATUS_LMCE;
+
     ret = vcpu_fill_mc_msrs(v, gstatus, mc_bank->mc_status,
                             mc_bank->mc_addr, mc_bank->mc_misc);
     if ( ret || !broadcast )
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@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.