]> xenbits.xensource.com Git - people/dwmw2/xen.git/commitdiff
live update: add helper functions for handling migration records
authorDavid Woodhouse <dwmw@amazon.co.uk>
Mon, 27 Jan 2020 23:46:19 +0000 (23:46 +0000)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Wed, 18 Mar 2020 23:42:36 +0000 (23:42 +0000)
On top of the basic byte stream handling for struct lu_stream, add
helper functions to create and process migration records of the form now
defined in <public/migration_stream.h>.

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
xen/common/lu/stream.c
xen/include/xen/lu.h

index 5318b7fe7e01e8b41ee495278f799503cf39f023..bb2c905da46bc5925981dd6c15aeb0be4a749f82 100644 (file)
@@ -33,6 +33,7 @@
 #include <xen/types.h>
 #include <xen/vmap.h>
 #include <xen/lu.h>
+#include <public/migration_stream.h>
 
 static int lu_stream_extend(struct lu_stream *stream, int nr_pages)
 {
@@ -105,6 +106,55 @@ int lu_stream_append(struct lu_stream *stream, const void *data, size_t size)
     return 0;
 }
 
+int lu_stream_open_record(struct lu_stream *stream, unsigned int type)
+{
+    struct mr_rhdr *hdr;
+
+    stream->last_hdr = stream->len;
+
+    hdr = lu_stream_reserve(stream, sizeof(hdr));
+    if (!hdr)
+        return -ENOMEM;
+
+    hdr->type = type;
+    hdr->length = 0;
+
+    lu_stream_end_reservation(stream, sizeof(*hdr));
+
+    return 0;
+}
+
+int lu_stream_close_record(struct lu_stream *stream)
+{
+    uint64_t zeroes = 0;
+    struct mr_rhdr *hdr;
+    int rc = 0;
+
+    hdr = (struct mr_rhdr *)(stream->data + stream->last_hdr);
+
+    hdr->length = stream->len - stream->last_hdr - sizeof(*hdr);
+
+    if (stream->len & 7)
+        rc = lu_stream_append(stream, &zeroes, 8 - (stream->len & 7));
+
+    return rc;
+}
+
+int lu_stream_append_record(struct lu_stream *stream, unsigned int type,
+                            void *rec, size_t len)
+{
+    int rc;
+
+
+    rc = lu_stream_open_record(stream, type);
+    if (!rc && len)
+        rc = lu_stream_append(stream, rec, len);
+    if (!rc)
+        rc = lu_stream_close_record(stream);
+
+    return 0;
+}
+
 void lu_stream_free(struct lu_stream *stream)
 {
     unsigned int order = get_order_from_bytes((stream->nr_pages + 1) * sizeof(mfn_t));
index 67d42f3232322f3b0857175d48e70f0e73124439..76a1337cd820ae609803b4cb428fee534f49ae2a 100644 (file)
@@ -5,10 +5,13 @@
 #include <xen/types.h>
 #include <xen/mm.h>
 
+#include <public/migration_stream.h>
+
 #define LIVE_UPDATE_MAGIC        (0x4c69766555706461UL & PAGE_MASK)
 
 struct lu_stream {
     mfn_t *pagelist;
+    size_t last_hdr;
     size_t len;
     int nr_pages;
     char *data;
@@ -17,6 +20,10 @@ struct lu_stream {
 void *lu_stream_reserve(struct lu_stream *stream, size_t size);
 void lu_stream_end_reservation(struct lu_stream *stream, size_t size);
 int lu_stream_append(struct lu_stream *stream, const void *data, size_t size);
+int lu_stream_open_record(struct lu_stream *stream, unsigned int type);
+int lu_stream_close_record(struct lu_stream *stream);
+int lu_stream_append_record(struct lu_stream *stream, unsigned int type,
+                            void *rec, size_t len);
 void lu_stream_free(struct lu_stream *stream);
 
 void lu_stream_map(struct lu_stream *stream, unsigned long mfns_phys,
@@ -25,6 +32,21 @@ void lu_reserve_pages(struct lu_stream *stream);
 /* Returns Dom0 in case the architecture needs to do anything special to it */
 struct domain *lu_restore_domains(struct lu_stream *stream);
 
+/* Pointer to the data immediately following a record header */
+#define LU_REC_DATA(hdr) ((const void *)&(hdr)[1])
+
+static inline struct mr_rhdr *lu_next_record(struct lu_stream *stream)
+{
+    struct mr_rhdr *hdr = (struct mr_rhdr *)(stream->data + stream->last_hdr);
+
+    if (stream->len < stream->last_hdr + sizeof(*hdr) ||
+        stream->len < stream->last_hdr + sizeof(*hdr) + hdr->length)
+        return NULL;
+
+    stream->last_hdr += sizeof(*hdr) + ROUNDUP(hdr->length, 1<<REC_ALIGN_ORDER);
+    return hdr;
+}
+
 #endif /* __XEN_LU_H__ */
 
 /*