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] vmce: Clean up implementation and setup/d

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] vmce: Clean up implementation and setup/destroy.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 06 May 2010 04:10:44 -0700
Delivery-date: Thu, 06 May 2010 04:16:12 -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 1273142349 -3600
# Node ID 26da9bb87405c64c02def8d5f11c66f15847bd02
# Parent  24a00bbe7cc0c1dd1293ac78f98b30399db64343
vmce: Clean up implementation and setup/destroy.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/cpu/mcheck/vmce.c |  274 +++++++++++++++++++----------------------
 xen/arch/x86/domain.c          |    2 
 xen/common/domain.c            |    2 
 xen/include/asm-x86/mce.h      |    3 
 4 files changed, 131 insertions(+), 150 deletions(-)

diff -r 24a00bbe7cc0 -r 26da9bb87405 xen/arch/x86/cpu/mcheck/vmce.c
--- a/xen/arch/x86/cpu/mcheck/vmce.c    Thu May 06 11:19:28 2010 +0100
+++ b/xen/arch/x86/cpu/mcheck/vmce.c    Thu May 06 11:39:09 2010 +0100
@@ -18,15 +18,10 @@
 #include "mce.h"
 #include "x86_mca.h"
 
+#define dom_vmce(x)   ((x)->arch.vmca_msrs)
+
 int vmce_init_msr(struct domain *d)
 {
-    if ( dom_vmce(d) )
-    {
-        dprintk(XENLOG_G_WARNING, "Domain %d has inited vMCE\n", d->domain_id);
-        return 0;
-    }
-
-    /* Allocate the vmca_msrs and mci_ctl togother */
     dom_vmce(d) = xmalloc(struct domain_mca_msrs);
     if ( !dom_vmce(d) )
         return -ENOMEM;
@@ -37,72 +32,73 @@ int vmce_init_msr(struct domain *d)
         xfree(dom_vmce(d));
         return -ENOMEM;
     }
-    memset(d->arch.vmca_msrs->mci_ctl, ~0,
-           sizeof(d->arch.vmca_msrs->mci_ctl));
+    memset(dom_vmce(d)->mci_ctl, ~0,
+           sizeof(dom_vmce(d)->mci_ctl));
 
     dom_vmce(d)->mcg_status = 0x0;
     dom_vmce(d)->mcg_cap = g_mcg_cap;
     dom_vmce(d)->mcg_ctl = ~(uint64_t)0x0;
     dom_vmce(d)->nr_injection = 0;
 
-    INIT_LIST_HEAD(&d->arch.vmca_msrs->impact_header);
-    spin_lock_init(&d->arch.vmca_msrs->lock);
+    INIT_LIST_HEAD(&dom_vmce(d)->impact_header);
+    spin_lock_init(&dom_vmce(d)->lock);
 
     return 0;
 }
 
-/*
- * Caller should make sure msr is bank msr */
+void vmce_destroy_msr(struct domain *d)
+{
+    if ( !dom_vmce(d) )
+        return;
+    xfree(dom_vmce(d)->mci_ctl);
+    xfree(dom_vmce(d));
+    dom_vmce(d) = NULL;
+}
+
 static int bank_mce_rdmsr(struct domain *d, uint32_t msr, uint64_t *val)
 {
     int bank, ret = 1;
-    struct domain_mca_msrs *vmce;
-    struct bank_entry *entry = NULL;
-
-    if (!d)
-        return -EINVAL;
-    vmce = dom_vmce(d);
-    ASSERT(vmce);
+    struct domain_mca_msrs *vmce = dom_vmce(d);
+    struct bank_entry *entry;
 
     bank = (msr - MSR_IA32_MC0_CTL) / 4;
-    if (bank >= nr_mce_banks)
+    if ( bank >= nr_mce_banks )
         return -1;
 
-    switch (msr & (MSR_IA32_MC0_CTL | 3))
+    switch ( msr & (MSR_IA32_MC0_CTL | 3) )
     {
     case MSR_IA32_MC0_CTL:
         *val = vmce->mci_ctl[bank] &
-          (h_mci_ctrl ? h_mci_ctrl[bank] : ~0UL);
+            (h_mci_ctrl ? h_mci_ctrl[bank] : ~0UL);
         mce_printk(MCE_VERBOSE, "MCE: rdmsr MC%u_CTL 0x%"PRIx64"\n",
-          bank, *val);
+                   bank, *val);
         break;
     case MSR_IA32_MC0_STATUS:
         /* Only error bank is read. Non-error banks simply return. */
         if ( !list_empty(&vmce->impact_header) )
         {
             entry = list_entry(vmce->impact_header.next,
-              struct bank_entry, list);
-            if (entry->bank == bank) {
+                               struct bank_entry, list);
+            if ( entry->bank == bank )
+            {
                 *val = entry->mci_status;
                 mce_printk(MCE_VERBOSE,
-                  "MCE: rd MC%u_STATUS in vMCE# context "
-                  "value 0x%"PRIx64"\n", bank, *val);
-            }
-            else
-                entry = NULL;
+                           "MCE: rd MC%u_STATUS in vMCE# context "
+                           "value 0x%"PRIx64"\n", bank, *val);
+            }
         }
         break;
     case MSR_IA32_MC0_ADDR:
         if ( !list_empty(&vmce->impact_header) )
         {
             entry = list_entry(vmce->impact_header.next,
-              struct bank_entry, list);
+                               struct bank_entry, list);
             if ( entry->bank == bank )
             {
                 *val = entry->mci_addr;
                 mce_printk(MCE_VERBOSE,
-                  "MCE: rdmsr MC%u_ADDR in vMCE# context "
-                  "0x%"PRIx64"\n", bank, *val);
+                           "MCE: rdmsr MC%u_ADDR in vMCE# context "
+                           "0x%"PRIx64"\n", bank, *val);
             }
         }
         break;
@@ -110,25 +106,25 @@ static int bank_mce_rdmsr(struct domain 
         if ( !list_empty(&vmce->impact_header) )
         {
             entry = list_entry(vmce->impact_header.next,
-              struct bank_entry, list);
+                               struct bank_entry, list);
             if ( entry->bank == bank )
             {
                 *val = entry->mci_misc;
                 mce_printk(MCE_VERBOSE,
-                  "MCE: rd MC%u_MISC in vMCE# context "
-                  "0x%"PRIx64"\n", bank, *val);
+                           "MCE: rd MC%u_MISC in vMCE# context "
+                           "0x%"PRIx64"\n", bank, *val);
             }
         }
         break;
     default:
         switch ( boot_cpu_data.x86_vendor )
         {
-            case X86_VENDOR_INTEL:
-                ret = intel_mce_rdmsr(msr, val);
-                break;
-            default:
-                ret = 0;
-                break;
+        case X86_VENDOR_INTEL:
+            ret = intel_mce_rdmsr(msr, val);
+            break;
+        default:
+            ret = 0;
+            break;
         }
         break;
     }
@@ -144,19 +140,12 @@ int vmce_rdmsr(uint32_t msr, uint64_t *v
 int vmce_rdmsr(uint32_t msr, uint64_t *val)
 {
     struct domain *d = current->domain;
-    struct domain_mca_msrs *vmce;
+    struct domain_mca_msrs *vmce = dom_vmce(d);
     int ret = 1;
 
     *val = 0;
 
-    vmce = dom_vmce(d);
-    if ( !vmce )
-    {
-        /* XXX more handle here */
-        return 0;
-    }
-
-    spin_lock(&d->arch.vmca_msrs->lock);
+    spin_lock(&dom_vmce(d)->lock);
 
     switch ( msr )
     {
@@ -164,79 +153,71 @@ int vmce_rdmsr(uint32_t msr, uint64_t *v
         *val = vmce->mcg_status;
         if (*val)
             mce_printk(MCE_VERBOSE,
-                "MCE: rdmsr MCG_STATUS 0x%"PRIx64"\n", *val);
+                       "MCE: rdmsr MCG_STATUS 0x%"PRIx64"\n", *val);
         break;
     case MSR_IA32_MCG_CAP:
         *val = vmce->mcg_cap;
         mce_printk(MCE_VERBOSE, "MCE: rdmsr MCG_CAP 0x%"PRIx64"\n",
-            *val);
+                   *val);
         break;
     case MSR_IA32_MCG_CTL:
         /* Always 0 if no CTL support */
         *val = vmce->mcg_ctl & h_mcg_ctl;
         mce_printk(MCE_VERBOSE, "MCE: rdmsr MCG_CTL 0x%"PRIx64"\n",
-            *val);
+                   *val);
         break;
     default:
-        if ( mce_bank_msr(msr) )
-            ret = bank_mce_rdmsr(d, msr, val);
-        else
-            ret = 0;
-        break;
-    }
-
-    spin_unlock(&d->arch.vmca_msrs->lock);
+        ret = mce_bank_msr(msr) ? bank_mce_rdmsr(d, msr, val) : 0;
+        break;
+    }
+
+    spin_unlock(&dom_vmce(d)->lock);
     return ret;
 }
 
-int bank_mce_wrmsr(struct domain *d, u32 msr, u64 val)
+static int bank_mce_wrmsr(struct domain *d, u32 msr, u64 val)
 {
     int bank, ret = 1;
-    struct domain_mca_msrs *vmce;
+    struct domain_mca_msrs *vmce = dom_vmce(d);
     struct bank_entry *entry = NULL;
 
-    if (!d)
-        return -EINVAL;
-    vmce = dom_vmce(d);
-    ASSERT(vmce && vmce->mci_ctl);
-
     bank = (msr - MSR_IA32_MC0_CTL) / 4;
-    if (bank >= nr_mce_banks)
+    if ( bank >= nr_mce_banks )
         return -EINVAL;
 
     switch ( msr & (MSR_IA32_MC0_CTL | 3) )
     {
     case MSR_IA32_MC0_CTL:
         vmce->mci_ctl[bank] = val;
-            break;
+        break;
     case MSR_IA32_MC0_STATUS:
-            /* 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 banks 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 == bank )
-                    entry->mci_status = val;
-                mce_printk(MCE_VERBOSE,
-                         "MCE: wr MC%u_STATUS %"PRIx64" in vMCE#\n",
-                         bank, val);
-            }
-            else
-                mce_printk(MCE_VERBOSE,
-                         "MCE: wr MC%u_STATUS %"PRIx64"\n", bank, val);
-            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 banks simply return.
+         */
+        if ( !list_empty(&dom_vmce(d)->impact_header) )
+        {
+            entry = list_entry(dom_vmce(d)->impact_header.next,
+                               struct bank_entry, list);
+            if ( entry->bank == bank )
+                entry->mci_status = val;
+            mce_printk(MCE_VERBOSE,
+                       "MCE: wr MC%u_STATUS %"PRIx64" in vMCE#\n",
+                       bank, val);
+        }
+        else
+            mce_printk(MCE_VERBOSE,
+                       "MCE: wr MC%u_STATUS %"PRIx64"\n", bank, val);
+        break;
     case MSR_IA32_MC0_ADDR:
-            mce_printk(MCE_QUIET, "MCE: MC%u_ADDR is read-only\n", bank);
-            ret = -1;
-            break;
+        mce_printk(MCE_QUIET, "MCE: MC%u_ADDR is read-only\n", bank);
+        ret = -1;
+        break;
     case MSR_IA32_MC0_MISC:
-            mce_printk(MCE_QUIET, "MCE: MC%u_MISC is read-only\n", bank);
-            ret = -1;
-            break;
+        mce_printk(MCE_QUIET, "MCE: MC%u_MISC is read-only\n", bank);
+        ret = -1;
+        break;
     default:
         switch ( boot_cpu_data.x86_vendor )
         {
@@ -262,13 +243,12 @@ int vmce_wrmsr(u32 msr, u64 val)
 {
     struct domain *d = current->domain;
     struct bank_entry *entry = NULL;
-    struct domain_mca_msrs *vmce;
+    struct domain_mca_msrs *vmce = dom_vmce(d);
     int ret = 1;
 
     if ( !g_mcg_cap )
         return 0;
 
-    vmce = dom_vmce(d);
     spin_lock(&vmce->lock);
 
     switch ( msr )
@@ -286,20 +266,20 @@ int vmce_wrmsr(u32 msr, u64 val)
             if ( !list_empty(&vmce->impact_header) )
             {
                 entry = list_entry(vmce->impact_header.next,
-                    struct bank_entry, list);
+                                   struct bank_entry, list);
                 if ( entry->mci_status & MCi_STATUS_VAL )
                     mce_printk(MCE_QUIET, "MCE: MCi_STATUS MSR should have "
-                                "been cleared before write MCG_STATUS MSR\n");
+                               "been cleared before write MCG_STATUS MSR\n");
 
                 mce_printk(MCE_QUIET, "MCE: Delete HVM last injection "
-                                "Node, nr_injection %u\n",
-                                vmce->nr_injection);
+                           "Node, nr_injection %u\n",
+                           vmce->nr_injection);
                 list_del(&entry->list);
                 xfree(entry);
             }
             else
                 mce_printk(MCE_QUIET, "MCE: Not found HVM guest"
-                    " last injection Node, something Wrong!\n");
+                           " last injection Node, something Wrong!\n");
         }
         break;
     case MSR_IA32_MCG_CAP:
@@ -307,10 +287,7 @@ int vmce_wrmsr(u32 msr, u64 val)
         ret = -1;
         break;
     default:
-        if ( mce_bank_msr(msr) )
-            ret = bank_mce_wrmsr(d, msr, val);
-        else
-            ret = 0;
+        ret = mce_bank_msr(msr) ? bank_mce_wrmsr(d, msr, val) : 0;
         break;
     }
 
@@ -323,47 +300,46 @@ int inject_vmce(struct domain *d)
     int cpu = smp_processor_id();
     cpumask_t affinity;
 
-    /* PV guest and HVM guest have different vMCE# injection
-     * methods*/
+    /* PV guest and HVM guest have different vMCE# injection methods. */
     if ( !test_and_set_bool(d->vcpu[0]->mce_pending) )
     {
-        if (d->is_hvm)
+        if ( d->is_hvm )
         {
             mce_printk(MCE_VERBOSE, "MCE: inject vMCE to HVM DOM %d\n",
-                        d->domain_id);
+                       d->domain_id);
             vcpu_kick(d->vcpu[0]);
         }
-        /* PV guest including DOM0 */
         else
         {
             mce_printk(MCE_VERBOSE, "MCE: inject vMCE to PV DOM%d\n",
-                        d->domain_id);
-            if (guest_has_trap_callback
-                   (d, 0, TRAP_machine_check))
+                       d->domain_id);
+            if ( guest_has_trap_callback(d, 0, TRAP_machine_check) )
             {
                 d->vcpu[0]->cpu_affinity_tmp =
-                        d->vcpu[0]->cpu_affinity;
+                    d->vcpu[0]->cpu_affinity;
                 cpus_clear(affinity);
                 cpu_set(cpu, affinity);
-                mce_printk(MCE_VERBOSE, "MCE: CPU%d set affinity, old %d\n", 
cpu,
-                            d->vcpu[0]->processor);
+                mce_printk(MCE_VERBOSE, "MCE: CPU%d set affinity, old %d\n",
+                           cpu, d->vcpu[0]->processor);
                 vcpu_set_affinity(d->vcpu[0], &affinity);
                 vcpu_kick(d->vcpu[0]);
             }
             else
             {
-                mce_printk(MCE_VERBOSE, "MCE: Kill PV guest with No MCE 
handler\n");
+                mce_printk(MCE_VERBOSE,
+                           "MCE: Kill PV guest with No MCE handler\n");
                 domain_crash(d);
             }
         }
     }
-    else {
+    else
+    {
         /* new vMCE comes while first one has not been injected yet,
          * in this case, inject fail. [We can't lose this vMCE for
          * the mce node's consistency].
-        */
+         */
         mce_printk(MCE_QUIET, "There's a pending vMCE waiting to be injected "
-                    " to this DOM%d!\n", d->domain_id);
+                   " to this DOM%d!\n", d->domain_id);
         return -1;
     }
     return 0;
@@ -376,14 +352,17 @@ int inject_vmce(struct domain *d)
  * processed by guest, the corresponding node will be deleted.
  * This node list is for GUEST vMCE# MSRS virtualization.
  */
-static struct bank_entry* alloc_bank_entry(void) {
+static struct bank_entry* alloc_bank_entry(void)
+{
     struct bank_entry *entry;
 
     entry = xmalloc(struct bank_entry);
-    if (!entry) {
+    if ( entry == NULL )
+    {
         printk(KERN_ERR "MCE: malloc bank_entry failed\n");
         return NULL;
     }
+
     memset(entry, 0x0, sizeof(entry));
     INIT_LIST_HEAD(&entry->list);
     return entry;
@@ -393,27 +372,28 @@ static struct bank_entry* alloc_bank_ent
  * MSR virtualization data
  * 1) Log down how many nr_injections of the impacted.
  * 2) Copy MCE# error bank to impacted DOM node list,
-      for vMCE# MSRs virtualization
-*/
-
+ *    for vMCE# MSRs virtualization
+ */
 int fill_vmsr_data(struct mcinfo_bank *mc_bank, struct domain *d,
-        uint64_t gstatus) {
+                   uint64_t gstatus) {
     struct bank_entry *entry;
 
     /* This error bank impacts one domain, we need to fill domain related
      * data for vMCE MSRs virtualization and vMCE# injection */
-    if (mc_bank->mc_domid != (uint16_t)~0) {
-        /* For HVM guest, Only when first vMCE is consumed by HVM guest 
successfully,
-         * will we generete another node and inject another vMCE
+    if ( mc_bank->mc_domid != (uint16_t)~0 )
+    {
+        /* For HVM guest, Only when first vMCE is consumed by HVM guest
+         * successfully, will we generete another node and inject another vMCE.
          */
-        if ( (d->is_hvm) && (d->arch.vmca_msrs->nr_injection > 0) )
+        if ( d->is_hvm && (dom_vmce(d)->nr_injection > 0) )
         {
             mce_printk(MCE_QUIET, "MCE: HVM guest has not handled previous"
-                        " vMCE yet!\n");
+                       " vMCE yet!\n");
             return -1;
         }
+
         entry = alloc_bank_entry();
-        if (entry == NULL)
+        if ( entry == NULL )
             return -1;
 
         entry->mci_status = mc_bank->mc_status;
@@ -421,29 +401,31 @@ int fill_vmsr_data(struct mcinfo_bank *m
         entry->mci_misc = mc_bank->mc_misc;
         entry->bank = mc_bank->mc_bank;
 
-        spin_lock(&d->arch.vmca_msrs->lock);
+        spin_lock(&dom_vmce(d)->lock);
         /* New error Node, insert to the tail of the per_dom data */
-        list_add_tail(&entry->list, &d->arch.vmca_msrs->impact_header);
+        list_add_tail(&entry->list, &dom_vmce(d)->impact_header);
         /* Fill MSR global status */
-        d->arch.vmca_msrs->mcg_status = gstatus;
+        dom_vmce(d)->mcg_status = gstatus;
         /* New node impact the domain, need another vMCE# injection*/
-        d->arch.vmca_msrs->nr_injection++;
-        spin_unlock(&d->arch.vmca_msrs->lock);
+        dom_vmce(d)->nr_injection++;
+        spin_unlock(&dom_vmce(d)->lock);
 
         mce_printk(MCE_VERBOSE,"MCE: Found error @[BANK%d "
-                "status %"PRIx64" addr %"PRIx64" domid %d]\n ",
-                mc_bank->mc_bank, mc_bank->mc_status, mc_bank->mc_addr,
-                mc_bank->mc_domid);
-    }
+                   "status %"PRIx64" addr %"PRIx64" domid %d]\n ",
+                   mc_bank->mc_bank, mc_bank->mc_status, mc_bank->mc_addr,
+                   mc_bank->mc_domid);
+    }
+
     return 0;
 }
 
-int vmce_domain_inject(struct mcinfo_bank *bank, struct domain *d, struct 
mcinfo_global *global)
+int vmce_domain_inject(
+    struct mcinfo_bank *bank, struct domain *d, struct mcinfo_global *global)
 {
     int ret;
 
     ret = fill_vmsr_data(bank, d, global->mc_gstatus);
-    if (ret < 0)
+    if ( ret < 0 )
         return ret;
 
     return inject_vmce(d);
diff -r 24a00bbe7cc0 -r 26da9bb87405 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Thu May 06 11:19:28 2010 +0100
+++ b/xen/arch/x86/domain.c     Thu May 06 11:39:09 2010 +0100
@@ -535,6 +535,7 @@ int arch_domain_create(struct domain *d,
 
  fail:
     d->is_dying = DOMDYING_dead;
+    vmce_destroy_msr(d);
     xfree(d->arch.pirq_irq);
     xfree(d->arch.irq_pirq);
     free_xenheap_page(d->shared_info);
@@ -562,6 +563,7 @@ void arch_domain_destroy(struct domain *
     if ( is_hvm_domain(d) )
         hvm_domain_destroy(d);
 
+    vmce_destroy_msr(d);
     pci_release_devices(d);
     free_domain_pirqs(d);
     if ( !is_idle_domain(d) )
diff -r 24a00bbe7cc0 -r 26da9bb87405 xen/common/domain.c
--- a/xen/common/domain.c       Thu May 06 11:19:28 2010 +0100
+++ b/xen/common/domain.c       Thu May 06 11:39:09 2010 +0100
@@ -625,8 +625,6 @@ static void complete_domain_destroy(stru
 
     xfree(d->pirq_mask);
     xfree(d->pirq_to_evtchn);
-    xfree(dom_vmce(d)->mci_ctl);
-    xfree(dom_vmce(d));
 
     xsm_free_security_domain(d);
     free_domain_struct(d);
diff -r 24a00bbe7cc0 -r 26da9bb87405 xen/include/asm-x86/mce.h
--- a/xen/include/asm-x86/mce.h Thu May 06 11:19:28 2010 +0100
+++ b/xen/include/asm-x86/mce.h Thu May 06 11:39:09 2010 +0100
@@ -27,10 +27,9 @@ struct domain_mca_msrs
     spinlock_t lock;
 };
 
-#define dom_vmce(x)   ((x)->arch.vmca_msrs)
-
 /* Guest vMCE MSRs virtualization */
 extern int vmce_init_msr(struct domain *d);
+extern void vmce_destroy_msr(struct domain *d);
 extern int vmce_wrmsr(uint32_t msr, uint64_t val);
 extern int vmce_rdmsr(uint32_t msr, uint64_t *val);
 #endif

_______________________________________________
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] vmce: Clean up implementation and setup/destroy., Xen patchbot-unstable <=