qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements
@ 2009-09-18 11:47 Andre Przywara
  2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 01/21] cpuid: move CPUID functions into separate file Andre Przywara
                   ` (21 more replies)
  0 siblings, 22 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:47 UTC (permalink / raw)
  To: qemu-devel

Hi,

an updated version of my last week's series.
Changes from v1 -> v2:
- fix build for non-i386 targets (thanks Anthony for spotting this)
- replace strtok() with QEMU's get_opt_name() (inspired by Amit Shah)
  (please see the notes below)
- fix multicore setup on Intel (thanks Dietmar Maurer for spotting this)
- removed unnecessary header file inclusions from cpuid.c
- fix and add various CPU models
- add kvm32 CPU model (for 32bit only migration)
- always expose all CPU models (regardless of the bitness)
----------------

The following patchset cleans up CPUID bit handling and adds some smaller
features.
The most prominent change is to move all CPUID related functions to a
separate file. About 40% of helper.c was actually CPUID related, so say
hello to cpuid.c. While at it, I fixed some formatting issues. (Patch 1-5)
Patch 6 replaces the awkward strtok() with the better get_opt_name().
  Please note: This renders the gotos useless. Shall they be removed?
  Second note: I pulled get_opt_name() from qemu-option.h into the file,
  because it did not work with linux-user due to a name clash:
  linux-user/mmap.c:qemu_malloc() and qemu-malloc.c:qemu_malloc()
  If anyone has a better solution, I am all ears.
Patch 7 & 8 add the CPUID feature flag names to the output of -cpu ?.
Patch 9 & 10 simplifies some code.
Patch 11 allows more CPUID leafs to be propagated to guests when -cpu host
is used, this should now reflect the host CPU's cache size.
Patch 12 fixes a bug with the multicore injection to the guest, where
the Linux kernel on Intel hosts would not recognize multiple cores.
Patch 13 adds a trimming feature (similar to KVM) to QEMU/TCG. The goal
is to describe CPU models more precisely by reflecting the feature bits of
the real hardware. Features that QEMU does not support are then masked.
If we add features to QEMU, we only need to adjust it in one location.
Patch 14 adjusts the size of the L2 cache described by leaf 4 to a more
conservative value of one megabyte. This prevents guests assuming too large
caches if they use optimized algorithms.
Patch 15-19 changes the CPU models to describe the actual CPUID bits
of the real silicon (checked with actual machines, x86info examples and
datasheets). Unsupported features will be masked.
Patch 20 adds a kvm32 CPU model, which is useful for migration.
Patch 21 finally exposes both the 32- and 64-bit CPU model also to QEMU32,
since the LM bit will be masked out.

Please review, comment and apply!
Thanks and Regards,
Andre.

--
Andre Przywara
AMD-Operating System Research Center (OSRC), Dresden, Germany
Tel: +49 351 448 3567 12
----to satisfy European Law for business letters:
Advanced Micro Devices GmbH
Karl-Hammerschmidt-Str. 34, 85609 Dornach b. Muenchen
Geschaeftsfuehrer: Andrew Bowd; Thomas M. McCoy; Giuliano Meroni
Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 01/21] cpuid: move CPUID functions into separate file
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
@ 2009-09-18 11:47 ` Andre Przywara
  2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 02/21] cpuid: fix over-long lines Andre Przywara
                   ` (20 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

about 40% of target-i386/helper.c consist of CPUID related functions.
Only one of them is a real TCG helper function. So move the whole
CPUID stuff out of this into a separate file to get better
maintainable parts.
This is only code reordering and should not affect QEMU's
functionality.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 Makefile.target      |    3 +
 target-i386/cpu.h    |    1 +
 target-i386/cpuid.c  |  771 ++++++++++++++++++++++++++++++++++++++++++++++++++
 target-i386/helper.c |  744 ------------------------------------------------
 4 files changed, 775 insertions(+), 744 deletions(-)
 create mode 100644 target-i386/cpuid.c

diff --git a/Makefile.target b/Makefile.target
index 28c7096..8d522a0 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -36,6 +36,9 @@ libobj-y += tcg/tcg.o tcg/tcg-runtime.o
 libobj-$(CONFIG_SOFTFLOAT) += fpu/softfloat.o
 libobj-$(CONFIG_NOSOFTFLOAT) += fpu/softfloat-native.o
 libobj-y += op_helper.o helper.o
+ifeq ($(TARGET_BASE_ARCH), i386)
+libobj-y += cpuid.o
+endif
 libobj-$(CONFIG_NEED_MMU) += mmu.o
 libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o
 libobj-$(TARGET_ALPHA) += alpha_palcode.o
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index b9a6392..b71d440 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -804,6 +804,7 @@ void cpu_x86_set_a20(CPUX86State *env, int a20_state);
 void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
                    uint32_t *eax, uint32_t *ebx,
                    uint32_t *ecx, uint32_t *edx);
+int cpu_x86_register (CPUX86State *env, const char *cpu_model);
 
 static inline int hw_breakpoint_enabled(unsigned long dr7, int index)
 {
diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
new file mode 100644
index 0000000..adcd0b6
--- /dev/null
+++ b/target-i386/cpuid.c
@@ -0,0 +1,771 @@
+/*
+ *  i386 CPUID handling
+ *
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "cpu.h"
+#include "kvm.h"
+
+//#define DEBUG_MMU
+
+/* feature flags taken from "Intel Processor Identification and the CPUID
+ * Instruction" and AMD's "CPUID Specification". In cases of disagreement
+ * about feature names, the Linux name is used. */
+static const char *feature_name[] = {
+    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+    "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
+    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
+    "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
+};
+static const char *ext_feature_name[] = {
+    "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est",
+    "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
+    NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, "hypervisor",
+};
+static const char *ext2_feature_name[] = {
+    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+    "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mtrr", "pge", "mca", "cmov",
+    "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
+    "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
+};
+static const char *ext3_feature_name[] = {
+    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
+    "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+};
+
+static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
+                                    uint32_t *ext_features,
+                                    uint32_t *ext2_features,
+                                    uint32_t *ext3_features)
+{
+    int i;
+    int found = 0;
+
+    for ( i = 0 ; i < 32 ; i++ )
+        if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
+            *features |= 1 << i;
+            found = 1;
+        }
+    for ( i = 0 ; i < 32 ; i++ )
+        if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {
+            *ext_features |= 1 << i;
+            found = 1;
+        }
+    for ( i = 0 ; i < 32 ; i++ )
+        if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {
+            *ext2_features |= 1 << i;
+            found = 1;
+        }
+    for ( i = 0 ; i < 32 ; i++ )
+        if (ext3_feature_name[i] && !strcmp (flagname, ext3_feature_name[i])) {
+            *ext3_features |= 1 << i;
+            found = 1;
+        }
+    if (!found) {
+        fprintf(stderr, "CPU feature %s not found\n", flagname);
+    }
+}
+
+typedef struct x86_def_t {
+    const char *name;
+    uint32_t level;
+    uint32_t vendor1, vendor2, vendor3;
+    int family;
+    int model;
+    int stepping;
+    uint32_t features, ext_features, ext2_features, ext3_features;
+    uint32_t xlevel;
+    char model_id[48];
+    int vendor_override;
+} x86_def_t;
+
+#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
+#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
+          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX)
+#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
+          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
+          CPUID_PSE36 | CPUID_FXSR)
+#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
+#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
+          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
+          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
+          CPUID_PAE | CPUID_SEP | CPUID_APIC)
+static x86_def_t x86_defs[] = {
+#ifdef TARGET_X86_64
+    {
+        .name = "qemu64",
+        .level = 4,
+        .vendor1 = CPUID_VENDOR_AMD_1,
+        .vendor2 = CPUID_VENDOR_AMD_2,
+        .vendor3 = CPUID_VENDOR_AMD_3,
+        .family = 6,
+        .model = 2,
+        .stepping = 3,
+        .features = PPRO_FEATURES |
+        /* these features are needed for Win64 and aren't fully implemented */
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
+        /* this feature is needed for Solaris and isn't fully implemented */
+            CPUID_PSE36,
+        .ext_features = CPUID_EXT_SSE3,
+        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
+            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+        .ext3_features = CPUID_EXT3_SVM,
+        .xlevel = 0x8000000A,
+        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
+    },
+    {
+        .name = "phenom",
+        .level = 5,
+        .vendor1 = CPUID_VENDOR_AMD_1,
+        .vendor2 = CPUID_VENDOR_AMD_2,
+        .vendor3 = CPUID_VENDOR_AMD_3,
+        .family = 16,
+        .model = 2,
+        .stepping = 3,
+        /* Missing: CPUID_VME, CPUID_HT */
+        .features = PPRO_FEATURES |
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
+            CPUID_PSE36,
+        /* Missing: CPUID_EXT_CX16, CPUID_EXT_POPCNT */
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
+        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
+        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
+            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
+            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
+            CPUID_EXT2_FFXSR,
+        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
+                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
+                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
+                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
+        .ext3_features = CPUID_EXT3_SVM,
+        .xlevel = 0x8000001A,
+        .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
+    },
+    {
+        .name = "core2duo",
+        .level = 10,
+        .family = 6,
+        .model = 15,
+        .stepping = 11,
+        /* The original CPU also implements these features:
+               CPUID_VME, CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
+               CPUID_TM, CPUID_PBE */
+        .features = PPRO_FEATURES |
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
+            CPUID_PSE36,
+        /* The original CPU also implements these ext features:
+               CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
+               CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3,
+        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+        /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
+        .xlevel = 0x80000008,
+        .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
+    },
+    {
+        .name = "kvm64",
+        .level = 5,
+        .vendor1 = CPUID_VENDOR_INTEL_1,
+        .vendor2 = CPUID_VENDOR_INTEL_2,
+        .vendor3 = CPUID_VENDOR_INTEL_3,
+        .family = 15,
+        .model = 6,
+        .stepping = 1,
+        /* Missing: CPUID_VME, CPUID_HT */
+        .features = PPRO_FEATURES |
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
+            CPUID_PSE36,
+        /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
+        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
+        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
+            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
+                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
+                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
+                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
+        .ext3_features = 0,
+        .xlevel = 0x80000008,
+        .model_id = "Common KVM processor"
+    },
+#endif
+    {
+        .name = "qemu32",
+        .level = 4,
+        .family = 6,
+        .model = 3,
+        .stepping = 3,
+        .features = PPRO_FEATURES,
+        .ext_features = CPUID_EXT_SSE3,
+        .xlevel = 0,
+        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
+    },
+    {
+        .name = "coreduo",
+        .level = 10,
+        .family = 6,
+        .model = 14,
+        .stepping = 8,
+        /* The original CPU also implements these features:
+               CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
+               CPUID_TM, CPUID_PBE */
+        .features = PPRO_FEATURES | CPUID_VME |
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA,
+        /* The original CPU also implements these ext features:
+               CPUID_EXT_VMX, CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_XTPR,
+               CPUID_EXT_PDCM */
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
+        .ext2_features = CPUID_EXT2_NX,
+        .xlevel = 0x80000008,
+        .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
+    },
+    {
+        .name = "486",
+        .level = 0,
+        .family = 4,
+        .model = 0,
+        .stepping = 0,
+        .features = I486_FEATURES,
+        .xlevel = 0,
+    },
+    {
+        .name = "pentium",
+        .level = 1,
+        .family = 5,
+        .model = 4,
+        .stepping = 3,
+        .features = PENTIUM_FEATURES,
+        .xlevel = 0,
+    },
+    {
+        .name = "pentium2",
+        .level = 2,
+        .family = 6,
+        .model = 5,
+        .stepping = 2,
+        .features = PENTIUM2_FEATURES,
+        .xlevel = 0,
+    },
+    {
+        .name = "pentium3",
+        .level = 2,
+        .family = 6,
+        .model = 7,
+        .stepping = 3,
+        .features = PENTIUM3_FEATURES,
+        .xlevel = 0,
+    },
+    {
+        .name = "athlon",
+        .level = 2,
+        .vendor1 = CPUID_VENDOR_AMD_1,
+        .vendor2 = CPUID_VENDOR_AMD_2,
+        .vendor3 = CPUID_VENDOR_AMD_3,
+        .family = 6,
+        .model = 2,
+        .stepping = 3,
+        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
+        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
+        .xlevel = 0x80000008,
+        /* XXX: put another string ? */
+        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
+    },
+    {
+        .name = "n270",
+        /* original is on level 10 */
+        .level = 5,
+        .family = 6,
+        .model = 28,
+        .stepping = 2,
+        .features = PPRO_FEATURES |
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME,
+            /* Missing: CPUID_DTS | CPUID_ACPI | CPUID_SS |
+             * CPUID_HT | CPUID_TM | CPUID_PBE */
+            /* Some CPUs got no CPUID_SEP */
+        .ext_features = CPUID_EXT_MONITOR |
+            CPUID_EXT_SSE3 /* PNI */ | CPUID_EXT_SSSE3,
+            /* Missing: CPUID_EXT_DSCPL | CPUID_EXT_EST |
+             * CPUID_EXT_TM2 | CPUID_EXT_XTPR */
+        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_NX,
+        /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
+        .xlevel = 0x8000000A,
+        .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
+    },
+};
+
+static void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax,
+                               uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
+
+static int cpu_x86_fill_model_id(char *str)
+{
+    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
+    int i;
+
+    for (i = 0; i < 3; i++) {
+        host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
+        memcpy(str + i * 16 +  0, &eax, 4);
+        memcpy(str + i * 16 +  4, &ebx, 4);
+        memcpy(str + i * 16 +  8, &ecx, 4);
+        memcpy(str + i * 16 + 12, &edx, 4);
+    }
+    return 0;
+}
+
+static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
+{
+    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
+
+    x86_cpu_def->name = "host";
+    host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
+    x86_cpu_def->level = eax;
+    x86_cpu_def->vendor1 = ebx;
+    x86_cpu_def->vendor2 = edx;
+    x86_cpu_def->vendor3 = ecx;
+
+    host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
+    x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
+    x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
+    x86_cpu_def->stepping = eax & 0x0F;
+    x86_cpu_def->ext_features = ecx;
+    x86_cpu_def->features = edx;
+
+    host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
+    x86_cpu_def->xlevel = eax;
+
+    host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);
+    x86_cpu_def->ext2_features = edx;
+    x86_cpu_def->ext3_features = ecx;
+    cpu_x86_fill_model_id(x86_cpu_def->model_id);
+    x86_cpu_def->vendor_override = 0;
+
+    return 0;
+}
+
+static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
+{
+    unsigned int i;
+    x86_def_t *def;
+
+    char *s = strdup(cpu_model);
+    char *featurestr, *name = strtok(s, ",");
+    uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
+    uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
+    uint32_t numvalue;
+
+    def = NULL;
+    for (i = 0; i < ARRAY_SIZE(x86_defs); i++) {
+        if (strcmp(name, x86_defs[i].name) == 0) {
+            def = &x86_defs[i];
+            break;
+        }
+    }
+    if (kvm_enabled() && strcmp(name, "host") == 0) {
+        cpu_x86_fill_host(x86_cpu_def);
+    } else if (!def) {
+        goto error;
+    } else {
+        memcpy(x86_cpu_def, def, sizeof(*def));
+    }
+
+    add_flagname_to_bitmaps("hypervisor", &plus_features,
+        &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
+
+    featurestr = strtok(NULL, ",");
+
+    while (featurestr) {
+        char *val;
+        if (featurestr[0] == '+') {
+            add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
+        } else if (featurestr[0] == '-') {
+            add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features);
+        } else if ((val = strchr(featurestr, '='))) {
+            *val = 0; val++;
+            if (!strcmp(featurestr, "family")) {
+                char *err;
+                numvalue = strtoul(val, &err, 0);
+                if (!*val || *err) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                x86_cpu_def->family = numvalue;
+            } else if (!strcmp(featurestr, "model")) {
+                char *err;
+                numvalue = strtoul(val, &err, 0);
+                if (!*val || *err || numvalue > 0xff) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                x86_cpu_def->model = numvalue;
+            } else if (!strcmp(featurestr, "stepping")) {
+                char *err;
+                numvalue = strtoul(val, &err, 0);
+                if (!*val || *err || numvalue > 0xf) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                x86_cpu_def->stepping = numvalue ;
+            } else if (!strcmp(featurestr, "level")) {
+                char *err;
+                numvalue = strtoul(val, &err, 0);
+                if (!*val || *err) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                x86_cpu_def->level = numvalue;
+            } else if (!strcmp(featurestr, "xlevel")) {
+                char *err;
+                numvalue = strtoul(val, &err, 0);
+                if (!*val || *err) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                if (numvalue < 0x80000000) {
+                    numvalue += 0x80000000;
+                }
+                x86_cpu_def->xlevel = numvalue;
+            } else if (!strcmp(featurestr, "vendor")) {
+                if (strlen(val) != 12) {
+                    fprintf(stderr, "vendor string must be 12 chars long\n");
+                    goto error;
+                }
+                x86_cpu_def->vendor1 = 0;
+                x86_cpu_def->vendor2 = 0;
+                x86_cpu_def->vendor3 = 0;
+                for(i = 0; i < 4; i++) {
+                    x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
+                    x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
+                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
+                }
+                x86_cpu_def->vendor_override = 1;
+            } else if (!strcmp(featurestr, "model_id")) {
+                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
+                        val);
+            } else {
+                fprintf(stderr, "unrecognized feature %s\n", featurestr);
+                goto error;
+            }
+        } else {
+            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
+            goto error;
+        }
+        featurestr = strtok(NULL, ",");
+    }
+    x86_cpu_def->features |= plus_features;
+    x86_cpu_def->ext_features |= plus_ext_features;
+    x86_cpu_def->ext2_features |= plus_ext2_features;
+    x86_cpu_def->ext3_features |= plus_ext3_features;
+    x86_cpu_def->features &= ~minus_features;
+    x86_cpu_def->ext_features &= ~minus_ext_features;
+    x86_cpu_def->ext2_features &= ~minus_ext2_features;
+    x86_cpu_def->ext3_features &= ~minus_ext3_features;
+    free(s);
+    return 0;
+
+error:
+    free(s);
+    return -1;
+}
+
+void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+{
+    unsigned int i;
+
+    for (i = 0; i < ARRAY_SIZE(x86_defs); i++)
+        (*cpu_fprintf)(f, "x86 %16s\n", x86_defs[i].name);
+}
+
+int cpu_x86_register (CPUX86State *env, const char *cpu_model)
+{
+    x86_def_t def1, *def = &def1;
+
+    if (cpu_x86_find_by_name(def, cpu_model) < 0)
+        return -1;
+    if (def->vendor1) {
+        env->cpuid_vendor1 = def->vendor1;
+        env->cpuid_vendor2 = def->vendor2;
+        env->cpuid_vendor3 = def->vendor3;
+    } else {
+        env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
+        env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
+        env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
+    }
+    env->cpuid_vendor_override = def->vendor_override;
+    env->cpuid_level = def->level;
+    if (def->family > 0x0f)
+        env->cpuid_version = 0xf00 | ((def->family - 0x0f) << 20);
+    else
+        env->cpuid_version = def->family << 8;
+    env->cpuid_version |= ((def->model & 0xf) << 4) | ((def->model >> 4) << 16);
+    env->cpuid_version |= def->stepping;
+    env->cpuid_features = def->features;
+    env->pat = 0x0007040600070406ULL;
+    env->cpuid_ext_features = def->ext_features;
+    env->cpuid_ext2_features = def->ext2_features;
+    env->cpuid_xlevel = def->xlevel;
+    env->cpuid_ext3_features = def->ext3_features;
+    {
+        const char *model_id = def->model_id;
+        int c, len, i;
+        if (!model_id)
+            model_id = "";
+        len = strlen(model_id);
+        for(i = 0; i < 48; i++) {
+            if (i >= len)
+                c = '\0';
+            else
+                c = (uint8_t)model_id[i];
+            env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
+        }
+    }
+    return 0;
+}
+
+static void host_cpuid(uint32_t function, uint32_t count,
+                       uint32_t *eax, uint32_t *ebx,
+                       uint32_t *ecx, uint32_t *edx)
+{
+#if defined(CONFIG_KVM)
+    uint32_t vec[4];
+
+#ifdef __x86_64__
+    asm volatile("cpuid"
+                 : "=a"(vec[0]), "=b"(vec[1]),
+                   "=c"(vec[2]), "=d"(vec[3])
+                 : "0"(function), "c"(count) : "cc");
+#else
+    asm volatile("pusha \n\t"
+                 "cpuid \n\t"
+                 "mov %%eax, 0(%2) \n\t"
+                 "mov %%ebx, 4(%2) \n\t"
+                 "mov %%ecx, 8(%2) \n\t"
+                 "mov %%edx, 12(%2) \n\t"
+                 "popa"
+                 : : "a"(function), "c"(count), "S"(vec)
+                 : "memory", "cc");
+#endif
+
+    if (eax)
+	*eax = vec[0];
+    if (ebx)
+	*ebx = vec[1];
+    if (ecx)
+	*ecx = vec[2];
+    if (edx)
+	*edx = vec[3];
+#endif
+}
+
+void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
+                   uint32_t *eax, uint32_t *ebx,
+                   uint32_t *ecx, uint32_t *edx)
+{
+    /* test if maximum index reached */
+    if (index & 0x80000000) {
+        if (index > env->cpuid_xlevel)
+            index = env->cpuid_level;
+    } else {
+        if (index > env->cpuid_level)
+            index = env->cpuid_level;
+    }
+
+    switch(index) {
+    case 0:
+        *eax = env->cpuid_level;
+        *ebx = env->cpuid_vendor1;
+        *edx = env->cpuid_vendor2;
+        *ecx = env->cpuid_vendor3;
+
+        /* sysenter isn't supported on compatibility mode on AMD.  and syscall
+         * isn't supported in compatibility mode on Intel.  so advertise the
+         * actuall cpu, and say goodbye to migration between different vendors
+         * is you use compatibility mode. */
+        if (kvm_enabled() && !env->cpuid_vendor_override)
+            host_cpuid(0, 0, NULL, ebx, ecx, edx);
+        break;
+    case 1:
+        *eax = env->cpuid_version;
+        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
+        *ecx = env->cpuid_ext_features;
+        *edx = env->cpuid_features;
+        if (env->nr_cores * env->nr_threads > 1) {
+            *ebx |= (env->nr_cores * env->nr_threads) << 16;
+            *edx |= 1 << 28;    /* HTT bit */
+        }
+        break;
+    case 2:
+        /* cache info: needed for Pentium Pro compatibility */
+        *eax = 1;
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0x2c307d;
+        break;
+    case 4:
+        /* cache info: needed for Core compatibility */
+        if (env->nr_cores > 1) {
+            *eax = (env->nr_cores - 1) << 26;
+        } else {
+            *eax = 0;
+        }
+        switch (count) {
+            case 0: /* L1 dcache info */
+                *eax |= 0x0000121;
+                *ebx = 0x1c0003f;
+                *ecx = 0x000003f;
+                *edx = 0x0000001;
+                break;
+            case 1: /* L1 icache info */
+                *eax |= 0x0000122;
+                *ebx = 0x1c0003f;
+                *ecx = 0x000003f;
+                *edx = 0x0000001;
+                break;
+            case 2: /* L2 cache info */
+                *eax |= 0x0000143;
+                if (env->nr_threads > 1) {
+                    *eax |= (env->nr_threads - 1) << 14;
+                }
+                *ebx = 0x3c0003f;
+                *ecx = 0x0000fff;
+                *edx = 0x0000001;
+                break;
+            default: /* end of info */
+                *eax = 0;
+                *ebx = 0;
+                *ecx = 0;
+                *edx = 0;
+                break;
+        }
+        break;
+    case 5:
+        /* mwait info: needed for Core compatibility */
+        *eax = 0; /* Smallest monitor-line size in bytes */
+        *ebx = 0; /* Largest monitor-line size in bytes */
+        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
+        *edx = 0;
+        break;
+    case 6:
+        /* Thermal and Power Leaf */
+        *eax = 0;
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0;
+        break;
+    case 9:
+        /* Direct Cache Access Information Leaf */
+        *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0;
+        break;
+    case 0xA:
+        /* Architectural Performance Monitoring Leaf */
+        *eax = 0;
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0;
+        break;
+    case 0x80000000:
+        *eax = env->cpuid_xlevel;
+        *ebx = env->cpuid_vendor1;
+        *edx = env->cpuid_vendor2;
+        *ecx = env->cpuid_vendor3;
+        break;
+    case 0x80000001:
+        *eax = env->cpuid_version;
+        *ebx = 0;
+        *ecx = env->cpuid_ext3_features;
+        *edx = env->cpuid_ext2_features;
+
+        if (env->nr_cores * env->nr_threads > 1 &&
+            env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
+            env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
+            env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
+            *ecx |= 1 << 1;    /* CmpLegacy bit */
+        }
+
+        if (kvm_enabled()) {
+            /* Nested SVM not yet supported in KVM */
+            *ecx &= ~CPUID_EXT3_SVM;
+        } else {
+            /* AMD 3DNow! is not supported in QEMU */
+            *edx &= ~(CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT);
+        }
+        break;
+    case 0x80000002:
+    case 0x80000003:
+    case 0x80000004:
+        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
+        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
+        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
+        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
+        break;
+    case 0x80000005:
+        /* cache info (L1 cache) */
+        *eax = 0x01ff01ff;
+        *ebx = 0x01ff01ff;
+        *ecx = 0x40020140;
+        *edx = 0x40020140;
+        break;
+    case 0x80000006:
+        /* cache info (L2 cache) */
+        *eax = 0;
+        *ebx = 0x42004200;
+        *ecx = 0x02008140;
+        *edx = 0;
+        break;
+    case 0x80000008:
+        /* virtual & phys address size in low 2 bytes. */
+/* XXX: This value must match the one used in the MMU code. */
+        if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
+            /* 64 bit processor */
+/* XXX: The physical address space is limited to 42 bits in exec.c. */
+            *eax = 0x00003028;	/* 48 bits virtual, 40 bits physical */
+        } else {
+            if (env->cpuid_features & CPUID_PSE36)
+                *eax = 0x00000024; /* 36 bits physical */
+            else
+                *eax = 0x00000020; /* 32 bits physical */
+        }
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0;
+        if (env->nr_cores * env->nr_threads > 1) {
+            *ecx |= (env->nr_cores * env->nr_threads) - 1;
+        }
+        break;
+    case 0x8000000A:
+        *eax = 0x00000001; /* SVM Revision */
+        *ebx = 0x00000010; /* nr of ASIDs */
+        *ecx = 0;
+        *edx = 0; /* optional features */
+        break;
+    default:
+        /* reserved values: zero */
+        *eax = 0;
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0;
+        break;
+    }
+}
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 8111f25..db78191 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -30,520 +30,6 @@
 
 //#define DEBUG_MMU
 
-/* feature flags taken from "Intel Processor Identification and the CPUID
- * Instruction" and AMD's "CPUID Specification". In cases of disagreement
- * about feature names, the Linux name is used. */
-static const char *feature_name[] = {
-    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
-    "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
-    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
-    "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
-};
-static const char *ext_feature_name[] = {
-    "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est",
-    "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
-    NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, "hypervisor",
-};
-static const char *ext2_feature_name[] = {
-    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
-    "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mtrr", "pge", "mca", "cmov",
-    "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
-    "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
-};
-static const char *ext3_feature_name[] = {
-    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
-    "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-};
-
-static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
-                                    uint32_t *ext_features,
-                                    uint32_t *ext2_features,
-                                    uint32_t *ext3_features)
-{
-    int i;
-    int found = 0;
-
-    for ( i = 0 ; i < 32 ; i++ )
-        if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
-            *features |= 1 << i;
-            found = 1;
-        }
-    for ( i = 0 ; i < 32 ; i++ )
-        if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {
-            *ext_features |= 1 << i;
-            found = 1;
-        }
-    for ( i = 0 ; i < 32 ; i++ )
-        if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {
-            *ext2_features |= 1 << i;
-            found = 1;
-        }
-    for ( i = 0 ; i < 32 ; i++ )
-        if (ext3_feature_name[i] && !strcmp (flagname, ext3_feature_name[i])) {
-            *ext3_features |= 1 << i;
-            found = 1;
-        }
-    if (!found) {
-        fprintf(stderr, "CPU feature %s not found\n", flagname);
-    }
-}
-
-typedef struct x86_def_t {
-    const char *name;
-    uint32_t level;
-    uint32_t vendor1, vendor2, vendor3;
-    int family;
-    int model;
-    int stepping;
-    uint32_t features, ext_features, ext2_features, ext3_features;
-    uint32_t xlevel;
-    char model_id[48];
-    int vendor_override;
-} x86_def_t;
-
-#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
-#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
-          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX)
-#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
-          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
-          CPUID_PSE36 | CPUID_FXSR)
-#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
-#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
-          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
-          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
-          CPUID_PAE | CPUID_SEP | CPUID_APIC)
-static x86_def_t x86_defs[] = {
-#ifdef TARGET_X86_64
-    {
-        .name = "qemu64",
-        .level = 4,
-        .vendor1 = CPUID_VENDOR_AMD_1,
-        .vendor2 = CPUID_VENDOR_AMD_2,
-        .vendor3 = CPUID_VENDOR_AMD_3,
-        .family = 6,
-        .model = 2,
-        .stepping = 3,
-        .features = PPRO_FEATURES | 
-        /* these features are needed for Win64 and aren't fully implemented */
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
-        /* this feature is needed for Solaris and isn't fully implemented */
-            CPUID_PSE36,
-        .ext_features = CPUID_EXT_SSE3,
-        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
-            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
-        .ext3_features = CPUID_EXT3_SVM,
-        .xlevel = 0x8000000A,
-        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
-    },
-    {
-        .name = "phenom",
-        .level = 5,
-        .vendor1 = CPUID_VENDOR_AMD_1,
-        .vendor2 = CPUID_VENDOR_AMD_2,
-        .vendor3 = CPUID_VENDOR_AMD_3,
-        .family = 16,
-        .model = 2,
-        .stepping = 3,
-        /* Missing: CPUID_VME, CPUID_HT */
-        .features = PPRO_FEATURES | 
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
-            CPUID_PSE36,
-        /* Missing: CPUID_EXT_CX16, CPUID_EXT_POPCNT */
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
-        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
-        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
-            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
-            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
-            CPUID_EXT2_FFXSR,
-        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
-                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
-                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
-                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
-        .ext3_features = CPUID_EXT3_SVM,
-        .xlevel = 0x8000001A,
-        .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
-    },
-    {
-        .name = "core2duo",
-        .level = 10,
-        .family = 6,
-        .model = 15,
-        .stepping = 11,
-	/* The original CPU also implements these features:
-               CPUID_VME, CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
-               CPUID_TM, CPUID_PBE */
-        .features = PPRO_FEATURES |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
-            CPUID_PSE36,
-	/* The original CPU also implements these ext features:
-               CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
-               CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3,
-        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
-        /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
-        .xlevel = 0x80000008,
-        .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
-    },
-    {
-        .name = "kvm64",
-        .level = 5,
-        .vendor1 = CPUID_VENDOR_INTEL_1,
-        .vendor2 = CPUID_VENDOR_INTEL_2,
-        .vendor3 = CPUID_VENDOR_INTEL_3,
-        .family = 15,
-        .model = 6,
-        .stepping = 1,
-        /* Missing: CPUID_VME, CPUID_HT */
-        .features = PPRO_FEATURES |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
-            CPUID_PSE36,
-        /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
-        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
-        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
-            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
-        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
-                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
-                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
-                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
-        .ext3_features = 0,
-        .xlevel = 0x80000008,
-        .model_id = "Common KVM processor"
-    },
-#endif
-    {
-        .name = "qemu32",
-        .level = 4,
-        .family = 6,
-        .model = 3,
-        .stepping = 3,
-        .features = PPRO_FEATURES,
-        .ext_features = CPUID_EXT_SSE3,
-        .xlevel = 0,
-        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
-    },
-    {
-        .name = "coreduo",
-        .level = 10,
-        .family = 6,
-        .model = 14,
-        .stepping = 8,
-        /* The original CPU also implements these features:
-               CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
-               CPUID_TM, CPUID_PBE */
-        .features = PPRO_FEATURES | CPUID_VME |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA,
-        /* The original CPU also implements these ext features:
-               CPUID_EXT_VMX, CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_XTPR,
-               CPUID_EXT_PDCM */
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
-        .ext2_features = CPUID_EXT2_NX,
-        .xlevel = 0x80000008,
-        .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
-    },
-    {
-        .name = "486",
-        .level = 0,
-        .family = 4,
-        .model = 0,
-        .stepping = 0,
-        .features = I486_FEATURES,
-        .xlevel = 0,
-    },
-    {
-        .name = "pentium",
-        .level = 1,
-        .family = 5,
-        .model = 4,
-        .stepping = 3,
-        .features = PENTIUM_FEATURES,
-        .xlevel = 0,
-    },
-    {
-        .name = "pentium2",
-        .level = 2,
-        .family = 6,
-        .model = 5,
-        .stepping = 2,
-        .features = PENTIUM2_FEATURES,
-        .xlevel = 0,
-    },
-    {
-        .name = "pentium3",
-        .level = 2,
-        .family = 6,
-        .model = 7,
-        .stepping = 3,
-        .features = PENTIUM3_FEATURES,
-        .xlevel = 0,
-    },
-    {
-        .name = "athlon",
-        .level = 2,
-        .vendor1 = CPUID_VENDOR_AMD_1,
-        .vendor2 = CPUID_VENDOR_AMD_2,
-        .vendor3 = CPUID_VENDOR_AMD_3,
-        .family = 6,
-        .model = 2,
-        .stepping = 3,
-        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
-        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
-        .xlevel = 0x80000008,
-        /* XXX: put another string ? */
-        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
-    },
-    {
-        .name = "n270",
-        /* original is on level 10 */
-        .level = 5,
-        .family = 6,
-        .model = 28,
-        .stepping = 2,
-        .features = PPRO_FEATURES |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME,
-            /* Missing: CPUID_DTS | CPUID_ACPI | CPUID_SS |
-             * CPUID_HT | CPUID_TM | CPUID_PBE */
-            /* Some CPUs got no CPUID_SEP */
-        .ext_features = CPUID_EXT_MONITOR |
-            CPUID_EXT_SSE3 /* PNI */ | CPUID_EXT_SSSE3,
-            /* Missing: CPUID_EXT_DSCPL | CPUID_EXT_EST |
-             * CPUID_EXT_TM2 | CPUID_EXT_XTPR */
-        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_NX,
-        /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
-        .xlevel = 0x8000000A,
-        .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
-    },
-};
-
-static void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax,
-                               uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
-
-static int cpu_x86_fill_model_id(char *str)
-{
-    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
-    int i;
-
-    for (i = 0; i < 3; i++) {
-        host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
-        memcpy(str + i * 16 +  0, &eax, 4);
-        memcpy(str + i * 16 +  4, &ebx, 4);
-        memcpy(str + i * 16 +  8, &ecx, 4);
-        memcpy(str + i * 16 + 12, &edx, 4);
-    }
-    return 0;
-}
-
-static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
-{
-    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
-
-    x86_cpu_def->name = "host";
-    host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
-    x86_cpu_def->level = eax;
-    x86_cpu_def->vendor1 = ebx;
-    x86_cpu_def->vendor2 = edx;
-    x86_cpu_def->vendor3 = ecx;
-
-    host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
-    x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
-    x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
-    x86_cpu_def->stepping = eax & 0x0F;
-    x86_cpu_def->ext_features = ecx;
-    x86_cpu_def->features = edx;
-
-    host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
-    x86_cpu_def->xlevel = eax;
-
-    host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);
-    x86_cpu_def->ext2_features = edx;
-    x86_cpu_def->ext3_features = ecx;
-    cpu_x86_fill_model_id(x86_cpu_def->model_id);
-    x86_cpu_def->vendor_override = 0;
-
-    return 0;
-}
-
-static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
-{
-    unsigned int i;
-    x86_def_t *def;
-
-    char *s = strdup(cpu_model);
-    char *featurestr, *name = strtok(s, ",");
-    uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
-    uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
-    uint32_t numvalue;
-
-    def = NULL;
-    for (i = 0; i < ARRAY_SIZE(x86_defs); i++) {
-        if (strcmp(name, x86_defs[i].name) == 0) {
-            def = &x86_defs[i];
-            break;
-        }
-    }
-    if (kvm_enabled() && strcmp(name, "host") == 0) {
-        cpu_x86_fill_host(x86_cpu_def);
-    } else if (!def) {
-        goto error;
-    } else {
-        memcpy(x86_cpu_def, def, sizeof(*def));
-    }
-
-    add_flagname_to_bitmaps("hypervisor", &plus_features,
-        &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
-
-    featurestr = strtok(NULL, ",");
-
-    while (featurestr) {
-        char *val;
-        if (featurestr[0] == '+') {
-            add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
-        } else if (featurestr[0] == '-') {
-            add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features);
-        } else if ((val = strchr(featurestr, '='))) {
-            *val = 0; val++;
-            if (!strcmp(featurestr, "family")) {
-                char *err;
-                numvalue = strtoul(val, &err, 0);
-                if (!*val || *err) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                x86_cpu_def->family = numvalue;
-            } else if (!strcmp(featurestr, "model")) {
-                char *err;
-                numvalue = strtoul(val, &err, 0);
-                if (!*val || *err || numvalue > 0xff) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                x86_cpu_def->model = numvalue;
-            } else if (!strcmp(featurestr, "stepping")) {
-                char *err;
-                numvalue = strtoul(val, &err, 0);
-                if (!*val || *err || numvalue > 0xf) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                x86_cpu_def->stepping = numvalue ;
-            } else if (!strcmp(featurestr, "level")) {
-                char *err;
-                numvalue = strtoul(val, &err, 0);
-                if (!*val || *err) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                x86_cpu_def->level = numvalue;
-            } else if (!strcmp(featurestr, "xlevel")) {
-                char *err;
-                numvalue = strtoul(val, &err, 0);
-                if (!*val || *err) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                if (numvalue < 0x80000000) {
-                	numvalue += 0x80000000;
-                }
-                x86_cpu_def->xlevel = numvalue;
-            } else if (!strcmp(featurestr, "vendor")) {
-                if (strlen(val) != 12) {
-                    fprintf(stderr, "vendor string must be 12 chars long\n");
-                    goto error;
-                }
-                x86_cpu_def->vendor1 = 0;
-                x86_cpu_def->vendor2 = 0;
-                x86_cpu_def->vendor3 = 0;
-                for(i = 0; i < 4; i++) {
-                    x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
-                    x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
-                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
-                }
-                x86_cpu_def->vendor_override = 1;
-            } else if (!strcmp(featurestr, "model_id")) {
-                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
-                        val);
-            } else {
-                fprintf(stderr, "unrecognized feature %s\n", featurestr);
-                goto error;
-            }
-        } else {
-            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
-            goto error;
-        }
-        featurestr = strtok(NULL, ",");
-    }
-    x86_cpu_def->features |= plus_features;
-    x86_cpu_def->ext_features |= plus_ext_features;
-    x86_cpu_def->ext2_features |= plus_ext2_features;
-    x86_cpu_def->ext3_features |= plus_ext3_features;
-    x86_cpu_def->features &= ~minus_features;
-    x86_cpu_def->ext_features &= ~minus_ext_features;
-    x86_cpu_def->ext2_features &= ~minus_ext2_features;
-    x86_cpu_def->ext3_features &= ~minus_ext3_features;
-    free(s);
-    return 0;
-
-error:
-    free(s);
-    return -1;
-}
-
-void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
-{
-    unsigned int i;
-
-    for (i = 0; i < ARRAY_SIZE(x86_defs); i++)
-        (*cpu_fprintf)(f, "x86 %16s\n", x86_defs[i].name);
-}
-
-static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
-{
-    x86_def_t def1, *def = &def1;
-
-    if (cpu_x86_find_by_name(def, cpu_model) < 0)
-        return -1;
-    if (def->vendor1) {
-        env->cpuid_vendor1 = def->vendor1;
-        env->cpuid_vendor2 = def->vendor2;
-        env->cpuid_vendor3 = def->vendor3;
-    } else {
-        env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
-        env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
-        env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
-    }
-    env->cpuid_vendor_override = def->vendor_override;
-    env->cpuid_level = def->level;
-    if (def->family > 0x0f)
-        env->cpuid_version = 0xf00 | ((def->family - 0x0f) << 20);
-    else
-        env->cpuid_version = def->family << 8;
-    env->cpuid_version |= ((def->model & 0xf) << 4) | ((def->model >> 4) << 16);
-    env->cpuid_version |= def->stepping;
-    env->cpuid_features = def->features;
-    env->pat = 0x0007040600070406ULL;
-    env->cpuid_ext_features = def->ext_features;
-    env->cpuid_ext2_features = def->ext2_features;
-    env->cpuid_xlevel = def->xlevel;
-    env->cpuid_ext3_features = def->ext3_features;
-    {
-        const char *model_id = def->model_id;
-        int c, len, i;
-        if (!model_id)
-            model_id = "";
-        len = strlen(model_id);
-        for(i = 0; i < 48; i++) {
-            if (i >= len)
-                c = '\0';
-            else
-                c = (uint8_t)model_id[i];
-            env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
-        }
-    }
-    return 0;
-}
 
 /* NOTE: must be called outside the CPU execute loop */
 void cpu_reset(CPUX86State *env)
@@ -1604,236 +1090,6 @@ static void mce_init(CPUX86State *cenv)
     }
 }
 
-static void host_cpuid(uint32_t function, uint32_t count,
-                       uint32_t *eax, uint32_t *ebx,
-                       uint32_t *ecx, uint32_t *edx)
-{
-#if defined(CONFIG_KVM)
-    uint32_t vec[4];
-
-#ifdef __x86_64__
-    asm volatile("cpuid"
-                 : "=a"(vec[0]), "=b"(vec[1]),
-                   "=c"(vec[2]), "=d"(vec[3])
-                 : "0"(function), "c"(count) : "cc");
-#else
-    asm volatile("pusha \n\t"
-                 "cpuid \n\t"
-                 "mov %%eax, 0(%2) \n\t"
-                 "mov %%ebx, 4(%2) \n\t"
-                 "mov %%ecx, 8(%2) \n\t"
-                 "mov %%edx, 12(%2) \n\t"
-                 "popa"
-                 : : "a"(function), "c"(count), "S"(vec)
-                 : "memory", "cc");
-#endif
-
-    if (eax)
-	*eax = vec[0];
-    if (ebx)
-	*ebx = vec[1];
-    if (ecx)
-	*ecx = vec[2];
-    if (edx)
-	*edx = vec[3];
-#endif
-}
-
-void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
-                   uint32_t *eax, uint32_t *ebx,
-                   uint32_t *ecx, uint32_t *edx)
-{
-    /* test if maximum index reached */
-    if (index & 0x80000000) {
-        if (index > env->cpuid_xlevel)
-            index = env->cpuid_level;
-    } else {
-        if (index > env->cpuid_level)
-            index = env->cpuid_level;
-    }
-
-    switch(index) {
-    case 0:
-        *eax = env->cpuid_level;
-        *ebx = env->cpuid_vendor1;
-        *edx = env->cpuid_vendor2;
-        *ecx = env->cpuid_vendor3;
-
-        /* sysenter isn't supported on compatibility mode on AMD.  and syscall
-         * isn't supported in compatibility mode on Intel.  so advertise the
-         * actuall cpu, and say goodbye to migration between different vendors
-         * is you use compatibility mode. */
-        if (kvm_enabled() && !env->cpuid_vendor_override)
-            host_cpuid(0, 0, NULL, ebx, ecx, edx);
-        break;
-    case 1:
-        *eax = env->cpuid_version;
-        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
-        *ecx = env->cpuid_ext_features;
-        *edx = env->cpuid_features;
-        if (env->nr_cores * env->nr_threads > 1) {
-            *ebx |= (env->nr_cores * env->nr_threads) << 16;
-            *edx |= 1 << 28;    /* HTT bit */
-        }
-        break;
-    case 2:
-        /* cache info: needed for Pentium Pro compatibility */
-        *eax = 1;
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0x2c307d;
-        break;
-    case 4:
-        /* cache info: needed for Core compatibility */
-        if (env->nr_cores > 1) {
-        	*eax = (env->nr_cores - 1) << 26;
-        } else {
-        	*eax = 0;
-        }
-        switch (count) {
-            case 0: /* L1 dcache info */
-                *eax |= 0x0000121;
-                *ebx = 0x1c0003f;
-                *ecx = 0x000003f;
-                *edx = 0x0000001;
-                break;
-            case 1: /* L1 icache info */
-                *eax |= 0x0000122;
-                *ebx = 0x1c0003f;
-                *ecx = 0x000003f;
-                *edx = 0x0000001;
-                break;
-            case 2: /* L2 cache info */
-                *eax |= 0x0000143;
-                if (env->nr_threads > 1) {
-                    *eax |= (env->nr_threads - 1) << 14;
-                }
-                *ebx = 0x3c0003f;
-                *ecx = 0x0000fff;
-                *edx = 0x0000001;
-                break;
-            default: /* end of info */
-                *eax = 0;
-                *ebx = 0;
-                *ecx = 0;
-                *edx = 0;
-                break;
-        }
-        break;
-    case 5:
-        /* mwait info: needed for Core compatibility */
-        *eax = 0; /* Smallest monitor-line size in bytes */
-        *ebx = 0; /* Largest monitor-line size in bytes */
-        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
-        *edx = 0;
-        break;
-    case 6:
-        /* Thermal and Power Leaf */
-        *eax = 0;
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0;
-        break;
-    case 9:
-        /* Direct Cache Access Information Leaf */
-        *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0;
-        break;
-    case 0xA:
-        /* Architectural Performance Monitoring Leaf */
-        *eax = 0;
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0;
-        break;
-    case 0x80000000:
-        *eax = env->cpuid_xlevel;
-        *ebx = env->cpuid_vendor1;
-        *edx = env->cpuid_vendor2;
-        *ecx = env->cpuid_vendor3;
-        break;
-    case 0x80000001:
-        *eax = env->cpuid_version;
-        *ebx = 0;
-        *ecx = env->cpuid_ext3_features;
-        *edx = env->cpuid_ext2_features;
-
-        if (env->nr_cores * env->nr_threads > 1 &&
-            env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
-            env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
-            env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
-            *ecx |= 1 << 1;    /* CmpLegacy bit */
-        }
-
-        if (kvm_enabled()) {
-            /* Nested SVM not yet supported in KVM */
-            *ecx &= ~CPUID_EXT3_SVM;
-        } else {
-            /* AMD 3DNow! is not supported in QEMU */
-            *edx &= ~(CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT);
-        }
-        break;
-    case 0x80000002:
-    case 0x80000003:
-    case 0x80000004:
-        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
-        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
-        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
-        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
-        break;
-    case 0x80000005:
-        /* cache info (L1 cache) */
-        *eax = 0x01ff01ff;
-        *ebx = 0x01ff01ff;
-        *ecx = 0x40020140;
-        *edx = 0x40020140;
-        break;
-    case 0x80000006:
-        /* cache info (L2 cache) */
-        *eax = 0;
-        *ebx = 0x42004200;
-        *ecx = 0x02008140;
-        *edx = 0;
-        break;
-    case 0x80000008:
-        /* virtual & phys address size in low 2 bytes. */
-/* XXX: This value must match the one used in the MMU code. */ 
-        if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
-            /* 64 bit processor */
-/* XXX: The physical address space is limited to 42 bits in exec.c. */
-            *eax = 0x00003028;	/* 48 bits virtual, 40 bits physical */
-        } else {
-            if (env->cpuid_features & CPUID_PSE36)
-                *eax = 0x00000024; /* 36 bits physical */
-            else
-                *eax = 0x00000020; /* 32 bits physical */
-        }
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0;
-        if (env->nr_cores * env->nr_threads > 1) {
-            *ecx |= (env->nr_cores * env->nr_threads) - 1;
-        }
-        break;
-    case 0x8000000A:
-        *eax = 0x00000001; /* SVM Revision */
-        *ebx = 0x00000010; /* nr of ASIDs */
-        *ecx = 0;
-        *edx = 0; /* optional features */
-        break;
-    default:
-        /* reserved values: zero */
-        *eax = 0;
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0;
-        break;
-    }
-}
-
-
 int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
                             target_ulong *base, unsigned int *limit,
                             unsigned int *flags)
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 02/21] cpuid: fix over-long lines
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
  2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 01/21] cpuid: move CPUID functions into separate file Andre Przywara
@ 2009-09-18 11:47 ` Andre Przywara
  2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 03/21] cpuid: replace magic number with named constant Andre Przywara
                   ` (19 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

split lines longer than 80 characters.
Only code formatting changed.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/cpuid.c |   26 ++++++++++++++++++--------
 1 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index adcd0b6..32d9b82 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -111,6 +111,7 @@ typedef struct x86_def_t {
           CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
           CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
           CPUID_PAE | CPUID_SEP | CPUID_APIC)
+
 static x86_def_t x86_defs[] = {
 #ifdef TARGET_X86_64
     {
@@ -285,8 +286,10 @@ static x86_def_t x86_defs[] = {
         .family = 6,
         .model = 2,
         .stepping = 3,
-        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
-        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
+        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME |
+            CPUID_MTRR | CPUID_MCA,
+        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
+            CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
         .xlevel = 0x80000008,
         /* XXX: put another string ? */
         .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
@@ -369,8 +372,10 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
 
     char *s = strdup(cpu_model);
     char *featurestr, *name = strtok(s, ",");
-    uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
-    uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
+    uint32_t plus_features = 0, plus_ext_features = 0;
+    uint32_t plus_ext2_features = 0, plus_ext3_features = 0;
+    uint32_t minus_features = 0, minus_ext_features = 0;
+    uint32_t minus_ext2_features = 0, minus_ext3_features = 0;
     uint32_t numvalue;
 
     def = NULL;
@@ -396,9 +401,12 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
     while (featurestr) {
         char *val;
         if (featurestr[0] == '+') {
-            add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
+            add_flagname_to_bitmaps(featurestr + 1, &plus_features,
+                &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
         } else if (featurestr[0] == '-') {
-            add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features);
+            add_flagname_to_bitmaps(featurestr + 1,
+                &minus_features, &minus_ext_features,
+                &minus_ext2_features, &minus_ext3_features);
         } else if ((val = strchr(featurestr, '='))) {
             *val = 0; val++;
             if (!strcmp(featurestr, "family")) {
@@ -466,7 +474,8 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
                 goto error;
             }
         } else {
-            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
+            fprintf(stderr, "feature string `%s' not in format "
+                "(+feature|-feature|feature=xyz)\n", featurestr);
             goto error;
         }
         featurestr = strtok(NULL, ",");
@@ -605,7 +614,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         break;
     case 1:
         *eax = env->cpuid_version;
-        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
+        /* CLFLUSH size in quad words, Linux wants it. */
+        *ebx = (env->cpuid_apic_id << 24) | 8 << 8;
         *ecx = env->cpuid_ext_features;
         *edx = env->cpuid_features;
         if (env->nr_cores * env->nr_threads > 1) {
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 03/21] cpuid: replace magic number with named constant
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
  2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 01/21] cpuid: move CPUID functions into separate file Andre Przywara
  2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 02/21] cpuid: fix over-long lines Andre Przywara
@ 2009-09-18 11:47 ` Andre Przywara
  2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 04/21] cpuid: fix comments Andre Przywara
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

CPUID leaf Fn8000_0001.EDX contains a copy of many Fn0000_0001.EDX bits.
Define a name for the mask to improve readability and avoid typos.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/cpuid.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 32d9b82..8d986fc 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -111,6 +111,7 @@ typedef struct x86_def_t {
           CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
           CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
           CPUID_PAE | CPUID_SEP | CPUID_APIC)
+#define EXT2_FEATURE_MASK 0x0183F3FF
 
 static x86_def_t x86_defs[] = {
 #ifdef TARGET_X86_64
@@ -129,7 +130,7 @@ static x86_def_t x86_defs[] = {
         /* this feature is needed for Solaris and isn't fully implemented */
             CPUID_PSE36,
         .ext_features = CPUID_EXT_SSE3,
-        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
+        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
             CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
         .ext3_features = CPUID_EXT3_SVM,
         .xlevel = 0x8000000A,
@@ -151,7 +152,7 @@ static x86_def_t x86_defs[] = {
         /* Missing: CPUID_EXT_CX16, CPUID_EXT_POPCNT */
         .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
         /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
-        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
+        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
             CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
             CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
             CPUID_EXT2_FFXSR,
@@ -288,7 +289,7 @@ static x86_def_t x86_defs[] = {
         .stepping = 3,
         .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME |
             CPUID_MTRR | CPUID_MCA,
-        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
+        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
             CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
         .xlevel = 0x80000008,
         /* XXX: put another string ? */
@@ -310,7 +311,7 @@ static x86_def_t x86_defs[] = {
             CPUID_EXT_SSE3 /* PNI */ | CPUID_EXT_SSSE3,
             /* Missing: CPUID_EXT_DSCPL | CPUID_EXT_EST |
              * CPUID_EXT_TM2 | CPUID_EXT_XTPR */
-        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_NX,
+        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) | CPUID_EXT2_NX,
         /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
         .xlevel = 0x8000000A,
         .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 04/21] cpuid: fix comments
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (2 preceding siblings ...)
  2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 03/21] cpuid: replace magic number with named constant Andre Przywara
@ 2009-09-18 11:47 ` Andre Przywara
  2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 05/21] cpuid: moved host_cpuid function and remove prototype Andre Przywara
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

Some comments regarding CPUID features were not up-to-date.
- Nested SVM is supported in qemu-kvm, but not in upstream qemu (yet).
- We support syscall/sysenter emulation in KVM now, so the comment
  explaining the vendor string issue can be more relaxed.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/cpuid.c |   12 +++++++-----
 1 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 8d986fc..bdc8fe0 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -606,10 +606,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         *edx = env->cpuid_vendor2;
         *ecx = env->cpuid_vendor3;
 
-        /* sysenter isn't supported on compatibility mode on AMD.  and syscall
-         * isn't supported in compatibility mode on Intel.  so advertise the
-         * actuall cpu, and say goodbye to migration between different vendors
-         * is you use compatibility mode. */
+        /* sysenter isn't supported on compatibility mode on AMD, syscall
+         * isn't supported in compatibility mode on Intel.
+         * Normally we advertise the actual cpu vendor, but you can override
+         * this if you want to use KVM's sysenter/syscall emulation
+         * in compatibility mode and when doing cross vendor migration
+         */
         if (kvm_enabled() && !env->cpuid_vendor_override)
             host_cpuid(0, 0, NULL, ebx, ecx, edx);
         break;
@@ -716,7 +718,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         }
 
         if (kvm_enabled()) {
-            /* Nested SVM not yet supported in KVM */
+            /* Nested SVM not yet supported in upstream QEMU */
             *ecx &= ~CPUID_EXT3_SVM;
         } else {
             /* AMD 3DNow! is not supported in QEMU */
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 05/21] cpuid: moved host_cpuid function and remove prototype
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (3 preceding siblings ...)
  2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 04/21] cpuid: fix comments Andre Przywara
@ 2009-09-18 11:47 ` Andre Przywara
  2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 06/21] cpuid: Replace strtok with get_opt_name Andre Przywara
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

the host_cpuid function was located at the end of the file and had
a prototype before it's first use. Move it up and remove the
prototype.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/cpuid.c |   71 ++++++++++++++++++++++++--------------------------
 1 files changed, 34 insertions(+), 37 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index bdc8fe0..fca4ba6 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -318,8 +318,40 @@ static x86_def_t x86_defs[] = {
     },
 };
 
-static void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax,
-                               uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
+static void host_cpuid(uint32_t function, uint32_t count,
+                       uint32_t *eax, uint32_t *ebx,
+                       uint32_t *ecx, uint32_t *edx)
+{
+#if defined(CONFIG_KVM)
+    uint32_t vec[4];
+
+#ifdef __x86_64__
+    asm volatile("cpuid"
+                 : "=a"(vec[0]), "=b"(vec[1]),
+                   "=c"(vec[2]), "=d"(vec[3])
+                 : "0"(function), "c"(count) : "cc");
+#else
+    asm volatile("pusha \n\t"
+                 "cpuid \n\t"
+                 "mov %%eax, 0(%2) \n\t"
+                 "mov %%ebx, 4(%2) \n\t"
+                 "mov %%ecx, 8(%2) \n\t"
+                 "mov %%edx, 12(%2) \n\t"
+                 "popa"
+                 : : "a"(function), "c"(count), "S"(vec)
+                 : "memory", "cc");
+#endif
+
+    if (eax)
+        *eax = vec[0];
+    if (ebx)
+        *ebx = vec[1];
+    if (ecx)
+        *ecx = vec[2];
+    if (edx)
+        *edx = vec[3];
+#endif
+}
 
 static int cpu_x86_fill_model_id(char *str)
 {
@@ -551,41 +583,6 @@ int cpu_x86_register (CPUX86State *env, const char *cpu_model)
     return 0;
 }
 
-static void host_cpuid(uint32_t function, uint32_t count,
-                       uint32_t *eax, uint32_t *ebx,
-                       uint32_t *ecx, uint32_t *edx)
-{
-#if defined(CONFIG_KVM)
-    uint32_t vec[4];
-
-#ifdef __x86_64__
-    asm volatile("cpuid"
-                 : "=a"(vec[0]), "=b"(vec[1]),
-                   "=c"(vec[2]), "=d"(vec[3])
-                 : "0"(function), "c"(count) : "cc");
-#else
-    asm volatile("pusha \n\t"
-                 "cpuid \n\t"
-                 "mov %%eax, 0(%2) \n\t"
-                 "mov %%ebx, 4(%2) \n\t"
-                 "mov %%ecx, 8(%2) \n\t"
-                 "mov %%edx, 12(%2) \n\t"
-                 "popa"
-                 : : "a"(function), "c"(count), "S"(vec)
-                 : "memory", "cc");
-#endif
-
-    if (eax)
-	*eax = vec[0];
-    if (ebx)
-	*ebx = vec[1];
-    if (ecx)
-	*ecx = vec[2];
-    if (edx)
-	*edx = vec[3];
-#endif
-}
-
 void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
                    uint32_t *eax, uint32_t *ebx,
                    uint32_t *ecx, uint32_t *edx)
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 06/21] cpuid: Replace strtok with get_opt_name
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (4 preceding siblings ...)
  2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 05/21] cpuid: moved host_cpuid function and remove prototype Andre Przywara
@ 2009-09-18 11:47 ` Andre Przywara
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 07/21] cpuid: add missing CPUID feature flag names Andre Przywara
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara, Andre Przywara

From: Andre Przywara <osp@andrep.de>

To avoid the non-reentrant capable strtok() use the QEMU defined
get_opt_name() to parse the -cpu parameter list. Since there is a
name clash between linux-user/mmap.c:qemu_malloc() and
qemu-malloc.c:qemu_malloc() I copied the small function from
qemu-option.c into cpuid.c. Not the best solution, bit IMO the
least intrusive and smallest one.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/cpuid.c |   34 ++++++++++++++++++++++++----------
 1 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index fca4ba6..ec88e20 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -26,6 +26,23 @@
 
 //#define DEBUG_MMU
 
+static const char *get_opt_name(char *buf, int buf_size,
+                                const char *p, char delim)
+{
+    char *q;
+
+    q = buf;
+    while (*p != '\0' && *p != delim) {
+        if (q && (q - buf) < buf_size - 1)
+            *q++ = *p;
+        p++;
+    }
+    if (q)
+        *q = '\0';
+
+    return p;
+}
+
 /* feature flags taken from "Intel Processor Identification and the CPUID
  * Instruction" and AMD's "CPUID Specification". In cases of disagreement
  * about feature names, the Linux name is used. */
@@ -403,22 +420,23 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
     unsigned int i;
     x86_def_t *def;
 
-    char *s = strdup(cpu_model);
-    char *featurestr, *name = strtok(s, ",");
+    const char* s;
+    char featurestr[64];
     uint32_t plus_features = 0, plus_ext_features = 0;
     uint32_t plus_ext2_features = 0, plus_ext3_features = 0;
     uint32_t minus_features = 0, minus_ext_features = 0;
     uint32_t minus_ext2_features = 0, minus_ext3_features = 0;
     uint32_t numvalue;
 
+    s = get_opt_name(featurestr, 64, cpu_model, ',');
     def = NULL;
     for (i = 0; i < ARRAY_SIZE(x86_defs); i++) {
-        if (strcmp(name, x86_defs[i].name) == 0) {
+        if (strcmp(featurestr, x86_defs[i].name) == 0) {
             def = &x86_defs[i];
             break;
         }
     }
-    if (kvm_enabled() && strcmp(name, "host") == 0) {
+    if (kvm_enabled() && strcmp(featurestr, "host") == 0) {
         cpu_x86_fill_host(x86_cpu_def);
     } else if (!def) {
         goto error;
@@ -429,10 +447,9 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
     add_flagname_to_bitmaps("hypervisor", &plus_features,
         &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
 
-    featurestr = strtok(NULL, ",");
-
-    while (featurestr) {
+    while (*s != 0) {
         char *val;
+        s = get_opt_name(featurestr, 64, s + 1, ',');
         if (featurestr[0] == '+') {
             add_flagname_to_bitmaps(featurestr + 1, &plus_features,
                 &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
@@ -511,7 +528,6 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
                 "(+feature|-feature|feature=xyz)\n", featurestr);
             goto error;
         }
-        featurestr = strtok(NULL, ",");
     }
     x86_cpu_def->features |= plus_features;
     x86_cpu_def->ext_features |= plus_ext_features;
@@ -521,11 +537,9 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
     x86_cpu_def->ext_features &= ~minus_ext_features;
     x86_cpu_def->ext2_features &= ~minus_ext2_features;
     x86_cpu_def->ext3_features &= ~minus_ext3_features;
-    free(s);
     return 0;
 
 error:
-    free(s);
     return -1;
 }
 
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 07/21] cpuid: add missing CPUID feature flag names
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (5 preceding siblings ...)
  2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 06/21] cpuid: Replace strtok with get_opt_name Andre Przywara
@ 2009-09-18 11:48 ` Andre Przywara
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 08/21] cpuid: list all known x86 CPUID feature flags Andre Przywara
                   ` (14 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

some CPUID feature flags had no string value, so they could not be
switched on or off from the command line.
Add names for the missing ones and obey the 80 characters limit on
the way.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/cpuid.c |   28 ++++++++++++++++++----------
 1 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index ec88e20..0d6e37a 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -49,24 +49,32 @@ static const char *get_opt_name(char *buf, int buf_size,
 static const char *feature_name[] = {
     "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
     "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
-    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
+    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
+        NULL, "ds" /* Intel dts */, "acpi", "mmx",
     "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
 };
 static const char *ext_feature_name[] = {
-    "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est",
-    "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
-    NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, "hypervisor",
+    "pni" /* Intel,AMD sse3 */, NULL, "dtes64", "monitor",
+        "ds_cpl", "vmx", "smx", "est",
+    "tm2", "ssse3", "cid", NULL, NULL /* FMA */, "cx16", "xtpr", "pdcm",
+    NULL, NULL, "dca", "sse4_1", "sse4_2", "x2apic", "movbe", "popcnt",
+    NULL, NULL /* AES */, "xsave", "osxsave",
+        NULL /* AVX */, NULL, NULL, "hypervisor",
 };
 static const char *ext2_feature_name[] = {
     "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
-    "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mtrr", "pge", "mca", "cmov",
-    "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
-    "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
+    "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall",
+        "mtrr", "pge", "mca", "cmov",
+    "pat", "pse36", NULL, NULL /* Linux mp */,
+        "nx" /* Intel xd */, NULL, "mmxext", "mmx",
+    "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp",
+        NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
 };
 static const char *ext3_feature_name[] = {
-    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
-    "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
+    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy",
+        "svm", "extapic" /* AMD ExtApicSpace */,
+        "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
+    "3dnowprefetch", "osvw", "ibs", "sse5", "skinit", "wdt", NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 };
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 08/21] cpuid: list all known x86 CPUID feature flags
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (6 preceding siblings ...)
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 07/21] cpuid: add missing CPUID feature flag names Andre Przywara
@ 2009-09-18 11:48 ` Andre Przywara
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 09/21] cpuid: remove unnecessary kvm_trim function Andre Przywara
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

-cpu ? currently gives us a list of known CPU models. Add a list
of known CPUID feature flags to the output.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/cpuid.c |   19 ++++++++++++++++++-
 1 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 0d6e37a..8243f44 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -553,10 +553,27 @@ error:
 
 void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
 {
-    unsigned int i;
+    unsigned int i, j;
+    const char **stringlist[] = {feature_name, ext_feature_name,
+                                 ext2_feature_name, ext3_feature_name};
 
     for (i = 0; i < ARRAY_SIZE(x86_defs); i++)
         (*cpu_fprintf)(f, "x86 %16s\n", x86_defs[i].name);
+
+    (*cpu_fprintf)(f, "x86 recognized feature flags:\n    ");
+    for (j = 0; j < 4; j++) {
+        for (i = 0; i < 32; i++) {
+            if (j == 2 && ((1 << i) & EXT2_FEATURE_MASK))
+                continue;
+            if (stringlist[j][i] == NULL)
+                continue;
+            (*cpu_fprintf)(f, "%s ", stringlist[j][i]);
+            if (i == 15)
+                (*cpu_fprintf)(f, "\n    ");
+        }
+        (*cpu_fprintf)(f, "\n    ");
+    }
+    return;
 }
 
 int cpu_x86_register (CPUX86State *env, const char *cpu_model)
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 09/21] cpuid: remove unnecessary kvm_trim function
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (7 preceding siblings ...)
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 08/21] cpuid: list all known x86 CPUID feature flags Andre Przywara
@ 2009-09-18 11:48 ` Andre Przywara
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 10/21] cpuid: simplify CPUID flag search function Andre Przywara
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

Correct me if I am wrong, but kvm_trim looks like a really bloated
implementation of a bitwise AND. So remove this function and replace
it with the real stuff.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/kvm.c |   27 ++++++---------------------
 1 files changed, 6 insertions(+), 21 deletions(-)

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index cab9fcc..ebc6c5a 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -117,19 +117,6 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, int reg)
 
 #endif
 
-static void kvm_trim_features(uint32_t *features, uint32_t supported)
-{
-    int i;
-    uint32_t mask;
-
-    for (i = 0; i < 32; ++i) {
-        mask = 1U << i;
-        if ((*features & mask) && !(supported & mask)) {
-            *features &= ~mask;
-        }
-    }
-}
-
 int kvm_arch_init_vcpu(CPUState *env)
 {
     struct {
@@ -141,18 +128,16 @@ int kvm_arch_init_vcpu(CPUState *env)
 
     env->mp_state = KVM_MP_STATE_RUNNABLE;
 
-    kvm_trim_features(&env->cpuid_features,
-        kvm_arch_get_supported_cpuid(env, 1, R_EDX));
+    env->cpuid_features &= kvm_arch_get_supported_cpuid(env, 1, R_EDX);
 
     i = env->cpuid_ext_features & CPUID_EXT_HYPERVISOR;
-    kvm_trim_features(&env->cpuid_ext_features,
-        kvm_arch_get_supported_cpuid(env, 1, R_ECX));
+    env->cpuid_ext_features &= kvm_arch_get_supported_cpuid(env, 1, R_ECX);
     env->cpuid_ext_features |= i;
 
-    kvm_trim_features(&env->cpuid_ext2_features,
-        kvm_arch_get_supported_cpuid(env, 0x80000001, R_EDX));
-    kvm_trim_features(&env->cpuid_ext3_features,
-        kvm_arch_get_supported_cpuid(env, 0x80000001, R_ECX));
+    env->cpuid_ext2_features &= kvm_arch_get_supported_cpuid(env, 0x80000001,
+                                                             R_EDX);
+    env->cpuid_ext3_features &= kvm_arch_get_supported_cpuid(env, 0x80000001,
+                                                             R_ECX);
 
     cpuid_i = 0;
 
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 10/21] cpuid: simplify CPUID flag search function
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (8 preceding siblings ...)
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 09/21] cpuid: remove unnecessary kvm_trim function Andre Przywara
@ 2009-09-18 11:48 ` Andre Przywara
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 11/21] cpuid: propagate further CPUID leafs when -cpu host Andre Przywara
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

avoid code duplication and handle the CPUID flag name search in a
loop.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/cpuid.c |   33 +++++++++++++--------------------
 1 files changed, 13 insertions(+), 20 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 8243f44..9fdaa6c 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -84,29 +84,22 @@ static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
                                     uint32_t *ext2_features,
                                     uint32_t *ext3_features)
 {
-    int i;
+    int i, j;
     int found = 0;
+    const char ** feature_names[4] = {feature_name, ext_feature_name,
+        ext2_feature_name, ext3_feature_name};
+    uint32_t* feature_flags[4] = {features, ext_features,
+        ext2_features, ext3_features};
 
-    for ( i = 0 ; i < 32 ; i++ )
-        if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
-            *features |= 1 << i;
-            found = 1;
-        }
-    for ( i = 0 ; i < 32 ; i++ )
-        if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {
-            *ext_features |= 1 << i;
-            found = 1;
-        }
-    for ( i = 0 ; i < 32 ; i++ )
-        if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {
-            *ext2_features |= 1 << i;
-            found = 1;
-        }
-    for ( i = 0 ; i < 32 ; i++ )
-        if (ext3_feature_name[i] && !strcmp (flagname, ext3_feature_name[i])) {
-            *ext3_features |= 1 << i;
-            found = 1;
+    for (j = 0; j < 4; j++) {
+        for (i = 0; i < 32; i++) {
+            if (feature_names[j][i] &&
+                !strcmp(flagname, feature_names[j][i])) {
+                *feature_flags[j] |= 1 << i;
+                found = 1;
+            }
         }
+    }
     if (!found) {
         fprintf(stderr, "CPU feature %s not found\n", flagname);
     }
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 11/21] cpuid: propagate further CPUID leafs when -cpu host
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (9 preceding siblings ...)
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 10/21] cpuid: simplify CPUID flag search function Andre Przywara
@ 2009-09-18 11:48 ` Andre Przywara
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 12/21] cpuid: Fix multicore setup on Intel Andre Przywara
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

-cpu host currently only propagates the CPU's family/model/stepping,
the brand name and the feature bits.
Add a whitelist of safe CPUID leafs to let the guest see the actual
CPU's cache details and other things.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/cpu.h   |    5 ++++-
 target-i386/cpuid.c |   28 ++++++++++++++++++++++------
 2 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index b71d440..0f00d6a 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -563,6 +563,9 @@ typedef union {
 
 #define NB_MMU_MODES 2
 
+#define CPUID_FLAGS_VENDOR_OVERRIDE 1
+#define CPUID_FLAGS_HOST 2
+
 typedef struct CPUX86State {
     /* standard registers */
     target_ulong regs[CPU_NB_REGS];
@@ -672,7 +675,7 @@ typedef struct CPUX86State {
     uint32_t cpuid_ext2_features;
     uint32_t cpuid_ext3_features;
     uint32_t cpuid_apic_id;
-    int cpuid_vendor_override;
+    uint32_t cpuid_flags;
 
     /* MTRRs */
     uint64_t mtrr_fixed[11];
diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 9fdaa6c..4f2b359 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -115,7 +115,7 @@ typedef struct x86_def_t {
     uint32_t features, ext_features, ext2_features, ext3_features;
     uint32_t xlevel;
     char model_id[48];
-    int vendor_override;
+    uint32_t flags;
 } x86_def_t;
 
 #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
@@ -411,7 +411,7 @@ static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
     x86_cpu_def->ext2_features = edx;
     x86_cpu_def->ext3_features = ecx;
     cpu_x86_fill_model_id(x86_cpu_def->model_id);
-    x86_cpu_def->vendor_override = 0;
+    x86_cpu_def->flags = CPUID_FLAGS_HOST;
 
     return 0;
 }
@@ -516,7 +516,7 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
                     x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
                     x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
                 }
-                x86_cpu_def->vendor_override = 1;
+                x86_cpu_def->flags |= CPUID_FLAGS_VENDOR_OVERRIDE;
             } else if (!strcmp(featurestr, "model_id")) {
                 pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
                         val);
@@ -584,7 +584,7 @@ int cpu_x86_register (CPUX86State *env, const char *cpu_model)
         env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
         env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
     }
-    env->cpuid_vendor_override = def->vendor_override;
+    env->cpuid_flags = def->flags;
     env->cpuid_level = def->level;
     if (def->family > 0x0f)
         env->cpuid_version = 0xf00 | ((def->family - 0x0f) << 20);
@@ -615,17 +615,32 @@ int cpu_x86_register (CPUX86State *env, const char *cpu_model)
     return 0;
 }
 
+#define CPUID_LEAF_PROPAGATE ((1 << 0x02) | (1 << 0x04) | (1 << 0x05) |\
+                             (1 << 0x0D))
+#define CPUID_LEAF_PROPAGATE_EXTENDED ((1 << 0x05) | (1 << 0x06) |\
+                                      (1 << 0x08) | (1 << 0x19) | (1 << 0x1A))
+
 void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
                    uint32_t *eax, uint32_t *ebx,
                    uint32_t *ecx, uint32_t *edx)
 {
-    /* test if maximum index reached */
     if (index & 0x80000000) {
+    /* test if maximum index reached */
         if (index > env->cpuid_xlevel)
             index = env->cpuid_level;
+        if ((env->cpuid_flags & CPUID_FLAGS_HOST) &&
+            ((1 << (index - 0x80000000)) & CPUID_LEAF_PROPAGATE_EXTENDED)) {
+            host_cpuid(index, count, eax, ebx, ecx, edx);
+            return;
+        }
     } else {
         if (index > env->cpuid_level)
             index = env->cpuid_level;
+        if ((env->cpuid_flags & CPUID_FLAGS_HOST) &&
+            ((1 << index) & CPUID_LEAF_PROPAGATE)) {
+            host_cpuid(index, count, eax, ebx, ecx, edx);
+            return;
+        }
     }
 
     switch(index) {
@@ -641,7 +656,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
          * this if you want to use KVM's sysenter/syscall emulation
          * in compatibility mode and when doing cross vendor migration
          */
-        if (kvm_enabled() && !env->cpuid_vendor_override)
+        if (kvm_enabled() && 
+            (env->cpuid_flags & CPUID_FLAGS_VENDOR_OVERRIDE) == 0)
             host_cpuid(0, 0, NULL, ebx, ecx, edx);
         break;
     case 1:
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 12/21] cpuid: Fix multicore setup on Intel
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (10 preceding siblings ...)
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 11/21] cpuid: propagate further CPUID leafs when -cpu host Andre Przywara
@ 2009-09-18 11:48 ` Andre Przywara
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 13/21] cpuid: add TCG feature bit trimming Andre Przywara
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

The multicore CPUID code detects whether the guest is an Intel or an
AMD CPU, because the Linux kernel is picky about the CmpLegacy bit.
KVM by default passes through the host's vendor, which was not
catched by the code. So fork out the vendor determining bits into a
separate function to be used from both places and always get the real
vendor.
This fixes KVM's multicore setup on Intel CPUs.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Reported-by: Dietmar Maurer <dietmar@proxmox.com>
---
 target-i386/cpuid.c |   49 +++++++++++++++++++++++++++++++------------------
 1 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 4f2b359..e76457c 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -615,6 +615,24 @@ int cpu_x86_register (CPUX86State *env, const char *cpu_model)
     return 0;
 }
 
+static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
+                             uint32_t *ecx, uint32_t *edx)
+{
+    *ebx = env->cpuid_vendor1;
+    *edx = env->cpuid_vendor2;
+    *ecx = env->cpuid_vendor3;
+
+    /* sysenter isn't supported on compatibility mode on AMD, syscall
+     * isn't supported in compatibility mode on Intel.
+     * Normally we advertise the actual cpu vendor, but you can override
+     * this if you want to use KVM's sysenter/syscall emulation
+     * in compatibility mode and when doing cross vendor migration
+     */
+    if (kvm_enabled() && 
+        (env->cpuid_flags & CPUID_FLAGS_VENDOR_OVERRIDE) == 0)
+        host_cpuid(0, 0, NULL, ebx, ecx, edx);
+}
+
 #define CPUID_LEAF_PROPAGATE ((1 << 0x02) | (1 << 0x04) | (1 << 0x05) |\
                              (1 << 0x0D))
 #define CPUID_LEAF_PROPAGATE_EXTENDED ((1 << 0x05) | (1 << 0x06) |\
@@ -646,19 +664,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
     switch(index) {
     case 0:
         *eax = env->cpuid_level;
-        *ebx = env->cpuid_vendor1;
-        *edx = env->cpuid_vendor2;
-        *ecx = env->cpuid_vendor3;
-
-        /* sysenter isn't supported on compatibility mode on AMD, syscall
-         * isn't supported in compatibility mode on Intel.
-         * Normally we advertise the actual cpu vendor, but you can override
-         * this if you want to use KVM's sysenter/syscall emulation
-         * in compatibility mode and when doing cross vendor migration
-         */
-        if (kvm_enabled() && 
-            (env->cpuid_flags & CPUID_FLAGS_VENDOR_OVERRIDE) == 0)
-            host_cpuid(0, 0, NULL, ebx, ecx, edx);
+        get_cpuid_vendor(env, ebx, ecx, edx);
         break;
     case 1:
         *eax = env->cpuid_version;
@@ -755,11 +761,18 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         *ecx = env->cpuid_ext3_features;
         *edx = env->cpuid_ext2_features;
 
-        if (env->nr_cores * env->nr_threads > 1 &&
-            env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
-            env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
-            env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
-            *ecx |= 1 << 1;    /* CmpLegacy bit */
+        /* The Linux kernel checks for the CMPLegacy bit and
+         * discards multiple thread information if it is set.
+         * So dont set it here for Intel to make Linux guests happy.
+         */
+        if (env->nr_cores * env->nr_threads > 1) {
+            uint32_t tebx, tecx, tedx;
+            get_cpuid_vendor(env, &tebx, &tecx, &tedx);
+            if (tebx != CPUID_VENDOR_INTEL_1 ||
+                tedx != CPUID_VENDOR_INTEL_2 ||
+                tecx != CPUID_VENDOR_INTEL_3) {
+                *ecx |= 1 << 1;    /* CmpLegacy bit */
+            }
         }
 
         if (kvm_enabled()) {
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 13/21] cpuid: add TCG feature bit trimming
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (11 preceding siblings ...)
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 12/21] cpuid: Fix multicore setup on Intel Andre Przywara
@ 2009-09-18 11:48 ` Andre Przywara
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 14/21] cpuid: decrease L2 cache for Intel and add comments Andre Przywara
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

In KVM we trim the user provided CPUID bits to match the host CPU's
one. Introduce a similar feature to QEMU/TCG. Create a mask of TCG's
capabilities and apply it to the user bits.
This allows to let the CPU models reflect their native archetypes.
(which will be send in a later patch).

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/cpuid.c |   27 ++++++++++++++++++++++++---
 1 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index e76457c..9f43ccd 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -131,6 +131,19 @@ typedef struct x86_def_t {
           CPUID_PAE | CPUID_SEP | CPUID_APIC)
 #define EXT2_FEATURE_MASK 0x0183F3FF
 
+#define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
+          CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
+          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
+          CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
+          CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS)
+#define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | \
+            CPUID_EXT_CX16 | CPUID_EXT_POPCNT | CPUID_EXT_XSAVE | \
+            CPUID_EXT_HYPERVISOR)
+#define TCG_EXT2_FEATURES ((TCG_FEATURES & EXT2_FEATURE_MASK) | \
+            CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | \
+            CPUID_EXT2_3DNOWEXT)
+#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM)
+
 static x86_def_t x86_defs[] = {
 #ifdef TARGET_X86_64
     {
@@ -598,6 +611,17 @@ int cpu_x86_register (CPUX86State *env, const char *cpu_model)
     env->cpuid_ext2_features = def->ext2_features;
     env->cpuid_xlevel = def->xlevel;
     env->cpuid_ext3_features = def->ext3_features;
+    if (!kvm_enabled()) {
+        env->cpuid_features &= TCG_FEATURES;
+        env->cpuid_ext_features &= TCG_EXT_FEATURES;
+        env->cpuid_ext2_features &= (TCG_EXT2_FEATURES
+#ifdef TARGET_X86_64
+                | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM);
+#else
+                );
+#endif
+        env->cpuid_ext3_features &= TCG_EXT3_FEATURES;
+    }
     {
         const char *model_id = def->model_id;
         int c, len, i;
@@ -778,9 +802,6 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         if (kvm_enabled()) {
             /* Nested SVM not yet supported in upstream QEMU */
             *ecx &= ~CPUID_EXT3_SVM;
-        } else {
-            /* AMD 3DNow! is not supported in QEMU */
-            *edx &= ~(CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT);
         }
         break;
     case 0x80000002:
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 14/21] cpuid: decrease L2 cache for Intel and add comments
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (12 preceding siblings ...)
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 13/21] cpuid: add TCG feature bit trimming Andre Przywara
@ 2009-09-18 11:48 ` Andre Przywara
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 15/21] cpuid: Adjust feature bit constants Andre Przywara
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

The Intel cache info leafs describe a Core2Duo with 4MB L2 Cache.
This is a pretty high value not reached by many host CPUs. So lower
this value to one MB to avoid guests assuming too large caches.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/cpuid.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 9f43ccd..8ec730c 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -716,25 +716,25 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
             *eax = 0;
         }
         switch (count) {
-            case 0: /* L1 dcache info */
+            case 0: /* L1 dcache info: 32KB */
                 *eax |= 0x0000121;
                 *ebx = 0x1c0003f;
                 *ecx = 0x000003f;
                 *edx = 0x0000001;
                 break;
-            case 1: /* L1 icache info */
+            case 1: /* L1 icache info: 32KB */
                 *eax |= 0x0000122;
                 *ebx = 0x1c0003f;
                 *ecx = 0x000003f;
                 *edx = 0x0000001;
                 break;
-            case 2: /* L2 cache info */
+            case 2: /* L2 cache info: 1024KB */
                 *eax |= 0x0000143;
                 if (env->nr_threads > 1) {
                     *eax |= (env->nr_threads - 1) << 14;
                 }
                 *ebx = 0x3c0003f;
-                *ecx = 0x0000fff;
+                *ecx = 0x00003ff;
                 *edx = 0x0000001;
                 break;
             default: /* end of info */
@@ -813,14 +813,14 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
         break;
     case 0x80000005:
-        /* cache info (L1 cache) */
+        /* cache info (L1 cache): 64KB L1D & L1I */
         *eax = 0x01ff01ff;
         *ebx = 0x01ff01ff;
         *ecx = 0x40020140;
         *edx = 0x40020140;
         break;
     case 0x80000006:
-        /* cache info (L2 cache) */
+        /* cache info (L2 cache): 512KB L2, no L3 */
         *eax = 0;
         *ebx = 0x42004200;
         *ecx = 0x02008140;
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 15/21] cpuid: Adjust feature bit constants
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (13 preceding siblings ...)
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 14/21] cpuid: decrease L2 cache for Intel and add comments Andre Przywara
@ 2009-09-18 11:48 ` Andre Przywara
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 16/21] cpuid: Update qemu64/32 CPU models Andre Przywara
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

Some constants defining common feature flags for well know CPUs were
not correct. Fix them and create additional ones which were used by
more than one CPU.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/cpuid.c |   26 +++++++++++++-------------
 1 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 8ec730c..bae90e7 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -118,17 +118,17 @@ typedef struct x86_def_t {
     uint32_t flags;
 } x86_def_t;
 
-#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
-#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
-          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX)
-#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
-          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
-          CPUID_PSE36 | CPUID_FXSR)
-#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
-#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
-          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
-          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
-          CPUID_PAE | CPUID_SEP | CPUID_APIC)
+#define I486_FEATURES (CPUID_FP87 | CPUID_VME)
+#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_PSE | \
+        CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_APIC)
+#define PPRO_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
+        CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV)
+#define PENTIUM2_FEATURES (PPRO_FEATURES | CPUID_FXSR | CPUID_PAT | \
+        CPUID_PSE36 | CPUID_MMX)
+#define K8_FEATURES (PENTIUM2_FEATURES | CPUID_SSE | CPUID_SSE2 | CPUID_CLFLUSH)
+#define FULL_FEATURES (K8_FEATURES | CPUID_DTS | CPUID_ACPI | CPUID_SS | \
+        CPUID_TM | CPUID_PBE)
+#define EXT2_FEATURES_64 (CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX)
 #define EXT2_FEATURE_MASK 0x0183F3FF
 
 #define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
@@ -288,7 +288,7 @@ static x86_def_t x86_defs[] = {
         .family = 5,
         .model = 4,
         .stepping = 3,
-        .features = PENTIUM_FEATURES,
+        .features = PENTIUM_FEATURES | CPUID_MMX,
         .xlevel = 0,
     },
     {
@@ -306,7 +306,7 @@ static x86_def_t x86_defs[] = {
         .family = 6,
         .model = 7,
         .stepping = 3,
-        .features = PENTIUM3_FEATURES,
+        .features = PENTIUM2_FEATURES | CPUID_SSE,
         .xlevel = 0,
     },
     {
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 16/21] cpuid: Update qemu64/32 CPU models
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (14 preceding siblings ...)
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 15/21] cpuid: Adjust feature bit constants Andre Przywara
@ 2009-09-18 11:48 ` Andre Przywara
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 17/21] cpuid: Fix CPU models to use new feature set names Andre Przywara
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

Since we now have a real TCG feature set, use it to describe the
artificial qemu CPUs (both 64 and 32-bit). If new features are added
to TCG, the capability of qemu64/32 will automatically be adjusted.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/cpuid.c |   25 +++++++++++++------------
 1 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index bae90e7..1ad21d3 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -155,15 +155,12 @@ static x86_def_t x86_defs[] = {
         .family = 6,
         .model = 2,
         .stepping = 3,
-        .features = PPRO_FEATURES |
-        /* these features are needed for Win64 and aren't fully implemented */
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
-        /* this feature is needed for Solaris and isn't fully implemented */
-            CPUID_PSE36,
-        .ext_features = CPUID_EXT_SSE3,
-        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
-            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
-        .ext3_features = CPUID_EXT3_SVM,
+        .features = TCG_FEATURES,
+        .ext_features = TCG_EXT_FEATURES,
+        /* 3DNow! is deprecated, so leave it out of the default feature set */
+        .ext2_features = (TCG_EXT2_FEATURES | EXT2_FEATURES_64) &
+                        ~(CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT),
+        .ext3_features = TCG_EXT3_FEATURES,
         .xlevel = 0x8000000A,
         .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
     },
@@ -249,9 +246,13 @@ static x86_def_t x86_defs[] = {
         .family = 6,
         .model = 3,
         .stepping = 3,
-        .features = PPRO_FEATURES,
-        .ext_features = CPUID_EXT_SSE3,
-        .xlevel = 0,
+        .features = TCG_FEATURES,
+        .ext_features = TCG_EXT_FEATURES,
+        /* 3DNow! is deprecated, so leave it out of the default feature set */
+        .ext2_features = (TCG_EXT2_FEATURES) &
+                        ~(CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT),
+        .ext3_features = TCG_EXT3_FEATURES,
+        .xlevel = 0x80000001,
         .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
     },
     {
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 17/21] cpuid: Fix CPU models to use new feature set names
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (15 preceding siblings ...)
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 16/21] cpuid: Update qemu64/32 CPU models Andre Przywara
@ 2009-09-18 11:48 ` Andre Przywara
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 18/21] cpuid: Fix 486 CPU model Andre Przywara
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

Since we now do proper CPUID masking (either TCG or KVM kernel based)
we can now expose the full feature set of each actual CPU model.
Unsupported features will be removed at runtime.
Update various CPU models to use the new feature flag names and
adjust them to match the real thing.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/cpuid.c |   94 ++++++++++++++++++--------------------------------
 1 files changed, 34 insertions(+), 60 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 1ad21d3..e4200ea 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -173,22 +173,18 @@ static x86_def_t x86_defs[] = {
         .family = 16,
         .model = 2,
         .stepping = 3,
-        /* Missing: CPUID_VME, CPUID_HT */
-        .features = PPRO_FEATURES |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
-            CPUID_PSE36,
-        /* Missing: CPUID_EXT_CX16, CPUID_EXT_POPCNT */
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
-        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
-        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
-            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
-            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
-            CPUID_EXT2_FFXSR,
-        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
-                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
-                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
-                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
-        .ext3_features = CPUID_EXT3_SVM,
+        .features = K8_FEATURES | CPUID_HT,
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR |
+            CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
+        .ext2_features = (K8_FEATURES & EXT2_FEATURE_MASK) | 
+            EXT2_FEATURES_64 | CPUID_EXT2_MMXEXT | CPUID_EXT2_FFXSR |
+            CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
+            CPUID_EXT2_3DNOWEXT | CPUID_EXT2_3DNOW,
+        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_CMP_LEG |
+            CPUID_EXT3_SVM | CPUID_EXT3_EXTAPIC | CPUID_EXT3_CR8LEG |
+            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A | CPUID_EXT3_MISALIGNSSE |
+            CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_OSVW | CPUID_EXT3_IBS |
+            CPUID_EXT3_SKINIT,
         .xlevel = 0x8000001A,
         .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
     },
@@ -198,18 +194,13 @@ static x86_def_t x86_defs[] = {
         .family = 6,
         .model = 15,
         .stepping = 11,
-        /* The original CPU also implements these features:
-               CPUID_VME, CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
-               CPUID_TM, CPUID_PBE */
-        .features = PPRO_FEATURES |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
-            CPUID_PSE36,
-        /* The original CPU also implements these ext features:
-               CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
-               CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3,
-        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
-        /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
+        .features = FULL_FEATURES,
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_DTES64 | CPUID_EXT_MONITOR |
+               CPUID_EXT_DSCPL | CPUID_EXT_VMX | CPUID_EXT_EST |
+               CPUID_EXT_TM2 | CPUID_EXT_SSSE3 |
+               CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
+        .ext2_features = EXT2_FEATURES_64,
+        .ext3_features = CPUID_EXT3_LAHF_LM,
         .xlevel = 0x80000008,
         .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
     },
@@ -222,19 +213,9 @@ static x86_def_t x86_defs[] = {
         .family = 15,
         .model = 6,
         .stepping = 1,
-        /* Missing: CPUID_VME, CPUID_HT */
-        .features = PPRO_FEATURES |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
-            CPUID_PSE36,
-        /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
+        .features = K8_FEATURES,
         .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
-        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
-        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
-            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
-        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
-                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
-                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
-                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
+        .ext2_features = (K8_FEATURES & EXT2_FEATURE_MASK) | EXT2_FEATURES_64,
         .ext3_features = 0,
         .xlevel = 0x80000008,
         .model_id = "Common KVM processor"
@@ -319,33 +300,26 @@ static x86_def_t x86_defs[] = {
         .family = 6,
         .model = 2,
         .stepping = 3,
-        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME |
-            CPUID_MTRR | CPUID_MCA,
-        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
-            CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
+        .features = PENTIUM2_FEATURES,
+        .ext2_features = (PENTIUM2_FEATURES & EXT2_FEATURE_MASK) |
+            CPUID_EXT2_SYSCALL | CPUID_EXT2_MMXEXT |
+            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
         .xlevel = 0x80000008,
-        /* XXX: put another string ? */
-        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
+        .model_id = "AMD Athlon(tm) Processor",
     },
     {
         .name = "n270",
-        /* original is on level 10 */
-        .level = 5,
+        .level = 10,
         .family = 6,
         .model = 28,
         .stepping = 2,
-        .features = PPRO_FEATURES |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME,
-            /* Missing: CPUID_DTS | CPUID_ACPI | CPUID_SS |
-             * CPUID_HT | CPUID_TM | CPUID_PBE */
-            /* Some CPUs got no CPUID_SEP */
-        .ext_features = CPUID_EXT_MONITOR |
-            CPUID_EXT_SSE3 /* PNI */ | CPUID_EXT_SSSE3,
-            /* Missing: CPUID_EXT_DSCPL | CPUID_EXT_EST |
-             * CPUID_EXT_TM2 | CPUID_EXT_XTPR */
-        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) | CPUID_EXT2_NX,
-        /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
-        .xlevel = 0x8000000A,
+        .features = FULL_FEATURES & ~CPUID_PSE36,
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_DTES64 | CPUID_EXT_MONITOR |
+            CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_SSSE3 |
+            CPUID_EXT_XTPR | CPUID_EXT_PDCM | CPUID_EXT_MOVBE,
+        .ext2_features = CPUID_EXT2_NX,
+        .ext3_features = CPUID_EXT3_LAHF_LM,
+        .xlevel = 0x80000008,
         .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
     },
 };
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 18/21] cpuid: Fix 486 CPU model
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (16 preceding siblings ...)
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 17/21] cpuid: Fix CPU models to use new feature set names Andre Przywara
@ 2009-09-18 11:48 ` Andre Przywara
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 19/21] cpuid: Add athlon64 " Andre Przywara
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

For the CPUID feature leaf to be actually useful, we should set
the maximum leaf to 1, so the guests will try to read it.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/cpuid.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index e4200ea..2e02556 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -257,9 +257,9 @@ static x86_def_t x86_defs[] = {
     },
     {
         .name = "486",
-        .level = 0,
+        .level = 1,
         .family = 4,
-        .model = 0,
+        .model = 1,
         .stepping = 0,
         .features = I486_FEATURES,
         .xlevel = 0,
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 19/21] cpuid: Add athlon64 CPU model
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (17 preceding siblings ...)
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 18/21] cpuid: Fix 486 CPU model Andre Przywara
@ 2009-09-18 11:48 ` Andre Przywara
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 20/21] cpuid: Add kvm32 " Andre Przywara
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

This new CPU model describes a dualcore Athlon 64.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/cpuid.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 2e02556..1721be2 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -165,6 +165,25 @@ static x86_def_t x86_defs[] = {
         .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
     },
     {
+        .name = "athlon64",
+        .level = 1,
+        .vendor1 = CPUID_VENDOR_AMD_1,
+        .vendor2 = CPUID_VENDOR_AMD_2,
+        .vendor3 = CPUID_VENDOR_AMD_3,
+        .family = 15,
+        .model = 67,
+        .stepping = 3,
+        .features = K8_FEATURES | CPUID_HT,
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
+        .ext2_features = (K8_FEATURES & EXT2_FEATURE_MASK) |
+            EXT2_FEATURES_64 | CPUID_EXT2_MMXEXT | CPUID_EXT2_FFXSR |
+            CPUID_EXT2_RDTSCP | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_3DNOW,
+        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_CMP_LEG |
+            CPUID_EXT3_SVM | CPUID_EXT3_EXTAPIC | CPUID_EXT3_CR8LEG,
+        .xlevel = 0x80000018,
+        .model_id = "AMD Athlon(tm) 64 X2 Dual Core Processor 6000+",
+    },
+    {
         .name = "phenom",
         .level = 5,
         .vendor1 = CPUID_VENDOR_AMD_1,
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 20/21] cpuid: Add kvm32 CPU model
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (18 preceding siblings ...)
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 19/21] cpuid: Add athlon64 " Andre Przywara
@ 2009-09-18 11:48 ` Andre Przywara
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 21/21] cpuid: Always expose 32 and 64-bit CPUs Andre Przywara
  2009-10-02 17:44 ` [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Anthony Liguori
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

Create a kvm32 CPU model that describes a least common denominator
for KVM capable guest CPUs. Useful for migration purposes.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/cpuid.c |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 1721be2..505fca5 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -256,6 +256,19 @@ static x86_def_t x86_defs[] = {
         .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
     },
     {
+        .name = "kvm32",
+        .level = 5,
+        .family = 15,
+        .model = 6,
+        .stepping = 1,
+        .features = K8_FEATURES,
+        .ext_features = CPUID_EXT_SSE3,
+        .ext2_features = K8_FEATURES & EXT2_FEATURE_MASK,
+        .ext3_features = 0,
+        .xlevel = 0x80000008,
+        .model_id = "Common 32-bit KVM processor"
+    },
+    {
         .name = "coreduo",
         .level = 10,
         .family = 6,
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH v2 21/21] cpuid: Always expose 32 and 64-bit CPUs
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (19 preceding siblings ...)
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 20/21] cpuid: Add kvm32 " Andre Przywara
@ 2009-09-18 11:48 ` Andre Przywara
  2009-10-02 17:44 ` [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Anthony Liguori
  21 siblings, 0 replies; 23+ messages in thread
From: Andre Przywara @ 2009-09-18 11:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andre Przywara

Since 64-bit capability is just another CPUID bit we now properly
mask, there is no reason anymore to hide the 64-bit capable CPU
models from a 32-bit only QEMU. All 64-bit CPUs can be used
perfectly in 32-bit legacy mode anyway, so these models also make
sense for 32-bit.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 target-i386/cpuid.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 505fca5..9d687fd 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -145,7 +145,6 @@ typedef struct x86_def_t {
 #define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM)
 
 static x86_def_t x86_defs[] = {
-#ifdef TARGET_X86_64
     {
         .name = "qemu64",
         .level = 4,
@@ -239,7 +238,6 @@ static x86_def_t x86_defs[] = {
         .xlevel = 0x80000008,
         .model_id = "Common KVM processor"
     },
-#endif
     {
         .name = "qemu32",
         .level = 4,
-- 
1.6.1.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements
  2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
                   ` (20 preceding siblings ...)
  2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 21/21] cpuid: Always expose 32 and 64-bit CPUs Andre Przywara
@ 2009-10-02 17:44 ` Anthony Liguori
  21 siblings, 0 replies; 23+ messages in thread
From: Anthony Liguori @ 2009-10-02 17:44 UTC (permalink / raw)
  To: Andre Przywara; +Cc: qemu-devel

Andre Przywara wrote:
> Hi,
>   
This breaks TCG and is not bisect friendly.  My guest is a 64-bit Ubuntu 
Karmic server image.  With the whole series applied, the guest doesn't 
boot.  With various combinations of patches applied, the guest will give 
an error about missing CPU features.

I'd suggest testing each patch with TCG.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2009-10-02 17:44 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-18 11:47 [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Andre Przywara
2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 01/21] cpuid: move CPUID functions into separate file Andre Przywara
2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 02/21] cpuid: fix over-long lines Andre Przywara
2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 03/21] cpuid: replace magic number with named constant Andre Przywara
2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 04/21] cpuid: fix comments Andre Przywara
2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 05/21] cpuid: moved host_cpuid function and remove prototype Andre Przywara
2009-09-18 11:47 ` [Qemu-devel] [PATCH v2 06/21] cpuid: Replace strtok with get_opt_name Andre Przywara
2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 07/21] cpuid: add missing CPUID feature flag names Andre Przywara
2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 08/21] cpuid: list all known x86 CPUID feature flags Andre Przywara
2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 09/21] cpuid: remove unnecessary kvm_trim function Andre Przywara
2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 10/21] cpuid: simplify CPUID flag search function Andre Przywara
2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 11/21] cpuid: propagate further CPUID leafs when -cpu host Andre Przywara
2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 12/21] cpuid: Fix multicore setup on Intel Andre Przywara
2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 13/21] cpuid: add TCG feature bit trimming Andre Przywara
2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 14/21] cpuid: decrease L2 cache for Intel and add comments Andre Przywara
2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 15/21] cpuid: Adjust feature bit constants Andre Przywara
2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 16/21] cpuid: Update qemu64/32 CPU models Andre Przywara
2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 17/21] cpuid: Fix CPU models to use new feature set names Andre Przywara
2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 18/21] cpuid: Fix 486 CPU model Andre Przywara
2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 19/21] cpuid: Add athlon64 " Andre Przywara
2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 20/21] cpuid: Add kvm32 " Andre Przywara
2009-09-18 11:48 ` [Qemu-devel] [PATCH v2 21/21] cpuid: Always expose 32 and 64-bit CPUs Andre Przywara
2009-10-02 17:44 ` [Qemu-devel] [PATCH v2 00/21] cpuid: cleanup, fixes and some enhancements Anthony Liguori

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).