* [Qemu-devel] [PATCH] Add definitions for current cpu models..
@ 2009-12-21 6:46 john cooper
[not found] ` <20091224130521.GD4781@amt.cnet>
0 siblings, 1 reply; 3+ messages in thread
From: john cooper @ 2009-12-21 6:46 UTC (permalink / raw)
To: KVM list; +Cc: john.cooper, qemu-devel
This adds definitions for contemporary processors
which may be selected via -cpu <model>, as an
alternative to the existing use of -cpu qemu64
augmented with a series of feature flags.
The primary motivation was determination of a
least common denominator within a given processor
class for simplification of guest migration. It
is still possible to modify an arbitrary model via
additional feature flags however the goal here was
to make doing so unnecessary in typical usage. The
other consideration was providing models names
reflective of current processors. Both AMD and
Intel have reviewed the models in terms of balancing
generality of migration vs. excessive feature
downgrade relative to released silicon.
A cpu feature 'check' option is also added which
warns when feature flags (either implicit in a cpu
model or explicit on the command line) would have
otherwise been quietly disabled for a guest.
This patch was tested relative to qemu-kvm.git.
Signed-off-by: john cooper <john.cooper@redhat.com>
---
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 9a50da6..a706cae 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -44,7 +44,7 @@ static const char *feature_name[] = {
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, "x2apic", NULL, "popcnt",
+ NULL, NULL, "dca", "sse4.1", "sse4.2", "x2apic", NULL, "popcnt",
NULL, NULL, NULL, NULL, NULL, NULL, NULL, "hypervisor",
};
static const char *ext2_feature_name[] = {
@@ -60,6 +60,18 @@ static const char *ext3_feature_name[] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
+/* collects per-function cpuid data
+ */
+typedef struct model_features_t {
+ uint32_t *guest_feat;
+ uint32_t *host_feat;
+ uint32_t check_feat;
+ const char **flag_names;
+ uint32_t cpuid;
+ } model_features_t;
+
+int check_cpuid = 0;
+
static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
uint32_t *ext_features,
uint32_t *ext2_features,
@@ -171,6 +183,139 @@ static x86_def_t x86_defs[] = {
.model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
},
{
+ .name = "Merom",
+ .level = 2,
+ .vendor1 = CPUID_VENDOR_INTEL_1,
+ .vendor2 = CPUID_VENDOR_INTEL_2,
+ .vendor3 = CPUID_VENDOR_INTEL_3,
+ .family = 6, /* P6 */
+ .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, /* from qemu64 */
+ .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
+ CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+ .ext3_features = CPUID_EXT3_SVM, /* from qemu64 */
+ .xlevel = 0x8000000A,
+ .model_id = "Intel Merom Core 2",
+ },
+ {
+ .name = "Penryn",
+ .level = 2,
+ .vendor1 = CPUID_VENDOR_INTEL_1,
+ .vendor2 = CPUID_VENDOR_INTEL_2,
+ .vendor3 = CPUID_VENDOR_INTEL_3,
+ .family = 6, /* P6 */
+ .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 |
+ CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE41,
+ .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
+ CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+ .ext3_features = CPUID_EXT3_SVM,
+ .xlevel = 0x8000000A,
+ .model_id = "Intel Penryn Core 2",
+ },
+ {
+ .name = "Nehalem",
+ .level = 2,
+ .vendor1 = CPUID_VENDOR_INTEL_1,
+ .vendor2 = CPUID_VENDOR_INTEL_2,
+ .vendor3 = CPUID_VENDOR_INTEL_3,
+ .family = 6, /* P6 */
+ .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 |
+ CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE41 |
+ CPUID_EXT_SSE42 | CPUID_EXT_POPCNT,
+ .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
+ CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+ .ext3_features = CPUID_EXT3_SVM,
+ .xlevel = 0x8000000A,
+ .model_id = "Intel Nehalem Core i7",
+ },
+ {
+ .name = "Opteron_G1",
+ .level = 5,
+ .vendor1 = CPUID_VENDOR_INTEL_1,
+ .vendor2 = CPUID_VENDOR_INTEL_2,
+ .vendor3 = CPUID_VENDOR_INTEL_3,
+ .family = 15,
+ .model = 6,
+ .stepping = 1,
+ .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 | CPUID_EXT_MONITOR,
+ .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
+ CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+ .ext3_features = CPUID_EXT3_SVM,
+ .xlevel = 0x80000008,
+ .model_id = "AMD Opteron G1",
+ },
+ {
+ .name = "Opteron_G2",
+ .level = 5,
+ .vendor1 = CPUID_VENDOR_INTEL_1,
+ .vendor2 = CPUID_VENDOR_INTEL_2,
+ .vendor3 = CPUID_VENDOR_INTEL_3,
+ .family = 15,
+ .model = 6,
+ .stepping = 1,
+ .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 | CPUID_EXT_CX16,
+ .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
+ .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
+ CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
+ CPUID_EXT2_RDTSCP,
+ .ext3_features = CPUID_EXT3_SVM,
+ .xlevel = 0x80000008,
+ .model_id = "AMD Opteron G2",
+ },
+ {
+ .name = "Opteron_G3",
+ .level = 5,
+ .vendor1 = CPUID_VENDOR_INTEL_1,
+ .vendor2 = CPUID_VENDOR_INTEL_2,
+ .vendor3 = CPUID_VENDOR_INTEL_3,
+ .family = 15,
+ .model = 6,
+ .stepping = 1,
+ .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 | CPUID_EXT_CX16,
+ .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_POPCNT,
+ .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
+ CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
+ CPUID_EXT2_RDTSCP,
+ .ext3_features = CPUID_EXT3_SVM | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
+ CPUID_EXT3_MISALIGNSSE,
+ .xlevel = 0x80000008,
+ .model_id = "AMD Opteron G3",
+ },
+ /* this feature is needed for Solaris and isn't fully implemented */
+ {
.name = "core2duo",
.level = 10,
.family = 6,
@@ -319,7 +464,7 @@ static x86_def_t x86_defs[] = {
/* 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,
@@ -370,6 +515,51 @@ static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
return 0;
}
+static int unavailable_host_feature(struct model_features_t *f, uint32_t mask)
+{
+ int i;
+
+ for (i = 0; i < 32; ++i)
+ if (1 << i & mask) {
+ fprintf(stderr, "warning: host cpuid %04x_%04x lacks requested"
+ " flag '%s' [0x%08x]\n",
+ f->cpuid >> 16, f->cpuid & 0xffff,
+ f->flag_names[i] ? f->flag_names[i] : "[reserved]", mask);
+ break;
+ }
+ return 0;
+}
+
+/* best effort attempt to inform user requested cpu flags aren't making
+ * their way to the guest. Note: ft[].check_feat ideally should be
+ * specified via a guest_def field to suppress report of extraneous flags.
+ */
+static int check_features_against_host(x86_def_t *guest_def)
+{
+ x86_def_t host_def;
+ uint32_t mask;
+ int rv, i;
+ struct model_features_t ft[] = {
+ {&guest_def->features, &host_def.features,
+ ~0, feature_name, 0x00000000},
+ {&guest_def->ext_features, &host_def.ext_features,
+ ~CPUID_EXT_HYPERVISOR, ext_feature_name, 0x00000001},
+ {&guest_def->ext2_features, &host_def.ext2_features,
+ ~PPRO_FEATURES, ext2_feature_name, 0x80000000},
+ {&guest_def->ext3_features, &host_def.ext3_features,
+ ~CPUID_EXT3_SVM, ext3_feature_name, 0x80000001}};
+
+ cpu_x86_fill_host(&host_def);
+ for (rv = 0, i = 0; i < sizeof (ft) / sizeof (ft[0]); ++i)
+ for (mask = 1; mask; mask <<= 1)
+ if (ft[i].check_feat & mask && *ft[i].guest_feat & mask &&
+ !(*ft[i].host_feat & mask)) {
+ unavailable_host_feature(&ft[i], mask);
+ rv = 1;
+ }
+ return (rv);
+}
+
static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
{
unsigned int i;
@@ -473,6 +663,8 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
fprintf(stderr, "unrecognized feature %s\n", featurestr);
goto error;
}
+ } else if (!strcmp(featurestr, "check")) {
+ check_cpuid = 1;
} else {
fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
goto error;
@@ -487,6 +679,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;
+ if (check_cpuid)
+ check_features_against_host(x86_cpu_def);
+
free(s);
return 0;
--
john.cooper@redhat.com
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [Qemu-devel] Re: [PATCH] Add definitions for current cpu models..
[not found] ` <20091224130521.GD4781@amt.cnet>
@ 2010-01-05 6:06 ` john cooper
0 siblings, 0 replies; 3+ messages in thread
From: john cooper @ 2010-01-05 6:06 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: john.cooper, qemu-devel, KVM list
Marcelo Tosatti wrote:
> On Mon, Dec 21, 2009 at 01:46:36AM -0500, john cooper wrote:
>> + {
>> + .name = "Opteron_G2",
>> + .level = 5,
>> + .vendor1 = CPUID_VENDOR_INTEL_1,
>> + .vendor2 = CPUID_VENDOR_INTEL_2,
>> + .vendor3 = CPUID_VENDOR_INTEL_3,
>
> Silly question: why a CPU named "Opteron_G2" uses intel vendor id's?
The feedback I had from AMD indicated using the Intel
strings for a family 15 cpu resulted in the least
amount of guest confusion. The upstream kvm64 model
does similarly.
Sorry for my late response here which was preempted
by the intervening holiday.
-john
--
john.cooper@redhat.com
^ permalink raw reply [flat|nested] 3+ messages in thread
* [Qemu-devel] Re: [PATCH] Add definitions for current cpu models..
2010-01-18 16:45 [Qemu-devel] " john cooper
@ 2010-01-20 23:20 ` Arnd Bergmann
0 siblings, 0 replies; 3+ messages in thread
From: Arnd Bergmann @ 2010-01-20 23:20 UTC (permalink / raw)
To: john cooper; +Cc: Przywara, Andre, qemu-devel, KVM list
On Monday 18 January 2010, john cooper wrote:
> + .name = "Conroe",
> + .level = 2,
> + .vendor1 = CPUID_VENDOR_INTEL_1,
> + .vendor2 = CPUID_VENDOR_INTEL_2,
> + .vendor3 = CPUID_VENDOR_INTEL_3,
> + .family = 6, /* P6 */
> + .model = 2,
^^^^^^^^ that looks wrong -- what is model 2 actually?
> + .stepping = 3,
> + .features = PPRO_FEATURES |
> + CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | /* note 1 */
> + CPUID_PSE36, /* note 2 */
> + .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_SSSE3,
> + .ext2_features = (PPRO_FEATURES & CPUID_EXT2_MASK) |
> + CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
> + .ext3_features = CPUID_EXT3_LAHF_LM,
> + .xlevel = 0x8000000A,
> + .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
> + },
Celeron_4x0 is a rather bad example, because it is based on the
single-core Conroe-L, which is family 6 / model 22 unlike all the dual-
and quad-core Merom/Conroe that are model 15.
> + {
> + .name = "Penryn",
> + .level = 2,
> + .vendor1 = CPUID_VENDOR_INTEL_1,
> + .vendor2 = CPUID_VENDOR_INTEL_2,
> + .vendor3 = CPUID_VENDOR_INTEL_3,
> + .family = 6, /* P6 */
> + .model = 2,
> + .stepping = 3,
> + .features = PPRO_FEATURES |
> + CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | /* note 1 */
> + CPUID_PSE36, /* note 2 */
> + .ext_features = CPUID_EXT_SSE3 |
> + CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE41,
> + .ext2_features = (PPRO_FEATURES & CPUID_EXT2_MASK) |
> + CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
> + .ext3_features = CPUID_EXT3_LAHF_LM,
> + .xlevel = 0x8000000A,
> + .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
> + },
This would be model 23 for Penryn-class Xeon/Core/Pentium/Celeron processors
without L3 cache.
> + {
> + .name = "Nehalem",
> + .level = 2,
> + .vendor1 = CPUID_VENDOR_INTEL_1,
> + .vendor2 = CPUID_VENDOR_INTEL_2,
> + .vendor3 = CPUID_VENDOR_INTEL_3,
> + .family = 6, /* P6 */
> + .model = 2,
> + .stepping = 3,
> + .features = PPRO_FEATURES |
> + CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | /* note 1 */
> + CPUID_PSE36, /* note 2 */
> + .ext_features = CPUID_EXT_SSE3 |
> + CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE41 |
> + CPUID_EXT_SSE42 | CPUID_EXT_POPCNT,
> + .ext2_features = (PPRO_FEATURES & CPUID_EXT2_MASK) |
> + CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
> + .ext3_features = CPUID_EXT3_LAHF_LM,
> + .xlevel = 0x8000000A,
> + .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
> + },
Apparently, not all the i7-9xx CPUs are Nehalem, the i7-980X is supposed
to be Westmere, which has more features.
Because of the complexity, I'd recommend passing down the *model* number
of the emulated CPU, the interesting Intel ones (those supported by KVM) being:
15-6: CedarMill/Presler/Dempsey/Tulsa (Pentium 4/Pentium D/Xeon 50xx/Xeon 71xx)
6-14: Yonah/Sossaman (Celeron M4xx, Core Solo/Duo, Pentium Dual-Core T1000, Xeon ULV)
6-15: Merom/Conroe/Kentsfield/Woodcrest/Clovertown/Tigerton
(Celeron M5xx/E1xxx/T1xxx, Pentium T2xxx/T3xxx/E2xxx,Core 2 Solo U2xxx,
Core 2 Duo E4xxx/E6xxx/Q6xxx/T5xxx/T7xxx/L7xxx/U7xxx/SP7xxx,
Xeon 30xx/32xx/51xx/52xx/72xx/73xx)
6-22: Penryn/Wolfdale/Yorkfield/Harpertown (Celeron 7xx/9xx/SU2xxx/T3xxx/E3xxx,
Pentium T4xxx/SU2xxx/SU4xxx/E5xxx/E6xxx, Core 2 Solo SU3xxx,
Core 2 Duo Pxxxx/SUxxxx/T6xxx/x8xxx/x9xxx,
Xeon 31xx/33xx/52xx/54xx)
6-26: Gainestown/Bloomfield (Xeon 35xx/55xx, Core i7-9xx)
6-28: Atom
6-29: Dunnington (Xeon 74xx)
6-30: Lynnfield/Clarksfield/JasperForest (Xeon 34xx, Core i7-8xx, Core i7-xxxQM,
Core i5-7xx)
6-37: Arrandale/Clarkdale (Dual-Core Core i3/i5/i7)
6-44: Gulftown (six-core)
Arnd
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2010-01-20 23:20 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-12-21 6:46 [Qemu-devel] [PATCH] Add definitions for current cpu models john cooper
[not found] ` <20091224130521.GD4781@amt.cnet>
2010-01-05 6:06 ` [Qemu-devel] " john cooper
-- strict thread matches above, loose matches on Subject: below --
2010-01-18 16:45 [Qemu-devel] " john cooper
2010-01-20 23:20 ` [Qemu-devel] " Arnd Bergmann
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).