WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 2/2] xl: add cpuid parsing and translation

To: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>, Keir Fraser <keir.fraser@xxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 2/2] xl: add cpuid parsing and translation
From: Andre Przywara <andre.przywara@xxxxxxx>
Date: Fri, 27 Aug 2010 14:57:54 +0200
Cc: xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
Delivery-date: Fri, 27 Aug 2010 06:05:38 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Thunderbird 2.0.0.23 (X11/20090820)
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@xxxxxxx>

--
Andre Przywara
AMD-Operating System Research Center (OSRC), Dresden, Germany
Tel: +49 351 448-3567-12
>From 042a22523e7ea68019e0a5733139671435d50ccf Mon Sep 17 00:00:00 2001
From: Andre Przywara <andre.przywara@xxxxxxx>
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@xxxxxxx>
---
 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

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH 2/2] xl: add cpuid parsing and translation, Andre Przywara <=