uint32_t vcpu);
#if defined(__i386__) || defined(__x86_64__)
+
+/*
+ * CPUID policy data, expressed in the legacy XEND format.
+ *
+ * Policy is an array of strings, 32 chars long:
+ * policy[0] = eax
+ * policy[1] = ebx
+ * policy[2] = ecx
+ * policy[3] = edx
+ *
+ * The format of the string is the following:
+ * '1' -> force to 1
+ * '0' -> force to 0
+ * 'x' -> we don't care (use default)
+ * 'k' -> pass through host value
+ * 's' -> legacy alias for 'k'
+ */
+struct xc_xend_cpuid {
+ union {
+ struct {
+ uint32_t leaf, subleaf;
+ };
+ uint32_t input[2];
+ };
+ char *policy[4];
+};
+
int xc_cpuid_set(xc_interface *xch,
uint32_t domid,
- const unsigned int *input,
- const char **config);
+ const struct xc_xend_cpuid *xend);
/*
* Make adjustments to the CPUID settings for a domain.
return ret;
}
-/*
- * Configure a single input with the informatiom from config.
- *
- * Config is an array of strings:
- * config[0] = eax
- * config[1] = ebx
- * config[2] = ecx
- * config[3] = edx
- *
- * The format of the string is the following:
- * '1' -> force to 1
- * '0' -> force to 0
- * 'x' -> we don't care (use default)
- * 'k' -> pass through host value
- * 's' -> legacy alias for 'k'
- *
- * 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,
- const char **config)
+ xc_interface *xch, uint32_t domid, const struct xc_xend_cpuid *xend)
{
int rc;
unsigned int i, j, regs[4] = {}, polregs[4] = {};
goto fail;
}
for ( i = 0; i < policy_leaves; ++i )
- if ( leaves[i].leaf == input[0] && leaves[i].subleaf == input[1] )
+ if ( leaves[i].leaf == xend->leaf &&
+ leaves[i].subleaf == xend->subleaf )
{
polregs[0] = leaves[i].a;
polregs[1] = leaves[i].b;
goto fail;
}
for ( i = 0; i < policy_leaves; ++i )
- if ( leaves[i].leaf == input[0] && leaves[i].subleaf == input[1] )
+ if ( leaves[i].leaf == xend->leaf &&
+ leaves[i].subleaf == xend->subleaf )
{
regs[0] = leaves[i].a;
regs[1] = leaves[i].b;
for ( i = 0; i < 4; i++ )
{
- if ( config[i] == NULL )
+ if ( xend->policy[i] == NULL )
{
regs[i] = polregs[i];
continue;
unsigned char polval = !!((polregs[i] & (1U << (31 - j))));
rc = -EINVAL;
- if ( !strchr("10xks", config[i][j]) )
+ if ( !strchr("10xks", xend->policy[i][j]) )
goto fail;
- if ( config[i][j] == '1' )
+ if ( xend->policy[i][j] == '1' )
val = 1;
- else if ( config[i][j] == '0' )
+ else if ( xend->policy[i][j] == '0' )
val = 0;
- else if ( config[i][j] == 'x' )
+ else if ( xend->policy[i][j] == 'x' )
val = polval;
if ( val )
}
/* Feed the transformed leaf back up to Xen. */
- leaves[0] = (xen_cpuid_leaf_t){ input[0], input[1],
+ leaves[0] = (xen_cpuid_leaf_t){ xend->leaf, xend->subleaf,
regs[0], regs[1], regs[2], regs[3] };
rc = xc_set_domain_cpu_policy(xch, domid, 1, leaves, 0, NULL,
&err_leaf, &err_subleaf, &err_msr);
void libxl_bitmap_init(libxl_bitmap *map);
void libxl_bitmap_dispose(libxl_bitmap *map);
-/* libxl_cpuid_policy_list is a dynamic array storing CPUID policies
- * for multiple leafs. It is terminated with an entry holding
- * XEN_CPUID_INPUT_UNUSED in input[0]
+/*
+ * libxl_cpuid_policy is opaque in the libxl ABI. Users of both libxl and
+ * libxc may not make assumptions about xc_xend_cpuid.
*/
-typedef struct libxl__cpuid_policy libxl_cpuid_policy;
+typedef struct xc_xend_cpuid libxl_cpuid_policy;
typedef libxl_cpuid_policy * libxl_cpuid_policy_list;
void libxl_cpuid_dispose(libxl_cpuid_policy_list *cpuid_list);
int libxl_cpuid_policy_list_length(const libxl_cpuid_policy_list *l);
char *sep, *val, *endptr;
int i;
const struct cpuid_flags *flag;
- struct libxl__cpuid_policy *entry;
+ struct xc_xend_cpuid *entry;
unsigned long num;
char flags[33], *resstr;
char *endptr;
unsigned long value;
uint32_t leaf, subleaf = XEN_CPUID_INPUT_UNUSED;
- struct libxl__cpuid_policy *entry;
+ struct xc_xend_cpuid *entry;
/* parse the leaf number */
value = strtoul(str, &endptr, 0);
return;
for (i = 0; cpuid[i].input[0] != XEN_CPUID_INPUT_UNUSED; i++)
- xc_cpuid_set(ctx->xch, domid, cpuid[i].input,
- (const char**)cpuid[i].policy);
+ xc_cpuid_set(ctx->xch, domid, &cpuid[i]);
}
static const char *input_names[2] = { "leaf", "subleaf" };
_hidden char *libxl__object_to_json(libxl_ctx *ctx, const char *type,
libxl__gen_json_callback gen, void *p);
- /* holds the CPUID response for a single CPUID leaf
- * input contains the value of the EAX and ECX register,
- * and each policy string contains a filter to apply to
- * the host given values for that particular leaf.
- */
-struct libxl__cpuid_policy {
- uint32_t input[2];
- char *policy[4];
-};
-
_hidden void libxl__cpuid_legacy(libxl_ctx *ctx, uint32_t domid,
libxl_domain_build_info *info);