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

[Xen-changelog] [xen-unstable] svm: Fix for AMD erratum 383 on Family 10h CPUs



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1274178085 -3600
# Node ID f40acba36be886e4b4e87afeacf39688f316dfe4
# Parent  e4028345ad48c442eb55b7bc08afdf1aede0aa2e
svm: Fix for AMD erratum 383 on Family 10h CPUs

This patches implements the workaround of AMD erratum 383 on family
10h CPUs. It destroys the guest VM when a MC error with a special
pattern is detected. Without this patch, a guest VM failure can
potentially crash Xen hypervisor and the whole system. The erratum
will be published in next version of guide.

Signed-off-by: Wei Huang <wei.huang2@xxxxxxx>
Signed-off-by: Joerg Roedel <joerg.roedel@xxxxxxx>
Signed-off-by: Christoph Egger <christoph.egger@xxxxxxx>
---
 xen/arch/x86/hvm/svm/svm.c      |   61 ++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-x86/msr-index.h |    6 +++
 2 files changed, 67 insertions(+)

diff -r e4028345ad48 -r f40acba36be8 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Mon May 17 18:52:01 2010 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c        Tue May 18 11:21:25 2010 +0100
@@ -73,6 +73,8 @@ static void *hsa[NR_CPUS] __read_mostly;
 /* vmcb used for extended host state */
 static void *root_vmcb[NR_CPUS] __read_mostly;
 
+static bool_t amd_erratum383_found __read_mostly;
+
 static void inline __update_guest_eip(
     struct cpu_user_regs *regs, unsigned int inst_len)
 {
@@ -840,6 +842,20 @@ static int svm_cpu_up_prepare(unsigned i
     return 0;
 }
 
+static void svm_init_erratum_383(struct cpuinfo_x86 *c)
+{
+    uint64_t msr_content;
+
+    /* only family 10h is affected */
+    if ( c->x86 != 0x10 )
+        return;
+
+    rdmsrl(MSR_AMD64_DC_CFG, msr_content);
+    wrmsrl(MSR_AMD64_DC_CFG, msr_content | (1ULL << 47));
+
+    amd_erratum383_found = 1;
+}
+
 static int svm_cpu_up(struct cpuinfo_x86 *c)
 {
     u32 eax, edx, phys_hsa_lo, phys_hsa_hi;   
@@ -864,6 +880,9 @@ static int svm_cpu_up(struct cpuinfo_x86
     phys_hsa_lo = (u32)phys_hsa;
     phys_hsa_hi = (u32)(phys_hsa >> 32);    
     wrmsr(MSR_K8_VM_HSAVE_PA, phys_hsa_lo, phys_hsa_hi);
+
+    /* check for erratum 383 */
+    svm_init_erratum_383(c);
 
     /* Initialize core's ASID handling. */
     svm_asid_init(c);
@@ -1284,6 +1303,47 @@ static void svm_vmexit_ud_intercept(stru
     default:
         hvm_emulate_writeback(&ctxt);
         break;
+    }
+}
+
+extern unsigned int nr_mce_banks; /* from mce.h */
+
+static int svm_is_erratum_383(struct cpu_user_regs *regs)
+{
+    uint64_t msr_content;
+    uint32_t i;
+    struct vcpu *v = current;
+
+    if ( !amd_erratum383_found )
+        return 0;
+
+    rdmsrl(MSR_IA32_MC0_STATUS, msr_content);
+    /* Bit 62 may or may not be set for this mce */
+    msr_content &= ~(1ULL << 62);
+
+    if ( msr_content != 0xb600000000010015ULL )
+        return 0;
+    
+    /* Clear MCi_STATUS registers */
+    for (i = 0; i < nr_mce_banks; i++)
+        wrmsrl(MSR_IA32_MCx_STATUS(i), 0ULL);
+    
+    rdmsrl(MSR_IA32_MCG_STATUS, msr_content);
+    wrmsrl(MSR_IA32_MCG_STATUS, msr_content & ~(1ULL << 2));
+
+    /* flush TLB */
+    flush_tlb_mask(&v->domain->domain_dirty_cpumask);
+
+    return 1;
+}
+
+static void svm_vmexit_mce_intercept(
+    struct vcpu *v, struct cpu_user_regs *regs)
+{
+    if ( svm_is_erratum_383(regs) )
+    {
+        gdprintk(XENLOG_ERR, "SVM hits AMD erratum 383\n");
+        domain_crash(v->domain);
     }
 }
 
@@ -1493,6 +1553,7 @@ asmlinkage void svm_vmexit_handler(struc
     /* Asynchronous event, handled when we STGI'd after the VMEXIT. */
     case VMEXIT_EXCEPTION_MC:
         HVMTRACE_0D(MCE);
+        svm_vmexit_mce_intercept(v, regs);
         break;
 
     case VMEXIT_VINTR:
diff -r e4028345ad48 -r f40acba36be8 xen/include/asm-x86/msr-index.h
--- a/xen/include/asm-x86/msr-index.h   Mon May 17 18:52:01 2010 +0100
+++ b/xen/include/asm-x86/msr-index.h   Tue May 18 11:21:25 2010 +0100
@@ -145,6 +145,11 @@
 #define MSR_IA32_MC8_STATUS            0x00000421
 #define MSR_IA32_MC8_ADDR              0x00000422
 #define MSR_IA32_MC8_MISC              0x00000423
+
+#define MSR_IA32_MCx_CTL(x)            (MSR_IA32_MC0_CTL + 4*(x))
+#define MSR_IA32_MCx_STATUS(x)         (MSR_IA32_MC0_STATUS + 4*(x))
+#define MSR_IA32_MCx_ADDR(x)           (MSR_IA32_MC0_ADDR + 4*(x))
+#define MSR_IA32_MCx_MISC(x)           (MSR_IA32_MC0_MISC + 4*(x)) 
 
 #define MSR_P6_PERFCTR0                        0x000000c1
 #define MSR_P6_PERFCTR1                        0x000000c2
@@ -225,6 +230,7 @@
 
 /* AMD64 MSRs */
 #define MSR_AMD64_NB_CFG               0xc001001f
+#define MSR_AMD64_DC_CFG               0xc0011022
 #define AMD64_NB_CFG_CF8_EXT_ENABLE_BIT        46
 
 /* AMD Family10h machine check MSRs */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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