* '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,
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;
}
}
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;
}