]> xenbits.xensource.com Git - people/hx242/xen.git/commitdiff
tools/libxc: Restore CPUID/MSR data found in the migration stream
authorAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 20 Dec 2019 19:38:26 +0000 (19:38 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 29 May 2020 16:33:03 +0000 (17:33 +0100)
With all other pieces in place, it is now safe to restore the CPUID and MSR
data in the migration stream, rather than discarding them and using the higher
level toolstacks compatibility logic.

While this is a small patch, it has large implications for migrated/resumed
domains.  Most obviously, the CPU family/model/stepping data,
cache/tlb/etc. will no longer change behind the guests back.

Another change is the interpretation of the Xend cpuid strings.  The 'k'
option is not a sensible thing to have ever supported, and 's' is how how the
stream will end up behaving.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
tools/libxc/xc_cpuid_x86.c
tools/libxc/xc_sr_common_x86.c

index f045b03223f42fe99c8d4fb7c923cdfc5d32aa5e..89d2ecdad288bb67210e8a882cfdd50fe82c0384 100644 (file)
@@ -273,10 +273,9 @@ int xc_set_domain_cpu_policy(xc_interface *xch, uint32_t domid,
  *   '0' -> force to 0
  *   'x' -> we don't care (use default)
  *   'k' -> pass through host value
- *   's' -> pass through the first time and then keep the same value
- *          across save/restore and migration.
+ *   's' -> legacy alias for 'k'
  *
- * For 's' and 'x' the configuration is overwritten with the value applied.
+ * In all cases, the returned string consists of just '0' and '1'.
  */
 int xc_cpuid_set(
     xc_interface *xch, uint32_t domid, const unsigned int *input,
@@ -402,7 +401,8 @@ int xc_cpuid_set(
                 clear_feature(31 - j, regs[i]);
 
             config_transformed[i][j] = config[i][j];
-            if ( config[i][j] == 's' )
+            /* All non 0/1 values get overwritten. */
+            if ( (config[i][j] & ~1) != '0' )
                 config_transformed[i][j] = '0' + val;
         }
     }
index a849891634e7bb9f53dd6f6e56ab474038fcf7d3..77ea044a746be2714c3ded015a153d90a857151a 100644 (file)
@@ -134,8 +134,30 @@ int handle_x86_msr_policy(struct xc_sr_context *ctx, struct xc_sr_record *rec)
 
 int x86_static_data_complete(struct xc_sr_context *ctx, unsigned int *missing)
 {
-    /* TODO: Become conditional on there being no data in the stream. */
-    *missing = XGR_SDD_MISSING_MSR | XGR_SDD_MISSING_CPUID;
+    xc_interface *xch = ctx->xch;
+    uint32_t nr_leaves = 0, nr_msrs = 0;
+    uint32_t err_l = ~0, err_s = ~0, err_m = ~0;
+
+    if ( ctx->x86.restore.cpuid.ptr )
+        nr_leaves = ctx->x86.restore.cpuid.size / sizeof(xen_cpuid_leaf_t);
+    else
+        *missing |= XGR_SDD_MISSING_CPUID;
+
+    if ( ctx->x86.restore.msr.ptr )
+        nr_msrs = ctx->x86.restore.msr.size / sizeof(xen_msr_entry_t);
+    else
+        *missing |= XGR_SDD_MISSING_MSR;
+
+    if ( (nr_leaves || nr_msrs) &&
+         xc_set_domain_cpu_policy(xch, ctx->domid,
+                                  nr_leaves, ctx->x86.restore.cpuid.ptr,
+                                  nr_msrs,   ctx->x86.restore.msr.ptr,
+                                  &err_l, &err_s, &err_m) )
+    {
+        PERROR("Failed to set CPUID policy: leaf %08x, subleaf %08x, msr %08x",
+               err_l, err_s, err_m);
+        return -1;
+    }
 
     return 0;
 }