[Xen-devel] [PATCH v2 14/17] libxc/save: Write X86_{CPUID, MSR}_DATA records

Andrew Cooper posted 17 patches 5 years, 10 months ago
[Xen-devel] [PATCH v2 14/17] libxc/save: Write X86_{CPUID, MSR}_DATA records
Posted by Andrew Cooper 5 years, 10 months ago
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  | 12 +++++++++-
 4 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/tools/libxc/xc_sr_common_x86.c b/tools/libxc/xc_sr_common_x86.c
index 8980299e9a..6267655dab 100644
--- a/tools/libxc/xc_sr_common_x86.c
+++ b/tools/libxc/xc_sr_common_x86.c
@@ -42,6 +42,56 @@ int handle_x86_tsc_info(struct xc_sr_context *ctx, struct xc_sr_record *rec)
     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 c458c1aa37..d1050981dd 100644
--- a/tools/libxc/xc_sr_common_x86.h
+++ b/tools/libxc/xc_sr_common_x86.h
@@ -15,6 +15,12 @@ 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);
 
 /*
+ * 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 93bcc1c273..acf9264dec 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 46019d962d..c7e246ef4f 100644
--- a/tools/libxc/xc_sr_save_x86_pv.c
+++ b/tools/libxc/xc_sr_save_x86_pv.c
@@ -1054,7 +1054,17 @@ 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);
+    int rc;
+
+    rc = write_x86_pv_info(ctx);
+    if ( rc )
+        return rc;
+
+    rc = write_x86_cpu_policy_records(ctx);
+    if ( rc )
+        return rc;
+
+    return 0;
 }
 
 static int x86_pv_start_of_stream(struct xc_sr_context *ctx)
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [PATCH v2 14/17] libxc/save: Write X86_{CPUID,MSR}_DATA records
Posted by Ian Jackson 5 years, 7 months ago
Andrew Cooper writes ("[PATCH v2 14/17] 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.

Thanks for your earlier explanation in the thread:

  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.

I still would have some comments about the compatibility implications
*in the commit message*; maybe an abbreviated version the text above.

Nevertheless,

Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>

Re: Ping [PATCH v2 14/17] libxc/save: Write X86_{CPUID,MSR}_DATA records
Posted by Andrew Cooper 5 years, 8 months ago
On 27/01/2020 14:34, Andrew Cooper wrote:
> 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  | 12 +++++++++-
>  4 files changed, 68 insertions(+), 2 deletions(-)
>
> diff --git a/tools/libxc/xc_sr_common_x86.c b/tools/libxc/xc_sr_common_x86.c
> index 8980299e9a..6267655dab 100644
> --- a/tools/libxc/xc_sr_common_x86.c
> +++ b/tools/libxc/xc_sr_common_x86.c
> @@ -42,6 +42,56 @@ int handle_x86_tsc_info(struct xc_sr_context *ctx, struct xc_sr_record *rec)
>      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 c458c1aa37..d1050981dd 100644
> --- a/tools/libxc/xc_sr_common_x86.h
> +++ b/tools/libxc/xc_sr_common_x86.h
> @@ -15,6 +15,12 @@ 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);
>  
>  /*
> + * 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 93bcc1c273..acf9264dec 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 46019d962d..c7e246ef4f 100644
> --- a/tools/libxc/xc_sr_save_x86_pv.c
> +++ b/tools/libxc/xc_sr_save_x86_pv.c
> @@ -1054,7 +1054,17 @@ 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);
> +    int rc;
> +
> +    rc = write_x86_pv_info(ctx);
> +    if ( rc )
> +        return rc;
> +
> +    rc = write_x86_cpu_policy_records(ctx);
> +    if ( rc )
> +        return rc;
> +
> +    return 0;
>  }
>  
>  static int x86_pv_start_of_stream(struct xc_sr_context *ctx)