diff mbox series

[12/12] libxc/save: Write X86_{CPUID, MSR}_DATA records

Message ID 20191224151932.6304-13-andrew.cooper3@citrix.com (mailing list archive)
State Superseded
Headers show
Series Support CPUID/MSR data in migration streams | expand

Commit Message

Andrew Cooper Dec. 24, 2019, 3:19 p.m. UTC
With all other plumbing in place, obtain the CPU Policy from Xen and
write it into the migration stream.

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_x86.c   | 50 ++++++++++++++++++++++++++++++++++++++++
 tools/libxc/xc_sr_common_x86.h   |  6 +++++
 tools/libxc/xc_sr_save_x86_hvm.c |  2 +-
 tools/libxc/xc_sr_save_x86_pv.c  |  3 ++-
 4 files changed, 59 insertions(+), 2 deletions(-)

Comments

Ian Jackson Jan. 14, 2020, 5:21 p.m. UTC | #1
Andrew Cooper writes ("[PATCH 12/12] libxc/save: Write X86_{CPUID,MSR}_DATA records"):
> With all other plumbing in place, obtain the CPU Policy from Xen and
> write it into the migration stream.

This looks good to me but:

This patch may need revision to handle the results of our discussion
about the ?: error handling idiom.

And I am still missing the text discussing compatibility.  Maybe I
have just overlooked it ?

Anyway, if it weren't for those two issues I would have acked the
patch.

Thanks,
Ian.
Andrew Cooper Jan. 15, 2020, 3:52 p.m. UTC | #2
On 14/01/2020 17:21, Ian Jackson wrote:
> Andrew Cooper writes ("[PATCH 12/12] libxc/save: Write X86_{CPUID,MSR}_DATA records"):
>> With all other plumbing in place, obtain the CPU Policy from Xen and
>> write it into the migration stream.
> This looks good to me but:
>
> This patch may need revision to handle the results of our discussion
> about the ?: error handling idiom.
>
> And I am still missing the text discussing compatibility.  Maybe I
> have just overlooked it ?

In all cases with migration development, the receive side logic
(previous patch) has to come before the save side logic (this patch), or
the result will break bisection with the receive side choking on an
unknown record type.

From the "whole series" point of view, compatibility is also the
destination side discarding the data because libxl still needs its order
of CPUID handling shuffling to cope.

~Andrew
diff mbox series

Patch

diff --git a/tools/libxc/xc_sr_common_x86.c b/tools/libxc/xc_sr_common_x86.c
index d4d86bb12f..09fb1d93d6 100644
--- a/tools/libxc/xc_sr_common_x86.c
+++ b/tools/libxc/xc_sr_common_x86.c
@@ -49,6 +49,56 @@  int x86_static_data_complete(struct xc_sr_context *ctx)
     return 0;
 }
 
+int write_x86_cpu_policy_records(struct xc_sr_context *ctx)
+{
+    xc_interface *xch = ctx->xch;
+    struct xc_sr_record cpuid = { .type = REC_TYPE_X86_CPUID_POLICY, };
+    struct xc_sr_record msrs  = { .type = REC_TYPE_X86_MSR_POLICY, };
+    uint32_t nr_leaves = 0, nr_msrs = 0;
+    int rc;
+
+    if ( xc_get_cpu_policy_size(xch, &nr_leaves, &nr_msrs) < 0 )
+    {
+        PERROR("Unable to get CPU Policy size");
+        return -1;
+    }
+
+    cpuid.data = malloc(nr_leaves * sizeof(xen_cpuid_leaf_t));
+    msrs.data  = malloc(nr_msrs   * sizeof(xen_msr_entry_t));
+    if ( !cpuid.data || !msrs.data )
+    {
+        ERROR("Cannot allocate memory for CPU Policy");
+        rc = -1;
+        goto out;
+    }
+
+    if ( xc_get_domain_cpu_policy(xch, ctx->domid, &nr_leaves, cpuid.data,
+                                  &nr_msrs, msrs.data) )
+    {
+        PERROR("Unable to get d%d CPU Policy", ctx->domid);
+        rc = -1;
+        goto out;
+    }
+
+    cpuid.length = nr_leaves * sizeof(xen_cpuid_leaf_t);
+    if ( cpuid.length )
+    {
+        rc = write_record(ctx, &cpuid);
+        if ( rc )
+            goto out;
+    }
+
+    msrs.length = nr_msrs * sizeof(xen_msr_entry_t);
+    if ( msrs.length )
+        rc = write_record(ctx, &msrs);
+
+ out:
+    free(cpuid.data);
+    free(msrs.data);
+
+    return rc;
+}
+
 int handle_x86_cpuid_policy(struct xc_sr_context *ctx, struct xc_sr_record *rec)
 {
     xc_interface *xch = ctx->xch;
diff --git a/tools/libxc/xc_sr_common_x86.h b/tools/libxc/xc_sr_common_x86.h
index f7fa4fe62b..7b1823eca9 100644
--- a/tools/libxc/xc_sr_common_x86.h
+++ b/tools/libxc/xc_sr_common_x86.h
@@ -20,6 +20,12 @@  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);
 
 /*
+ * Obtains a domains CPU Policy from Xen, and writes X86_{CPUID,MSR}_POLICY
+ * records into the stream.
+ */
+int write_x86_cpu_policy_records(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.
  */
diff --git a/tools/libxc/xc_sr_save_x86_hvm.c b/tools/libxc/xc_sr_save_x86_hvm.c
index c146e827bc..5b95d20b19 100644
--- a/tools/libxc/xc_sr_save_x86_hvm.c
+++ b/tools/libxc/xc_sr_save_x86_hvm.c
@@ -172,7 +172,7 @@  static int x86_hvm_setup(struct xc_sr_context *ctx)
 
 static int x86_hvm_static_data(struct xc_sr_context *ctx)
 {
-    return 0;
+    return write_x86_cpu_policy_records(ctx);
 }
 
 static int x86_hvm_start_of_stream(struct xc_sr_context *ctx)
diff --git a/tools/libxc/xc_sr_save_x86_pv.c b/tools/libxc/xc_sr_save_x86_pv.c
index 9d1ca6ead7..2e9aa9ea16 100644
--- a/tools/libxc/xc_sr_save_x86_pv.c
+++ b/tools/libxc/xc_sr_save_x86_pv.c
@@ -1030,7 +1030,8 @@  static int x86_pv_setup(struct xc_sr_context *ctx)
 
 static int x86_pv_static_data(struct xc_sr_context *ctx)
 {
-    return write_x86_pv_info(ctx);
+    return (write_x86_pv_info(ctx) ?:
+            write_x86_cpu_policy_records(ctx));
 }
 
 static int x86_pv_start_of_stream(struct xc_sr_context *ctx)