[Xen-devel] [PATCH] libxc: migrate migration stream definitions into Xen public headers

David Woodhouse posted 1 patch 4 years, 1 month ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/xen tags/patchew/723edf8e07ed0cbaacb6bce40bb98de3b88d69be.camel@infradead.org
Maintainers: George Dunlap <George.Dunlap@eu.citrix.com>, Andrew Cooper <andrew.cooper3@citrix.com>, Ian Jackson <ian.jackson@eu.citrix.com>, Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>, Stefano Stabellini <sstabellini@kernel.org>, Julien Grall <julien@xen.org>, Jan Beulich <jbeulich@suse.com>, Wei Liu <wl@xen.org>
tools/libxc/xc_sr_common.c            |  20 ++---
tools/libxc/xc_sr_common_x86.c        |   4 +-
tools/libxc/xc_sr_restore.c           |   2 +-
tools/libxc/xc_sr_restore_x86_hvm.c   |   4 +-
tools/libxc/xc_sr_restore_x86_pv.c    |   8 +-
tools/libxc/xc_sr_save.c              |   2 +-
tools/libxc/xc_sr_save_x86_hvm.c      |   4 +-
tools/libxc/xc_sr_save_x86_pv.c       |  12 +--
tools/libxc/xc_sr_stream_format.h     |  97 +-------------------
xen/include/Makefile                  |   2 +-
xen/include/public/migration_stream.h | 125 ++++++++++++++++++++++++++
11 files changed, 156 insertions(+), 124 deletions(-)
create mode 100644 xen/include/public/migration_stream.h
[Xen-devel] [PATCH] libxc: migrate migration stream definitions into Xen public headers
Posted by David Woodhouse 4 years, 1 month ago
From: David Woodhouse <dwmw@amazon.co.uk>

These data structures will be used for live update, which is basically
just live migration from one Xen to the next on the same machine via
in-memory data structures, instead of across the network.

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Well-excellent-carry-on-then-by: Ian Jackson <ian.jackson@eu.citrix.com>
Go-with-that-for-now-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/libxc/xc_sr_common.c            |  20 ++---
 tools/libxc/xc_sr_common_x86.c        |   4 +-
 tools/libxc/xc_sr_restore.c           |   2 +-
 tools/libxc/xc_sr_restore_x86_hvm.c   |   4 +-
 tools/libxc/xc_sr_restore_x86_pv.c    |   8 +-
 tools/libxc/xc_sr_save.c              |   2 +-
 tools/libxc/xc_sr_save_x86_hvm.c      |   4 +-
 tools/libxc/xc_sr_save_x86_pv.c       |  12 +--
 tools/libxc/xc_sr_stream_format.h     |  97 +-------------------
 xen/include/Makefile                  |   2 +-
 xen/include/public/migration_stream.h | 125 ++++++++++++++++++++++++++
 11 files changed, 156 insertions(+), 124 deletions(-)
 create mode 100644 xen/include/public/migration_stream.h

diff --git a/tools/libxc/xc_sr_common.c b/tools/libxc/xc_sr_common.c
index dd9a11b4b5..92f9332e73 100644
--- a/tools/libxc/xc_sr_common.c
+++ b/tools/libxc/xc_sr_common.c
@@ -91,7 +91,7 @@ int write_split_record(struct xc_sr_context *ctx, struct xc_sr_record *rec,
 int read_record(struct xc_sr_context *ctx, int fd, struct xc_sr_record *rec)
 {
     xc_interface *xch = ctx->xch;
-    struct xc_sr_rhdr rhdr;
+    struct mr_rhdr rhdr;
     size_t datasz;
 
     if ( read_exact(fd, &rhdr, sizeof(rhdr)) )
@@ -142,15 +142,15 @@ static void __attribute__((unused)) build_assertions(void)
 {
     BUILD_BUG_ON(sizeof(struct xc_sr_ihdr) != 24);
     BUILD_BUG_ON(sizeof(struct xc_sr_dhdr) != 16);
-    BUILD_BUG_ON(sizeof(struct xc_sr_rhdr) != 8);
-
-    BUILD_BUG_ON(sizeof(struct xc_sr_rec_page_data_header)  != 8);
-    BUILD_BUG_ON(sizeof(struct xc_sr_rec_x86_pv_info)       != 8);
-    BUILD_BUG_ON(sizeof(struct xc_sr_rec_x86_pv_p2m_frames) != 8);
-    BUILD_BUG_ON(sizeof(struct xc_sr_rec_x86_pv_vcpu_hdr)   != 8);
-    BUILD_BUG_ON(sizeof(struct xc_sr_rec_x86_tsc_info)      != 24);
-    BUILD_BUG_ON(sizeof(struct xc_sr_rec_hvm_params_entry)  != 16);
-    BUILD_BUG_ON(sizeof(struct xc_sr_rec_hvm_params)        != 8);
+    BUILD_BUG_ON(sizeof(struct mr_rhdr) != 8);
+
+    BUILD_BUG_ON(sizeof(struct mr_page_data_header)  != 8);
+    BUILD_BUG_ON(sizeof(struct mr_x86_pv_info)       != 8);
+    BUILD_BUG_ON(sizeof(struct mr_x86_pv_p2m_frames) != 8);
+    BUILD_BUG_ON(sizeof(struct mr_x86_pv_vcpu_hdr)   != 8);
+    BUILD_BUG_ON(sizeof(struct mr_x86_tsc_info)      != 24);
+    BUILD_BUG_ON(sizeof(struct mr_hvm_params_entry)  != 16);
+    BUILD_BUG_ON(sizeof(struct mr_hvm_params)        != 8);
 }
 
 /*
diff --git a/tools/libxc/xc_sr_common_x86.c b/tools/libxc/xc_sr_common_x86.c
index 011684df97..1627ff72d6 100644
--- a/tools/libxc/xc_sr_common_x86.c
+++ b/tools/libxc/xc_sr_common_x86.c
@@ -3,7 +3,7 @@
 int write_x86_tsc_info(struct xc_sr_context *ctx)
 {
     xc_interface *xch = ctx->xch;
-    struct xc_sr_rec_x86_tsc_info tsc = {};
+    struct mr_x86_tsc_info tsc = {};
     struct xc_sr_record rec = {
         .type = REC_TYPE_X86_TSC_INFO,
         .length = sizeof(tsc),
@@ -23,7 +23,7 @@ int write_x86_tsc_info(struct xc_sr_context *ctx)
 int handle_x86_tsc_info(struct xc_sr_context *ctx, struct xc_sr_record *rec)
 {
     xc_interface *xch = ctx->xch;
-    struct xc_sr_rec_x86_tsc_info *tsc = rec->data;
+    struct mr_x86_tsc_info *tsc = rec->data;
 
     if ( rec->length != sizeof(*tsc) )
     {
diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c
index 5e31908ca8..29c264ecc7 100644
--- a/tools/libxc/xc_sr_restore.c
+++ b/tools/libxc/xc_sr_restore.c
@@ -335,7 +335,7 @@ static int process_page_data(struct xc_sr_context *ctx, unsigned int count,
 static int handle_page_data(struct xc_sr_context *ctx, struct xc_sr_record *rec)
 {
     xc_interface *xch = ctx->xch;
-    struct xc_sr_rec_page_data_header *pages = rec->data;
+    struct mr_page_data_header *pages = rec->data;
     unsigned int i, pages_of_data = 0;
     int rc = -1;
 
diff --git a/tools/libxc/xc_sr_restore_x86_hvm.c b/tools/libxc/xc_sr_restore_x86_hvm.c
index 3f78248f32..e5b25f4280 100644
--- a/tools/libxc/xc_sr_restore_x86_hvm.c
+++ b/tools/libxc/xc_sr_restore_x86_hvm.c
@@ -25,8 +25,8 @@ static int handle_hvm_params(struct xc_sr_context *ctx,
                              struct xc_sr_record *rec)
 {
     xc_interface *xch = ctx->xch;
-    struct xc_sr_rec_hvm_params *hdr = rec->data;
-    struct xc_sr_rec_hvm_params_entry *entry = hdr->param;
+    struct mr_hvm_params *hdr = rec->data;
+    struct mr_hvm_params_entry *entry = hdr->param;
     unsigned int i;
     int rc;
 
diff --git a/tools/libxc/xc_sr_restore_x86_pv.c b/tools/libxc/xc_sr_restore_x86_pv.c
index 16e738884e..8e43ddcfd7 100644
--- a/tools/libxc/xc_sr_restore_x86_pv.c
+++ b/tools/libxc/xc_sr_restore_x86_pv.c
@@ -585,7 +585,7 @@ static int update_guest_p2m(struct xc_sr_context *ctx)
  * Cross-check the legitimate combinations.
  */
 static bool valid_x86_pv_info_combination(
-    const struct xc_sr_rec_x86_pv_info *info)
+    const struct mr_x86_pv_info *info)
 {
     switch ( info->guest_width )
     {
@@ -602,7 +602,7 @@ static int handle_x86_pv_info(struct xc_sr_context *ctx,
                               struct xc_sr_record *rec)
 {
     xc_interface *xch = ctx->xch;
-    struct xc_sr_rec_x86_pv_info *info = rec->data;
+    struct mr_x86_pv_info *info = rec->data;
 
     if ( ctx->x86.pv.restore.seen_pv_info )
     {
@@ -675,7 +675,7 @@ static int handle_x86_pv_p2m_frames(struct xc_sr_context *ctx,
                                     struct xc_sr_record *rec)
 {
     xc_interface *xch = ctx->xch;
-    struct xc_sr_rec_x86_pv_p2m_frames *data = rec->data;
+    struct mr_x86_pv_p2m_frames *data = rec->data;
     unsigned int start, end, x, fpp = PAGE_SIZE / ctx->x86.pv.width;
     int rc;
 
@@ -734,7 +734,7 @@ static int handle_x86_pv_vcpu_blob(struct xc_sr_context *ctx,
                                    struct xc_sr_record *rec)
 {
     xc_interface *xch = ctx->xch;
-    struct xc_sr_rec_x86_pv_vcpu_hdr *vhdr = rec->data;
+    struct mr_x86_pv_vcpu_hdr *vhdr = rec->data;
     struct xc_sr_x86_pv_restore_vcpu *vcpu;
     const char *rec_name;
     size_t blobsz;
diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c
index fa736a311f..41af26909e 100644
--- a/tools/libxc/xc_sr_save.c
+++ b/tools/libxc/xc_sr_save.c
@@ -87,7 +87,7 @@ static int write_batch(struct xc_sr_context *ctx)
     void *page, *orig_page;
     uint64_t *rec_pfns = NULL;
     struct iovec *iov = NULL; int iovcnt = 0;
-    struct xc_sr_rec_page_data_header hdr = { 0 };
+    struct mr_page_data_header hdr = { 0 };
     struct xc_sr_record rec = {
         .type = REC_TYPE_PAGE_DATA,
     };
diff --git a/tools/libxc/xc_sr_save_x86_hvm.c b/tools/libxc/xc_sr_save_x86_hvm.c
index d99efe65e5..c4dc42479f 100644
--- a/tools/libxc/xc_sr_save_x86_hvm.c
+++ b/tools/libxc/xc_sr_save_x86_hvm.c
@@ -80,8 +80,8 @@ static int write_hvm_params(struct xc_sr_context *ctx)
     };
 
     xc_interface *xch = ctx->xch;
-    struct xc_sr_rec_hvm_params_entry entries[ARRAY_SIZE(params)];
-    struct xc_sr_rec_hvm_params hdr = {
+    struct mr_hvm_params_entry entries[ARRAY_SIZE(params)];
+    struct mr_hvm_params hdr = {
         .count = 0,
     };
     struct xc_sr_record rec = {
diff --git a/tools/libxc/xc_sr_save_x86_pv.c b/tools/libxc/xc_sr_save_x86_pv.c
index f3ccf5bb4b..916c5aad41 100644
--- a/tools/libxc/xc_sr_save_x86_pv.c
+++ b/tools/libxc/xc_sr_save_x86_pv.c
@@ -485,7 +485,7 @@ static int write_one_vcpu_basic(struct xc_sr_context *ctx, uint32_t id)
     unsigned int i, gdt_count;
     int rc = -1;
     vcpu_guest_context_any_t vcpu;
-    struct xc_sr_rec_x86_pv_vcpu_hdr vhdr = {
+    struct mr_x86_pv_vcpu_hdr vhdr = {
         .vcpu_id = id,
     };
     struct xc_sr_record rec = {
@@ -583,7 +583,7 @@ static int write_one_vcpu_basic(struct xc_sr_context *ctx, uint32_t id)
 static int write_one_vcpu_extended(struct xc_sr_context *ctx, uint32_t id)
 {
     xc_interface *xch = ctx->xch;
-    struct xc_sr_rec_x86_pv_vcpu_hdr vhdr = {
+    struct mr_x86_pv_vcpu_hdr vhdr = {
         .vcpu_id = id,
     };
     struct xc_sr_record rec = {
@@ -620,7 +620,7 @@ static int write_one_vcpu_xsave(struct xc_sr_context *ctx, uint32_t id)
     xc_interface *xch = ctx->xch;
     int rc = -1;
     DECLARE_HYPERCALL_BUFFER(void, buffer);
-    struct xc_sr_rec_x86_pv_vcpu_hdr vhdr = {
+    struct mr_x86_pv_vcpu_hdr vhdr = {
         .vcpu_id = id,
     };
     struct xc_sr_record rec = {
@@ -686,7 +686,7 @@ static int write_one_vcpu_msrs(struct xc_sr_context *ctx, uint32_t id)
     int rc = -1;
     size_t buffersz;
     DECLARE_HYPERCALL_BUFFER(void, buffer);
-    struct xc_sr_rec_x86_pv_vcpu_hdr vhdr = {
+    struct mr_x86_pv_vcpu_hdr vhdr = {
         .vcpu_id = id,
     };
     struct xc_sr_record rec = {
@@ -793,7 +793,7 @@ static int write_all_vcpu_information(struct xc_sr_context *ctx)
  */
 static int write_x86_pv_info(struct xc_sr_context *ctx)
 {
-    struct xc_sr_rec_x86_pv_info info = {
+    struct mr_x86_pv_info info = {
         .guest_width = ctx->x86.pv.width,
         .pt_levels = ctx->x86.pv.levels,
     };
@@ -816,7 +816,7 @@ static int write_x86_pv_p2m_frames(struct xc_sr_context *ctx)
     int rc; unsigned int i;
     size_t datasz = ctx->x86.pv.p2m_frames * sizeof(uint64_t);
     uint64_t *data = NULL;
-    struct xc_sr_rec_x86_pv_p2m_frames hdr = {
+    struct mr_x86_pv_p2m_frames hdr = {
         .end_pfn = ctx->x86.pv.max_pfn,
     };
     struct xc_sr_record rec = {
diff --git a/tools/libxc/xc_sr_stream_format.h b/tools/libxc/xc_sr_stream_format.h
index 37a7da6eab..0700cde54f 100644
--- a/tools/libxc/xc_sr_stream_format.h
+++ b/tools/libxc/xc_sr_stream_format.h
@@ -1,6 +1,8 @@
 #ifndef __STREAM_FORMAT__H
 #define __STREAM_FORMAT__H
 
+#include <xen/migration_stream.h>
+
 /*
  * C structures for the Migration v2 stream format.
  * See docs/specs/libxc-migration-stream.pandoc
@@ -41,101 +43,6 @@ struct xc_sr_dhdr
     uint32_t xen_minor;
 };
 
-#define DHDR_TYPE_X86_PV  0x00000001U
-#define DHDR_TYPE_X86_HVM 0x00000002U
-
-/*
- * Record Header
- */
-struct xc_sr_rhdr
-{
-    uint32_t type;
-    uint32_t length;
-};
-
-/* All records must be aligned up to an 8 octet boundary */
-#define REC_ALIGN_ORDER               (3U)
-/* Somewhat arbitrary - 128MB */
-#define REC_LENGTH_MAX                (128U << 20)
-
-#define REC_TYPE_END                        0x00000000U
-#define REC_TYPE_PAGE_DATA                  0x00000001U
-#define REC_TYPE_X86_PV_INFO                0x00000002U
-#define REC_TYPE_X86_PV_P2M_FRAMES          0x00000003U
-#define REC_TYPE_X86_PV_VCPU_BASIC          0x00000004U
-#define REC_TYPE_X86_PV_VCPU_EXTENDED       0x00000005U
-#define REC_TYPE_X86_PV_VCPU_XSAVE          0x00000006U
-#define REC_TYPE_SHARED_INFO                0x00000007U
-#define REC_TYPE_X86_TSC_INFO               0x00000008U
-#define REC_TYPE_HVM_CONTEXT                0x00000009U
-#define REC_TYPE_HVM_PARAMS                 0x0000000aU
-#define REC_TYPE_TOOLSTACK                  0x0000000bU
-#define REC_TYPE_X86_PV_VCPU_MSRS           0x0000000cU
-#define REC_TYPE_VERIFY                     0x0000000dU
-#define REC_TYPE_CHECKPOINT                 0x0000000eU
-#define REC_TYPE_CHECKPOINT_DIRTY_PFN_LIST  0x0000000fU
-
-#define REC_TYPE_OPTIONAL             0x80000000U
-
-/* PAGE_DATA */
-struct xc_sr_rec_page_data_header
-{
-    uint32_t count;
-    uint32_t _res1;
-    uint64_t pfn[0];
-};
-
-#define PAGE_DATA_PFN_MASK  0x000fffffffffffffULL
-#define PAGE_DATA_TYPE_MASK 0xf000000000000000ULL
-
-/* X86_PV_INFO */
-struct xc_sr_rec_x86_pv_info
-{
-    uint8_t guest_width;
-    uint8_t pt_levels;
-    uint8_t _res[6];
-};
-
-/* X86_PV_P2M_FRAMES */
-struct xc_sr_rec_x86_pv_p2m_frames
-{
-    uint32_t start_pfn;
-    uint32_t end_pfn;
-    uint64_t p2m_pfns[0];
-};
-
-/* X86_PV_VCPU_{BASIC,EXTENDED,XSAVE,MSRS} */
-struct xc_sr_rec_x86_pv_vcpu_hdr
-{
-    uint32_t vcpu_id;
-    uint32_t _res1;
-    uint8_t context[0];
-};
-
-/* X86_TSC_INFO */
-struct xc_sr_rec_x86_tsc_info
-{
-    uint32_t mode;
-    uint32_t khz;
-    uint64_t nsec;
-    uint32_t incarnation;
-    uint32_t _res1;
-};
-
-/* HVM_PARAMS */
-struct xc_sr_rec_hvm_params_entry
-{
-    uint64_t index;
-    uint64_t value;
-};
-
-struct xc_sr_rec_hvm_params
-{
-    uint32_t count;
-    uint32_t _res1;
-    struct xc_sr_rec_hvm_params_entry param[0];
-};
-
 #endif
 /*
  * Local variables:
diff --git a/xen/include/Makefile b/xen/include/Makefile
index c3e0283d34..9161716e8f 100644
--- a/xen/include/Makefile
+++ b/xen/include/Makefile
@@ -101,7 +101,7 @@ all: headers.chk headers99.chk headers++.chk
 PUBLIC_HEADERS := $(filter-out public/arch-% public/dom0_ops.h, $(wildcard public/*.h public/*/*.h) $(public-y))
 
 PUBLIC_C99_HEADERS := public/io/9pfs.h public/io/pvcalls.h
-PUBLIC_ANSI_HEADERS := $(filter-out public/%ctl.h public/xsm/% public/%hvm/save.h $(PUBLIC_C99_HEADERS), $(PUBLIC_HEADERS))
+PUBLIC_ANSI_HEADERS := $(filter-out public/%ctl.h public/migration_stream.h public/xsm/% public/%hvm/save.h $(PUBLIC_C99_HEADERS), $(PUBLIC_HEADERS))
 
 public/io/9pfs.h-prereq := string
 public/io/pvcalls.h-prereq := string
diff --git a/xen/include/public/migration_stream.h b/xen/include/public/migration_stream.h
new file mode 100644
index 0000000000..de5b736362
--- /dev/null
+++ b/xen/include/public/migration_stream.h
@@ -0,0 +1,125 @@
+#ifndef __XEN_MIGRATION_STREAM_H__
+#define __XEN_MIGRATION_STREAM_H__
+
+#if !defined(__XEN__) && !defined(__XEN_TOOLS__)
+#error "Migration stream definitions are intended for use by node control tools only"
+#endif
+
+/*
+ * C structures for the Migration and Live Update.
+ * See docs/specs/libxc-migration-stream.pandoc
+ */
+
+#include "xen.h"
+
+/*
+ * The domain types are used in the libxc stream domain header and will also
+ * be used in corresponding records for live update.
+ */
+#define DHDR_TYPE_X86_PV  0x00000001U
+#define DHDR_TYPE_X86_HVM 0x00000002U
+
+/*
+ * Record Header
+ */
+struct mr_rhdr
+{
+    uint32_t type;
+    uint32_t length;
+};
+
+/* All records must be aligned up to an 8 octet boundary */
+#define REC_ALIGN_ORDER               (3U)
+/* Somewhat arbitrary - 128MB */
+#define REC_LENGTH_MAX                (128U << 20)
+
+#define REC_TYPE_END                        0x00000000U
+#define REC_TYPE_PAGE_DATA                  0x00000001U
+#define REC_TYPE_X86_PV_INFO                0x00000002U
+#define REC_TYPE_X86_PV_P2M_FRAMES          0x00000003U
+#define REC_TYPE_X86_PV_VCPU_BASIC          0x00000004U
+#define REC_TYPE_X86_PV_VCPU_EXTENDED       0x00000005U
+#define REC_TYPE_X86_PV_VCPU_XSAVE          0x00000006U
+#define REC_TYPE_SHARED_INFO                0x00000007U
+#define REC_TYPE_X86_TSC_INFO               0x00000008U
+#define REC_TYPE_HVM_CONTEXT                0x00000009U
+#define REC_TYPE_HVM_PARAMS                 0x0000000aU
+#define REC_TYPE_TOOLSTACK                  0x0000000bU
+#define REC_TYPE_X86_PV_VCPU_MSRS           0x0000000cU
+#define REC_TYPE_VERIFY                     0x0000000dU
+#define REC_TYPE_CHECKPOINT                 0x0000000eU
+#define REC_TYPE_CHECKPOINT_DIRTY_PFN_LIST  0x0000000fU
+
+#define REC_TYPE_OPTIONAL             0x80000000U
+#define REC_TYPE_LIVE_UPDATE          0x40000000U
+
+/* PAGE_DATA */
+struct mr_page_data_header
+{
+    uint32_t count;
+    uint32_t _res1;
+    uint64_t pfn[0];
+};
+
+#define PAGE_DATA_PFN_MASK  0x000fffffffffffffULL
+#define PAGE_DATA_TYPE_MASK 0xf000000000000000ULL
+
+/* X86_PV_INFO */
+struct mr_x86_pv_info
+{
+    uint8_t guest_width;
+    uint8_t pt_levels;
+    uint8_t _res[6];
+};
+
+/* X86_PV_P2M_FRAMES */
+struct mr_x86_pv_p2m_frames
+{
+    uint32_t start_pfn;
+    uint32_t end_pfn;
+    uint64_t p2m_pfns[0];
+};
+
+/* X86_PV_VCPU_{BASIC,EXTENDED,XSAVE,MSRS} */
+struct mr_x86_pv_vcpu_hdr
+{
+    uint32_t vcpu_id;
+    uint32_t _res1;
+    uint8_t context[0];
+};
+
+/* X86_TSC_INFO */
+struct mr_x86_tsc_info
+{
+    uint32_t mode;
+    uint32_t khz;
+    uint64_t nsec;
+    uint32_t incarnation;
+    uint32_t _res1;
+};
+
+/* HVM_PARAMS */
+struct mr_hvm_params_entry
+{
+    uint64_t index;
+    uint64_t value;
+};
+
+struct mr_hvm_params
+{
+    uint32_t count;
+    uint32_t _res1;
+    struct mr_hvm_params_entry param[0];
+};
+
+#endif /* __XEN_MIGRATION_STREAM_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel