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-changelog

[Xen-changelog] [xen-unstable] Implements Guest MCE# MSR read/write virt

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Implements Guest MCE# MSR read/write virtualization
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 20 Mar 2009 10:45:17 -0700
Delivery-date: Fri, 20 Mar 2009 10:45:53 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1237569893 0
# Node ID cc60defe5b9697ab0e068caa4fd1f8798bfe5104
# Parent  c44c963ea1625314aef37487f0bc9e0924f39614
Implements Guest MCE# MSR read/write virtualization

Signed-off-by: Jiang, Yunhong <yunhong.jiang@xxxxxxxxx>
Signed-off-by: Ke, Liping <liping.ke@xxxxxxxxx>
---
 xen/arch/x86/cpu/mcheck/mce_intel.c |  257 ++++++++++++++++++++++++++++++++++++
 xen/arch/x86/traps.c                |   21 ++
 xen/include/asm-x86/msr-index.h     |   24 +++
 3 files changed, 300 insertions(+), 2 deletions(-)

diff -r c44c963ea162 -r cc60defe5b96 xen/arch/x86/cpu/mcheck/mce_intel.c
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c       Fri Mar 20 17:24:29 2009 +0000
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c       Fri Mar 20 17:24:53 2009 +0000
@@ -812,3 +812,260 @@ int intel_mcheck_init(struct cpuinfo_x86
     open_softirq(MACHINE_CHECK_SOFTIRQ, mce_softirq);
     return 1;
 }
+
+/* Guest vMCE# MSRs virtualization ops (rdmsr/wrmsr) */
+int intel_mce_wrmsr(u32 msr, u32 lo, u32 hi)
+{
+    struct domain *d = current->domain;
+    struct bank_entry *entry = NULL;
+    uint64_t value = (u64)hi << 32 | lo;
+    int ret = 0;
+
+    spin_lock(&mce_locks);
+    switch(msr)
+    {
+        case MSR_IA32_MCG_CTL:
+            if (value != (u64)~0x0 && value != 0x0) {
+                printk(KERN_ERR "MCE: value writen to MCG_CTL"
+                    "should be all 0s or 1s\n");
+                ret = -1;
+                break;
+            }
+            if (!d || is_idle_domain(d)) {
+                printk(KERN_ERR "MCE: wrmsr not in DOM context, skip\n");
+                break;
+            }
+            d->arch.vmca_msrs.mcg_ctl = value;
+            break;
+        case MSR_IA32_MCG_STATUS:
+            if (!d || is_idle_domain(d)) {
+                printk(KERN_ERR "MCE: wrmsr not in DOM context, skip\n");
+                break;
+            }
+            d->arch.vmca_msrs.mcg_status = value;
+            printk(KERN_DEBUG "MCE: wrmsr MCG_CTL %lx\n", value);
+            break;
+        case MSR_IA32_MC0_CTL2:
+        case MSR_IA32_MC1_CTL2:
+        case MSR_IA32_MC2_CTL2:
+        case MSR_IA32_MC3_CTL2:
+        case MSR_IA32_MC4_CTL2:
+        case MSR_IA32_MC5_CTL2:
+        case MSR_IA32_MC6_CTL2:
+        case MSR_IA32_MC7_CTL2:
+        case MSR_IA32_MC8_CTL2:
+            printk(KERN_ERR "We have disabled CMCI capability, "
+                    "Guest should not write this MSR!\n");
+            break;
+        case MSR_IA32_MC0_CTL:
+        case MSR_IA32_MC1_CTL:
+        case MSR_IA32_MC2_CTL:
+        case MSR_IA32_MC3_CTL:
+        case MSR_IA32_MC4_CTL:
+        case MSR_IA32_MC5_CTL:
+        case MSR_IA32_MC6_CTL:
+        case MSR_IA32_MC7_CTL:
+        case MSR_IA32_MC8_CTL:
+            if (value != (u64)~0x0 && value != 0x0) {
+                printk(KERN_ERR "MCE: value writen to MCi_CTL"
+                    "should be all 0s or 1s\n");
+                ret = -1;
+                break;
+            }
+            if (!d || is_idle_domain(d)) {
+                printk(KERN_ERR "MCE: wrmsr not in DOM context, skip\n");
+                break;
+            }
+            d->arch.vmca_msrs.mci_ctl[(msr - MSR_IA32_MC0_CTL)/4] = value;
+            break;
+        case MSR_IA32_MC0_STATUS:
+        case MSR_IA32_MC1_STATUS:
+        case MSR_IA32_MC2_STATUS:
+        case MSR_IA32_MC3_STATUS:
+        case MSR_IA32_MC4_STATUS:
+        case MSR_IA32_MC5_STATUS:
+        case MSR_IA32_MC6_STATUS:
+        case MSR_IA32_MC7_STATUS:
+        case MSR_IA32_MC8_STATUS:
+            if (!d || is_idle_domain(d)) {
+                /* Just skip */
+                printk(KERN_ERR "mce wrmsr: not in domain context!\n");
+                break;
+            }
+            /* Give the first entry of the list, it corresponds to current
+             * vMCE# injection. When vMCE# is finished processing by the
+             * the guest, this node will be deleted.
+             * Only error bank is written. Non-error bank simply return.
+             */
+            if ( !list_empty(&d->arch.vmca_msrs.impact_header) ) {
+                entry = list_entry(d->arch.vmca_msrs.impact_header.next,
+                    struct bank_entry, list);
+                if ( entry->bank == (msr - MSR_IA32_MC0_STATUS)/4 ) {
+                    entry->mci_status = value;
+                }
+                printk(KERN_DEBUG "MCE: wmrsr mci_status in vMCE# context\n");
+            }
+            printk(KERN_DEBUG "MCE: wrmsr mci_status val:%lx\n", value);
+            break;
+    }
+    spin_unlock(&mce_locks);
+    return ret;
+}
+
+int intel_mce_rdmsr(u32 msr, u32 *lo, u32 *hi)
+{
+    struct domain *d = current->domain;
+    int ret = 0;
+    struct bank_entry *entry = NULL;
+
+    *lo = *hi = 0x0;
+    spin_lock(&mce_locks);
+    switch(msr)
+    {
+        case MSR_IA32_MCG_STATUS:
+            if (!d || is_idle_domain(d)) {
+                printk(KERN_ERR "MCE: rdmsr not in domain context!\n");
+                *lo = *hi = 0x0;
+                break;
+            }
+            *lo = (u32)d->arch.vmca_msrs.mcg_status;
+            *hi = (u32)(d->arch.vmca_msrs.mcg_status >> 32);
+            printk(KERN_DEBUG "MCE: rd MCG_STATUS lo %x hi %x\n", *lo, *hi);
+            break;
+        case MSR_IA32_MCG_CAP:
+            if (!d || is_idle_domain(d)) {
+                printk(KERN_ERR "MCE: rdmsr not in domain context!\n");
+                *lo = *hi = 0x0;
+                break;
+            }
+            *lo = (u32)d->arch.vmca_msrs.mcg_cap;
+            *hi = (u32)(d->arch.vmca_msrs.mcg_cap >> 32);
+            printk(KERN_DEBUG "MCE: rdmsr MCG_CAP lo %x hi %x\n", *lo, *hi);
+            break;
+        case MSR_IA32_MCG_CTL:
+            if (!d || is_idle_domain(d)) {
+                printk(KERN_ERR "MCE: rdmsr not in domain context!\n");
+                *lo = *hi = 0x0;
+                break;
+            }
+            *lo = (u32)d->arch.vmca_msrs.mcg_ctl;
+            *hi = (u32)(d->arch.vmca_msrs.mcg_ctl >> 32);
+            printk(KERN_DEBUG "MCE: rdmsr MCG_CTL lo %x hi %x\n", *lo, *hi);
+            break;
+        case MSR_IA32_MC0_CTL2:
+        case MSR_IA32_MC1_CTL2:
+        case MSR_IA32_MC2_CTL2:
+        case MSR_IA32_MC3_CTL2:
+        case MSR_IA32_MC4_CTL2:
+        case MSR_IA32_MC5_CTL2:
+        case MSR_IA32_MC6_CTL2:
+        case MSR_IA32_MC7_CTL2:
+        case MSR_IA32_MC8_CTL2:
+            printk(KERN_WARNING "We have disabled CMCI capability, "
+                    "Guest should not read this MSR!\n");
+            break;
+        case MSR_IA32_MC0_CTL:
+        case MSR_IA32_MC1_CTL:
+        case MSR_IA32_MC2_CTL:
+        case MSR_IA32_MC3_CTL:
+        case MSR_IA32_MC4_CTL:
+        case MSR_IA32_MC5_CTL:
+        case MSR_IA32_MC6_CTL:
+        case MSR_IA32_MC7_CTL:
+        case MSR_IA32_MC8_CTL:
+            if (!d || is_idle_domain(d)) {
+                printk(KERN_ERR "MCE: rdmsr not in domain context!\n");
+                *lo = *hi = 0x0;
+                break;
+            }
+            *lo = (u32)d->arch.vmca_msrs.mci_ctl[(msr - MSR_IA32_MC0_CTL)/4];
+            *hi =
+                (u32)(d->arch.vmca_msrs.mci_ctl[(msr - MSR_IA32_MC0_CTL)/4]
+                    >> 32);
+            printk(KERN_DEBUG "MCE: rdmsr MCi_CTL lo %x hi %x\n", *lo, *hi);
+            break;
+        case MSR_IA32_MC0_STATUS:
+        case MSR_IA32_MC1_STATUS:
+        case MSR_IA32_MC2_STATUS:
+        case MSR_IA32_MC3_STATUS:
+        case MSR_IA32_MC4_STATUS:
+        case MSR_IA32_MC5_STATUS:
+        case MSR_IA32_MC6_STATUS:
+        case MSR_IA32_MC7_STATUS:
+        case MSR_IA32_MC8_STATUS:
+            /* Only error bank is read. Non-error bank simply return */
+            *lo = *hi = 0x0;
+            printk(KERN_DEBUG "MCE: rdmsr mci_status\n");
+            if (!d || is_idle_domain(d)) {
+                printk(KERN_ERR "mce_rdmsr: not in domain context!\n");
+                break;
+            }
+            if (!list_empty(&d->arch.vmca_msrs.impact_header)) {
+                entry = list_entry(d->arch.vmca_msrs.impact_header.next,
+                    struct bank_entry, list);
+                if ( entry->bank == (msr - MSR_IA32_MC0_STATUS)/4 ) {
+                    *lo = entry->mci_status;
+                    *hi = entry->mci_status >> 32;
+                    printk(KERN_DEBUG "MCE: rdmsr MCi_STATUS in vmCE# context "
+                        "lo %x hi %x\n", *lo, *hi);
+                }
+            }
+            break;
+        case MSR_IA32_MC0_ADDR:
+        case MSR_IA32_MC1_ADDR:
+        case MSR_IA32_MC2_ADDR:
+        case MSR_IA32_MC3_ADDR:
+        case MSR_IA32_MC4_ADDR:
+        case MSR_IA32_MC5_ADDR:
+        case MSR_IA32_MC6_ADDR:
+        case MSR_IA32_MC7_ADDR:
+        case MSR_IA32_MC8_ADDR:
+            *lo = *hi = 0x0;
+            if (!d || is_idle_domain(d)) {
+                printk(KERN_ERR "mce_rdmsr: not in domain context!\n");
+                break;
+            }
+            if (!list_empty(&d->arch.vmca_msrs.impact_header)) {
+                entry = list_entry(d->arch.vmca_msrs.impact_header.next,
+                    struct bank_entry, list);
+                if ( entry->bank == (msr - MSR_IA32_MC0_ADDR)/4 ) {
+                    *lo = entry->mci_addr;
+                    *hi = entry->mci_addr >> 32;
+                    printk(KERN_DEBUG "MCE: rdmsr MCi_ADDR in vMCE# context "
+                        "lo %x hi %x\n", *lo, *hi);
+                }
+            }
+            break;
+        case MSR_IA32_MC0_MISC:
+        case MSR_IA32_MC1_MISC:
+        case MSR_IA32_MC2_MISC:
+        case MSR_IA32_MC3_MISC:
+        case MSR_IA32_MC4_MISC:
+        case MSR_IA32_MC5_MISC:
+        case MSR_IA32_MC6_MISC:
+        case MSR_IA32_MC7_MISC:
+        case MSR_IA32_MC8_MISC:
+            *lo = *hi = 0x0;
+            if (!d || is_idle_domain(d)) {
+                printk(KERN_ERR "MCE: rdmsr not in domain context!\n");
+                break;
+            }
+            if (!list_empty(&d->arch.vmca_msrs.impact_header)) {
+                entry = list_entry(d->arch.vmca_msrs.impact_header.next,
+                    struct bank_entry, list);
+                if ( entry->bank == (msr - MSR_IA32_MC0_MISC)/4 ) {
+                    *lo = entry->mci_misc;
+                    *hi = entry->mci_misc >> 32;
+                    printk(KERN_DEBUG "MCE: rdmsr MCi_MISC in vMCE# context "
+                        " lo %x hi %x\n", *lo, *hi);
+                }
+            }
+            break;
+        default:
+            break;
+    }
+    spin_unlock(&mce_locks);
+    return ret;
+}
+
+
diff -r c44c963ea162 -r cc60defe5b96 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Fri Mar 20 17:24:29 2009 +0000
+++ b/xen/arch/x86/traps.c      Fri Mar 20 17:24:53 2009 +0000
@@ -728,8 +728,6 @@ static void pv_cpuid(struct cpu_user_reg
         if ( !opt_allow_hugepage )
             __clear_bit(X86_FEATURE_PSE, &d);
         __clear_bit(X86_FEATURE_PGE, &d);
-        __clear_bit(X86_FEATURE_MCE, &d);
-        __clear_bit(X86_FEATURE_MCA, &d);
         __clear_bit(X86_FEATURE_PSE36, &d);
     }
     switch ( (uint32_t)regs->eax )
@@ -1638,6 +1636,10 @@ static int is_cpufreq_controller(struct 
     return ((cpufreq_controller == FREQCTL_dom0_kernel) &&
             (d->domain_id == 0));
 }
+
+/*Intel vMCE MSRs virtualization*/
+extern int intel_mce_wrmsr(u32 msr, u32 lo,  u32 hi);
+extern int intel_mce_rdmsr(u32 msr, u32 *lo,  u32 *hi);
 
 static int emulate_privileged_op(struct cpu_user_regs *regs)
 {
@@ -2206,6 +2208,15 @@ static int emulate_privileged_op(struct 
         default:
             if ( wrmsr_hypervisor_regs(regs->ecx, eax, edx) )
                 break;
+            if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
+                if ( intel_mce_wrmsr(regs->ecx, eax, edx) != 0) {
+                    gdprintk(XENLOG_ERR, "MCE: vMCE MSRS(%lx) Write"
+                        " (%x:%x) Fails! ", regs->ecx, edx, eax);
+                    goto fail;
+                }
+                break;
+            }
+
             if ( (rdmsr_safe(regs->ecx, l, h) != 0) ||
                  (eax != l) || (edx != h) )
         invalid:
@@ -2289,6 +2300,12 @@ static int emulate_privileged_op(struct 
                         _p(regs->ecx));*/
             if ( rdmsr_safe(regs->ecx, regs->eax, regs->edx) )
                 goto fail;
+
+            if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
+                if ( intel_mce_rdmsr(regs->ecx, &eax, &edx) != 0)
+                    printk(KERN_ERR "MCE: Not MCE MSRs %lx\n", regs->ecx);
+            }
+
             break;
         }
         break;
diff -r c44c963ea162 -r cc60defe5b96 xen/include/asm-x86/msr-index.h
--- a/xen/include/asm-x86/msr-index.h   Fri Mar 20 17:24:29 2009 +0000
+++ b/xen/include/asm-x86/msr-index.h   Fri Mar 20 17:24:53 2009 +0000
@@ -96,29 +96,53 @@
 #define CMCI_EN                        (1UL<<30)
 #define CMCI_THRESHOLD_MASK            0x7FFF
 
+#define MSR_IA32_MC1_CTL               0x00000404
+#define MSR_IA32_MC1_CTL2              0x00000281
 #define MSR_IA32_MC1_STATUS            0x00000405
 #define MSR_IA32_MC1_ADDR              0x00000406
 #define MSR_IA32_MC1_MISC              0x00000407
 
 #define MSR_IA32_MC2_CTL               0x00000408
+#define MSR_IA32_MC2_CTL2              0x00000282
 #define MSR_IA32_MC2_STATUS            0x00000409
 #define MSR_IA32_MC2_ADDR              0x0000040A
 #define MSR_IA32_MC2_MISC              0x0000040B
 
+#define MSR_IA32_MC3_CTL2              0x00000283
 #define MSR_IA32_MC3_CTL               0x0000040C
 #define MSR_IA32_MC3_STATUS            0x0000040D
 #define MSR_IA32_MC3_ADDR              0x0000040E
 #define MSR_IA32_MC3_MISC              0x0000040F
 
+#define MSR_IA32_MC4_CTL2              0x00000284
 #define MSR_IA32_MC4_CTL               0x00000410
 #define MSR_IA32_MC4_STATUS            0x00000411
 #define MSR_IA32_MC4_ADDR              0x00000412
 #define MSR_IA32_MC4_MISC              0x00000413
 
+#define MSR_IA32_MC5_CTL2              0x00000285
 #define MSR_IA32_MC5_CTL               0x00000414
 #define MSR_IA32_MC5_STATUS            0x00000415
 #define MSR_IA32_MC5_ADDR              0x00000416
 #define MSR_IA32_MC5_MISC              0x00000417
+
+#define MSR_IA32_MC6_CTL2              0x00000286
+#define MSR_IA32_MC6_CTL               0x00000418
+#define MSR_IA32_MC6_STATUS            0x00000419
+#define MSR_IA32_MC6_ADDR              0x0000041A
+#define MSR_IA32_MC6_MISC              0x0000041B
+
+#define MSR_IA32_MC7_CTL2              0x00000287
+#define MSR_IA32_MC7_CTL               0x0000041C
+#define MSR_IA32_MC7_STATUS            0x0000041D
+#define MSR_IA32_MC7_ADDR              0x0000041E
+#define MSR_IA32_MC7_MISC              0x0000041F
+
+#define MSR_IA32_MC8_CTL2              0x00000288
+#define MSR_IA32_MC8_CTL               0x00000420
+#define MSR_IA32_MC8_STATUS            0x00000421
+#define MSR_IA32_MC8_ADDR              0x00000422
+#define MSR_IA32_MC8_MISC              0x00000423
 
 #define MSR_P6_PERFCTR0                        0x000000c1
 #define MSR_P6_PERFCTR1                        0x000000c2

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Implements Guest MCE# MSR read/write virtualization, Xen patchbot-unstable <=