* [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements
@ 2009-09-10 22:20 Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 01/12] cpuid: move CPUID functions into separate file Andre Przywara
` (13 more replies)
0 siblings, 14 replies; 18+ messages in thread
From: Andre Przywara @ 2009-09-10 22:20 UTC (permalink / raw)
To: qemu-devel
Hi,
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 & 7 add the CPUID feature flag names to the output of -cpu ?.
Patch 8 & 9 simplify some code.
Patch 10 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 11 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.
I will send a patch fixing the CPU models later.
Patch 12 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.
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] 18+ messages in thread
* [Qemu-devel] [PATCH 01/12] cpuid: move CPUID functions into separate file
2009-09-10 22:20 [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements Andre Przywara
@ 2009-09-10 22:20 ` Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 02/12] cpuid: fix over-long lines Andre Przywara
` (12 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Andre Przywara @ 2009-09-10 22:20 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 | 2 +-
target-i386/cpu.h | 1 +
target-i386/cpuid.c | 775 ++++++++++++++++++++++++++++++++++++++++++++++++++
target-i386/helper.c | 744 ------------------------------------------------
4 files changed, 777 insertions(+), 745 deletions(-)
create mode 100644 target-i386/cpuid.c
diff --git a/Makefile.target b/Makefile.target
index 0fe8b6a..e46ea37 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -35,7 +35,7 @@ libobj-y = exec.o translate-all.o cpu-exec.o translate.o
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
+libobj-y += op_helper.o helper.o cpuid.o
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..0c0c0b7
--- /dev/null
+++ b/target-i386/cpuid.c
@@ -0,0 +1,775 @@
+/*
+ * 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 <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <signal.h>
+
+#include "cpu.h"
+#include "exec-all.h"
+#include "qemu-common.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 27063e5..f28fb15 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)
@@ -1605,236 +1091,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] 18+ messages in thread
* [Qemu-devel] [PATCH 02/12] cpuid: fix over-long lines
2009-09-10 22:20 [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 01/12] cpuid: move CPUID functions into separate file Andre Przywara
@ 2009-09-10 22:20 ` Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 03/12] cpuid: replace magic number with named constant Andre Przywara
` (11 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Andre Przywara @ 2009-09-10 22:20 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 | 25 +++++++++++++++++--------
1 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 0c0c0b7..b610834 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -289,8 +289,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 & EXT2_FEATURE_MASK) |
+ CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
.xlevel = 0x80000008,
/* XXX: put another string ? */
.model_id = "QEMU Virtual CPU version " QEMU_VERSION,
@@ -373,8 +375,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;
@@ -400,9 +404,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")) {
@@ -470,7 +477,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, ",");
@@ -609,7 +617,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] 18+ messages in thread
* [Qemu-devel] [PATCH 03/12] cpuid: replace magic number with named constant
2009-09-10 22:20 [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 01/12] cpuid: move CPUID functions into separate file Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 02/12] cpuid: fix over-long lines Andre Przywara
@ 2009-09-10 22:20 ` Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 04/12] cpuid: fix comments Andre Przywara
` (10 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Andre Przywara @ 2009-09-10 22:20 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 | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index b610834..9ed9fb2 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -115,6 +115,8 @@ 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
{
@@ -132,7 +134,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,
@@ -154,7 +156,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,
@@ -313,7 +315,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] 18+ messages in thread
* [Qemu-devel] [PATCH 04/12] cpuid: fix comments
2009-09-10 22:20 [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements Andre Przywara
` (2 preceding siblings ...)
2009-09-10 22:20 ` [Qemu-devel] [PATCH 03/12] cpuid: replace magic number with named constant Andre Przywara
@ 2009-09-10 22:20 ` Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 05/12] cpuid: moved host_cpuid function and remove prototype Andre Przywara
` (9 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Andre Przywara @ 2009-09-10 22:20 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 9ed9fb2..7b69ff4 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -610,10 +610,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;
@@ -720,7 +722,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] 18+ messages in thread
* [Qemu-devel] [PATCH 05/12] cpuid: moved host_cpuid function and remove prototype
2009-09-10 22:20 [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements Andre Przywara
` (3 preceding siblings ...)
2009-09-10 22:20 ` [Qemu-devel] [PATCH 04/12] cpuid: fix comments Andre Przywara
@ 2009-09-10 22:20 ` Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 06/12] cpuid: add missing CPUID feature flag names Andre Przywara
` (8 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Andre Przywara @ 2009-09-10 22:20 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 7b69ff4..9ddf714 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -322,8 +322,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)
{
@@ -555,41 +587,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] 18+ messages in thread
* [Qemu-devel] [PATCH 06/12] cpuid: add missing CPUID feature flag names
2009-09-10 22:20 [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements Andre Przywara
` (4 preceding siblings ...)
2009-09-10 22:20 ` [Qemu-devel] [PATCH 05/12] cpuid: moved host_cpuid function and remove prototype Andre Przywara
@ 2009-09-10 22:20 ` Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 07/12] cpuid: list all known x86 CPUID feature flags Andre Przywara
` (7 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Andre Przywara @ 2009-09-10 22:20 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 9ddf714..ab3565e 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -36,24 +36,32 @@
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] 18+ messages in thread
* [Qemu-devel] [PATCH 07/12] cpuid: list all known x86 CPUID feature flags
2009-09-10 22:20 [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements Andre Przywara
` (5 preceding siblings ...)
2009-09-10 22:20 ` [Qemu-devel] [PATCH 06/12] cpuid: add missing CPUID feature flag names Andre Przywara
@ 2009-09-10 22:20 ` Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 08/12] cpuid: remove unnecessary kvm_trim function Andre Przywara
` (6 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Andre Przywara @ 2009-09-10 22:20 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 ab3565e..e62dc04 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -543,10 +543,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] 18+ messages in thread
* [Qemu-devel] [PATCH 08/12] cpuid: remove unnecessary kvm_trim function
2009-09-10 22:20 [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements Andre Przywara
` (6 preceding siblings ...)
2009-09-10 22:20 ` [Qemu-devel] [PATCH 07/12] cpuid: list all known x86 CPUID feature flags Andre Przywara
@ 2009-09-10 22:20 ` Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 09/12] cpuid: simplify CPUID flag search function Andre Przywara
` (5 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Andre Przywara @ 2009-09-10 22:20 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] 18+ messages in thread
* [Qemu-devel] [PATCH 09/12] cpuid: simplify CPUID flag search function
2009-09-10 22:20 [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements Andre Przywara
` (7 preceding siblings ...)
2009-09-10 22:20 ` [Qemu-devel] [PATCH 08/12] cpuid: remove unnecessary kvm_trim function Andre Przywara
@ 2009-09-10 22:20 ` Andre Przywara
2009-09-11 7:55 ` Amit Shah
2009-09-10 22:20 ` [Qemu-devel] [PATCH 10/12] cpuid: propagate further CPUID leafs when -cpu host Andre Przywara
` (4 subsequent siblings)
13 siblings, 1 reply; 18+ messages in thread
From: Andre Przywara @ 2009-09-10 22:20 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 e62dc04..4be1449 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -71,29 +71,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] 18+ messages in thread
* [Qemu-devel] [PATCH 10/12] cpuid: propagate further CPUID leafs when -cpu host
2009-09-10 22:20 [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements Andre Przywara
` (8 preceding siblings ...)
2009-09-10 22:20 ` [Qemu-devel] [PATCH 09/12] cpuid: simplify CPUID flag search function Andre Przywara
@ 2009-09-10 22:20 ` Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 11/12] cpuid: add TCG feature bit trimming Andre Przywara
` (3 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Andre Przywara @ 2009-09-10 22:20 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 4be1449..ca8fc45 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -102,7 +102,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)
@@ -398,7 +398,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;
}
@@ -503,7 +503,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);
@@ -574,7 +574,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);
@@ -605,17 +605,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) {
@@ -631,7 +646,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] 18+ messages in thread
* [Qemu-devel] [PATCH 11/12] cpuid: add TCG feature bit trimming
2009-09-10 22:20 [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements Andre Przywara
` (9 preceding siblings ...)
2009-09-10 22:20 ` [Qemu-devel] [PATCH 10/12] cpuid: propagate further CPUID leafs when -cpu host Andre Przywara
@ 2009-09-10 22:20 ` Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 12/12] cpuid: decrease L2 cache for Intel and add comments Andre Przywara
` (2 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Andre Przywara @ 2009-09-10 22:20 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 ca8fc45..b35523c 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -118,6 +118,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
{
@@ -588,6 +601,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;
@@ -755,9 +779,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] 18+ messages in thread
* [Qemu-devel] [PATCH 12/12] cpuid: decrease L2 cache for Intel and add comments
2009-09-10 22:20 [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements Andre Przywara
` (10 preceding siblings ...)
2009-09-10 22:20 ` [Qemu-devel] [PATCH 11/12] cpuid: add TCG feature bit trimming Andre Przywara
@ 2009-09-10 22:20 ` Andre Przywara
2009-09-11 7:55 ` [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements Amit Shah
2009-09-14 17:08 ` Anthony Liguori
13 siblings, 0 replies; 18+ messages in thread
From: Andre Przywara @ 2009-09-10 22:20 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 b35523c..7b3f31b 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -700,25 +700,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 */
@@ -790,14 +790,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] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 09/12] cpuid: simplify CPUID flag search function
2009-09-10 22:20 ` [Qemu-devel] [PATCH 09/12] cpuid: simplify CPUID flag search function Andre Przywara
@ 2009-09-11 7:55 ` Amit Shah
2009-09-11 19:30 ` Andre Przywara
0 siblings, 1 reply; 18+ messages in thread
From: Amit Shah @ 2009-09-11 7:55 UTC (permalink / raw)
To: Andre Przywara; +Cc: qemu-devel
On (Fri) Sep 11 2009 [00:20:54], Andre Przywara wrote:
> 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 e62dc04..4be1449 100644
> --- a/target-i386/cpuid.c
> +++ b/target-i386/cpuid.c
> @@ -71,29 +71,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);
> }
This just reports the entire string, right? Not just the feature as the
printf suggests.
Amit
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements
2009-09-10 22:20 [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements Andre Przywara
` (11 preceding siblings ...)
2009-09-10 22:20 ` [Qemu-devel] [PATCH 12/12] cpuid: decrease L2 cache for Intel and add comments Andre Przywara
@ 2009-09-11 7:55 ` Amit Shah
2009-09-14 17:08 ` Anthony Liguori
13 siblings, 0 replies; 18+ messages in thread
From: Amit Shah @ 2009-09-11 7:55 UTC (permalink / raw)
To: Andre Przywara; +Cc: qemu-devel
On (Fri) Sep 11 2009 [00:20:45], Andre Przywara wrote:
> Hi,
>
> 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 & 7 add the CPUID feature flag names to the output of -cpu ?.
> Patch 8 & 9 simplify some code.
> Patch 10 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 11 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.
> I will send a patch fixing the CPU models later.
> Patch 12 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.
>
> Please review, comment and apply!
Looks like a good series!
> Thanks and Regards,
> Andre.
Amit
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 09/12] cpuid: simplify CPUID flag search function
2009-09-11 7:55 ` Amit Shah
@ 2009-09-11 19:30 ` Andre Przywara
2009-09-14 7:23 ` Amit Shah
0 siblings, 1 reply; 18+ messages in thread
From: Andre Przywara @ 2009-09-11 19:30 UTC (permalink / raw)
To: Amit Shah; +Cc: qemu-devel
Amit Shah wrote:
> On (Fri) Sep 11 2009 [00:20:54], Andre Przywara wrote:
>> avoid code duplication and handle the CPUID flag name search in a
>> loop.
>> --- a/target-i386/cpuid.c
>> +++ b/target-i386/cpuid.c
>> @@ -71,29 +71,22 @@ static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
>> uint32_t *ext2_features,
>> uint32_t *ext3_features)
>> {
>>...
>> + 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);
>> }
>
> This just reports the entire string, right? Not just the feature as the
> printf suggests.
What makes you think so? flagname is just the single flag (being
returned by strtok in the caller, wich null-terminates its results).
Otherwise the strcmp() above would not work either...
Unknown flags will be reported, but do not abort QEMU (I checked this
myself by accident ;-)
Regards,
Andre.
--
Andre Przywara
AMD-OSRC (Dresden)
Tel: x29712
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 09/12] cpuid: simplify CPUID flag search function
2009-09-11 19:30 ` Andre Przywara
@ 2009-09-14 7:23 ` Amit Shah
0 siblings, 0 replies; 18+ messages in thread
From: Amit Shah @ 2009-09-14 7:23 UTC (permalink / raw)
To: Andre Przywara; +Cc: qemu-devel
On (Fri) Sep 11 2009 [21:30:52], Andre Przywara wrote:
> Amit Shah wrote:
>> On (Fri) Sep 11 2009 [00:20:54], Andre Przywara wrote:
>>> avoid code duplication and handle the CPUID flag name search in a
>>> loop.
>>> --- a/target-i386/cpuid.c
>>> +++ b/target-i386/cpuid.c
>>> @@ -71,29 +71,22 @@ static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
>>> uint32_t *ext2_features,
>>> uint32_t *ext3_features)
>>> {
> >>...
>>> + 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);
>>> }
>>
>> This just reports the entire string, right? Not just the feature as the
>> printf suggests.
> What makes you think so? flagname is just the single flag (being
> returned by strtok in the caller, wich null-terminates its results).
> Otherwise the strcmp() above would not work either...
> Unknown flags will be reported, but do not abort QEMU (I checked this
> myself by accident ;-)
strtok, right. It'd be good to remove that. Esp with QemuOpts it would
be easier
Amit
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements
2009-09-10 22:20 [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements Andre Przywara
` (12 preceding siblings ...)
2009-09-11 7:55 ` [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements Amit Shah
@ 2009-09-14 17:08 ` Anthony Liguori
13 siblings, 0 replies; 18+ messages in thread
From: Anthony Liguori @ 2009-09-14 17:08 UTC (permalink / raw)
To: Andre Przywara; +Cc: qemu-devel
Andre Przywara wrote:
> Hi,
>
> 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 & 7 add the CPUID feature flag names to the output of -cpu ?.
> Patch 8 & 9 simplify some code.
> Patch 10 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 11 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.
> I will send a patch fixing the CPU models later.
> Patch 12 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.
>
This series breaks the build for non-i386 targets as it unconditionally
adds cpuid.o to libqemu even though that file only exists for target-i386.
Regards,
Anthony Liguori
> Please review, comment and apply!
> Thanks and Regards,
> Andre.
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2009-09-14 17:08 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-10 22:20 [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 01/12] cpuid: move CPUID functions into separate file Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 02/12] cpuid: fix over-long lines Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 03/12] cpuid: replace magic number with named constant Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 04/12] cpuid: fix comments Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 05/12] cpuid: moved host_cpuid function and remove prototype Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 06/12] cpuid: add missing CPUID feature flag names Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 07/12] cpuid: list all known x86 CPUID feature flags Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 08/12] cpuid: remove unnecessary kvm_trim function Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 09/12] cpuid: simplify CPUID flag search function Andre Przywara
2009-09-11 7:55 ` Amit Shah
2009-09-11 19:30 ` Andre Przywara
2009-09-14 7:23 ` Amit Shah
2009-09-10 22:20 ` [Qemu-devel] [PATCH 10/12] cpuid: propagate further CPUID leafs when -cpu host Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 11/12] cpuid: add TCG feature bit trimming Andre Przywara
2009-09-10 22:20 ` [Qemu-devel] [PATCH 12/12] cpuid: decrease L2 cache for Intel and add comments Andre Przywara
2009-09-11 7:55 ` [Qemu-devel] [PATCH 0/12] cpuid: cleanup and some enhancements Amit Shah
2009-09-14 17:08 ` 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).