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-changelog

[Xen-changelog] [xen-unstable] xl: implement parsing of cpuid parameter

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] xl: implement parsing of cpuid parameter and translate to Xen interface
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sat, 09 Oct 2010 14:56:18 -0700
Delivery-date: Sat, 09 Oct 2010 15:08:02 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Andre Przywara <andre.przywara@xxxxxxx>
# Date 1285950041 -3600
# Node ID 27c01a2e2a470f4650890d654d7fe052b6e2777c
# Parent  b89fa6d3f7540b52c57827c8036d5737f3eb0f3d
xl: implement parsing of cpuid parameter and translate to Xen interface

Parses a string enumerating cpuid flags and their behavior.
The syntax is: cpuid = "host,<flagname>=[01xks],..."
Supports:
0: clear this flag
1: set this flag
x: don't care, use the default handling
k: use the host value
s: as k, but keep stable across migrations

For multiple bit flags there have to be numbers passed (hex or dec),
like: family=0x10,model=4

Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx>
Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
committer: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
---
 tools/libxl/libxl.c      |  219 +++++++++++++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl.h      |    1 
 tools/libxl/xl_cmdimpl.c |   11 ++
 3 files changed, 231 insertions(+)

diff -r b89fa6d3f754 -r 27c01a2e2a47 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c       Fri Oct 01 15:42:46 2010 +0100
+++ b/tools/libxl/libxl.c       Fri Oct 01 17:20:41 2010 +0100
@@ -3524,6 +3524,225 @@ uint32_t libxl_vm_get_start_time(libxl_c
     return ret;
 }
 
+#define CPUID_REG_INV 0
+#define CPUID_REG_EAX 1
+#define CPUID_REG_EBX 2
+#define CPUID_REG_ECX 3
+#define CPUID_REG_EDX 4
+
+/* mapping CPUID features to names
+ * holds a "name" for each feature, specified by the "leaf" number (and an
+ * optional "subleaf" in ECX), the "reg"ister (EAX-EDX) used and a number of
+ * bits starting with "bit" and being "length" bits long.
+ * Used for the static structure describing all features.
+ */
+struct cpuid_flags {
+    char* name;
+    uint32_t leaf;
+    uint32_t subleaf;
+    int reg;
+    int bit;
+    int length;
+};
+
+/* go through the dynamic array finding the entry for a specified leaf.
+ * if no entry exists, allocate one and return that.
+ */
+static libxl_cpuid_policy_list cpuid_find_match(libxl_cpuid_policy_list *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((*list)[0]) * (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;
+}
+
+/* parse a single key=value pair and translate it into the libxc
+ * used interface using 32-characters strings for each register.
+ * Will overwrite earlier entries and thus can be called multiple
+ * times.
+ */
+int libxl_cpuid_parse_config(libxl_cpuid_policy_list *cpuid, const char* str)
+{
+#define NA XEN_CPUID_INPUT_UNUSED
+    struct cpuid_flags cpuid_flags[] = {
+        {"maxleaf",      0x00000000, NA, CPUID_REG_EAX,  0, 32},
+      /* the following two entries are subject to tweaking later in the code */
+        {"family",       0x00000001, NA, CPUID_REG_EAX,  8,  8},
+        {"model",        0x00000001, NA, CPUID_REG_EAX,  4,  8},
+        {"stepping",     0x00000001, NA, CPUID_REG_EAX,  0,  4},
+        {"localapicid",  0x00000001, NA, CPUID_REG_EBX, 24,  8},
+        {"proccount",    0x00000001, NA, CPUID_REG_EBX, 16,  8},
+        {"clflush",      0x00000001, NA, CPUID_REG_EBX,  8,  8},
+        {"brandid",      0x00000001, NA, CPUID_REG_EBX,  0,  8},
+        {"f16c",         0x00000001, NA, CPUID_REG_ECX, 29,  1},
+        {"avx",          0x00000001, NA, CPUID_REG_ECX, 28,  1},
+        {"osxsave",      0x00000001, NA, CPUID_REG_ECX, 27,  1},
+        {"xsave",        0x00000001, NA, CPUID_REG_ECX, 26,  1},
+        {"aes",          0x00000001, NA, CPUID_REG_ECX, 25,  1},
+        {"popcnt",       0x00000001, NA, CPUID_REG_ECX, 23,  1},
+        {"movbe",        0x00000001, NA, CPUID_REG_ECX, 22,  1},
+        {"x2apic",       0x00000001, NA, CPUID_REG_ECX, 21,  1},
+        {"sse4.2",       0x00000001, NA, CPUID_REG_ECX, 20,  1},
+        {"sse4.1",       0x00000001, NA, CPUID_REG_ECX, 19,  1},
+        {"dca",          0x00000001, NA, CPUID_REG_ECX, 18,  1},
+        {"pdcm",         0x00000001, NA, CPUID_REG_ECX, 15,  1},
+        {"xtpr",         0x00000001, NA, CPUID_REG_ECX, 14,  1},
+        {"cmpxchg16",    0x00000001, NA, CPUID_REG_ECX, 13,  1},
+        {"cntxid",       0x00000001, NA, CPUID_REG_ECX, 10,  1},
+        {"ssse3",        0x00000001, NA, CPUID_REG_ECX,  9,  1},
+        {"tm2",          0x00000001, NA, CPUID_REG_ECX,  8,  1},
+        {"est",          0x00000001, NA, CPUID_REG_ECX,  7,  1},
+        {"smx",          0x00000001, NA, CPUID_REG_ECX,  6,  1},
+        {"vmx",          0x00000001, NA, CPUID_REG_ECX,  5,  1},
+        {"dscpl",        0x00000001, NA, CPUID_REG_ECX,  4,  1},
+        {"monitor",      0x00000001, NA, CPUID_REG_ECX,  3,  1},
+        {"dtes64",       0x00000001, NA, CPUID_REG_ECX,  2,  1},
+        {"sse3",         0x00000001, NA, CPUID_REG_ECX,  0,  1},
+        {"pbe",          0x00000001, NA, CPUID_REG_EDX, 31,  1},
+        {"ia64",         0x00000001, NA, CPUID_REG_EDX, 30,  1},
+        {"tm",           0x00000001, NA, CPUID_REG_EDX, 29,  1},
+        {"htt",          0x00000001, NA, CPUID_REG_EDX, 28,  1},
+        {"ss",           0x00000001, NA, CPUID_REG_EDX, 27,  1},
+        {"sse2",         0x00000001, NA, CPUID_REG_EDX, 26,  1},
+        {"sse",          0x00000001, NA, CPUID_REG_EDX, 25,  1},
+        {"fxsr",         0x00000001, NA, CPUID_REG_EDX, 24,  1},
+        {"mmx",          0x00000001, NA, CPUID_REG_EDX, 23,  1},
+        {"acpi",         0x00000001, NA, CPUID_REG_EDX, 22,  1},
+        {"ds",           0x00000001, NA, CPUID_REG_EDX, 21,  1},
+        {"clfsh",        0x00000001, NA, CPUID_REG_EDX, 19,  1},
+        {"psn",          0x00000001, NA, CPUID_REG_EDX, 18,  1},
+        {"pse36",        0x00000001, NA, CPUID_REG_EDX, 17,  1},
+        {"pat",          0x00000001, NA, CPUID_REG_EDX, 16,  1},
+        {"cmov",         0x00000001, NA, CPUID_REG_EDX, 15,  1},
+        {"mca",          0x00000001, NA, CPUID_REG_EDX, 14,  1},
+        {"pge",          0x00000001, NA, CPUID_REG_EDX, 13,  1},
+        {"mtrr",         0x00000001, NA, CPUID_REG_EDX, 12,  1},
+        {"sysenter",     0x00000001, NA, CPUID_REG_EDX, 11,  1},
+        {"apic",         0x00000001, NA, CPUID_REG_EDX,  9,  1},
+        {"cmpxchg8",     0x00000001, NA, CPUID_REG_EDX,  8,  1},
+        {"mce",          0x00000001, NA, CPUID_REG_EDX,  7,  1},
+        {"pae",          0x00000001, NA, CPUID_REG_EDX,  6,  1},
+        {"msr",          0x00000001, NA, CPUID_REG_EDX,  5,  1},
+        {"tsc",          0x00000001, NA, CPUID_REG_EDX,  4,  1},
+        {"pse",          0x00000001, NA, CPUID_REG_EDX,  3,  1},
+        {"de",           0x00000001, NA, CPUID_REG_EDX,  2,  1},
+        {"vme",          0x00000001, NA, CPUID_REG_EDX,  1,  1},
+        {"fpu",          0x00000001, NA, CPUID_REG_EDX,  0,  1},
+        {"topoext",      0x80000001, NA, CPUID_REG_ECX, 22,  1},
+        {"tbm",          0x80000001, NA, CPUID_REG_ECX, 21,  1},
+        {"nodeid",       0x80000001, NA, CPUID_REG_ECX, 19,  1},
+        {"fma4",         0x80000001, NA, CPUID_REG_ECX, 16,  1},
+        {"lwp",          0x80000001, NA, CPUID_REG_ECX, 15,  1},
+        {"wdt",          0x80000001, NA, CPUID_REG_ECX, 13,  1},
+        {"skinit",       0x80000001, NA, CPUID_REG_ECX, 12,  1},
+        {"xop",          0x80000001, NA, CPUID_REG_ECX, 11,  1},
+        {"ibs",          0x80000001, NA, CPUID_REG_ECX, 10,  1},
+        {"osvw",         0x80000001, NA, CPUID_REG_ECX, 10,  1},
+        {"3dnowprefetch",0x80000001, NA, CPUID_REG_ECX,  8,  1},
+        {"misalignsse",  0x80000001, NA, CPUID_REG_ECX,  7,  1},
+        {"sse4a",        0x80000001, NA, CPUID_REG_ECX,  6,  1},
+        {"abm",          0x80000001, NA, CPUID_REG_ECX,  5,  1},
+        {"altmovcr8",    0x80000001, NA, CPUID_REG_ECX,  4,  1},
+        {"extapic",      0x80000001, NA, CPUID_REG_ECX,  3,  1},
+        {"svm",          0x80000001, NA, CPUID_REG_ECX,  2,  1},
+        {"cmplegacy",    0x80000001, NA, CPUID_REG_ECX,  1,  1},
+        {"lahfsahf",     0x80000001, NA, CPUID_REG_ECX,  0,  1},
+        {"3dnow",        0x80000001, NA, CPUID_REG_EDX, 31,  1},
+        {"3dnowext",     0x80000001, NA, CPUID_REG_EDX, 30,  1},
+        {"lm",           0x80000001, NA, CPUID_REG_EDX, 29,  1},
+        {"rdtscp",       0x80000001, NA, CPUID_REG_EDX, 27,  1},
+        {"page1gb",      0x80000001, NA, CPUID_REG_EDX, 26,  1},
+        {"ffxsr",        0x80000001, NA, CPUID_REG_EDX, 25,  1},
+        {"mmxext",       0x80000001, NA, CPUID_REG_EDX, 22,  1},
+        {"nx",           0x80000001, NA, CPUID_REG_EDX, 20,  1},
+        {"syscall",      0x80000001, NA, CPUID_REG_EDX, 11,  1},
+        {"procpkg",      0x00000004,  0, CPUID_REG_EAX, 26,  6},
+        {"apicidsize",   0x80000008, NA, CPUID_REG_ECX, 12,  4},
+        {"nc",           0x80000008, NA, CPUID_REG_ECX,  0,  8},
+
+        {NULL, 0, CPUID_REG_INV, 0, 0}
+    };
+#undef NA
+    char *sep, *val, *endptr;
+    int i;
+    struct cpuid_flags *flag;
+    struct libxl__cpuid_policy *entry;
+    unsigned long num;
+    char flags[33], *resstr;
+
+    sep = strchr(str, '=');
+    if (sep == NULL) {
+        return 1;
+    } else {
+        val = sep + 1;
+    }
+    for (flag = cpuid_flags; flag->name != NULL; flag++) {
+        if(!strncmp(str, flag->name, sep - str) && flag->name[sep - str] == 0)
+            break;
+    }
+    if (flag->name == NULL) {
+        return 2;
+    }
+    entry = cpuid_find_match(cpuid, flag->leaf, flag->subleaf);
+    resstr = entry->policy[flag->reg - 1];
+    if (resstr == NULL) {
+        resstr = strdup("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
+    }
+    num = strtoull(val, &endptr, 0);
+    flags[flag->length] = 0;
+    if (endptr != val) {
+        /* is this was a valid number, write the binary form into the string */
+        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:
+            return 3;
+        }
+    }
+    /* the family and model entry is potentially split up across
+     * two fields in Fn0000_0001_EAX, so handle them here separately.
+     */
+    if (!strncmp(str, "family", sep - str)) {
+        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 (!strncmp(str, "model", sep - str)) {
+        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;
+
+    return 0;
+}
+
 char *libxl_tmem_list(libxl_ctx *ctx, uint32_t domid, int use_long)
 {
     int rc;
diff -r b89fa6d3f754 -r 27c01a2e2a47 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h       Fri Oct 01 15:42:46 2010 +0100
+++ b/tools/libxl/libxl.h       Fri Oct 01 17:20:41 2010 +0100
@@ -411,6 +411,7 @@ int libxl_device_pci_list_assigned(libxl
 int libxl_device_pci_list_assigned(libxl_ctx *ctx, libxl_device_pci **list, 
uint32_t domid, int *num);
 int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, 
int *num);
 int libxl_device_pci_parse_bdf(libxl_ctx *ctx, libxl_device_pci *pcidev, const 
char *str);
+int libxl_cpuid_parse_config(libxl_cpuid_policy_list *cpuid, const char* str);
 
 /*
  * Functions for allowing users of libxl to store private data
diff -r b89fa6d3f754 -r 27c01a2e2a47 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c  Fri Oct 01 15:42:46 2010 +0100
+++ b/tools/libxl/xl_cmdimpl.c  Fri Oct 01 17:20:41 2010 +0100
@@ -1085,6 +1085,17 @@ skip_vfb:
         }
     }
 
+    if (!xlu_cfg_get_string(config, "cpuid", &buf)) {
+        char *buf2, *p, *strtok_ptr;
+
+        buf2 = strdup(buf);
+        p = strtok_r(buf2, ",", &strtok_ptr);
+        for (p = strtok_r(NULL, ",", &strtok_ptr); p != NULL;
+             p = strtok_r(NULL, ",", &strtok_ptr))
+            libxl_cpuid_parse_config(&b_info->cpuid, p);
+        free(buf2);
+    }
+
     if (c_info->hvm == 1) {
         /* init dm from c and b */
         init_dm_info(dm_info, c_info, b_info);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] xl: implement parsing of cpuid parameter and translate to Xen interface, Xen patchbot-unstable <=