... in the save/restore code.
This patch replaces direct mapping of the shared_info_frame (retrieved
using XEN_DOMCTL_getdomaininfo) with save/load of the domain context
SHARED_INFO record.
No modifications are made to the definition of the migration stream at
this point. Subsequent patches will define a record in the libxc domain
image format for passing domain context and convert the save/restore code
to use that.
Signed-off-by: Paul Durrant
---
Cc: Ian Jackson
Cc: Wei Liu
v2:
- Re-based (now making use of DOMAIN_SAVE_FLAG_IGNORE)
---
tools/libxc/xc_sr_common.h | 7 +++-
tools/libxc/xc_sr_common_x86.c | 59 ++
tools/libxc/xc_sr_common_x86.h | 4 ++
tools/libxc/xc_sr_common_x86_pv.c | 53 +++
tools/libxc/xc_sr_common_x86_pv.h | 3 ++
tools/libxc/xc_sr_restore_x86_pv.c | 40
tools/libxc/xc_sr_save_x86_pv.c| 26 ++---
tools/libxc/xg_save_restore.h | 1 +
8 files changed, 144 insertions(+), 49 deletions(-)
diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
index 5dd51ccb15..db6519cdcc 100644
--- a/tools/libxc/xc_sr_common.h
+++ b/tools/libxc/xc_sr_common.h
@@ -287,6 +287,11 @@ struct xc_sr_context
{
struct /* x86 */
{
+struct {
+void *buffer;
+unsigned int len;
+} domain_context;
+
struct /* x86 PV guest. */
{
/* 4 or 8; 32 or 64 bit domain */
@@ -314,7 +319,7 @@ struct xc_sr_context
/* The guest pfns containing the p2m leaves */
xen_pfn_t *p2m_pfns;
-/* Read-only mapping of guests shared info page */
+/* Pointer to shared_info (located in context buffer) */
shared_info_any_t *shinfo;
/* p2m generation count for verifying validity of local p2m. */
diff --git a/tools/libxc/xc_sr_common_x86.c b/tools/libxc/xc_sr_common_x86.c
index 011684df97..e87dc0f0f3 100644
--- a/tools/libxc/xc_sr_common_x86.c
+++ b/tools/libxc/xc_sr_common_x86.c
@@ -42,6 +42,65 @@ int handle_x86_tsc_info(struct xc_sr_context *ctx, struct
xc_sr_record *rec)
return 0;
}
+int x86_get_context(struct xc_sr_context *ctx)
+{
+xc_interface *xch = ctx->xch;
+size_t len = 0;
+int rc;
+
+if ( ctx->x86.domain_context.buffer )
+{
+ERROR("Domain context already present");
+return -1;
+}
+
+rc = xc_domain_getcontext(xch, ctx->domid, NULL, );
+if ( rc < 0 )
+{
+PERROR("Unable to get size of domain context");
+return -1;
+}
+
+ctx->x86.domain_context.buffer = malloc(len);
+if ( ctx->x86.domain_context.buffer == NULL )
+{
+PERROR("Unable to allocate memory for domain context");
+return -1;
+}
+
+rc = xc_domain_getcontext(xch, ctx->domid,
+ ctx->x86.domain_context.buffer, );
+if ( rc < 0 )
+{
+PERROR("Unable to get domain context");
+return -1;
+}
+
+ctx->x86.domain_context.len = len;
+
+return 0;
+}
+
+int x86_set_context(struct xc_sr_context *ctx)
+{
+xc_interface *xch = ctx->xch;
+
+if ( !ctx->x86.domain_context.buffer )
+{
+ERROR("Domain context not present");
+return -1;
+}
+
+return xc_domain_setcontext(xch, ctx->domid,
+ctx->x86.domain_context.buffer,
+ctx->x86.domain_context.len);
+}
+
+void x86_cleanup(struct xc_sr_context *ctx)
+{
+free(ctx->x86.domain_context.buffer);
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxc/xc_sr_common_x86.h b/tools/libxc/xc_sr_common_x86.h
index ebc4355bd1..501c9e52ba 100644
--- a/tools/libxc/xc_sr_common_x86.h
+++ b/tools/libxc/xc_sr_common_x86.h
@@ -14,6 +14,10 @@ int write_x86_tsc_info(struct xc_sr_context *ctx);
*/
int handle_x86_tsc_info(struct xc_sr_context *ctx, struct xc_sr_record *rec);
+int x86_get_context(struct xc_sr_context *ctx);
+int x86_set_context(struct xc_sr_context *ctx);
+void x86_cleanup(struct xc_sr_context *ctx);
+
#endif
/*
* Local variables:
diff --git a/tools/libxc/xc_sr_common_x86_pv.c
b/tools/libxc/xc_sr_common_x86_pv.c
index d3d425cb82..7354fd6052 100644
--- a/tools/libxc/xc_sr_common_x86_pv.c
+++ b/tools/libxc/xc_sr_common_x86_pv.c
@@ -182,6 +182,59 @@ int x86_pv_map_m2p(struct xc_sr_context *ctx)
return rc;
}
+int x86_pv_get_shinfo(struct xc_sr_context *ctx)
+{
+unsigned int off = 0;
+struct domain_save_descriptor *desc;
+int rc;
+
+rc = x86_get_context(ctx);
+if ( rc )
+return rc;
+
+do {
+if ( ctx->x86.domain_context.len - off < sizeof(*desc) )
+return -1;
+
+desc = ctx->x86.domain_context.buffer + off;
+off += sizeof(*desc);
+
+switch (desc->typecode)
+{
+case DOMAIN_SAVE_CODE(SHARED_INFO):
+{
+