@@ -308,6 +308,16 @@ struct xc_sr_context
{
struct /* x86 */
{
+ /* Common save/restore data. */
+ union
+ {
+ struct
+ {
+ /* X86_{CPUID,MSR}_DATA blobs for CPU Policy. */
+ struct xc_sr_blob cpuid, msr;
+ } restore;
+ };
+
struct /* x86 PV guest. */
{
/* 4 or 8; 32 or 64 bit domain */
@@ -49,6 +49,46 @@ int x86_static_data_complete(struct xc_sr_context *ctx)
return 0;
}
+int handle_x86_cpuid_policy(struct xc_sr_context *ctx, struct xc_sr_record *rec)
+{
+ xc_interface *xch = ctx->xch;
+ int rc;
+
+ if ( rec->length == 0 ||
+ rec->length % sizeof(xen_cpuid_leaf_t) != 0 )
+ {
+ ERROR("X86_CPUID_POLICY size %u should be multiple of %zu",
+ rec->length, sizeof(xen_cpuid_leaf_t));
+ return -1;
+ }
+
+ rc = update_blob(&ctx->x86.restore.cpuid, rec->data, rec->length);
+ if ( rc )
+ ERROR("Unable to allocate %u bytes for X86_CPUID_POLICY", rec->length);
+
+ return rc;
+}
+
+int handle_x86_msr_policy(struct xc_sr_context *ctx, struct xc_sr_record *rec)
+{
+ xc_interface *xch = ctx->xch;
+ int rc;
+
+ if ( rec->length == 0 ||
+ rec->length % sizeof(xen_msr_entry_t) != 0 )
+ {
+ ERROR("X86_MSR_POLICY size %u should be multiple of %zu",
+ rec->length, sizeof(xen_cpuid_leaf_t));
+ return -1;
+ }
+
+ rc = update_blob(&ctx->x86.restore.msr, rec->data, rec->length);
+ if ( rc )
+ ERROR("Unable to allocate %u bytes for X86_MSR_POLICY", rec->length);
+
+ return rc;
+}
+
/*
* Local variables:
* mode: C
@@ -19,6 +19,20 @@ int handle_x86_tsc_info(struct xc_sr_context *ctx, struct xc_sr_record *rec);
*/
int x86_static_data_complete(struct xc_sr_context *ctx);
+/*
+ * Parses an X86_CPUID_POLICY record and stashes the content for application
+ * when a STATIC_DATA_END record is encountered.
+ */
+int handle_x86_cpuid_policy(struct xc_sr_context *ctx,
+ struct xc_sr_record *rec);
+
+/*
+ * Parses an X86_MSR_POLICY record and stashes the content for application
+ * when a STATIC_DATA_END record is encountered.
+ */
+int handle_x86_msr_policy(struct xc_sr_context *ctx,
+ struct xc_sr_record *rec);
+
#endif
/*
* Local variables:
@@ -171,6 +171,12 @@ static int x86_hvm_process_record(struct xc_sr_context *ctx,
case REC_TYPE_HVM_PARAMS:
return handle_hvm_params(ctx, rec);
+ case REC_TYPE_X86_CPUID_POLICY:
+ return handle_x86_cpuid_policy(ctx, rec);
+
+ case REC_TYPE_X86_MSR_POLICY:
+ return handle_x86_msr_policy(ctx, rec);
+
default:
return RECORD_NOT_PROCESSED;
}
@@ -227,6 +233,9 @@ static int x86_hvm_cleanup(struct xc_sr_context *ctx)
{
free(ctx->x86.hvm.restore.context.ptr);
+ free(ctx->x86.restore.cpuid.ptr);
+ free(ctx->x86.restore.msr.ptr);
+
return 0;
}
@@ -1102,6 +1102,12 @@ static int x86_pv_process_record(struct xc_sr_context *ctx,
case REC_TYPE_X86_TSC_INFO:
return handle_x86_tsc_info(ctx, rec);
+ case REC_TYPE_X86_CPUID_POLICY:
+ return handle_x86_cpuid_policy(ctx, rec);
+
+ case REC_TYPE_X86_MSR_POLICY:
+ return handle_x86_msr_policy(ctx, rec);
+
default:
return RECORD_NOT_PROCESSED;
}
@@ -1173,6 +1179,9 @@ static int x86_pv_cleanup(struct xc_sr_context *ctx)
if ( ctx->x86.pv.m2p )
munmap(ctx->x86.pv.m2p, ctx->x86.pv.nr_m2p_frames * PAGE_SIZE);
+ free(ctx->x86.restore.cpuid.ptr);
+ free(ctx->x86.restore.msr.ptr);
+
return 0;
}
For now, the data are just stashed, and discarded at the end. This will be addressed when the TODO in x86_static_data_complete() is addressed. No practical change to behaviour - this is all plumbing work. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> --- CC: Ian Jackson <Ian.Jackson@citrix.com> CC: Wei Liu <wl@xen.org> --- tools/libxc/xc_sr_common.h | 10 ++++++++++ tools/libxc/xc_sr_common_x86.c | 40 +++++++++++++++++++++++++++++++++++++ tools/libxc/xc_sr_common_x86.h | 14 +++++++++++++ tools/libxc/xc_sr_restore_x86_hvm.c | 9 +++++++++ tools/libxc/xc_sr_restore_x86_pv.c | 9 +++++++++ 5 files changed, 82 insertions(+)