* [PATCH 2/2] xl: add cpuid parsing and translation
@ 2010-08-27 12:57 Andre Przywara
0 siblings, 0 replies; only message in thread
From: Andre Przywara @ 2010-08-27 12:57 UTC (permalink / raw)
To: Stefano Stabellini, Keir Fraser; +Cc: xen-devel
[-- Attachment #1: Type: text/plain, Size: 296 bytes --]
Hi,
this one actually parses the cpuid option string and translates it into
the 32-character string libxc expects.
Please comment!
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
--
Andre Przywara
AMD-Operating System Research Center (OSRC), Dresden, Germany
Tel: +49 351 448-3567-12
[-- Attachment #2: 0002-xl-implement-parsing-of-cpuid-parameter-and-translat.patch --]
[-- Type: text/x-patch, Size: 9936 bytes --]
>From 042a22523e7ea68019e0a5733139671435d50ccf Mon Sep 17 00:00:00 2001
From: Andre Przywara <andre.przywara@amd.com>
Date: Thu, 19 Aug 2010 11:51:00 +0200
Subject: [PATCH 2/2] xl: implement parsing of cpuid parameter and translate to Xen interface
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
tools/libxl/xl_cmdimpl.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 209 insertions(+), 0 deletions(-)
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 0fa516b..180d0c4 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -562,6 +562,212 @@ static int parse_action_on_shutdown(const char *buf, enum action_on_shutdown *a)
return 0;
}
+#define REG_INV 0
+#define REG_EAX 1
+#define REG_EBX 2
+#define REG_ECX 3
+#define REG_EDX 4
+
+struct cpuid_flags {
+ char* name;
+ uint32_t leaf;
+ int reg;
+ int bit;
+ int length;
+};
+
+static libxl_cpuid_type* cpuid_find_match(libxl_cpuid_type **list,
+ uint32_t leaf, uint32_t subleaf)
+{
+ int i = 0;
+
+ if (*list != NULL) {
+ for (i = 0; (*list)[i].input[0] != XEN_CPUID_INPUT_UNUSED; i++) {
+ if ((*list)[i].input[0] == leaf && (*list)[i].input[1] == subleaf)
+ return *list + i;
+ }
+ }
+ *list = realloc(*list, sizeof(libxl_cpuid_type) * (i + 2));
+ (*list)[i].input[0] = leaf;
+ (*list)[i].input[1] = subleaf;
+ memset((*list)[i].policy, 0, 4 * sizeof(char*));
+ (*list)[i + 1].input[0] = XEN_CPUID_INPUT_UNUSED;
+ return *list + i;
+}
+
+static libxl_cpuid_type* parse_cpuid(const char* cpuidstr)
+{
+ struct cpuid_flags cpuid_flags[] = {
+ {"maxleaf", 0x00000000, REG_EAX, 0, 32},
+ {"family", 0x00000001, REG_EAX, 8, 8}, /* subject to tweaking */
+ {"model", 0x00000001, REG_EAX, 4, 8}, /* subject to tweaking */
+ {"stepping", 0x00000001, REG_EAX, 0, 4},
+ {"localapicid", 0x00000001, REG_EBX, 24, 8},
+ {"proccount", 0x00000001, REG_EBX, 16, 8},
+ {"clflush", 0x00000001, REG_EBX, 8, 8},
+ {"brandid", 0x00000001, REG_EBX, 0, 8},
+ {"osxsave", 0x00000001, REG_ECX, 27, 1},
+ {"xsave", 0x00000001, REG_ECX, 26, 1},
+ {"popcnt", 0x00000001, REG_ECX, 23, 1},
+ {"movbe", 0x00000001, REG_ECX, 22, 1},
+ {"x2apic", 0x00000001, REG_ECX, 21, 1},
+ {"sse4.2", 0x00000001, REG_ECX, 20, 1},
+ {"sse4.1", 0x00000001, REG_ECX, 19, 1},
+ {"dca", 0x00000001, REG_ECX, 18, 1},
+ {"pdcm", 0x00000001, REG_ECX, 15, 1},
+ {"xtpr", 0x00000001, REG_ECX, 14, 1},
+ {"cmpxchg16", 0x00000001, REG_ECX, 13, 1},
+ {"cntxid", 0x00000001, REG_ECX, 10, 1},
+ {"ssse3", 0x00000001, REG_ECX, 9, 1},
+ {"tm2", 0x00000001, REG_ECX, 8, 1},
+ {"est", 0x00000001, REG_ECX, 7, 1},
+ {"smx", 0x00000001, REG_ECX, 6, 1},
+ {"vmx", 0x00000001, REG_ECX, 5, 1},
+ {"dscpl", 0x00000001, REG_ECX, 4, 1},
+ {"monitor", 0x00000001, REG_ECX, 3, 1},
+ {"dtes64", 0x00000001, REG_ECX, 2, 1},
+ {"sse3", 0x00000001, REG_ECX, 0, 1},
+ {"pbe", 0x00000001, REG_EDX, 31, 1},
+ {"ia64", 0x00000001, REG_EDX, 30, 1},
+ {"tm", 0x00000001, REG_EDX, 29, 1},
+ {"htt", 0x00000001, REG_EDX, 28, 1},
+ {"ss", 0x00000001, REG_EDX, 27, 1},
+ {"sse2", 0x00000001, REG_EDX, 26, 1},
+ {"sse", 0x00000001, REG_EDX, 25, 1},
+ {"fxsr", 0x00000001, REG_EDX, 24, 1},
+ {"mmx", 0x00000001, REG_EDX, 23, 1},
+ {"acpi", 0x00000001, REG_EDX, 22, 1},
+ {"ds", 0x00000001, REG_EDX, 21, 1},
+ {"clfsh", 0x00000001, REG_EDX, 19, 1},
+ {"psn", 0x00000001, REG_EDX, 18, 1},
+ {"pse36", 0x00000001, REG_EDX, 17, 1},
+ {"pat", 0x00000001, REG_EDX, 16, 1},
+ {"cmov", 0x00000001, REG_EDX, 15, 1},
+ {"mca", 0x00000001, REG_EDX, 14, 1},
+ {"pge", 0x00000001, REG_EDX, 13, 1},
+ {"mtrr", 0x00000001, REG_EDX, 12, 1},
+ {"sysenter", 0x00000001, REG_EDX, 11, 1},
+ {"apic", 0x00000001, REG_EDX, 9, 1},
+ {"cmpxchg8", 0x00000001, REG_EDX, 8, 1},
+ {"mce", 0x00000001, REG_EDX, 7, 1},
+ {"pae", 0x00000001, REG_EDX, 6, 1},
+ {"msr", 0x00000001, REG_EDX, 5, 1},
+ {"tsc", 0x00000001, REG_EDX, 4, 1},
+ {"pse", 0x00000001, REG_EDX, 3, 1},
+ {"de", 0x00000001, REG_EDX, 2, 1},
+ {"vme", 0x00000001, REG_EDX, 1, 1},
+ {"fpu", 0x00000001, REG_EDX, 0, 1},
+ {"wdt", 0x80000001, REG_ECX, 13, 1},
+ {"skinit", 0x80000001, REG_ECX, 12, 1},
+ {"xop", 0x80000001, REG_ECX, 11, 1},
+ {"ibs", 0x80000001, REG_ECX, 10, 1},
+ {"osvw", 0x80000001, REG_ECX, 10, 1},
+ {"3dnowprefetch",0x80000001, REG_ECX, 8, 1},
+ {"misalignsse", 0x80000001, REG_ECX, 7, 1},
+ {"sse4a", 0x80000001, REG_ECX, 6, 1},
+ {"abm", 0x80000001, REG_ECX, 5, 1},
+ {"altmovcr8", 0x80000001, REG_ECX, 4, 1},
+ {"extapic", 0x80000001, REG_ECX, 3, 1},
+ {"svm", 0x80000001, REG_ECX, 2, 1},
+ {"cmplegacy", 0x80000001, REG_ECX, 1, 1},
+ {"lahfsahf", 0x80000001, REG_ECX, 0, 1},
+ {"3dnowext", 0x80000001, REG_EDX, 31, 1},
+ {"3dnow", 0x80000001, REG_EDX, 30, 1},
+ {"lm", 0x80000001, REG_EDX, 29, 1},
+ {"rdtscp", 0x80000001, REG_EDX, 27, 1},
+ {"page1gb", 0x80000001, REG_EDX, 26, 1},
+ {"ffxsr", 0x80000001, REG_EDX, 25, 1},
+ {"mmxext", 0x80000001, REG_EDX, 22, 1},
+ {"nx", 0x80000001, REG_EDX, 20, 1},
+ {"syscall", 0x80000001, REG_EDX, 11, 1},
+ {"apicidsize", 0x80000008, REG_ECX, 12, 4},
+ {"nc", 0x80000008, REG_ECX, 0, 8},
+
+ {NULL, 0, 0, 0, 0}
+ };
+ char *buf, *strtok_ptr, *p, *val, *endptr;
+ int i;
+ struct cpuid_flags *flag;
+ libxl_cpuid_type *cpuid_info = NULL, *entry;
+ unsigned long num;
+ char flags[33], *resstr;
+
+ buf = strdup(cpuidstr);
+ p = strtok_r(buf, ",", &strtok_ptr);
+ /* base model is ignored for now */
+ for (; p; p = strtok_r(NULL, ",", &strtok_ptr)) {
+ val = strchr(p, '=');
+ /* detect leading + or - for en/disabling feature bits */
+ if (val == NULL) {
+ if (*p == '+') {
+ p++;
+ val = "1";
+ } else if (*p == '-') {
+ p++;
+ val = "0";
+ } else
+ continue;
+ } else {
+ *val++ = 0;
+ }
+ for (flag = cpuid_flags; flag->name != NULL; flag++)
+ if(!strcmp(p, flag->name))
+ break;
+ if (flag->name == NULL) {
+ fprintf(stderr, "cpuid: could not find feature called \"%s\"\n", p);
+ continue;
+ }
+ entry = cpuid_find_match(&cpuid_info, flag->leaf,
+ XEN_CPUID_INPUT_UNUSED);
+ resstr = entry->policy[flag->reg - 1];
+ if (resstr == NULL)
+ resstr = strdup("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
+ num = strtoull(val, &endptr, 0);
+ flags[flag->length] = 0;
+ if (endptr != val) {
+ for (i = 0; i < flag->length; i++)
+ flags[flag->length - 1 - i] = "01"[!!(num & (1 << i))];
+ } else {
+ switch(val[0]) {
+ case 'x': case 'k': case 's':
+ memset(flags, val[0], flag->length);
+ break;
+ default:
+ fprintf(stderr,
+ "invalid value \"%s\" for flag \"%s\"\n",
+ val, p);
+ continue;
+ }
+ }
+ /* the family and model entry is potentially split up across
+ * two fields in Fn0000_0001_EAX, so handle them here separately.
+ */
+ if (!strcmp(p, "family")) {
+ if (num < 16) {
+ memcpy(resstr + (32 - 4) - flag->bit, flags + 4, 4);
+ memcpy(resstr + (32 - 8) - 20, "00000000", 8);
+ } else {
+ num -= 15;
+ memcpy(resstr + (32 - 4) - flag->bit, "1111", 4);
+ for (i = 0; i < 7; i++) {
+ flags[7 - i] = "01"[num & 1];
+ num >>= 1;
+ }
+ memcpy(resstr + (32 - 8) - 20, flags, 8);
+ }
+ } else if (!strcmp(p, "model")) {
+ memcpy(resstr + (32 - 4) - 16, flags, 4);
+ memcpy(resstr + (32 - 4) - flag->bit, flags + 4, 4);
+ } else
+ memcpy(resstr + (32 - flag->length) - flag->bit, flags,
+ flag->length);
+ entry->policy[flag->reg - 1] = resstr;
+ }
+ free(buf);
+
+ return cpuid_info;
+}
+
static void parse_config_data(const char *configfile_filename_report,
const char *configfile_data,
int configfile_len,
@@ -1001,6 +1207,9 @@ skip_vfb:
}
}
+ if (!xlu_cfg_get_string(config, "cpuid", &buf))
+ b_info->cpuid = parse_cpuid(buf);
+
if (c_info->hvm == 1) {
/* init dm from c and b */
init_dm_info(dm_info, c_info, b_info);
--
1.6.4
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2010-08-27 12:57 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-27 12:57 [PATCH 2/2] xl: add cpuid parsing and translation Andre Przywara
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.