|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v3 3/6] libxl: introduce MSR data in libxl_cpuid_policy
Add a new array field to libxl_cpuid_policy in order to store the MSR
policies.
Adding the MSR data in the libxl_cpuid_policy_list type is done so
that existing users can seamlessly pass MSR features as part of the
CPUID data, without requiring the introduction of a separate
domain_build_info field, and a new set of handlers functions.
Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
Changes since v2:
- Unconditionally call free().
- Implement the JSON marshaling functions.
---
It would be nice to rename the json output field to 'cpu_policy'
instead of 'cpuid', so that it looks like:
"cpu_policy": {
"cpuid": [
{
"leaf": 7,
"subleaf": 0,
"edx": "xx1xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
{
"leaf": 1,
"ebx": "xxxxxxxxxxxxxxxx00010000xxxxxxxx"
}
}
}
],
"msr": [
{
"index": 266,
"policy":
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1xx1x1"
}
]
},
Sadly I have no idea how to do that, and can be done in a followup
change anyway.
---
tools/libs/light/libxl_cpuid.c | 142 ++++++++++++++++++++++++++----
tools/libs/light/libxl_internal.h | 1 +
tools/libs/light/libxl_types.idl | 2 +-
3 files changed, 128 insertions(+), 17 deletions(-)
diff --git a/tools/libs/light/libxl_cpuid.c b/tools/libs/light/libxl_cpuid.c
index 3c8b2a72c0b8..68b797886642 100644
--- a/tools/libs/light/libxl_cpuid.c
+++ b/tools/libs/light/libxl_cpuid.c
@@ -16,7 +16,7 @@
int libxl__cpuid_policy_is_empty(libxl_cpuid_policy_list *pl)
{
- return !libxl_cpuid_policy_list_length(pl);
+ return !*pl || (!libxl_cpuid_policy_list_length(pl) && !(*pl)->msr);
}
void libxl_cpuid_dispose(libxl_cpuid_policy_list *pl)
@@ -40,6 +40,8 @@ void libxl_cpuid_dispose(libxl_cpuid_policy_list *pl)
free(policy->cpuid);
}
+ free(policy->msr);
+
free(policy);
*pl = NULL;
return;
@@ -516,7 +518,8 @@ int libxl__cpuid_legacy(libxl_ctx *ctx, uint32_t domid,
bool restore,
r = xc_cpuid_apply_policy(ctx->xch, domid, restore, NULL, 0,
pae, itsc, nested_virt,
- info->cpuid ? info->cpuid->cpuid : NULL, NULL);
+ info->cpuid ? info->cpuid->cpuid : NULL,
+ info->cpuid ? info->cpuid->msr : NULL);
if (r)
LOGEVD(ERROR, -r, domid, "Failed to apply CPUID policy");
@@ -528,16 +531,22 @@ static const char *input_names[2] = { "leaf", "subleaf" };
static const char *policy_names[4] = { "eax", "ebx", "ecx", "edx" };
/*
* Aiming for:
- * [
- * { 'leaf': 'val-eax',
- * 'subleaf': 'val-ecx',
- * 'eax': 'filter',
- * 'ebx': 'filter',
- * 'ecx': 'filter',
- * 'edx': 'filter' },
- * { 'leaf': 'val-eax', ..., 'eax': 'filter', ... },
- * ... etc ...
- * ]
+ * { 'cpuid': [
+ * { 'leaf': 'val-eax',
+ * 'subleaf': 'val-ecx',
+ * 'eax': 'filter',
+ * 'ebx': 'filter',
+ * 'ecx': 'filter',
+ * 'edx': 'filter' },
+ * { 'leaf': 'val-eax', ..., 'eax': 'filter', ... },
+ * ... etc ...
+ * ],
+ * 'msr': [
+ * { 'index': 'val-index',
+ * 'policy': 'filter', },
+ * ... etc ...
+ * ],
+ * }
*/
yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen hand,
@@ -545,9 +554,16 @@ yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen
hand,
{
libxl_cpuid_policy_list policy = *pl;
struct xc_xend_cpuid *cpuid;
+ struct xc_msr *msr;
yajl_gen_status s;
int i, j;
+ s = yajl_gen_map_open(hand);
+ if (s != yajl_gen_status_ok) goto out;
+
+ s = libxl__yajl_gen_asciiz(hand, "cpuid");
+ if (s != yajl_gen_status_ok) goto out;
+
s = yajl_gen_array_open(hand);
if (s != yajl_gen_status_ok) goto out;
@@ -582,6 +598,39 @@ yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen
hand,
empty:
s = yajl_gen_array_close(hand);
+ if (s != yajl_gen_status_ok) goto out;
+
+ s = libxl__yajl_gen_asciiz(hand, "msr");
+ if (s != yajl_gen_status_ok) goto out;
+
+ s = yajl_gen_array_open(hand);
+ if (s != yajl_gen_status_ok) goto out;
+
+ if (!policy || !policy->msr) goto done;
+ msr = policy->msr;
+
+ for (i = 0; msr[i].index != XC_MSR_INPUT_UNUSED; i++) {
+ s = yajl_gen_map_open(hand);
+ if (s != yajl_gen_status_ok) goto out;
+
+ s = libxl__yajl_gen_asciiz(hand, "index");
+ if (s != yajl_gen_status_ok) goto out;
+ s = yajl_gen_integer(hand, msr[i].index);
+ if (s != yajl_gen_status_ok) goto out;
+ s = libxl__yajl_gen_asciiz(hand, "policy");
+ if (s != yajl_gen_status_ok) goto out;
+ s = yajl_gen_string(hand,
+ (const unsigned char *)msr[i].policy, 64);
+ if (s != yajl_gen_status_ok) goto out;
+
+ s = yajl_gen_map_close(hand);
+ if (s != yajl_gen_status_ok) goto out;
+ }
+
+done:
+ s = yajl_gen_array_close(hand);
+ if (s != yajl_gen_status_ok) goto out;
+ s = yajl_gen_map_close(hand);
out:
return s;
}
@@ -592,17 +641,24 @@ int libxl__cpuid_policy_list_parse_json(libxl__gc *gc,
{
int i, size;
struct xc_xend_cpuid *l;
+ struct xc_msr *msr;
+ const libxl__json_object *co;
flexarray_t *array;
- if (!libxl__json_object_is_array(o))
+ if (!libxl__json_object_is_map(o))
return ERROR_FAIL;
- array = libxl__json_object_get_array(o);
+ co = libxl__json_map_get("cpuid", o, JSON_ARRAY);
+ if (!libxl__json_object_is_array(co))
+ return ERROR_FAIL;
+
+ *p = libxl__calloc(NOGC, 1, sizeof(**p));
+
+ array = libxl__json_object_get_array(co);
if (!array->count)
- return 0;
+ goto cpuid_empty;
size = array->count;
- *p = libxl__calloc(NOGC, 1, sizeof(**p));
/* need one extra slot as sentinel */
l = (*p)->cpuid = libxl__calloc(NOGC, size + 1,
sizeof(struct xc_xend_cpuid));
@@ -642,6 +698,40 @@ int libxl__cpuid_policy_list_parse_json(libxl__gc *gc,
}
}
+cpuid_empty:
+ co = libxl__json_map_get("msr", o, JSON_ARRAY);
+ if (!libxl__json_object_is_array(co))
+ return ERROR_FAIL;
+
+ array = libxl__json_object_get_array(co);
+ if (!array->count)
+ return 0;
+ size = array->count;
+ /* need one extra slot as sentinel */
+ msr = (*p)->msr = libxl__calloc(NOGC, size + 1, sizeof(struct xc_msr));
+
+ msr[size].index = XC_MSR_INPUT_UNUSED;
+
+ for (i = 0; i < size; i++) {
+ const libxl__json_object *t, *r;
+
+ if (flexarray_get(array, i, (void**)&t) != 0)
+ return ERROR_FAIL;
+
+ if (!libxl__json_object_is_map(t))
+ return ERROR_FAIL;
+
+ r = libxl__json_map_get("index", t, JSON_INTEGER);
+ if (!r) return ERROR_FAIL;
+ msr[i].index = libxl__json_object_get_integer(r);
+ r = libxl__json_map_get("policy", t, JSON_STRING);
+ if (!r) return ERROR_FAIL;
+ if (strlen(libxl__json_object_get_string(r)) !=
+ ARRAY_SIZE(msr[i].policy) - 1)
+ return ERROR_FAIL;
+ strcpy(msr[i].policy, libxl__json_object_get_string(r));
+ }
+
return 0;
}
@@ -677,6 +767,10 @@ void libxl_cpuid_policy_list_copy(libxl_ctx *ctx,
}
*pdst = libxl__calloc(NOGC, 1, sizeof(**pdst));
+
+ if (!(*psrc)->cpuid)
+ goto copy_msr;
+
dst = &(*pdst)->cpuid;
src = &(*psrc)->cpuid;
len = libxl_cpuid_policy_list_length(psrc);
@@ -696,6 +790,22 @@ void libxl_cpuid_policy_list_copy(libxl_ctx *ctx,
(*dst)[i].policy[j] = NULL;
}
+copy_msr:
+ if ((*psrc)->msr) {
+ const struct xc_msr *msr = (*psrc)->msr;
+
+ for (i = 0; msr[i].index != XC_MSR_INPUT_UNUSED; i++)
+ ;
+ len = i;
+ (*pdst)->msr = libxl__calloc(NOGC, len + 1, sizeof(struct xc_msr));
+ (*pdst)->msr[len].index = XC_MSR_INPUT_UNUSED;
+
+ for (i = 0; i < len; i++) {
+ (*pdst)->msr[i].index = msr[i].index;
+ strcpy((*pdst)->msr[i].policy, msr[i].policy);
+ }
+ }
+
out:
GC_FREE;
}
diff --git a/tools/libs/light/libxl_internal.h
b/tools/libs/light/libxl_internal.h
index ef882cff3912..b1a7cd9f615b 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -4871,6 +4871,7 @@ _hidden int libxl__domain_set_paging_mempool_size(
struct libxl__cpu_policy {
struct xc_xend_cpuid *cpuid;
+ struct xc_msr *msr;
};
#endif
diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
index 9e48bb772646..887824fdd828 100644
--- a/tools/libs/light/libxl_types.idl
+++ b/tools/libs/light/libxl_types.idl
@@ -19,7 +19,7 @@ libxl_mac = Builtin("mac", json_parse_type="JSON_STRING",
passby=PASS_BY_REFEREN
libxl_bitmap = Builtin("bitmap", json_parse_type="JSON_ARRAY",
dispose_fn="libxl_bitmap_dispose", passby=PASS_BY_REFERENCE,
check_default_fn="libxl_bitmap_is_empty",
copy_fn="libxl_bitmap_copy_alloc")
libxl_cpuid_policy_list = Builtin("cpuid_policy_list",
dispose_fn="libxl_cpuid_dispose", passby=PASS_BY_REFERENCE,
- json_parse_type="JSON_ARRAY",
check_default_fn="libxl__cpuid_policy_is_empty",
+ json_parse_type="JSON_MAP",
check_default_fn="libxl__cpuid_policy_is_empty",
copy_fn="libxl_cpuid_policy_list_copy")
libxl_string_list = Builtin("string_list",
dispose_fn="libxl_string_list_dispose", passby=PASS_BY_REFERENCE,
--
2.41.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |