WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] Fix for AMD erratum 383 on Family 10h CPUs

To: "'xen-devel@xxxxxxxxxxxxxxxxxxx'" <xen-devel@xxxxxxxxxxxxxxxxxxx>, Keir Fraser <keir.fraser@xxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] Fix for AMD erratum 383 on Family 10h CPUs
From: Wei Huang <wei.huang2@xxxxxxx>
Date: Mon, 17 May 2010 13:57:25 -0500
Cc:
Delivery-date: Mon, 17 May 2010 12:06:51 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Thunderbird 2.0.0.17 (X11/20080914)
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>


diff -r baccadfd9418 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Fri May 14 08:05:05 2010 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c        Mon May 17 07:37:19 2010 -0500
@@ -72,6 +72,9 @@
 
 /* vmcb used for extended host state */
 static void *root_vmcb[NR_CPUS] __read_mostly;
+
+/* for AMD erratum 383 */
+static bool_t amd_erratum383_found __read_mostly;
 
 static void inline __update_guest_eip(
     struct cpu_user_regs *regs, unsigned int inst_len)
@@ -828,6 +831,20 @@
     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;   
@@ -852,6 +869,9 @@
     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);
@@ -1275,6 +1295,45 @@
     }
 }
 
+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);
+    }
+}
+
 static void wbinvd_ipi(void *info)
 {
     wbinvd();
@@ -1480,6 +1539,7 @@
     /* 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 baccadfd9418 xen/include/asm-x86/msr-index.h
--- a/xen/include/asm-x86/msr-index.h   Fri May 14 08:05:05 2010 +0100
+++ b/xen/include/asm-x86/msr-index.h   Mon May 17 07:37:19 2010 -0500
@@ -146,6 +146,11 @@
 #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
 #define MSR_P6_EVNTSEL0                        0x00000186
@@ -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-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>