All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andre Przywara <andre.przywara@amd.com>
To: Stefano Stabellini <stefano.stabellini@eu.citrix.com>,
	Ian Campbell <Ian.Campbell@citrix.com>
Cc: xen-devel <xen-devel@lists.xensource.com>,
	Keir Fraser <keir.fraser@eu.citrix.com>
Subject: [PATCH 3/5] xl: implement parsing of cpuid parameter and translate to Xen interface
Date: Thu, 16 Sep 2010 15:08:27 +0200	[thread overview]
Message-ID: <4C9216CB.6070506@amd.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 521 bytes --]

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

Instead of the bits there can also be numbers passed (hex or dec),
like: family=0x10,model=4

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: 0003-xl-implement-parsing-of-cpuid-parameter-and-translat.patch --]
[-- Type: text/x-patch, Size: 12229 bytes --]

>From 5781070f32f6438b17a926fcf935ecde727dd92d 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 3/5] xl: implement parsing of cpuid parameter and translate to Xen interface

parses a string enumerating cpuid flags and their behavior. 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

The syntax is: cpuid = "host,<flagname>=[01xks],..."
Instead of the bits there can also be numbers passed (hex or dec),
like: family=0x10,model=4

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 tools/libxl/libxl.c      |  219 ++++++++++++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl.h      |    1 +
 tools/libxl/xl_cmdimpl.c |   11 +++
 3 files changed, 231 insertions(+), 0 deletions(-)

diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index fafb1a6..8005512 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -3228,6 +3228,225 @@ uint32_t libxl_vm_get_start_time(libxl_ctx *ctx, uint32_t domid)
     return ret;
 }
 
+#define REG_INV 0
+#define REG_EAX 1
+#define REG_EBX 2
+#define REG_ECX 3
+#define 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, REG_EAX,  0, 32},
+      /* the following two entries are subject to tweaking later in the code */
+        {"family",       0x00000001, NA, REG_EAX,  8,  8},
+        {"model",        0x00000001, NA, REG_EAX,  4,  8},
+        {"stepping",     0x00000001, NA, REG_EAX,  0,  4},
+        {"localapicid",  0x00000001, NA, REG_EBX, 24,  8},
+        {"proccount",    0x00000001, NA, REG_EBX, 16,  8},
+        {"clflush",      0x00000001, NA, REG_EBX,  8,  8},
+        {"brandid",      0x00000001, NA, REG_EBX,  0,  8},
+        {"f16c",         0x00000001, NA, REG_ECX, 29,  1},
+        {"avx",          0x00000001, NA, REG_ECX, 28,  1},
+        {"osxsave",      0x00000001, NA, REG_ECX, 27,  1},
+        {"xsave",        0x00000001, NA, REG_ECX, 26,  1},
+        {"aes",          0x00000001, NA, REG_ECX, 25,  1},
+        {"popcnt",       0x00000001, NA, REG_ECX, 23,  1},
+        {"movbe",        0x00000001, NA, REG_ECX, 22,  1},
+        {"x2apic",       0x00000001, NA, REG_ECX, 21,  1},
+        {"sse4.2",       0x00000001, NA, REG_ECX, 20,  1},
+        {"sse4.1",       0x00000001, NA, REG_ECX, 19,  1},
+        {"dca",          0x00000001, NA, REG_ECX, 18,  1},
+        {"pdcm",         0x00000001, NA, REG_ECX, 15,  1},
+        {"xtpr",         0x00000001, NA, REG_ECX, 14,  1},
+        {"cmpxchg16",    0x00000001, NA, REG_ECX, 13,  1},
+        {"cntxid",       0x00000001, NA, REG_ECX, 10,  1},
+        {"ssse3",        0x00000001, NA, REG_ECX,  9,  1},
+        {"tm2",          0x00000001, NA, REG_ECX,  8,  1},
+        {"est",          0x00000001, NA, REG_ECX,  7,  1},
+        {"smx",          0x00000001, NA, REG_ECX,  6,  1},
+        {"vmx",          0x00000001, NA, REG_ECX,  5,  1},
+        {"dscpl",        0x00000001, NA, REG_ECX,  4,  1},
+        {"monitor",      0x00000001, NA, REG_ECX,  3,  1},
+        {"dtes64",       0x00000001, NA, REG_ECX,  2,  1},
+        {"sse3",         0x00000001, NA, REG_ECX,  0,  1},
+        {"pbe",          0x00000001, NA, REG_EDX, 31,  1},
+        {"ia64",         0x00000001, NA, REG_EDX, 30,  1},
+        {"tm",           0x00000001, NA, REG_EDX, 29,  1},
+        {"htt",          0x00000001, NA, REG_EDX, 28,  1},
+        {"ss",           0x00000001, NA, REG_EDX, 27,  1},
+        {"sse2",         0x00000001, NA, REG_EDX, 26,  1},
+        {"sse",          0x00000001, NA, REG_EDX, 25,  1},
+        {"fxsr",         0x00000001, NA, REG_EDX, 24,  1},
+        {"mmx",          0x00000001, NA, REG_EDX, 23,  1},
+        {"acpi",         0x00000001, NA, REG_EDX, 22,  1},
+        {"ds",           0x00000001, NA, REG_EDX, 21,  1},
+        {"clfsh",        0x00000001, NA, REG_EDX, 19,  1},
+        {"psn",          0x00000001, NA, REG_EDX, 18,  1},
+        {"pse36",        0x00000001, NA, REG_EDX, 17,  1},
+        {"pat",          0x00000001, NA, REG_EDX, 16,  1},
+        {"cmov",         0x00000001, NA, REG_EDX, 15,  1},
+        {"mca",          0x00000001, NA, REG_EDX, 14,  1},
+        {"pge",          0x00000001, NA, REG_EDX, 13,  1},
+        {"mtrr",         0x00000001, NA, REG_EDX, 12,  1},
+        {"sysenter",     0x00000001, NA, REG_EDX, 11,  1},
+        {"apic",         0x00000001, NA, REG_EDX,  9,  1},
+        {"cmpxchg8",     0x00000001, NA, REG_EDX,  8,  1},
+        {"mce",          0x00000001, NA, REG_EDX,  7,  1},
+        {"pae",          0x00000001, NA, REG_EDX,  6,  1},
+        {"msr",          0x00000001, NA, REG_EDX,  5,  1},
+        {"tsc",          0x00000001, NA, REG_EDX,  4,  1},
+        {"pse",          0x00000001, NA, REG_EDX,  3,  1},
+        {"de",           0x00000001, NA, REG_EDX,  2,  1},
+        {"vme",          0x00000001, NA, REG_EDX,  1,  1},
+        {"fpu",          0x00000001, NA, REG_EDX,  0,  1},
+        {"topoext",      0x80000001, NA, REG_ECX, 22,  1},
+        {"tbm",          0x80000001, NA, REG_ECX, 21,  1},
+        {"nodeid",       0x80000001, NA, REG_ECX, 19,  1},
+        {"fma4",         0x80000001, NA, REG_ECX, 16,  1},
+        {"lwp",          0x80000001, NA, REG_ECX, 15,  1},
+        {"wdt",          0x80000001, NA, REG_ECX, 13,  1},
+        {"skinit",       0x80000001, NA, REG_ECX, 12,  1},
+        {"xop",          0x80000001, NA, REG_ECX, 11,  1},
+        {"ibs",          0x80000001, NA, REG_ECX, 10,  1},
+        {"osvw",         0x80000001, NA, REG_ECX, 10,  1},
+        {"3dnowprefetch",0x80000001, NA, REG_ECX,  8,  1},
+        {"misalignsse",  0x80000001, NA, REG_ECX,  7,  1},
+        {"sse4a",        0x80000001, NA, REG_ECX,  6,  1},
+        {"abm",          0x80000001, NA, REG_ECX,  5,  1},
+        {"altmovcr8",    0x80000001, NA, REG_ECX,  4,  1},
+        {"extapic",      0x80000001, NA, REG_ECX,  3,  1},
+        {"svm",          0x80000001, NA, REG_ECX,  2,  1},
+        {"cmplegacy",    0x80000001, NA, REG_ECX,  1,  1},
+        {"lahfsahf",     0x80000001, NA, REG_ECX,  0,  1},
+        {"3dnow",        0x80000001, NA, REG_EDX, 31,  1},
+        {"3dnowext",     0x80000001, NA, REG_EDX, 30,  1},
+        {"lm",           0x80000001, NA, REG_EDX, 29,  1},
+        {"rdtscp",       0x80000001, NA, REG_EDX, 27,  1},
+        {"page1gb",      0x80000001, NA, REG_EDX, 26,  1},
+        {"ffxsr",        0x80000001, NA, REG_EDX, 25,  1},
+        {"mmxext",       0x80000001, NA, REG_EDX, 22,  1},
+        {"nx",           0x80000001, NA, REG_EDX, 20,  1},
+        {"syscall",      0x80000001, NA, REG_EDX, 11,  1},
+        {"procpkg",      0x00000004,  0, REG_EAX, 26,  6},
+        {"apicidsize",   0x80000008, NA, REG_ECX, 12,  4},
+        {"nc",           0x80000008, NA, REG_ECX,  0,  8},
+
+        {NULL, 0, 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 --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 728baf2..60e4d71 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -392,6 +392,7 @@ int libxl_device_pci_shutdown(libxl_ctx *ctx, uint32_t domid);
 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 --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 9d73ac7..646f162 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1012,6 +1012,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);
-- 
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

             reply	other threads:[~2010-09-16 13:08 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-16 13:08 Andre Przywara [this message]
2010-09-16 15:38 ` [PATCH 3/5] xl: implement parsing of cpuid parameter and translate to Xen interface Ian Campbell
2010-09-16 18:49   ` Andre Przywara
  -- strict thread matches above, loose matches on Subject: below --
2010-09-08  9:21 Andre Przywara

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4C9216CB.6070506@amd.com \
    --to=andre.przywara@amd.com \
    --cc=Ian.Campbell@citrix.com \
    --cc=keir.fraser@eu.citrix.com \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.