[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 4 of 5] Add code to track the address of the VM generation id buffer across a



# HG changeset patch
# User Paul Durrant <paul.durrant@xxxxxxxxxx>
# Date 1322482489 0
# Node ID c4613164ee1c5f3bf2085008359ebb5b7924c660
# Parent  3886d406c13aa66b2af123d52a1bef8b6f41d144
Add code to track the address of the VM generation id buffer across a
save/restore or migrate and inject a new value.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>

diff -r 3886d406c13a -r c4613164ee1c tools/firmware/hvmloader/acpi/build.c
--- a/tools/firmware/hvmloader/acpi/build.c     Mon Nov 28 12:14:48 2011 +0000
+++ b/tools/firmware/hvmloader/acpi/build.c     Mon Nov 28 12:14:49 2011 +0000
@@ -23,6 +23,7 @@
 #include "ssdt_pm.h"
 #include "../config.h"
 #include "../util.h"
+#include <xen/hvm/params.h>
 
 #define align16(sz)        (((sz) + 15) & ~15)
 #define fixed_strcpy(d, s) strncpy((d), (s), sizeof(d))
@@ -308,6 +309,7 @@ unsigned long new_vm_gid(void)
     gid = strtoll(xenstore_read("platform/generation-id", "0"), NULL, 0);
     *(uint64_t *)buf = gid;
 
+    set_param(HVM_PARAM_VM_GENERATION_ID_ADDR, virt_to_phys(buf));
     return virt_to_phys(buf);    
 }
 
diff -r 3886d406c13a -r c4613164ee1c tools/firmware/hvmloader/util.c
--- a/tools/firmware/hvmloader/util.c   Mon Nov 28 12:14:48 2011 +0000
+++ b/tools/firmware/hvmloader/util.c   Mon Nov 28 12:14:49 2011 +0000
@@ -26,6 +26,7 @@
 #include <xen/xen.h>
 #include <xen/memory.h>
 #include <xen/sched.h>
+#include <xen/hvm/hvm_op.h>
 
 void wrmsr(uint32_t idx, uint64_t v)
 {
@@ -792,6 +793,17 @@ int hpet_exists(unsigned long hpet_base)
     return ((hpet_id >> 16) == 0x8086);
 }
 
+void set_param(int param, uint64_t value)
+{
+    struct xen_hvm_param p;
+
+    p.domid = DOMID_SELF;
+    p.index = param;
+    p.value = value;
+    if ( hypercall_hvm_op(HVMOP_set_param, &p) != 0 )
+        BUG();
+}
+
 /*
  * Local variables:
  * mode: C
diff -r 3886d406c13a -r c4613164ee1c tools/firmware/hvmloader/util.h
--- a/tools/firmware/hvmloader/util.h   Mon Nov 28 12:14:48 2011 +0000
+++ b/tools/firmware/hvmloader/util.h   Mon Nov 28 12:14:49 2011 +0000
@@ -228,6 +228,8 @@ void perform_tests(void);
 
 extern char _start[], _end[];
 
+void set_param(int param, uint64_t value);
+
 #endif /* __HVMLOADER_UTIL_H__ */
 
 /*
diff -r 3886d406c13a -r c4613164ee1c tools/libxc/ia64/xc_ia64_linux_restore.c
--- a/tools/libxc/ia64/xc_ia64_linux_restore.c  Mon Nov 28 12:14:48 2011 +0000
+++ b/tools/libxc/ia64/xc_ia64_linux_restore.c  Mon Nov 28 12:14:49 2011 +0000
@@ -548,7 +548,8 @@ int
 xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
                   unsigned int store_evtchn, unsigned long *store_mfn,
                   unsigned int console_evtchn, unsigned long *console_mfn,
-                  unsigned int hvm, unsigned int pae, int superpages)
+                  unsigned int hvm, unsigned int pae, int superpages,
+                  uint64_t gid)
 {
     DECLARE_DOMCTL;
     int rc = 1;
diff -r 3886d406c13a -r c4613164ee1c tools/libxc/xc_domain_restore.c
--- a/tools/libxc/xc_domain_restore.c   Mon Nov 28 12:14:48 2011 +0000
+++ b/tools/libxc/xc_domain_restore.c   Mon Nov 28 12:14:49 2011 +0000
@@ -676,6 +676,7 @@ typedef struct {
     uint64_t console_pfn;
     uint64_t acpi_ioport_location;
     uint64_t viridian;
+    uint64_t vm_gid_addr;
 } pagebuf_t;
 
 static int pagebuf_init(pagebuf_t* buf)
@@ -820,6 +821,17 @@ static int pagebuf_get_one(xc_interface 
         }
         return pagebuf_get_one(xch, ctx, buf, fd, dom);
 
+    case XC_SAVE_ID_HVM_GENERATION_ID_ADDR:
+        /* Skip padding 4 bytes then read the generation id buffer location. */
+        if ( RDEXACT(fd, &buf->vm_gid_addr, sizeof(uint32_t)) ||
+             RDEXACT(fd, &buf->vm_gid_addr, sizeof(uint64_t)) )
+        {
+            PERROR("error read the generation id buffer location");
+            return -1;
+        }
+        DPRINTF("read generation id buffer address");
+        return pagebuf_get_one(xch, ctx, buf, fd, dom);
+
     default:
         if ( (count > MAX_BATCH_SIZE) || (count < 0) ) {
             ERROR("Max batch size exceeded (%d). Giving up.", count);
@@ -1186,7 +1198,8 @@ static int apply_batch(xc_interface *xch
 int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
                       unsigned int store_evtchn, unsigned long *store_mfn,
                       unsigned int console_evtchn, unsigned long *console_mfn,
-                      unsigned int hvm, unsigned int pae, int superpages)
+                      unsigned int hvm, unsigned int pae, int superpages,
+                      uint64_t gid)
 {
     DECLARE_DOMCTL;
     int rc = 1, frc, i, j, n, m, pae_extended_cr3 = 0, ext_vcpucontext = 0;
@@ -1386,6 +1399,34 @@ int xc_domain_restore(xc_interface *xch,
                 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_gid_addr ) {
+                unsigned int offset;
+                unsigned char *buf;
+
+                /*
+                 * Map the VM generation id buffer and inject the new value.
+                 */
+
+                pfn = pagebuf.vm_gid_addr >> PAGE_SHIFT;
+                offset = pagebuf.vm_gid_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);
+                *(unsigned long long *)(buf + offset) = gid;
+                munmap(buf, PAGE_SIZE);
+
+                xc_set_hvm_param(xch, dom, HVM_PARAM_VM_GENERATION_ID_ADDR,
+                                 pagebuf.vm_gid_addr);
+            }
+
             break;  /* our work here is done */
         }
 
diff -r 3886d406c13a -r c4613164ee1c tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c      Mon Nov 28 12:14:48 2011 +0000
+++ b/tools/libxc/xc_domain_save.c      Mon Nov 28 12:14:49 2011 +0000
@@ -1518,6 +1518,17 @@ int xc_domain_save(xc_interface *xch, in
             PERROR("Error when writing the viridian flag");
             goto out;
         }
+
+        chunk.id = XC_SAVE_ID_HVM_GENERATION_ID_ADDR;
+        chunk.data = 0;
+        xc_get_hvm_param(xch, dom, HVM_PARAM_VM_GENERATION_ID_ADDR,
+                         (unsigned long *)&chunk.data);
+
+        if ((chunk.data != 0) && wrexact(io_fd, &chunk, sizeof(chunk)))
+        {
+            PERROR("Error when writing the generation id buffer location for 
guest");
+            goto out;
+        }
     }
 
     if ( !callbacks->checkpoint )
diff -r 3886d406c13a -r c4613164ee1c tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h    Mon Nov 28 12:14:48 2011 +0000
+++ b/tools/libxc/xenguest.h    Mon Nov 28 12:14:49 2011 +0000
@@ -71,12 +71,14 @@ int xc_domain_save(xc_interface *xch, in
  * @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 gid the new generation id of the VM
  * @return 0 on success, -1 on failure
  */
 int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
                       unsigned int store_evtchn, unsigned long *store_mfn,
                       unsigned int console_evtchn, unsigned long *console_mfn,
-                      unsigned int hvm, unsigned int pae, int superpages);
+                      unsigned int hvm, unsigned int pae, int superpages,
+                      uint64_t gid);
 /**
  * xc_domain_restore writes a file to disk that contains the device
  * model saved state.
diff -r 3886d406c13a -r c4613164ee1c tools/libxc/xg_save_restore.h
--- a/tools/libxc/xg_save_restore.h     Mon Nov 28 12:14:48 2011 +0000
+++ b/tools/libxc/xg_save_restore.h     Mon Nov 28 12:14:49 2011 +0000
@@ -135,6 +135,7 @@
 #define XC_SAVE_ID_LAST_CHECKPOINT    -9 /* Commit to restoring after 
completion of current iteration. */
 #define XC_SAVE_ID_HVM_ACPI_IOPORTS_LOCATION -10
 #define XC_SAVE_ID_HVM_VIRIDIAN       -11
+#define XC_SAVE_ID_HVM_GENERATION_ID_ADDR -12
 
 /*
 ** We process save/restore/migrate in batches of pages; the below
diff -r 3886d406c13a -r c4613164ee1c tools/libxl/libxl_dom.c
--- a/tools/libxl/libxl_dom.c   Mon Nov 28 12:14:48 2011 +0000
+++ b/tools/libxl/libxl_dom.c   Mon Nov 28 12:14:49 2011 +0000
@@ -340,16 +340,19 @@ int libxl__domain_restore_common(libxl__
     /* read signature */
     int rc;
     int hvm, pae, superpages;
+    uint64_t gid;
     switch (info->type) {
     case LIBXL_DOMAIN_TYPE_HVM:
         hvm = 1;
         superpages = 1;
         pae = info->u.hvm.pae;
+        gid = info->u.hvm.generation_id;
         break;
     case LIBXL_DOMAIN_TYPE_PV:
         hvm = 0;
         superpages = 0;
         pae = 1;
+        gid = 0;
         break;
     default:
         return ERROR_INVAL;
@@ -357,7 +360,7 @@ int libxl__domain_restore_common(libxl__
     rc = xc_domain_restore(ctx->xch, fd, domid,
                            state->store_port, &state->store_mfn,
                            state->console_port, &state->console_mfn,
-                           hvm, pae, superpages);
+                           hvm, pae, superpages, gid);
     if ( rc ) {
         LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "restoring domain");
         return ERROR_FAIL;
diff -r 3886d406c13a -r c4613164ee1c tools/xcutils/xc_restore.c
--- a/tools/xcutils/xc_restore.c        Mon Nov 28 12:14:48 2011 +0000
+++ b/tools/xcutils/xc_restore.c        Mon Nov 28 12:14:49 2011 +0000
@@ -24,6 +24,7 @@ main(int argc, char **argv)
     int io_fd, ret;
     int superpages;
     unsigned long store_mfn, console_mfn;
+    uint64_t gid;
 
     if ( (argc != 8) && (argc != 9) )
         errx(1, "usage: %s iofd domid store_evtchn "
@@ -40,13 +41,18 @@ main(int argc, char **argv)
     hvm  = atoi(argv[5]);
     pae  = atoi(argv[6]);
     apic = atoi(argv[7]);
-    if ( argc == 9 )
+    if ( argc >= 9 )
            superpages = atoi(argv[8]);
     else
            superpages = !!hvm;
+    if ( argc >= 10 )
+           gid = strtoll(argv[9], NULL, 0);
+    else
+           gid = 0;
 
     ret = xc_domain_restore(xch, io_fd, domid, store_evtchn, &store_mfn,
-                            console_evtchn, &console_mfn, hvm, pae, 
superpages);
+                            console_evtchn, &console_mfn, hvm, pae, superpages,
+                            gid);
 
     if ( ret == 0 )
     {
diff -r 3886d406c13a -r c4613164ee1c xen/include/public/hvm/params.h
--- a/xen/include/public/hvm/params.h   Mon Nov 28 12:14:48 2011 +0000
+++ b/xen/include/public/hvm/params.h   Mon Nov 28 12:14:49 2011 +0000
@@ -142,6 +142,9 @@
 /* Boolean: Enable nestedhvm (hvm only) */
 #define HVM_PARAM_NESTEDHVM    24
 
-#define HVM_NR_PARAMS          27
+/* Address of VM generation id buffer */
+#define HVM_PARAM_VM_GENERATION_ID_ADDR 27
+
+#define HVM_NR_PARAMS          28
 
 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.