All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv5 0/8] tools: rework VM Generation ID
@ 2014-06-12 15:04 David Vrabel
  2014-06-12 15:04 ` [PATCH 1/8] libxc: allow xc_get/set_hvm_param() to get/set 64-bit values David Vrabel
                   ` (7 more replies)
  0 siblings, 8 replies; 23+ messages in thread
From: David Vrabel @ 2014-06-12 15:04 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Jackson, Ian Campbell, Stefano Stabellini

This series reworks the VM Generation ID to a) conform to the
published spec from Microsoft; b) simplify the save/restore code; and
c) extend the libxl API to allow toolstacks to use this feature.

The VM Generation ID must be regenerated with a new random ID after
certain VM operations. Since xl lacks infrastructure for tracking the
life-cycle of snapshots and clones (etc), the safe option of always
using a new generation ID is used.

You can download the spec from:

  http://www.microsoft.com/en-us/download/details.aspx?id=30707

Patch status ([A]cked, [M]odified, [N]ew):

M libxc: allow xc_get/set_hvm_param() to get/set 64-bit
N libxl: add libxl__random_bytes() which fills a buffer
A hvmloader: add helper functions to get/set HVM params
A hvm: add HVM_PARAM_VM_GENERATION_ID_ADDR
A libxc,libxl,hvmloader: strip out outdated VM generation
M libxl: allow a generation ID to be specified at domain
M xl: generate a new random VM generation ID if requested
A docs: update docs for the ~/platform/generation-id key

Changes in v5:

- Rebase on staging to fix some conflicts.
- Add libxl__random_bytes()
- Rename field to ms_vm_genid.
- Toolstacks can generate a fully random generation ID with
  libxl_vm_genid_generate().

Changes in v4:

- Allow xc_get/get_hvm_params() to get/set 64-bit values.
- Const-ify libxl_uuid_*() calls.
- Minor tweaks to libxl internals (gc as param, use GCSPRINTF()).

Changes in v3:

- Specify generation ID in libxl_domain_build_info instead of having
  to call a function to set it.
- Improve docs.

Changes in v2:

- Use libxl_uuid for the generation ID.
- Add "generation_id" option to xl domain configuration file and use
  this to set a random generation ID every time.

David

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 1/8] libxc: allow xc_get/set_hvm_param() to get/set 64-bit values
  2014-06-12 15:04 [PATCHv5 0/8] tools: rework VM Generation ID David Vrabel
@ 2014-06-12 15:04 ` David Vrabel
  2014-06-18 11:26   ` Ian Campbell
  2014-06-18 13:05   ` Ian Campbell
  2014-06-12 15:04 ` [PATCH 2/8] libxl: add libxl__random_bytes() which fills a buffer with random bytes David Vrabel
                   ` (6 subsequent siblings)
  7 siblings, 2 replies; 23+ messages in thread
From: David Vrabel @ 2014-06-12 15:04 UTC (permalink / raw)
  To: xen-devel; +Cc: David Vrabel, Ian Jackson, Ian Campbell, Stefano Stabellini

HVMOP_get_param and HVMOP_set_param take a uint32_t for the parameter
index and a uint64_t for the value.  So, make the corresponding libxc
function take the same types.

Signed-off-by: David Vrabel <david.vrabel@citrix.com>
---
 tools/libxc/xc_cpuid_x86.c          |   11 +++++-----
 tools/libxc/xc_domain.c             |    4 ++--
 tools/libxc/xc_domain_save.c        |   39 ++++++++++++-----------------------
 tools/libxc/xc_resume.c             |    2 +-
 tools/libxc/xenctrl.h               |    4 ++--
 tools/libxl/libxl.c                 |    2 +-
 tools/libxl/libxl_dom.c             |   10 ++++++---
 tools/python/xen/lowlevel/xc/xc.c   |    4 ++--
 tools/tests/xen-access/xen-access.c |    5 +++--
 9 files changed, 36 insertions(+), 45 deletions(-)

diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
index 4772ca7..0541bc6 100644
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -276,13 +276,12 @@ static void xc_cpuid_hvm_policy(
 {
     DECLARE_DOMCTL;
     char brand[13];
-    unsigned long nestedhvm;
-    unsigned long pae;
+    uint64_t val;
     int is_pae, is_nestedhvm;
     uint64_t xfeature_mask;
 
-    xc_get_hvm_param(xch, domid, HVM_PARAM_PAE_ENABLED, &pae);
-    is_pae = !!pae;
+    xc_get_hvm_param(xch, domid, HVM_PARAM_PAE_ENABLED, &val);
+    is_pae = !!val;
 
     /* Detecting Xen's atitude towards XSAVE */
     memset(&domctl, 0, sizeof(domctl));
@@ -291,8 +290,8 @@ static void xc_cpuid_hvm_policy(
     do_domctl(xch, &domctl);
     xfeature_mask = domctl.u.vcpuextstate.xfeature_mask;
 
-    xc_get_hvm_param(xch, domid, HVM_PARAM_NESTEDHVM, &nestedhvm);
-    is_nestedhvm = !!nestedhvm;
+    xc_get_hvm_param(xch, domid, HVM_PARAM_NESTEDHVM, &val);
+    is_nestedhvm = !!val;
 
     switch ( input[0] )
     {
diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index 37ed141..528c987 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -1242,7 +1242,7 @@ int xc_domain_send_trigger(xc_interface *xch,
     return do_domctl(xch, &domctl);
 }
 
-int xc_set_hvm_param(xc_interface *handle, domid_t dom, int param, unsigned long value)
+int xc_set_hvm_param(xc_interface *handle, domid_t dom, uint32_t param, uint64_t value)
 {
     DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_param_t, arg);
@@ -1263,7 +1263,7 @@ int xc_set_hvm_param(xc_interface *handle, domid_t dom, int param, unsigned long
     return rc;
 }
 
-int xc_get_hvm_param(xc_interface *handle, domid_t dom, int param, unsigned long *value)
+int xc_get_hvm_param(xc_interface *handle, domid_t dom, uint32_t param, uint64_t *value)
 {
     DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_param_t, arg);
diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
index 778cbde..ba52198 100644
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -1645,8 +1645,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
 
         chunk.id = XC_SAVE_ID_HVM_IDENT_PT;
         chunk.data = 0;
-        xc_get_hvm_param(xch, dom, HVM_PARAM_IDENT_PT,
-                         (unsigned long *)&chunk.data);
+        xc_get_hvm_param(xch, dom, HVM_PARAM_IDENT_PT, &chunk.data);
 
         if ( (chunk.data != 0) &&
              wrexact(io_fd, &chunk, sizeof(chunk)) )
@@ -1657,8 +1656,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
 
         chunk.id = XC_SAVE_ID_HVM_PAGING_RING_PFN;
         chunk.data = 0;
-        xc_get_hvm_param(xch, dom, HVM_PARAM_PAGING_RING_PFN,
-                         (unsigned long *)&chunk.data);
+        xc_get_hvm_param(xch, dom, HVM_PARAM_PAGING_RING_PFN, &chunk.data);
 
         if ( (chunk.data != 0) &&
              wrexact(io_fd, &chunk, sizeof(chunk)) )
@@ -1669,8 +1667,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
 
         chunk.id = XC_SAVE_ID_HVM_ACCESS_RING_PFN;
         chunk.data = 0;
-        xc_get_hvm_param(xch, dom, HVM_PARAM_ACCESS_RING_PFN,
-                         (unsigned long *)&chunk.data);
+        xc_get_hvm_param(xch, dom, HVM_PARAM_ACCESS_RING_PFN, &chunk.data);
 
         if ( (chunk.data != 0) &&
              wrexact(io_fd, &chunk, sizeof(chunk)) )
@@ -1681,8 +1678,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
 
         chunk.id = XC_SAVE_ID_HVM_SHARING_RING_PFN;
         chunk.data = 0;
-        xc_get_hvm_param(xch, dom, HVM_PARAM_SHARING_RING_PFN,
-                         (unsigned long *)&chunk.data);
+        xc_get_hvm_param(xch, dom, HVM_PARAM_SHARING_RING_PFN, &chunk.data);
 
         if ( (chunk.data != 0) &&
              wrexact(io_fd, &chunk, sizeof(chunk)) )
@@ -1693,8 +1689,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
 
         chunk.id = XC_SAVE_ID_HVM_VM86_TSS;
         chunk.data = 0;
-        xc_get_hvm_param(xch, dom, HVM_PARAM_VM86_TSS,
-                         (unsigned long *)&chunk.data);
+        xc_get_hvm_param(xch, dom, HVM_PARAM_VM86_TSS, &chunk.data);
 
         if ( (chunk.data != 0) &&
              wrexact(io_fd, &chunk, sizeof(chunk)) )
@@ -1705,8 +1700,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
 
         chunk.id = XC_SAVE_ID_HVM_CONSOLE_PFN;
         chunk.data = 0;
-        xc_get_hvm_param(xch, dom, HVM_PARAM_CONSOLE_PFN,
-                         (unsigned long *)&chunk.data);
+        xc_get_hvm_param(xch, dom, HVM_PARAM_CONSOLE_PFN, &chunk.data);
 
         if ( (chunk.data != 0) &&
              wrexact(io_fd, &chunk, sizeof(chunk)) )
@@ -1717,8 +1711,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
 
         chunk.id = XC_SAVE_ID_HVM_ACPI_IOPORTS_LOCATION;
         chunk.data = 0;
-        xc_get_hvm_param(xch, dom, HVM_PARAM_ACPI_IOPORTS_LOCATION,
-                         (unsigned long *)&chunk.data);
+        xc_get_hvm_param(xch, dom, HVM_PARAM_ACPI_IOPORTS_LOCATION, &chunk.data);
 
         if ((chunk.data != 0) && wrexact(io_fd, &chunk, sizeof(chunk)))
         {
@@ -1728,8 +1721,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
 
         chunk.id = XC_SAVE_ID_HVM_VIRIDIAN;
         chunk.data = 0;
-        xc_get_hvm_param(xch, dom, HVM_PARAM_VIRIDIAN,
-                         (unsigned long *)&chunk.data);
+        xc_get_hvm_param(xch, dom, HVM_PARAM_VIRIDIAN, &chunk.data);
 
         if ( (chunk.data != 0) &&
              wrexact(io_fd, &chunk, sizeof(chunk)) )
@@ -1740,8 +1732,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
 
         chunk.id = XC_SAVE_ID_HVM_IOREQ_SERVER_PFN;
         chunk.data = 0;
-        xc_get_hvm_param(xch, dom, HVM_PARAM_IOREQ_SERVER_PFN,
-                         (unsigned long *)&chunk.data);
+        xc_get_hvm_param(xch, dom, HVM_PARAM_IOREQ_SERVER_PFN, &chunk.data);
 
         if ( (chunk.data != 0) &&
              wrexact(io_fd, &chunk, sizeof(chunk)) )
@@ -1752,8 +1743,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
 
         chunk.id = XC_SAVE_ID_HVM_NR_IOREQ_SERVER_PAGES;
         chunk.data = 0;
-        xc_get_hvm_param(xch, dom, HVM_PARAM_NR_IOREQ_SERVER_PAGES,
-                         (unsigned long *)&chunk.data);
+        xc_get_hvm_param(xch, dom, HVM_PARAM_NR_IOREQ_SERVER_PAGES, &chunk.data);
 
         if ( (chunk.data != 0) &&
              wrexact(io_fd, &chunk, sizeof(chunk)) )
@@ -1827,12 +1817,9 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
 
         /* Save magic-page locations. */
         memset(magic_pfns, 0, sizeof(magic_pfns));
-        xc_get_hvm_param(xch, dom, HVM_PARAM_IOREQ_PFN,
-                         (unsigned long *)&magic_pfns[0]);
-        xc_get_hvm_param(xch, dom, HVM_PARAM_BUFIOREQ_PFN,
-                         (unsigned long *)&magic_pfns[1]);
-        xc_get_hvm_param(xch, dom, HVM_PARAM_STORE_PFN,
-                         (unsigned long *)&magic_pfns[2]);
+        xc_get_hvm_param(xch, dom, HVM_PARAM_IOREQ_PFN, &magic_pfns[0]);
+        xc_get_hvm_param(xch, dom, HVM_PARAM_BUFIOREQ_PFN, &magic_pfns[1]);
+        xc_get_hvm_param(xch, dom, HVM_PARAM_STORE_PFN, &magic_pfns[2]);
         if ( wrexact(io_fd, magic_pfns, sizeof(magic_pfns)) )
         {
             PERROR("Error when writing to state file (7)");
diff --git a/tools/libxc/xc_resume.c b/tools/libxc/xc_resume.c
index e423814..226b5e9 100644
--- a/tools/libxc/xc_resume.c
+++ b/tools/libxc/xc_resume.c
@@ -51,7 +51,7 @@ static int modify_returncode(xc_interface *xch, uint32_t domid)
     if ( info.hvm )
     {
         /* HVM guests without PV drivers have no return code to modify. */
-        unsigned long irq = 0;
+        uint64_t irq = 0;
         xc_get_hvm_param(xch, domid, HVM_PARAM_CALLBACK_IRQ, &irq);
         if ( !irq )
             return 0;
diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
index b55d857..da5a9dc 100644
--- a/tools/libxc/xenctrl.h
+++ b/tools/libxc/xenctrl.h
@@ -1808,8 +1808,8 @@ const xc_error *xc_get_last_error(xc_interface *handle);
 void xc_clear_last_error(xc_interface *xch);
 
 
-int xc_set_hvm_param(xc_interface *handle, domid_t dom, int param, unsigned long value);
-int xc_get_hvm_param(xc_interface *handle, domid_t dom, int param, unsigned long *value);
+int xc_set_hvm_param(xc_interface *handle, domid_t dom, uint32_t param, uint64_t value);
+int xc_get_hvm_param(xc_interface *handle, domid_t dom, uint32_t param, uint64_t *value);
 
 /*
  * IOREQ Server API. (See section on IOREQ Servers in public/hvm_op.h).
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 4b66afc..170c0a5 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -885,7 +885,7 @@ int libxl__domain_pvcontrol_available(libxl__gc *gc, uint32_t domid)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
 
-    unsigned long pvdriver = 0;
+    uint64_t pvdriver = 0;
     int ret;
 
     libxl_domain_type domtype = libxl__domain_type(gc, domid);
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 661999c..b8cc40c 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -490,6 +490,7 @@ static int hvm_build_set_params(xc_interface *handle, uint32_t domid,
 {
     struct hvm_info_table *va_hvm;
     uint8_t *va_map, sum;
+    uint64_t str_mfn, cons_mfn;
     int i;
 
     va_map = xc_map_foreign_range(handle, domid,
@@ -508,11 +509,14 @@ static int hvm_build_set_params(xc_interface *handle, uint32_t domid,
     va_hvm->checksum -= sum;
     munmap(va_map, XC_PAGE_SIZE);
 
-    xc_get_hvm_param(handle, domid, HVM_PARAM_STORE_PFN, store_mfn);
-    xc_get_hvm_param(handle, domid, HVM_PARAM_CONSOLE_PFN, console_mfn);
+    xc_get_hvm_param(handle, domid, HVM_PARAM_STORE_PFN, &str_mfn);
+    xc_get_hvm_param(handle, domid, HVM_PARAM_CONSOLE_PFN, &cons_mfn);
     xc_set_hvm_param(handle, domid, HVM_PARAM_STORE_EVTCHN, store_evtchn);
     xc_set_hvm_param(handle, domid, HVM_PARAM_CONSOLE_EVTCHN, console_evtchn);
 
+    *store_mfn = str_mfn;
+    *console_mfn = cons_mfn;
+
     xc_dom_gnttab_hvm_seed(handle, domid, *console_mfn, *store_mfn, console_domid, store_domid);
     return 0;
 }
@@ -1070,7 +1074,7 @@ static void domain_suspend_callback_common(libxl__egc *egc,
                                            libxl__domain_suspend_state *dss)
 {
     STATE_AO_GC(dss->ao);
-    unsigned long hvm_s_state = 0, hvm_pvdrv = 0;
+    uint64_t hvm_s_state = 0, hvm_pvdrv = 0;
     int ret, rc;
 
     /* Convenience aliases */
diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c
index cb34446..43ac133 100644
--- a/tools/python/xen/lowlevel/xc/xc.c
+++ b/tools/python/xen/lowlevel/xc/xc.c
@@ -550,7 +550,7 @@ static PyObject *pyxc_get_hvm_param(XcObject *self,
 {
     uint32_t dom;
     int param;
-    unsigned long value;
+    uint64_t value;
 
     static char *kwd_list[] = { "domid", "param", NULL }; 
     if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
@@ -560,7 +560,7 @@ static PyObject *pyxc_get_hvm_param(XcObject *self,
     if ( xc_get_hvm_param(self->xc_handle, dom, param, &value) != 0 )
         return pyxc_error_to_exception(self->xc_handle);
 
-    return PyLong_FromUnsignedLong(value);
+    return PyLong_FromUnsignedLongLong(value);
 
 }
 
diff --git a/tools/tests/xen-access/xen-access.c b/tools/tests/xen-access/xen-access.c
index 0a84bd5..d493f21 100644
--- a/tools/tests/xen-access/xen-access.c
+++ b/tools/tests/xen-access/xen-access.c
@@ -223,6 +223,7 @@ xenaccess_t *xenaccess_init(xc_interface **xch_r, domid_t domain_id)
     xenaccess_t *xenaccess = 0;
     xc_interface *xch;
     int rc;
+    uint64_t val;
     unsigned long ring_pfn, mmap_pfn;
 
     xch = xc_interface_open(NULL, NULL, 0);
@@ -247,8 +248,8 @@ xenaccess_t *xenaccess_init(xc_interface **xch_r, domid_t domain_id)
 
     /* Map the ring page */
     xc_get_hvm_param(xch, xenaccess->mem_event.domain_id, 
-                        HVM_PARAM_ACCESS_RING_PFN, &ring_pfn);
-    mmap_pfn = ring_pfn;
+                        HVM_PARAM_ACCESS_RING_PFN, &val);
+    mmap_pfn = ring_pfn = val;
     xenaccess->mem_event.ring_page = 
         xc_map_foreign_batch(xch, xenaccess->mem_event.domain_id, 
                                 PROT_READ | PROT_WRITE, &mmap_pfn, 1);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2/8] libxl: add libxl__random_bytes() which fills a buffer with random bytes
  2014-06-12 15:04 [PATCHv5 0/8] tools: rework VM Generation ID David Vrabel
  2014-06-12 15:04 ` [PATCH 1/8] libxc: allow xc_get/set_hvm_param() to get/set 64-bit values David Vrabel
@ 2014-06-12 15:04 ` David Vrabel
  2014-06-18 11:28   ` Ian Campbell
  2014-06-12 15:04 ` [PATCH 3/8] hvmloader: add helper functions to get/set HVM params David Vrabel
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 23+ messages in thread
From: David Vrabel @ 2014-06-12 15:04 UTC (permalink / raw)
  To: xen-devel; +Cc: David Vrabel, Ian Jackson, Ian Campbell, Stefano Stabellini

The random bytes are obtained from /dev/urandom and are suitable for
almost all uses (except for generating long-lived secure keys).

Documentation suggests that /dev/urandom is widely available on Unix-like
systems (such FreeBSD and NetBSD).

A public libxl_random_bytes() (or similar) could be trivially added,
if this required in the future.

Signed-off-by: David Vrabel <david.vrabel@citrix.com>
---
 tools/libxl/libxl_internal.h |    2 ++
 tools/libxl/libxl_utils.c    |   22 ++++++++++++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index a0d4f24..a9343e8 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3180,6 +3180,8 @@ int libxl__uint64_parse_json(libxl__gc *gc, const libxl__json_object *o,
 int libxl__string_parse_json(libxl__gc *gc, const libxl__json_object *o,
                              char **p);
 
+int libxl__random_bytes(libxl__gc *gc, uint8_t *buf, size_t len);
+
 #endif
 
 /*
diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c
index 476921e..3be01a5 100644
--- a/tools/libxl/libxl_utils.c
+++ b/tools/libxl/libxl_utils.c
@@ -1014,6 +1014,28 @@ int libxl_domid_valid_guest(uint32_t domid)
 }
 
 /*
+ * Fill @buf with @len random bytes.
+ */
+int libxl__random_bytes(libxl__gc *gc, uint8_t *buf, size_t len)
+{
+    static const char *dev = "/dev/urandom";
+    int fd;
+    int ret;
+
+    fd = open(dev, O_RDONLY | O_CLOEXEC);
+    if (fd < 0) {
+        LOGE(ERROR, "failed to open \"%s\"", dev);
+        return ERROR_FAIL;
+    }
+
+    ret = libxl_read_exactly(CTX, fd, buf, len, dev, NULL);
+
+    close(fd);
+
+    return ret;
+}
+
+/*
  * Local variables:
  * mode: C
  * c-basic-offset: 4
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 3/8] hvmloader: add helper functions to get/set HVM params
  2014-06-12 15:04 [PATCHv5 0/8] tools: rework VM Generation ID David Vrabel
  2014-06-12 15:04 ` [PATCH 1/8] libxc: allow xc_get/set_hvm_param() to get/set 64-bit values David Vrabel
  2014-06-12 15:04 ` [PATCH 2/8] libxl: add libxl__random_bytes() which fills a buffer with random bytes David Vrabel
@ 2014-06-12 15:04 ` David Vrabel
  2014-06-12 15:04 ` [PATCH 4/8] hvm: add HVM_PARAM_VM_GENERATION_ID_ADDR David Vrabel
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 23+ messages in thread
From: David Vrabel @ 2014-06-12 15:04 UTC (permalink / raw)
  To: xen-devel; +Cc: David Vrabel, Ian Jackson, Ian Campbell, Stefano Stabellini

Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 tools/firmware/hvmloader/Makefile    |    1 +
 tools/firmware/hvmloader/hvm_param.c |   36 ++++++++++++++++++++++++++++++++++
 tools/firmware/hvmloader/hvmloader.c |   14 ++-----------
 tools/firmware/hvmloader/util.h      |    9 +++++++++
 tools/firmware/hvmloader/xenbus.c    |   14 +++++--------
 5 files changed, 53 insertions(+), 21 deletions(-)
 create mode 100644 tools/firmware/hvmloader/hvm_param.c

diff --git a/tools/firmware/hvmloader/Makefile b/tools/firmware/hvmloader/Makefile
index 00ee952..46a79c5 100644
--- a/tools/firmware/hvmloader/Makefile
+++ b/tools/firmware/hvmloader/Makefile
@@ -31,6 +31,7 @@ CFLAGS += $(CFLAGS_xeninclude)
 OBJS  = hvmloader.o mp_tables.o util.o smbios.o 
 OBJS += smp.o cacheattr.o xenbus.o
 OBJS += e820.o pci.o pir.o ctype.o
+OBJS += hvm_param.o
 ifeq ($(debug),y)
 OBJS += tests.o
 endif
diff --git a/tools/firmware/hvmloader/hvm_param.c b/tools/firmware/hvmloader/hvm_param.c
new file mode 100644
index 0000000..f7d8720
--- /dev/null
+++ b/tools/firmware/hvmloader/hvm_param.c
@@ -0,0 +1,36 @@
+/*
+ * hvm_param.c: get/set HVM params.
+ *
+ * Copyright (C) 2014 Citrix Systems R&D Ltd.
+ */
+#include "util.h"
+#include "config.h"
+#include "hypercall.h"
+
+#include <xen/hvm/params.h>
+
+int hvm_param_get(uint32_t index, uint64_t *value)
+{
+    struct xen_hvm_param p;
+    int ret;
+
+    p.domid = DOMID_SELF;
+    p.index = index;
+
+    ret = hypercall_hvm_op(HVMOP_get_param, &p);
+    if (ret == 0)
+        *value = p.value;
+
+    return ret;
+}
+
+int hvm_param_set(uint32_t index, uint64_t value)
+{
+    struct xen_hvm_param p;
+
+    p.domid = DOMID_SELF;
+    p.index = index;
+    p.value = value;
+
+    return hypercall_hvm_op(HVMOP_set_param, &p);
+}
diff --git a/tools/firmware/hvmloader/hvmloader.c b/tools/firmware/hvmloader/hvmloader.c
index 1cc8cf2..7b0da38 100644
--- a/tools/firmware/hvmloader/hvmloader.c
+++ b/tools/firmware/hvmloader/hvmloader.c
@@ -176,14 +176,10 @@ static void cmos_write_memory_size(void)
 static void init_vm86_tss(void)
 {
     void *tss;
-    struct xen_hvm_param p;
 
     tss = mem_alloc(128, 128);
     memset(tss, 0, 128);
-    p.domid = DOMID_SELF;
-    p.index = HVM_PARAM_VM86_TSS;
-    p.value = virt_to_phys(tss);
-    hypercall_hvm_op(HVMOP_set_param, &p);
+    hvm_param_set(HVM_PARAM_VM86_TSS, virt_to_phys(tss));
     printf("vm86 TSS at %08lx\n", virt_to_phys(tss));
 }
 
@@ -314,12 +310,6 @@ int main(void)
 
     if ( acpi_enabled )
     {
-        struct xen_hvm_param p = {
-            .domid = DOMID_SELF,
-            .index = HVM_PARAM_ACPI_IOPORTS_LOCATION,
-            .value = 1,
-        };
-
         if ( bios->acpi_build_tables )
         {
             printf("Loading ACPI ...\n");
@@ -328,7 +318,7 @@ int main(void)
 
         acpi_enable_sci();
 
-        hypercall_hvm_op(HVMOP_set_param, &p);
+        hvm_param_set(HVM_PARAM_ACPI_IOPORTS_LOCATION, 1);
     }
 
     init_vm86_tss();
diff --git a/tools/firmware/hvmloader/util.h b/tools/firmware/hvmloader/util.h
index 9ccb905..e4b6be4 100644
--- a/tools/firmware/hvmloader/util.h
+++ b/tools/firmware/hvmloader/util.h
@@ -210,6 +210,15 @@ const char *xenstore_read(const char *path, const char *default_resp);
  */
 int xenstore_write(const char *path, const char *value);
 
+
+/* Get a HVM param.
+ */
+int hvm_param_get(uint32_t index, uint64_t *value);
+
+/* Set a HVM param.
+ */
+int hvm_param_set(uint32_t index, uint64_t value);
+
 /* Setup PCI bus */
 void pci_setup(void);
 
diff --git a/tools/firmware/hvmloader/xenbus.c b/tools/firmware/hvmloader/xenbus.c
index fe72e97..64c2176 100644
--- a/tools/firmware/hvmloader/xenbus.c
+++ b/tools/firmware/hvmloader/xenbus.c
@@ -41,21 +41,17 @@ static char payload[XENSTORE_PAYLOAD_MAX + 1];  /* Unmarshalling area */
  * Call once, before any other xenbus actions. */
 void xenbus_setup(void)
 {
-    xen_hvm_param_t param;
+    uint64_t val;
 
     /* Ask Xen where the xenbus shared page is. */
-    param.domid = DOMID_SELF;
-    param.index = HVM_PARAM_STORE_PFN;
-    if ( hypercall_hvm_op(HVMOP_get_param, &param) )
+    if ( hvm_param_get(HVM_PARAM_STORE_PFN, &val) )
         BUG();
-    rings = (void *) (unsigned long) (param.value << PAGE_SHIFT);
+    rings = (void *) (unsigned long) (val << PAGE_SHIFT);
 
     /* Ask Xen where the xenbus event channel is. */
-    param.domid = DOMID_SELF;
-    param.index = HVM_PARAM_STORE_EVTCHN;
-    if ( hypercall_hvm_op(HVMOP_get_param, &param) )
+    if ( hvm_param_get(HVM_PARAM_STORE_EVTCHN, &val) )
         BUG();
-    event = param.value;
+    event = val;
 
     printf("Xenbus rings @0x%lx, event channel %lu\n",
            (unsigned long) rings, (unsigned long) event);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 4/8] hvm: add HVM_PARAM_VM_GENERATION_ID_ADDR
  2014-06-12 15:04 [PATCHv5 0/8] tools: rework VM Generation ID David Vrabel
                   ` (2 preceding siblings ...)
  2014-06-12 15:04 ` [PATCH 3/8] hvmloader: add helper functions to get/set HVM params David Vrabel
@ 2014-06-12 15:04 ` David Vrabel
  2014-06-12 15:04 ` [PATCH 5/8] libxc, libxl, hvmloader: strip out outdated VM generation ID implementation David Vrabel
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 23+ messages in thread
From: David Vrabel @ 2014-06-12 15:04 UTC (permalink / raw)
  To: xen-devel; +Cc: David Vrabel, Ian Jackson, Ian Campbell, Stefano Stabellini

HVM_PARAM_VM_GENERATION_ID_ADDR is the guest physical address of the
VM Generation ID.  This parameter will be written by hvmloader and read
by the toolstack when updating the gen. ID (e.g., after restoring from a
snapshot).

A HVM parameter is easier for the save/restore code to work with (than
a XenStore key).

Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
 xen/include/public/hvm/params.h |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h
index f830bdd..614ff5f 100644
--- a/xen/include/public/hvm/params.h
+++ b/xen/include/public/hvm/params.h
@@ -148,6 +148,9 @@
 #define HVM_PARAM_IOREQ_SERVER_PFN 32
 #define HVM_PARAM_NR_IOREQ_SERVER_PAGES 33
 
-#define HVM_NR_PARAMS          34
+/* Location of the VM Generation ID in guest physical address space. */
+#define HVM_PARAM_VM_GENERATION_ID_ADDR 34
+
+#define HVM_NR_PARAMS          35
 
 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 5/8] libxc, libxl, hvmloader: strip out outdated VM generation ID implementation
  2014-06-12 15:04 [PATCHv5 0/8] tools: rework VM Generation ID David Vrabel
                   ` (3 preceding siblings ...)
  2014-06-12 15:04 ` [PATCH 4/8] hvm: add HVM_PARAM_VM_GENERATION_ID_ADDR David Vrabel
@ 2014-06-12 15:04 ` David Vrabel
  2014-06-12 15:04 ` [PATCH 6/8] libxl: allow a generation ID to be specified at domain creation David Vrabel
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 23+ messages in thread
From: David Vrabel @ 2014-06-12 15:04 UTC (permalink / raw)
  To: xen-devel; +Cc: David Vrabel, Ian Jackson, Ian Campbell, Stefano Stabellini

The VM generation ID support in libxc/libxl was based on a draft
specification which subsequently changed considerably.  Remove much of
the code in anticipation of introducing something simpler that
conforms to the current specification from Microsoft.

Switch to using a HVM param (HVM_PARAM_VM_GENERATION_ID_ADDR) instead
of the hvmloader/generation-id-address XenStore key.  This simplifies
save/restore since it only needs to transfer the value of this param.

There are no changes to the migration stream format or the public
libxl API.

Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 tools/firmware/hvmloader/acpi/build.c |    9 +++----
 tools/libxc/xc_domain_restore.c       |   44 +++------------------------------
 tools/libxc/xc_domain_save.c          |    5 ++--
 tools/libxc/xenguest.h                |    8 ++----
 tools/libxl/libxl_create.c            |   12 +++------
 tools/libxl/libxl_dom.c               |   25 ++-----------------
 tools/libxl/libxl_internal.h          |    8 ++----
 tools/libxl/libxl_save_callout.c      |   10 +++-----
 tools/libxl/libxl_save_helper.c       |    9 +++----
 tools/libxl/libxl_save_msgs_gen.pl    |    3 +--
 10 files changed, 26 insertions(+), 107 deletions(-)

diff --git a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acpi/build.c
index 5c42d89..1431296 100644
--- a/tools/firmware/hvmloader/acpi/build.c
+++ b/tools/firmware/hvmloader/acpi/build.c
@@ -24,6 +24,7 @@
 #include "../config.h"
 #include "../util.h"
 #include <xen/hvm/hvm_xs_strings.h>
+#include <xen/hvm/params.h>
 
 #define ACPI_MAX_SECONDARY_TABLES 16
 
@@ -362,7 +363,6 @@ static int construct_secondary_tables(unsigned long *table_ptrs,
 static int new_vm_gid(struct acpi_info *acpi_info)
 {
     uint64_t vm_gid[2], *buf;
-    char addr[12];
     const char * s;
     char *end;
 
@@ -383,12 +383,9 @@ static int new_vm_gid(struct acpi_info *acpi_info)
         return 0;
     memcpy(buf, vm_gid, sizeof(vm_gid));
 
-    /* set into ACPI table and XenStore the address */
+    /* set into ACPI table and HVM param the address */
     acpi_info->vm_gid_addr = virt_to_phys(buf);
-    if ( snprintf(addr, sizeof(addr), "0x%lx", virt_to_phys(buf))
-         >= sizeof(addr) )
-        return 0;
-    xenstore_write("hvmloader/generation-id-address", addr);
+    hvm_param_set(HVM_PARAM_VM_GENERATION_ID_ADDR, acpi_info->vm_gid_addr);
 
     return 1;
 }
diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
index b80f867..fe44e4c 100644
--- a/tools/libxc/xc_domain_restore.c
+++ b/tools/libxc/xc_domain_restore.c
@@ -1431,8 +1431,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
                       domid_t store_domid, unsigned int console_evtchn,
                       unsigned long *console_mfn, domid_t console_domid,
                       unsigned int hvm, unsigned int pae, int superpages,
-                      int no_incr_generationid, int checkpointed_stream,
-                      unsigned long *vm_generationid_addr,
+                      int checkpointed_stream,
                       struct restore_callbacks *callbacks)
 {
     DECLARE_DOMCTL;
@@ -1657,44 +1656,9 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
                 xc_set_hvm_param(xch, dom, HVM_PARAM_VM86_TSS, pagebuf.vm86_tss);
             if ( pagebuf.console_pfn )
                 console_pfn = pagebuf.console_pfn;
-            if ( pagebuf.vm_generationid_addr ) {
-                if ( !no_incr_generationid ) {
-                    unsigned int offset;
-                    unsigned char *buf;
-                    unsigned long long generationid;
-
-                    /*
-                     * Map the VM generation id buffer and inject the new value.
-                     */
-
-                    pfn = pagebuf.vm_generationid_addr >> PAGE_SHIFT;
-                    offset = pagebuf.vm_generationid_addr & (PAGE_SIZE - 1);
-                
-                    if ( (pfn >= dinfo->p2m_size) ||
-                         (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB) )
-                    {
-                        ERROR("generation id buffer frame is bad");
-                        goto out;
-                    }
-
-                    mfn = ctx->p2m[pfn];
-                    buf = xc_map_foreign_range(xch, dom, PAGE_SIZE,
-                                               PROT_READ | PROT_WRITE, mfn);
-                    if ( buf == NULL )
-                    {
-                        ERROR("xc_map_foreign_range for generation id"
-                              " buffer failed");
-                        goto out;
-                    }
-
-                    generationid = *(unsigned long long *)(buf + offset);
-                    *(unsigned long long *)(buf + offset) = generationid + 1;
-
-                    munmap(buf, PAGE_SIZE);
-                }
-
-                *vm_generationid_addr = pagebuf.vm_generationid_addr;
-            }
+            if ( pagebuf.vm_generationid_addr )
+                xc_set_hvm_param(xch, dom, HVM_PARAM_VM_GENERATION_ID_ADDR,
+                                 pagebuf.vm_generationid_addr);
 
             break;  /* our work here is done */
         }
diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
index ba52198..a314d1e 100644
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -802,8 +802,7 @@ static int save_tsc_info(xc_interface *xch, uint32_t dom, int io_fd)
 
 int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
                    uint32_t max_factor, uint32_t flags,
-                   struct save_callbacks* callbacks, int hvm,
-                   unsigned long vm_generationid_addr)
+                   struct save_callbacks* callbacks, int hvm)
 {
     xc_dominfo_t info;
     DECLARE_DOMCTL;
@@ -1634,7 +1633,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
         } chunk = { 0, };
 
         chunk.id = XC_SAVE_ID_HVM_GENERATION_ID_ADDR;
-        chunk.data = vm_generationid_addr;
+        xc_get_hvm_param(xch, dom, HVM_PARAM_VM_GENERATION_ID_ADDR, &chunk.data);
 
         if ( (chunk.data != 0) &&
              wrexact(io_fd, &chunk, sizeof(chunk)) )
diff --git a/tools/libxc/xenguest.h b/tools/libxc/xenguest.h
index 1f216cd..40bbac8 100644
--- a/tools/libxc/xenguest.h
+++ b/tools/libxc/xenguest.h
@@ -86,8 +86,7 @@ struct save_callbacks {
  */
 int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
                    uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
-                   struct save_callbacks* callbacks, int hvm,
-                   unsigned long vm_generationid_addr);
+                   struct save_callbacks* callbacks, int hvm);
 
 
 /* callbacks provided by xc_domain_restore */
@@ -113,9 +112,7 @@ struct restore_callbacks {
  * @parm hvm non-zero if this is a HVM restore
  * @parm pae non-zero if this HVM domain has PAE support enabled
  * @parm superpages non-zero to allocate guest memory with superpages
- * @parm no_incr_generationid non-zero if generation id is NOT to be incremented
  * @parm checkpointed_stream non-zero if the far end of the stream is using checkpointing
- * @parm vm_generationid_addr returned with the address of the generation id buffer
  * @parm callbacks non-NULL to receive a callback to restore toolstack
  *       specific data
  * @return 0 on success, -1 on failure
@@ -125,8 +122,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
                       domid_t store_domid, unsigned int console_evtchn,
                       unsigned long *console_mfn, domid_t console_domid,
                       unsigned int hvm, unsigned int pae, int superpages,
-                      int no_incr_generationid, int checkpointed_stream,
-                      unsigned long *vm_generationid_addr,
+                      int checkpointed_stream,
                       struct restore_callbacks *callbacks);
 /**
  * xc_domain_restore writes a file to disk that contains the device
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index d015cf4..cae6f53 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -584,12 +584,7 @@ retry_transaction:
                         ARRAY_SIZE(rwperm));
     }
 
-    if (info->type == LIBXL_DOMAIN_TYPE_HVM)
-        libxl__xs_mkdir(gc, t,
-            libxl__sprintf(gc, "%s/hvmloader/generation-id-address", dom_path),
-                        rwperm, ARRAY_SIZE(rwperm));
-
-                    vm_list = libxl_list_vm(ctx, &nb_vm);
+    vm_list = libxl_list_vm(ctx, &nb_vm);
     if (!vm_list) {
         LOG(ERROR, "cannot get number of running guests");
         rc = ERROR_FAIL;
@@ -903,7 +898,7 @@ static void domcreate_bootloader_done(libxl__egc *egc,
         goto out;
     }
     libxl__xc_domain_restore(egc, dcs,
-                             hvm, pae, superpages, 1);
+                             hvm, pae, superpages);
     return;
 
  out:
@@ -911,7 +906,7 @@ static void domcreate_bootloader_done(libxl__egc *egc,
 }
 
 void libxl__srm_callout_callback_restore_results(unsigned long store_mfn,
-          unsigned long console_mfn, unsigned long genidad, void *user)
+          unsigned long console_mfn, void *user)
 {
     libxl__save_helper_state *shs = user;
     libxl__domain_create_state *dcs = CONTAINER_OF(shs, *dcs, shs);
@@ -920,7 +915,6 @@ void libxl__srm_callout_callback_restore_results(unsigned long store_mfn,
 
     state->store_mfn =            store_mfn;
     state->console_mfn =          console_mfn;
-    state->vm_generationid_addr = genidad;
     shs->need_results =           0;
 }
 
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index b8cc40c..8485488 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -279,7 +279,6 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
 
     state->store_port = xc_evtchn_alloc_unbound(ctx->xch, domid, state->store_domid);
     state->console_port = xc_evtchn_alloc_unbound(ctx->xch, domid, state->console_domid);
-    state->vm_generationid_addr = 0;
 
     if (info->type == LIBXL_DOMAIN_TYPE_HVM)
         hvm_set_conf_params(ctx->xch, domid, info);
@@ -297,7 +296,7 @@ int libxl__build_post(libxl__gc *gc, uint32_t domid,
     libxl_ctx *ctx = libxl__gc_owner(gc);
     char *dom_path, *vm_path;
     xs_transaction_t t;
-    char **ents, **hvm_ents;
+    char **ents;
     int i, rc;
 
     rc = libxl_domain_sched_params_set(CTX, domid, &info->sched_params);
@@ -334,13 +333,6 @@ int libxl__build_post(libxl__gc *gc, uint32_t domid,
                             ? "online" : "offline";
     }
 
-    hvm_ents = NULL;
-    if (info->type == LIBXL_DOMAIN_TYPE_HVM) {
-        hvm_ents = libxl__calloc(gc, 3, sizeof(char *));
-        hvm_ents[0] = "hvmloader/generation-id-address";
-        hvm_ents[1] = GCSPRINTF("0x%lx", state->vm_generationid_addr);
-    }
-
     dom_path = libxl__xs_get_dompath(gc, domid);
     if (!dom_path) {
         return ERROR_FAIL;
@@ -351,9 +343,6 @@ retry_transaction:
     t = xs_transaction_start(ctx->xsh);
 
     libxl__xs_writev(gc, t, dom_path, ents);
-    if (info->type == LIBXL_DOMAIN_TYPE_HVM)
-        libxl__xs_writev(gc, t, dom_path, hvm_ents);
-
     libxl__xs_writev(gc, t, dom_path, local_ents);
     libxl__xs_writev(gc, t, vm_path, vms_ents);
 
@@ -1506,7 +1495,6 @@ void libxl__domain_suspend(libxl__egc *egc, libxl__domain_suspend_state *dss)
     STATE_AO_GC(dss->ao);
     int port;
     int rc = ERROR_FAIL;
-    unsigned long vm_generationid_addr;
 
     /* Convenience aliases */
     const uint32_t domid = dss->domid;
@@ -1525,19 +1513,10 @@ void libxl__domain_suspend(libxl__egc *egc, libxl__domain_suspend_state *dss)
 
     switch (type) {
     case LIBXL_DOMAIN_TYPE_HVM: {
-        char *path;
-        char *addr;
-
-        path = GCSPRINTF("%s/hvmloader/generation-id-address",
-                              libxl__xs_get_dompath(gc, domid));
-        addr = libxl__xs_read(gc, XBT_NULL, path);
-
-        vm_generationid_addr = (addr) ? strtoul(addr, NULL, 0) : 0;
         dss->hvm = 1;
         break;
     }
     case LIBXL_DOMAIN_TYPE_PV:
-        vm_generationid_addr = 0;
         dss->hvm = 0;
         break;
     default:
@@ -1584,7 +1563,7 @@ void libxl__domain_suspend(libxl__egc *egc, libxl__domain_suspend_state *dss)
     callbacks->switch_qemu_logdirty = libxl__domain_suspend_common_switch_qemu_logdirty;
     dss->shs.callbacks.save.toolstack_save = libxl__toolstack_save;
 
-    libxl__xc_domain_save(egc, dss, vm_generationid_addr);
+    libxl__xc_domain_save(egc, dss);
     return;
 
  out:
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index a9343e8..d4f32a9 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -960,8 +960,6 @@ typedef struct {
     uint32_t console_domid;
     unsigned long console_mfn;
 
-    unsigned long vm_generationid_addr;
-
     char *saved_state;
 
     libxl__file_reference pv_kernel;
@@ -2791,8 +2789,7 @@ _hidden void libxl__domain_suspend(libxl__egc *egc,
 
 
 /* calls libxl__xc_domain_suspend_done when done */
-_hidden void libxl__xc_domain_save(libxl__egc*, libxl__domain_suspend_state*,
-                                   unsigned long vm_generationid_addr);
+_hidden void libxl__xc_domain_save(libxl__egc*, libxl__domain_suspend_state*);
 /* If rc==0 then retval is the return value from xc_domain_save
  * and errnoval is the errno value it provided.
  * If rc!=0, retval and errnoval are undefined. */
@@ -2816,8 +2813,7 @@ _hidden int libxl__toolstack_save(uint32_t domid, uint8_t **buf,
 /* calls libxl__xc_domain_restore_done when done */
 _hidden void libxl__xc_domain_restore(libxl__egc *egc,
                                       libxl__domain_create_state *dcs,
-                                      int hvm, int pae, int superpages,
-                                      int no_incr_generationid);
+                                      int hvm, int pae, int superpages);
 /* If rc==0 then retval is the return value from xc_domain_save
  * and errnoval is the errno value it provided.
  * If rc!=0, retval and errnoval are undefined. */
diff --git a/tools/libxl/libxl_save_callout.c b/tools/libxl/libxl_save_callout.c
index c35da4d..1c9f806 100644
--- a/tools/libxl/libxl_save_callout.c
+++ b/tools/libxl/libxl_save_callout.c
@@ -41,8 +41,7 @@ static void helper_done(libxl__egc *egc, libxl__save_helper_state *shs);
 /*----- entrypoints -----*/
 
 void libxl__xc_domain_restore(libxl__egc *egc, libxl__domain_create_state *dcs,
-                              int hvm, int pae, int superpages,
-                              int no_incr_generationid)
+                              int hvm, int pae, int superpages)
 {
     STATE_AO_GC(dcs->ao);
 
@@ -59,7 +58,7 @@ void libxl__xc_domain_restore(libxl__egc *egc, libxl__domain_create_state *dcs,
         state->store_port,
         state->store_domid, state->console_port,
         state->console_domid,
-        hvm, pae, superpages, no_incr_generationid,
+        hvm, pae, superpages,
         cbflags, dcs->checkpointed_stream,
     };
 
@@ -75,8 +74,7 @@ void libxl__xc_domain_restore(libxl__egc *egc, libxl__domain_create_state *dcs,
                argnums, ARRAY_SIZE(argnums));
 }
 
-void libxl__xc_domain_save(libxl__egc *egc, libxl__domain_suspend_state *dss,
-                           unsigned long vm_generationid_addr)
+void libxl__xc_domain_save(libxl__egc *egc, libxl__domain_suspend_state *dss)
 {
     STATE_AO_GC(dss->ao);
     int r, rc, toolstack_data_fd = -1;
@@ -112,7 +110,7 @@ void libxl__xc_domain_save(libxl__egc *egc, libxl__domain_suspend_state *dss,
     }
 
     const unsigned long argnums[] = {
-        dss->domid, 0, 0, dss->xcflags, dss->hvm, vm_generationid_addr,
+        dss->domid, 0, 0, dss->xcflags, dss->hvm,
         toolstack_data_fd, toolstack_data_len,
         cbflags,
     };
diff --git a/tools/libxl/libxl_save_helper.c b/tools/libxl/libxl_save_helper.c
index b259bd0..c760dd3 100644
--- a/tools/libxl/libxl_save_helper.c
+++ b/tools/libxl/libxl_save_helper.c
@@ -211,7 +211,6 @@ int main(int argc, char **argv)
         uint32_t max_factor =      strtoul(NEXTARG,0,10);
         uint32_t flags =           strtoul(NEXTARG,0,10);
         int hvm =                  atoi(NEXTARG);
-        unsigned long genidad =    strtoul(NEXTARG,0,10);
         toolstack_save_fd  =       atoi(NEXTARG);
         toolstack_save_len =       strtoul(NEXTARG,0,10);
         unsigned cbflags =         strtoul(NEXTARG,0,10);
@@ -224,7 +223,7 @@ int main(int argc, char **argv)
 
         startup("save");
         r = xc_domain_save(xch, io_fd, dom, max_iters, max_factor, flags,
-                           &helper_save_callbacks, hvm, genidad);
+                           &helper_save_callbacks, hvm);
         complete(r);
 
     } else if (!strcmp(mode,"--restore-domain")) {
@@ -238,7 +237,6 @@ int main(int argc, char **argv)
         unsigned int hvm =         strtoul(NEXTARG,0,10);
         unsigned int pae =         strtoul(NEXTARG,0,10);
         int superpages =           strtoul(NEXTARG,0,10);
-        int no_incr_genidad =      strtoul(NEXTARG,0,10);
         unsigned cbflags =         strtoul(NEXTARG,0,10);
         int checkpointed =         strtoul(NEXTARG,0,10);
         assert(!*++argv);
@@ -247,15 +245,14 @@ int main(int argc, char **argv)
 
         unsigned long store_mfn = 0;
         unsigned long console_mfn = 0;
-        unsigned long genidad = 0;
 
         startup("restore");
         r = xc_domain_restore(xch, io_fd, dom, store_evtchn, &store_mfn,
                               store_domid, console_evtchn, &console_mfn,
                               console_domid, hvm, pae, superpages,
-                              no_incr_genidad, checkpointed, &genidad,
+                              checkpointed,
                               &helper_restore_callbacks);
-        helper_stub_restore_results(store_mfn,console_mfn,genidad,0);
+        helper_stub_restore_results(store_mfn,console_mfn,0);
         complete(r);
 
     } else {
diff --git a/tools/libxl/libxl_save_msgs_gen.pl b/tools/libxl/libxl_save_msgs_gen.pl
index 745e2ac..88f4921 100755
--- a/tools/libxl/libxl_save_msgs_gen.pl
+++ b/tools/libxl/libxl_save_msgs_gen.pl
@@ -32,8 +32,7 @@ our @msgs = (
     [  7, 'rcxW',   "toolstack_restore",     [qw(uint32_t domid
                                                 BLOCK tsdata)] ],
     [  8, 'r',      "restore_results",       ['unsigned long', 'store_mfn',
-                                              'unsigned long', 'console_mfn',
-                                              'unsigned long', 'genidad'] ],
+                                              'unsigned long', 'console_mfn'] ],
     [  9, 'srW',    "complete",              [qw(int retval
                                                  int errnoval)] ],
 );
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 6/8] libxl: allow a generation ID to be specified at domain creation
  2014-06-12 15:04 [PATCHv5 0/8] tools: rework VM Generation ID David Vrabel
                   ` (4 preceding siblings ...)
  2014-06-12 15:04 ` [PATCH 5/8] libxc, libxl, hvmloader: strip out outdated VM generation ID implementation David Vrabel
@ 2014-06-12 15:04 ` David Vrabel
  2014-06-18  5:18   ` Hongyang Yang
  2014-06-18 11:33   ` Ian Campbell
  2014-06-12 15:04 ` [PATCH 7/8] xl: generate a new random VM generation ID if requested David Vrabel
  2014-06-12 15:04 ` [PATCH 8/8] docs: update docs for the ~/platform/generation-id key David Vrabel
  7 siblings, 2 replies; 23+ messages in thread
From: David Vrabel @ 2014-06-12 15:04 UTC (permalink / raw)
  To: xen-devel; +Cc: David Vrabel, Ian Jackson, Ian Campbell, Stefano Stabellini

Toolstacks may specify a VM generation ID using the u.hvm.ms_vm_genid
field in the libxl_domain_build_info structure, when creating a
domain.

The toolstack is responsible for providing the correct generation ID
according to the Microsoft specification (e.g., generating new random
ones with libxl_ms_vm_genid_generate() as appropriate when restoring).

Although the specification requires that a ACPI Notify event is raised
if the generation ID is changed, the generation ID is never changed
when the domain is in a state to receive such an event (it's either
newly created or suspended).

Signed-off-by: David Vrabel <david.vrabel@citrix.com>
---
 tools/libxl/Makefile         |    1 +
 tools/libxl/libxl.h          |    7 +++
 tools/libxl/libxl_dom.c      |   10 ++++
 tools/libxl/libxl_genid.c    |  104 ++++++++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_internal.h |    4 ++
 tools/libxl/libxl_types.idl  |    2 +
 6 files changed, 128 insertions(+)
 create mode 100644 tools/libxl/libxl_genid.c

diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index 4cfa275..6499aa7 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -77,6 +77,7 @@ LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \
 			libxl_json.o libxl_aoutils.o libxl_numa.o \
 			libxl_save_callout.o _libxl_save_msgs_callout.o \
 			libxl_qmp.o libxl_event.o libxl_fork.o $(LIBXL_OBJS-y)
+LIBXL_OBJS += libxl_genid.o
 LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
 
 LIBXL_TESTS += timedereg
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 17b8a7b..ab2f66a 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -104,6 +104,11 @@
 #define LIBXL_HAVE_BUILDINFO_EVENT_CHANNELS 1
 
 /*
+ * libxl_domain_build_info has the u.hvm.ms_vm_genid field.
+ */
+#define LIBXL_HAVE_BUILDINFO_HVM_MS_VM_GENID 1
+
+/*
  * LIBXL_HAVE_DEVICE_DISK_DIRECT_IO_SAFE indicates that a
  * 'direct_io_safe' field (of boolean type) is present in
  * libxl_device_disk.
@@ -1189,6 +1194,8 @@ int libxl_flask_getenforce(libxl_ctx *ctx);
 int libxl_flask_setenforce(libxl_ctx *ctx, int mode);
 int libxl_flask_loadpolicy(libxl_ctx *ctx, void *policy, uint32_t size);
 
+int libxl_ms_vm_genid_generate(libxl_ctx *ctx, libxl_uuid *uuid);
+
 /* misc */
 
 /* Each of these sets or clears the flag according to whether the
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 8485488..21ce07f 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -314,6 +314,16 @@ int libxl__build_post(libxl__gc *gc, uint32_t domid,
     if (info->cpuid != NULL)
         libxl_cpuid_set(ctx, domid, info->cpuid);
 
+    if (info->type == LIBXL_DOMAIN_TYPE_HVM 
+        && !libxl_uuid_is_nil(&info->u.hvm.ms_vm_genid)) {
+        rc = libxl__ms_vm_genid_set(gc, domid,
+                                    &info->u.hvm.ms_vm_genid);
+        if (rc) {
+            LOG(ERROR, "Failed to set VM Generation ID");
+            return rc;
+        }
+    }
+
     ents = libxl__calloc(gc, 12 + (info->max_vcpus * 2) + 2, sizeof(char *));
     ents[0] = "memory/static-max";
     ents[1] = GCSPRINTF("%"PRId64, info->max_memkb);
diff --git a/tools/libxl/libxl_genid.c b/tools/libxl/libxl_genid.c
new file mode 100644
index 0000000..565ed00
--- /dev/null
+++ b/tools/libxl/libxl_genid.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2014 Citrix Systems R&D Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#include "libxl_osdeps.h" /* must come before any other headers */
+
+#include "libxl_internal.h"
+
+#include <xenctrl.h>
+#include <xen/hvm/params.h>
+
+/*
+ * Generate a random VM generation ID.
+ *
+ * This is similar to libxl_uuid_generate() except that all bits are
+ * random, as required by the specification.
+ * 
+ * Returns ERROR_FAIL if a suitable source of random numbers is not
+ * available.
+ *
+ * See Microsoft's "Virtual Machine Generation ID" specification for
+ * further details, including when a new generation ID is required.
+ *
+ *   http://www.microsoft.com/en-us/download/details.aspx?id=30707
+ */
+int libxl_ms_vm_genid_generate(libxl_ctx *ctx, libxl_uuid *uuid)
+{
+    GC_INIT(ctx);
+    int ret;
+
+    ret = libxl__random_bytes(gc, libxl_uuid_bytearray(uuid), 16);
+
+    GC_FREE;
+    return ret;
+}
+
+int libxl__ms_vm_genid_set(libxl__gc *gc, uint32_t domid,
+                           const libxl_uuid *uuid)
+{
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+    const char *dom_path;
+    uint64_t genid[2];
+    uint64_t paddr = 0;
+    int rc;
+
+    memcpy(genid, libxl_uuid_bytearray_const(uuid), 16);
+
+    /*
+     * Set the "platform/generation-id" XenStore key to pass the ID to
+     * hvmloader.
+     */
+    dom_path = libxl__xs_get_dompath(gc, domid);
+    if (!dom_path) {
+        rc = ERROR_FAIL;
+        goto out;
+    }
+    rc = libxl__xs_write(gc, XBT_NULL,
+                         GCSPRINTF("%s/platform/generation-id", dom_path),
+                         "%"PRIu64 ":%" PRIu64, genid[0], genid[1]);
+    if (rc < 0)
+        goto out;
+
+    /*
+     * Update the ID in guest memory (if available).
+     */
+    xc_get_hvm_param(ctx->xch, domid, HVM_PARAM_VM_GENERATION_ID_ADDR, &paddr);
+    if (paddr) {
+        void *vaddr;
+
+        vaddr = xc_map_foreign_range(ctx->xch, domid, XC_PAGE_SIZE,
+                                     PROT_READ | PROT_WRITE,
+                                     paddr >> XC_PAGE_SHIFT);
+        if (vaddr == NULL) {
+            rc = ERROR_FAIL;
+            goto out;
+        }
+        memcpy(vaddr + (paddr & ~XC_PAGE_MASK), genid, 2 * sizeof(*genid));
+        munmap(vaddr, XC_PAGE_SIZE);
+
+        /*
+         * The spec requires an ACPI Notify event is injected into the
+         * guest when the generation ID is changed.
+         *
+         * This is only called for domains that are suspended or newly
+         * created and they won't be in a state to receive such an
+         * event.
+         */
+    }
+
+    rc = 0;
+
+  out:
+    return rc;
+}
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index d4f32a9..fa9a150 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3086,6 +3086,10 @@ void libxl__numa_candidate_put_nodemap(libxl__gc *gc,
     libxl_bitmap_copy(CTX, &cndt->nodemap, nodemap);
 }
 
+_hidden int libxl__ms_vm_genid_set(libxl__gc *gc, uint32_t domid,
+                                   const libxl_uuid *uuid);
+
+
 /* Som handy macros for defbool type. */
 #define LIBXL__DEFBOOL_DEFAULT     (0)
 #define LIBXL__DEFBOOL_FALSE       (-1)
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index f0f6e34..1c5e687 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -371,6 +371,8 @@ libxl_domain_build_info = Struct("domain_build_info",[
                                        ("xen_platform_pci", libxl_defbool),
                                        ("usbdevice_list",   libxl_string_list),
                                        ("vendor_device",    libxl_vendor_device),
+                                       # See libxl_ms_vm_genid_generate()
+                                       ("ms_vm_genid",      libxl_uuid),
                                        ])),
                  ("pv", Struct(None, [("kernel", string),
                                       ("slack_memkb", MemKB),
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 7/8] xl: generate a new random VM generation ID if requested
  2014-06-12 15:04 [PATCHv5 0/8] tools: rework VM Generation ID David Vrabel
                   ` (5 preceding siblings ...)
  2014-06-12 15:04 ` [PATCH 6/8] libxl: allow a generation ID to be specified at domain creation David Vrabel
@ 2014-06-12 15:04 ` David Vrabel
  2014-06-18 11:37   ` Ian Campbell
  2014-06-12 15:04 ` [PATCH 8/8] docs: update docs for the ~/platform/generation-id key David Vrabel
  7 siblings, 1 reply; 23+ messages in thread
From: David Vrabel @ 2014-06-12 15:04 UTC (permalink / raw)
  To: xen-devel; +Cc: David Vrabel, Ian Jackson, Ian Campbell, Stefano Stabellini

If the "generation_id" option is set in the domain configuration,
generate and set a new random VM generation ID every time a domain is
created or restored.

xl lacks the infrastructure to fully track the lifecycle of VM images
as they are snapshotted and cloned (etc) so always using a new ID is
the safe option and ensures that a new one will be used where it matters.

Signed-off-by: David Vrabel <david.vrabel@citrix.com>
---
 docs/man/xl.cfg.pod.5    |   14 ++++++++++++++
 tools/libxl/xl_cmdimpl.c |    9 +++++++++
 2 files changed, 23 insertions(+)

diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
index c087cbc..6176e2f 100644
--- a/docs/man/xl.cfg.pod.5
+++ b/docs/man/xl.cfg.pod.5
@@ -936,6 +936,20 @@ number of vendor defined SMBIOS structures (type 128 - 255). Since SMBIOS
 structures do not present their overall size, each entry in the file must be
 preceded by a 32b integer indicating the size of the next structure.
 
+=item B<generation_id=BOOLEAN>
+
+Provide a VM generation ID to the guest.
+
+The VM generation ID as a 128-bit random number that a guest may use
+to determine if the guest has been restored from an earlier snapshot,
+or cloned.
+
+This is required for Microsoft Windows Server 2012 (and later) domain
+controllers.
+
+See also "Virtual Machine Generation ID" by Microsoft
+(http://www.microsoft.com/en-us/download/details.aspx?id=30707).
+
 =back 
 
 =head3 Guest Virtual Time Controls
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 64a1c77..ad50e21 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1021,6 +1021,15 @@ static void parse_config_data(const char *config_source,
                                &b_info->u.hvm.smbios_firmware, 0);
         xlu_cfg_replace_string(config, "acpi_firmware",
                                &b_info->u.hvm.acpi_firmware, 0);
+
+        /* Generate and set a new random VM Generation ID? */
+        if (!xlu_cfg_get_long(config, "generation_id", &l, 0)) {
+            e = libxl_ms_vm_genid_generate(ctx, &b_info->u.hvm.ms_vm_genid);
+            if (e) {
+                fprintf(stderr, "ERROR: no random numbers available for \"generation_id\"\n");
+                exit(1);
+            }
+        }
         break;
     case LIBXL_DOMAIN_TYPE_PV:
     {
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 8/8] docs: update docs for the ~/platform/generation-id key
  2014-06-12 15:04 [PATCHv5 0/8] tools: rework VM Generation ID David Vrabel
                   ` (6 preceding siblings ...)
  2014-06-12 15:04 ` [PATCH 7/8] xl: generate a new random VM generation ID if requested David Vrabel
@ 2014-06-12 15:04 ` David Vrabel
  7 siblings, 0 replies; 23+ messages in thread
From: David Vrabel @ 2014-06-12 15:04 UTC (permalink / raw)
  To: xen-devel; +Cc: David Vrabel, Ian Jackson, Ian Campbell, Stefano Stabellini

Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 docs/misc/xenstore-paths.markdown |   24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/docs/misc/xenstore-paths.markdown b/docs/misc/xenstore-paths.markdown
index 70ab7f4..ea67536 100644
--- a/docs/misc/xenstore-paths.markdown
+++ b/docs/misc/xenstore-paths.markdown
@@ -166,11 +166,6 @@ use the xenstore-based protocol instead (see ~/control/shutdown,
 below) even if the guest has advertised support for the event channel
 protocol.
 
-#### ~/hvmloader/generation-id-address = ADDRESS [r,HVM,INTERNAL]
-
-The hexadecimal representation of the address of the domain's
-"generation id".
-
 #### ~/hvmloader/allow-memory-relocate = ("1"|"0") [HVM,INTERNAL]
 
 If the default low MMIO hole (below 4GiB) is not big enough for all
@@ -193,9 +188,22 @@ Various platform properties.
 
 #### ~/platform/generation-id = INTEGER ":" INTEGER [HVM,INTERNAL]
 
-Two 64 bit values that represent the Windows Generation ID.
-Is used by the BIOS initializer to get this value.
-If not present or "0:0" (all zeroes) device will not be present to the machine.
+The lower and upper 64-bit words of the 128-bit VM Generation ID.
+
+This key is used by hvmloader to create the ACPI VM Generation ID
+device.  It initialises a 16 octet region of guest memory with this
+value.  The guest physical address of this region is saved in the
+HVM_PARAM_VM_GENERATION_ID_ADDR HVM parameter.
+
+If this key is not present, is empty, or is all-zeros ("0:0") then the
+ACPI device is not created.
+
+When restoring a guest, the toolstack may (in certain circumstances)
+need generate a new random generation ID and write it to guest memory
+at the guest physical address in HVM_PARAM_VM_GENERATION_ID_ADDR.
+
+See Microsoft's "Virtual Machine Generation ID" specification for the
+circumstances where the generation ID needs to be changed.
 
 ### Frontend device paths
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH 6/8] libxl: allow a generation ID to be specified at domain creation
  2014-06-12 15:04 ` [PATCH 6/8] libxl: allow a generation ID to be specified at domain creation David Vrabel
@ 2014-06-18  5:18   ` Hongyang Yang
  2014-06-18  9:38     ` David Vrabel
  2014-06-18 11:33   ` Ian Campbell
  1 sibling, 1 reply; 23+ messages in thread
From: Hongyang Yang @ 2014-06-18  5:18 UTC (permalink / raw)
  To: David Vrabel, xen-devel; +Cc: Ian Jackson, Ian Campbell, Stefano Stabellini

Hi David,

there are 2 lines that have whitespace.

Applying: libxl: allow a generation ID to be specified at domain creation
/media/sda5/work/remus/.git/rebase-apply/patch:56: trailing whitespace.
     if (info->type == LIBXL_DOMAIN_TYPE_HVM
/media/sda5/work/remus/.git/rebase-apply/patch:101: trailing whitespace.
  *
warning: 2 lines add whitespace errors.

On 06/12/2014 11:04 PM, David Vrabel wrote:
> Toolstacks may specify a VM generation ID using the u.hvm.ms_vm_genid
> field in the libxl_domain_build_info structure, when creating a
> domain.
>
> The toolstack is responsible for providing the correct generation ID
> according to the Microsoft specification (e.g., generating new random
> ones with libxl_ms_vm_genid_generate() as appropriate when restoring).
>
> Although the specification requires that a ACPI Notify event is raised
> if the generation ID is changed, the generation ID is never changed
> when the domain is in a state to receive such an event (it's either
> newly created or suspended).
>
> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
> ---
>   tools/libxl/Makefile         |    1 +
>   tools/libxl/libxl.h          |    7 +++
>   tools/libxl/libxl_dom.c      |   10 ++++
>   tools/libxl/libxl_genid.c    |  104 ++++++++++++++++++++++++++++++++++++++++++
>   tools/libxl/libxl_internal.h |    4 ++
>   tools/libxl/libxl_types.idl  |    2 +
>   6 files changed, 128 insertions(+)
>   create mode 100644 tools/libxl/libxl_genid.c
>
> diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
> index 4cfa275..6499aa7 100644
> --- a/tools/libxl/Makefile
> +++ b/tools/libxl/Makefile
> @@ -77,6 +77,7 @@ LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \
>   			libxl_json.o libxl_aoutils.o libxl_numa.o \
>   			libxl_save_callout.o _libxl_save_msgs_callout.o \
>   			libxl_qmp.o libxl_event.o libxl_fork.o $(LIBXL_OBJS-y)
> +LIBXL_OBJS += libxl_genid.o
>   LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
>
>   LIBXL_TESTS += timedereg
> diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
> index 17b8a7b..ab2f66a 100644
> --- a/tools/libxl/libxl.h
> +++ b/tools/libxl/libxl.h
> @@ -104,6 +104,11 @@
>   #define LIBXL_HAVE_BUILDINFO_EVENT_CHANNELS 1
>
>   /*
> + * libxl_domain_build_info has the u.hvm.ms_vm_genid field.
> + */
> +#define LIBXL_HAVE_BUILDINFO_HVM_MS_VM_GENID 1
> +
> +/*
>    * LIBXL_HAVE_DEVICE_DISK_DIRECT_IO_SAFE indicates that a
>    * 'direct_io_safe' field (of boolean type) is present in
>    * libxl_device_disk.
> @@ -1189,6 +1194,8 @@ int libxl_flask_getenforce(libxl_ctx *ctx);
>   int libxl_flask_setenforce(libxl_ctx *ctx, int mode);
>   int libxl_flask_loadpolicy(libxl_ctx *ctx, void *policy, uint32_t size);
>
> +int libxl_ms_vm_genid_generate(libxl_ctx *ctx, libxl_uuid *uuid);
> +
>   /* misc */
>
>   /* Each of these sets or clears the flag according to whether the
> diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
> index 8485488..21ce07f 100644
> --- a/tools/libxl/libxl_dom.c
> +++ b/tools/libxl/libxl_dom.c
> @@ -314,6 +314,16 @@ int libxl__build_post(libxl__gc *gc, uint32_t domid,
>       if (info->cpuid != NULL)
>           libxl_cpuid_set(ctx, domid, info->cpuid);
>
> +    if (info->type == LIBXL_DOMAIN_TYPE_HVM
> +        && !libxl_uuid_is_nil(&info->u.hvm.ms_vm_genid)) {
> +        rc = libxl__ms_vm_genid_set(gc, domid,
> +                                    &info->u.hvm.ms_vm_genid);
> +        if (rc) {
> +            LOG(ERROR, "Failed to set VM Generation ID");
> +            return rc;
> +        }
> +    }
> +
>       ents = libxl__calloc(gc, 12 + (info->max_vcpus * 2) + 2, sizeof(char *));
>       ents[0] = "memory/static-max";
>       ents[1] = GCSPRINTF("%"PRId64, info->max_memkb);
> diff --git a/tools/libxl/libxl_genid.c b/tools/libxl/libxl_genid.c
> new file mode 100644
> index 0000000..565ed00
> --- /dev/null
> +++ b/tools/libxl/libxl_genid.c
> @@ -0,0 +1,104 @@
> +/*
> + * Copyright (C) 2014 Citrix Systems R&D Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU Lesser General Public License as published
> + * by the Free Software Foundation; version 2.1 only. with the special
> + * exception on linking described in file LICENSE.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU Lesser General Public License for more details.
> + */
> +
> +#include "libxl_osdeps.h" /* must come before any other headers */
> +
> +#include "libxl_internal.h"
> +
> +#include <xenctrl.h>
> +#include <xen/hvm/params.h>
> +
> +/*
> + * Generate a random VM generation ID.
> + *
> + * This is similar to libxl_uuid_generate() except that all bits are
> + * random, as required by the specification.
> + *
> + * Returns ERROR_FAIL if a suitable source of random numbers is not
> + * available.
> + *
> + * See Microsoft's "Virtual Machine Generation ID" specification for
> + * further details, including when a new generation ID is required.
> + *
> + *   http://www.microsoft.com/en-us/download/details.aspx?id=30707
> + */
> +int libxl_ms_vm_genid_generate(libxl_ctx *ctx, libxl_uuid *uuid)
> +{
> +    GC_INIT(ctx);
> +    int ret;
> +
> +    ret = libxl__random_bytes(gc, libxl_uuid_bytearray(uuid), 16);
> +
> +    GC_FREE;
> +    return ret;
> +}
> +
> +int libxl__ms_vm_genid_set(libxl__gc *gc, uint32_t domid,
> +                           const libxl_uuid *uuid)
> +{
> +    libxl_ctx *ctx = libxl__gc_owner(gc);
> +    const char *dom_path;
> +    uint64_t genid[2];
> +    uint64_t paddr = 0;
> +    int rc;
> +
> +    memcpy(genid, libxl_uuid_bytearray_const(uuid), 16);
> +
> +    /*
> +     * Set the "platform/generation-id" XenStore key to pass the ID to
> +     * hvmloader.
> +     */
> +    dom_path = libxl__xs_get_dompath(gc, domid);
> +    if (!dom_path) {
> +        rc = ERROR_FAIL;
> +        goto out;
> +    }
> +    rc = libxl__xs_write(gc, XBT_NULL,
> +                         GCSPRINTF("%s/platform/generation-id", dom_path),
> +                         "%"PRIu64 ":%" PRIu64, genid[0], genid[1]);
> +    if (rc < 0)
> +        goto out;
> +
> +    /*
> +     * Update the ID in guest memory (if available).
> +     */
> +    xc_get_hvm_param(ctx->xch, domid, HVM_PARAM_VM_GENERATION_ID_ADDR, &paddr);
> +    if (paddr) {
> +        void *vaddr;
> +
> +        vaddr = xc_map_foreign_range(ctx->xch, domid, XC_PAGE_SIZE,
> +                                     PROT_READ | PROT_WRITE,
> +                                     paddr >> XC_PAGE_SHIFT);
> +        if (vaddr == NULL) {
> +            rc = ERROR_FAIL;
> +            goto out;
> +        }
> +        memcpy(vaddr + (paddr & ~XC_PAGE_MASK), genid, 2 * sizeof(*genid));
> +        munmap(vaddr, XC_PAGE_SIZE);
> +
> +        /*
> +         * The spec requires an ACPI Notify event is injected into the
> +         * guest when the generation ID is changed.
> +         *
> +         * This is only called for domains that are suspended or newly
> +         * created and they won't be in a state to receive such an
> +         * event.
> +         */
> +    }
> +
> +    rc = 0;
> +
> +  out:
> +    return rc;
> +}
> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
> index d4f32a9..fa9a150 100644
> --- a/tools/libxl/libxl_internal.h
> +++ b/tools/libxl/libxl_internal.h
> @@ -3086,6 +3086,10 @@ void libxl__numa_candidate_put_nodemap(libxl__gc *gc,
>       libxl_bitmap_copy(CTX, &cndt->nodemap, nodemap);
>   }
>
> +_hidden int libxl__ms_vm_genid_set(libxl__gc *gc, uint32_t domid,
> +                                   const libxl_uuid *uuid);
> +
> +
>   /* Som handy macros for defbool type. */
>   #define LIBXL__DEFBOOL_DEFAULT     (0)
>   #define LIBXL__DEFBOOL_FALSE       (-1)
> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> index f0f6e34..1c5e687 100644
> --- a/tools/libxl/libxl_types.idl
> +++ b/tools/libxl/libxl_types.idl
> @@ -371,6 +371,8 @@ libxl_domain_build_info = Struct("domain_build_info",[
>                                          ("xen_platform_pci", libxl_defbool),
>                                          ("usbdevice_list",   libxl_string_list),
>                                          ("vendor_device",    libxl_vendor_device),
> +                                       # See libxl_ms_vm_genid_generate()
> +                                       ("ms_vm_genid",      libxl_uuid),
>                                          ])),
>                    ("pv", Struct(None, [("kernel", string),
>                                         ("slack_memkb", MemKB),
>

-- 
Thanks,
Yang.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 6/8] libxl: allow a generation ID to be specified at domain creation
  2014-06-18  5:18   ` Hongyang Yang
@ 2014-06-18  9:38     ` David Vrabel
  2014-06-18  9:39       ` Ian Campbell
  0 siblings, 1 reply; 23+ messages in thread
From: David Vrabel @ 2014-06-18  9:38 UTC (permalink / raw)
  To: Hongyang Yang, David Vrabel, xen-devel
  Cc: Ian Jackson, Ian Campbell, Stefano Stabellini

On 18/06/14 06:18, Hongyang Yang wrote:
> Hi David,
> 
> there are 2 lines that have whitespace.
> 
> Applying: libxl: allow a generation ID to be specified at domain creation
> /media/sda5/work/remus/.git/rebase-apply/patch:56: trailing whitespace.
>     if (info->type == LIBXL_DOMAIN_TYPE_HVM
> /media/sda5/work/remus/.git/rebase-apply/patch:101: trailing whitespace.
>  *
> warning: 2 lines add whitespace errors.

Ian, are you happy to apply with --whitespace=fix?  Or do want a respin?

David

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 6/8] libxl: allow a generation ID to be specified at domain creation
  2014-06-18  9:38     ` David Vrabel
@ 2014-06-18  9:39       ` Ian Campbell
  0 siblings, 0 replies; 23+ messages in thread
From: Ian Campbell @ 2014-06-18  9:39 UTC (permalink / raw)
  To: David Vrabel; +Cc: xen-devel, Hongyang Yang, Ian Jackson, Stefano Stabellini

On Wed, 2014-06-18 at 10:38 +0100, David Vrabel wrote:
> On 18/06/14 06:18, Hongyang Yang wrote:
> > Hi David,
> > 
> > there are 2 lines that have whitespace.
> > 
> > Applying: libxl: allow a generation ID to be specified at domain creation
> > /media/sda5/work/remus/.git/rebase-apply/patch:56: trailing whitespace.
> >     if (info->type == LIBXL_DOMAIN_TYPE_HVM
> > /media/sda5/work/remus/.git/rebase-apply/patch:101: trailing whitespace.
> >  *
> > warning: 2 lines add whitespace errors.
> 
> Ian, are you happy to apply with --whitespace=fix?  Or do want a respin?

I'll fix it as I go.

(never heard of that option, how useful!)

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/8] libxc: allow xc_get/set_hvm_param() to get/set 64-bit values
  2014-06-12 15:04 ` [PATCH 1/8] libxc: allow xc_get/set_hvm_param() to get/set 64-bit values David Vrabel
@ 2014-06-18 11:26   ` Ian Campbell
  2014-06-18 13:05   ` Ian Campbell
  1 sibling, 0 replies; 23+ messages in thread
From: Ian Campbell @ 2014-06-18 11:26 UTC (permalink / raw)
  To: David Vrabel; +Cc: xen-devel, Ian Jackson, Stefano Stabellini

On Thu, 2014-06-12 at 16:04 +0100, David Vrabel wrote:
> HVMOP_get_param and HVMOP_set_param take a uint32_t for the parameter
> index and a uint64_t for the value.  So, make the corresponding libxc
> function take the same types.
> 
> Signed-off-by: David Vrabel <david.vrabel@citrix.com>

Acked-by: Ian Campbell <ian.campbell@citrix.com>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 2/8] libxl: add libxl__random_bytes() which fills a buffer with random bytes
  2014-06-12 15:04 ` [PATCH 2/8] libxl: add libxl__random_bytes() which fills a buffer with random bytes David Vrabel
@ 2014-06-18 11:28   ` Ian Campbell
  2014-06-18 11:43     ` Roger Pau Monné
  0 siblings, 1 reply; 23+ messages in thread
From: Ian Campbell @ 2014-06-18 11:28 UTC (permalink / raw)
  To: David Vrabel; +Cc: xen-devel, Roger Pau Monne, Ian Jackson, Stefano Stabellini

On Thu, 2014-06-12 at 16:04 +0100, David Vrabel wrote:
> The random bytes are obtained from /dev/urandom and are suitable for
> almost all uses (except for generating long-lived secure keys).
> 
> Documentation suggests that /dev/urandom is widely available on Unix-like
> systems (such FreeBSD and NetBSD).

This seems likely to me. Roger, can you confirm?

> A public libxl_random_bytes() (or similar) could be trivially added,
> if this required in the future.
> 
> Signed-off-by: David Vrabel <david.vrabel@citrix.com>

Acked-by: Ian Campbell <ian.campbell@citrix.com>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 6/8] libxl: allow a generation ID to be specified at domain creation
  2014-06-12 15:04 ` [PATCH 6/8] libxl: allow a generation ID to be specified at domain creation David Vrabel
  2014-06-18  5:18   ` Hongyang Yang
@ 2014-06-18 11:33   ` Ian Campbell
  2014-06-18 12:09     ` David Vrabel
  1 sibling, 1 reply; 23+ messages in thread
From: Ian Campbell @ 2014-06-18 11:33 UTC (permalink / raw)
  To: David Vrabel; +Cc: xen-devel, Ian Jackson, Stefano Stabellini

On Thu, 2014-06-12 at 16:04 +0100, David Vrabel wrote:
> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> index f0f6e34..1c5e687 100644
> --- a/tools/libxl/libxl_types.idl
> +++ b/tools/libxl/libxl_types.idl
> @@ -371,6 +371,8 @@ libxl_domain_build_info = Struct("domain_build_info",[
>                                         ("xen_platform_pci", libxl_defbool),
>                                         ("usbdevice_list",   libxl_string_list),
>                                         ("vendor_device",    libxl_vendor_device),
> +                                       # See libxl_ms_vm_genid_generate()
> +                                       ("ms_vm_genid",      libxl_uuid),

When we discussed this IRL I thought we had decided that this should be
a new libxl_ms_vm_genid type, effectively a typedef of uint8_t[16],
similar to libxl_mac and libxl_hwcap[[0]]. This would avoid any
suggestion that one of the more structured forms of UUID would be
appropriate here.

I appreciate that you tried to address that with the comment, but I fear
it might not be terribly effective in practice...

Other than that the implementation here all looks ok to me.

Ian.

[[0]] I suppose we are getting to close to wanting idl.py to contains
Bytes(n) as a generic type. I won't ask you to do that though.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 7/8] xl: generate a new random VM generation ID if requested
  2014-06-12 15:04 ` [PATCH 7/8] xl: generate a new random VM generation ID if requested David Vrabel
@ 2014-06-18 11:37   ` Ian Campbell
  0 siblings, 0 replies; 23+ messages in thread
From: Ian Campbell @ 2014-06-18 11:37 UTC (permalink / raw)
  To: David Vrabel; +Cc: xen-devel, Ian Jackson, Stefano Stabellini

On Thu, 2014-06-12 at 16:04 +0100, David Vrabel wrote:
> diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
> index 64a1c77..ad50e21 100644
> --- a/tools/libxl/xl_cmdimpl.c
> +++ b/tools/libxl/xl_cmdimpl.c
> @@ -1021,6 +1021,15 @@ static void parse_config_data(const char *config_source,
>                                 &b_info->u.hvm.smbios_firmware, 0);
>          xlu_cfg_replace_string(config, "acpi_firmware",
>                                 &b_info->u.hvm.acpi_firmware, 0);
> +
> +        /* Generate and set a new random VM Generation ID? */
> +        if (!xlu_cfg_get_long(config, "generation_id", &l, 0)) {

xlu_cfg_* returns present/notpresent not the value. You need to check
the actual value of l here. Otherwise generation_id=0 in the cfg will
cause it to be unexpectedly generated.

Did you want to rename this key to ms_vm_genid for consistency?

I suppose there is no call for actually specifying a genid? If there
were then I'd suggest 
	ms_vm_genid = "generate"

as the syntax leaving the way open for a future extension of giving a
number here.

> +            e = libxl_ms_vm_genid_generate(ctx, &b_info->u.hvm.ms_vm_genid);
> +            if (e) {
> +                fprintf(stderr, "ERROR: no random numbers available for \"generation_id\"\n");

That's very specific. How about "unable to generate ..."?

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 2/8] libxl: add libxl__random_bytes() which fills a buffer with random bytes
  2014-06-18 11:28   ` Ian Campbell
@ 2014-06-18 11:43     ` Roger Pau Monné
  2014-06-18 13:10       ` Ian Campbell
  0 siblings, 1 reply; 23+ messages in thread
From: Roger Pau Monné @ 2014-06-18 11:43 UTC (permalink / raw)
  To: Ian Campbell, David Vrabel; +Cc: xen-devel, Ian Jackson, Stefano Stabellini

On 18/06/14 13:28, Ian Campbell wrote:
> On Thu, 2014-06-12 at 16:04 +0100, David Vrabel wrote:
>> The random bytes are obtained from /dev/urandom and are suitable for
>> almost all uses (except for generating long-lived secure keys).
>>
>> Documentation suggests that /dev/urandom is widely available on Unix-like
>> systems (such FreeBSD and NetBSD).
> 
> This seems likely to me. Roger, can you confirm?

Yes, I can confirm /dev/urandom exists on FreeBSD, I've already checked
when I saw the patch. It seems to exists on NetBSD also:

http://netbsd.gw.com/cgi-bin/man-cgi?urandom+4+NetBSD-current

But I don't have a system to test with and confirm.

Roger.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 6/8] libxl: allow a generation ID to be specified at domain creation
  2014-06-18 11:33   ` Ian Campbell
@ 2014-06-18 12:09     ` David Vrabel
  2014-06-18 12:25       ` Ian Campbell
  0 siblings, 1 reply; 23+ messages in thread
From: David Vrabel @ 2014-06-18 12:09 UTC (permalink / raw)
  To: Ian Campbell, David Vrabel; +Cc: xen-devel, Ian Jackson, Stefano Stabellini

On 18/06/14 12:33, Ian Campbell wrote:
> On Thu, 2014-06-12 at 16:04 +0100, David Vrabel wrote:
>> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
>> index f0f6e34..1c5e687 100644
>> --- a/tools/libxl/libxl_types.idl
>> +++ b/tools/libxl/libxl_types.idl
>> @@ -371,6 +371,8 @@ libxl_domain_build_info = Struct("domain_build_info",[
>>                                         ("xen_platform_pci", libxl_defbool),
>>                                         ("usbdevice_list",   libxl_string_list),
>>                                         ("vendor_device",    libxl_vendor_device),
>> +                                       # See libxl_ms_vm_genid_generate()
>> +                                       ("ms_vm_genid",      libxl_uuid),
> 
> When we discussed this IRL I thought we had decided that this should be
> a new libxl_ms_vm_genid type, effectively a typedef of uint8_t[16],
> similar to libxl_mac and libxl_hwcap[[0]]. This would avoid any
> suggestion that one of the more structured forms of UUID would be
> appropriate here.

I kept the libxl_uuid type in the end because it allowed me to use
libxl_uuid_is_nil() without having to re-implement an equivalent.

> I appreciate that you tried to address that with the comment, but I fear
> it might not be terribly effective in practice...

A toolstack author cannot use the ms_vm_genid field correctly without
reading the Microsoft document and that's clear on the requirements.

Do you still want a new typedef?

David

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 6/8] libxl: allow a generation ID to be specified at domain creation
  2014-06-18 12:09     ` David Vrabel
@ 2014-06-18 12:25       ` Ian Campbell
  2014-06-18 13:22         ` David Vrabel
  0 siblings, 1 reply; 23+ messages in thread
From: Ian Campbell @ 2014-06-18 12:25 UTC (permalink / raw)
  To: David Vrabel; +Cc: xen-devel, Ian Jackson, Stefano Stabellini

On Wed, 2014-06-18 at 13:09 +0100, David Vrabel wrote:
> On 18/06/14 12:33, Ian Campbell wrote:
> > On Thu, 2014-06-12 at 16:04 +0100, David Vrabel wrote:
> >> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> >> index f0f6e34..1c5e687 100644
> >> --- a/tools/libxl/libxl_types.idl
> >> +++ b/tools/libxl/libxl_types.idl
> >> @@ -371,6 +371,8 @@ libxl_domain_build_info = Struct("domain_build_info",[
> >>                                         ("xen_platform_pci", libxl_defbool),
> >>                                         ("usbdevice_list",   libxl_string_list),
> >>                                         ("vendor_device",    libxl_vendor_device),
> >> +                                       # See libxl_ms_vm_genid_generate()
> >> +                                       ("ms_vm_genid",      libxl_uuid),
> > 
> > When we discussed this IRL I thought we had decided that this should be
> > a new libxl_ms_vm_genid type, effectively a typedef of uint8_t[16],
> > similar to libxl_mac and libxl_hwcap[[0]]. This would avoid any
> > suggestion that one of the more structured forms of UUID would be
> > appropriate here.
> 
> I kept the libxl_uuid type in the end because it allowed me to use
> libxl_uuid_is_nil() without having to re-implement an equivalent.

Doesn't sound too tricky though.

> > I appreciate that you tried to address that with the comment, but I fear
> > it might not be terribly effective in practice...
> 
> A toolstack author cannot use the ms_vm_genid field correctly without
> reading the Microsoft document and that's clear on the requirements.

What's not clear is that libxl_uuid_generate() doesn't (necessarily)
meet the spec. Using a different type would stop people from using that.

> Do you still want a new typedef?

I think it would be best.

Ian.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/8] libxc: allow xc_get/set_hvm_param() to get/set 64-bit values
  2014-06-12 15:04 ` [PATCH 1/8] libxc: allow xc_get/set_hvm_param() to get/set 64-bit values David Vrabel
  2014-06-18 11:26   ` Ian Campbell
@ 2014-06-18 13:05   ` Ian Campbell
  1 sibling, 0 replies; 23+ messages in thread
From: Ian Campbell @ 2014-06-18 13:05 UTC (permalink / raw)
  To: David Vrabel; +Cc: xen-devel, Ian Jackson, Stefano Stabellini

On Thu, 2014-06-12 at 16:04 +0100, David Vrabel wrote:
> HVMOP_get_param and HVMOP_set_param take a uint32_t for the parameter
> index and a uint64_t for the value.  So, make the corresponding libxc
> function take the same types.

Sadly:

<builddir>tools/qemu-xen-dir/xen-all.c: In function 'xen_hvm_init':
<builddir>tools/qemu-xen-dir/xen-all.c:1101:5: error: passing argument 4 of 'xc_get_hvm_param' from incompatible pointer type [-Werror]
In file included from <builddir>tools/qemu-xen-dir/include/hw/xen/xen_common.h:9:0,
                 from <builddir>tools/qemu-xen-dir/xen-all.c:15:
<builddir>tools/../tools/libxc/xenctrl.h:1812:5: note: expected 'uint64_t *' but argument is of type 'long unsigned int *'
<builddir>tools/qemu-xen-dir/xen-all.c:1110:5: error: passing argument 4 of 'xc_get_hvm_param' from incompatible pointer type [-Werror]
In file included from <builddir>tools/qemu-xen-dir/include/hw/xen/xen_common.h:9:0,
                 from <builddir>tools/qemu-xen-dir/xen-all.c:15:
<builddir>tools/../tools/libxc/xenctrl.h:1812:5: note: expected 'uint64_t *' but argument is of type 'long unsigned int *'
<builddir>tools/qemu-xen-dir/xen-all.c:1132:13: error: passing argument 4 of 'xc_get_hvm_param' from incompatible pointer type [-Werror]
In file included from <builddir>tools/qemu-xen-dir/include/hw/xen/xen_common.h:9:0,
                 from <builddir>tools/qemu-xen-dir/xen-all.c:15:
<builddir>tools/../tools/libxc/xenctrl.h:1812:5: note: expected 'uint64_t *' but argument is of type 'long unsigned int *'
cc1: all warnings being treated as errors

So I don't think it is going to be possible to just make this change so
easily. You'd need to to at least upstream a qemu patch which involved a
configure check I think :-(

You might find it easier to introduce a new name for these functions,
although sadly the only really sensible one is already taken...

:-/

Ian.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 2/8] libxl: add libxl__random_bytes() which fills a buffer with random bytes
  2014-06-18 11:43     ` Roger Pau Monné
@ 2014-06-18 13:10       ` Ian Campbell
  0 siblings, 0 replies; 23+ messages in thread
From: Ian Campbell @ 2014-06-18 13:10 UTC (permalink / raw)
  To: Roger Pau Monné
  Cc: xen-devel, Ian Jackson, David Vrabel, Stefano Stabellini

On Wed, 2014-06-18 at 13:43 +0200, Roger Pau Monné wrote:
> On 18/06/14 13:28, Ian Campbell wrote:
> > On Thu, 2014-06-12 at 16:04 +0100, David Vrabel wrote:
> >> The random bytes are obtained from /dev/urandom and are suitable for
> >> almost all uses (except for generating long-lived secure keys).
> >>
> >> Documentation suggests that /dev/urandom is widely available on Unix-like
> >> systems (such FreeBSD and NetBSD).
> > 
> > This seems likely to me. Roger, can you confirm?
> 
> Yes, I can confirm /dev/urandom exists on FreeBSD, I've already checked
> when I saw the patch. It seems to exists on NetBSD also:
> 
> http://netbsd.gw.com/cgi-bin/man-cgi?urandom+4+NetBSD-current
> 
> But I don't have a system to test with and confirm.

Thanks, that's good enough for me. Thanks.

Ian.



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 6/8] libxl: allow a generation ID to be specified at domain creation
  2014-06-18 12:25       ` Ian Campbell
@ 2014-06-18 13:22         ` David Vrabel
  0 siblings, 0 replies; 23+ messages in thread
From: David Vrabel @ 2014-06-18 13:22 UTC (permalink / raw)
  To: Ian Campbell, David Vrabel; +Cc: xen-devel, Ian Jackson, Stefano Stabellini

On 18/06/14 13:25, Ian Campbell wrote:
> On Wed, 2014-06-18 at 13:09 +0100, David Vrabel wrote:
>> On 18/06/14 12:33, Ian Campbell wrote:
>>> On Thu, 2014-06-12 at 16:04 +0100, David Vrabel wrote:
>>>> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
>>>> index f0f6e34..1c5e687 100644
>>>> --- a/tools/libxl/libxl_types.idl
>>>> +++ b/tools/libxl/libxl_types.idl
>>>> @@ -371,6 +371,8 @@ libxl_domain_build_info = Struct("domain_build_info",[
>>>>                                         ("xen_platform_pci", libxl_defbool),
>>>>                                         ("usbdevice_list",   libxl_string_list),
>>>>                                         ("vendor_device",    libxl_vendor_device),
>>>> +                                       # See libxl_ms_vm_genid_generate()
>>>> +                                       ("ms_vm_genid",      libxl_uuid),
>>>
>>> When we discussed this IRL I thought we had decided that this should be
>>> a new libxl_ms_vm_genid type, effectively a typedef of uint8_t[16],
>>> similar to libxl_mac and libxl_hwcap[[0]]. This would avoid any
>>> suggestion that one of the more structured forms of UUID would be
>>> appropriate here.
>>
>> I kept the libxl_uuid type in the end because it allowed me to use
>> libxl_uuid_is_nil() without having to re-implement an equivalent.
> 
> Doesn't sound too tricky though.
> 
>>> I appreciate that you tried to address that with the comment, but I fear
>>> it might not be terribly effective in practice...
>>
>> A toolstack author cannot use the ms_vm_genid field correctly without
>> reading the Microsoft document and that's clear on the requirements.
> 
> What's not clear is that libxl_uuid_generate() doesn't (necessarily)
> meet the spec. Using a different type would stop people from using that.
> 
>> Do you still want a new typedef?
> 
> I think it would be best.

I started doing this and I now disagree (even more).

Using a new types requires duplicating the uuid json pack/unpack code
and prevents toolstacks from using standard uuid library functions for
dealing with the generation ID (e.g., if they need to (un)serailize the
ID or store it in a database etc.).

The benefits of using libxl_uuid out weight your concern that some one
might not use the documented function for generating a valid ID, IMO.

David

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 7/8] xl: generate a new random VM generation ID if requested
  2014-06-18 16:12 [PATCHv6 0/8] tools: rework VM Generation ID David Vrabel
@ 2014-06-18 16:12 ` David Vrabel
  0 siblings, 0 replies; 23+ messages in thread
From: David Vrabel @ 2014-06-18 16:12 UTC (permalink / raw)
  To: xen-devel; +Cc: David Vrabel, Ian Jackson, Ian Campbell, Stefano Stabellini

If the "generation_id" option is set in the domain configuration,
generate and set a new random VM generation ID every time a domain is
created or restored.

xl lacks the infrastructure to fully track the lifecycle of VM images
as they are snapshotted and cloned (etc) so always using a new ID is
the safe option and ensures that a new one will be used where it matters.

Signed-off-by: David Vrabel <david.vrabel@citrix.com>
---
 docs/man/xl.cfg.pod.5    |   29 +++++++++++++++++++++++++++++
 tools/libxl/xl_cmdimpl.c |   15 +++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
index c087cbc..ff9ea77 100644
--- a/docs/man/xl.cfg.pod.5
+++ b/docs/man/xl.cfg.pod.5
@@ -936,6 +936,35 @@ number of vendor defined SMBIOS structures (type 128 - 255). Since SMBIOS
 structures do not present their overall size, each entry in the file must be
 preceded by a 32b integer indicating the size of the next structure.
 
+=item B<ms_vm_genid="OPTION">
+
+Provide a VM generation ID to the guest.
+
+The VM generation ID as a 128-bit random number that a guest may use
+to determine if the guest has been restored from an earlier snapshot
+or cloned.
+
+This is required for Microsoft Windows Server 2012 (and later) domain
+controllers.
+
+Valid options are:
+
+=over 4
+
+=item B<"generate">
+
+Generate a random VM generation ID every time the domain is created or
+restored.
+
+=item B<"none">
+
+Do not provide a VM generation ID.
+
+=back
+
+See also "Virtual Machine Generation ID" by Microsoft
+(http://www.microsoft.com/en-us/download/details.aspx?id=30707).
+
 =back 
 
 =head3 Guest Virtual Time Controls
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 64a1c77..6a67c9c 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1021,6 +1021,21 @@ static void parse_config_data(const char *config_source,
                                &b_info->u.hvm.smbios_firmware, 0);
         xlu_cfg_replace_string(config, "acpi_firmware",
                                &b_info->u.hvm.acpi_firmware, 0);
+
+        if (!xlu_cfg_get_string(config, "ms_vm_genid", &buf, 0)) {
+            if (!strcmp(buf, "generate")) {
+                e = libxl_ms_vm_genid_generate(ctx, &b_info->u.hvm.ms_vm_genid);
+                if (e) {
+                    fprintf(stderr, "ERROR: failed to generate a VM Generation ID\n");
+                    exit(1);
+                }
+            } else if (!strcmp(buf, "none")) {
+                ;
+            } else {
+                    fprintf(stderr, "ERROR: \"ms_vm_genid\" option must be \"generate\" or \"none\"\n");
+                    exit(1);
+            }
+        }
         break;
     case LIBXL_DOMAIN_TYPE_PV:
     {
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2014-06-18 16:13 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-12 15:04 [PATCHv5 0/8] tools: rework VM Generation ID David Vrabel
2014-06-12 15:04 ` [PATCH 1/8] libxc: allow xc_get/set_hvm_param() to get/set 64-bit values David Vrabel
2014-06-18 11:26   ` Ian Campbell
2014-06-18 13:05   ` Ian Campbell
2014-06-12 15:04 ` [PATCH 2/8] libxl: add libxl__random_bytes() which fills a buffer with random bytes David Vrabel
2014-06-18 11:28   ` Ian Campbell
2014-06-18 11:43     ` Roger Pau Monné
2014-06-18 13:10       ` Ian Campbell
2014-06-12 15:04 ` [PATCH 3/8] hvmloader: add helper functions to get/set HVM params David Vrabel
2014-06-12 15:04 ` [PATCH 4/8] hvm: add HVM_PARAM_VM_GENERATION_ID_ADDR David Vrabel
2014-06-12 15:04 ` [PATCH 5/8] libxc, libxl, hvmloader: strip out outdated VM generation ID implementation David Vrabel
2014-06-12 15:04 ` [PATCH 6/8] libxl: allow a generation ID to be specified at domain creation David Vrabel
2014-06-18  5:18   ` Hongyang Yang
2014-06-18  9:38     ` David Vrabel
2014-06-18  9:39       ` Ian Campbell
2014-06-18 11:33   ` Ian Campbell
2014-06-18 12:09     ` David Vrabel
2014-06-18 12:25       ` Ian Campbell
2014-06-18 13:22         ` David Vrabel
2014-06-12 15:04 ` [PATCH 7/8] xl: generate a new random VM generation ID if requested David Vrabel
2014-06-18 11:37   ` Ian Campbell
2014-06-12 15:04 ` [PATCH 8/8] docs: update docs for the ~/platform/generation-id key David Vrabel
2014-06-18 16:12 [PATCHv6 0/8] tools: rework VM Generation ID David Vrabel
2014-06-18 16:12 ` [PATCH 7/8] xl: generate a new random VM generation ID if requested David Vrabel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.