Skip to content

Commit

Permalink
Add cpu model configuration support..
Browse files Browse the repository at this point in the history
This is a reimplementation of prior versions which adds
the ability to define cpu models for contemporary processors.
The added models are likewise selected via -cpu <name>,
and are intended to displace the existing convention
of "-cpu qemu64" augmented with a series of feature flags.

A primary motivation was determination of a least common
denominator within a given processor class to simplify 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.

This version of the patch replaces the prior hard wired
definitions with a configuration file approach for new
models.  Existing models are thus far left as-is but may
easily be transitioned to (or may be overridden by) the
configuration file representation.

Proposed new model definitions are provided here for current
AMD and Intel processors.  Each model consists of a name
used to select it on the command line (-cpu <name>), and a
model_id which corresponds to a least common denominator
commercial instance of the processor class.

A table of names/model_ids may be queried via "-cpu ?model":

        :
    x86       Opteron_G3  AMD Opteron 23xx (Gen 3 Class Opteron)
    x86       Opteron_G2  AMD Opteron 22xx (Gen 2 Class Opteron)
    x86       Opteron_G1  AMD Opteron 240 (Gen 1 Class Opteron)
    x86          Nehalem  Intel Core i7 9xx (Nehalem Class Core i7)
    x86           Penryn  Intel Core 2 Duo P9xxx (Penryn Class Core 2)
    x86           Conroe  Intel Celeron_4x0 (Conroe/Merom Class Core 2)
        :

Also added is "-cpu ?dump" which exhaustively outputs all config
data for all defined models, and "-cpu ?cpuid" which enumerates
all qemu recognized CPUID feature flags.

The pseudo cpuid flag 'check' when added to the feature flag list
will warn when feature flags (either implicit in a cpu model or
explicit on the command line) would have otherwise been quietly
unavailable to a guest:

    # qemu-system-x86_64 ... -cpu Nehalem,check
    warning: host cpuid 0000_0001 lacks requested flag 'sse4.2|sse4_2' [0x00100000]
    warning: host cpuid 0000_0001 lacks requested flag 'popcnt' [0x00800000]

A similar 'enforce' pseudo flag exists which in addition
to the above causes qemu to error exit if requested flags are
unavailable.

Configuration data for a cpu model resides in the target config
file which by default will be installed as:

    /usr/local/etc/qemu/target-<arch>.conf

The format of this file should be self explanatory given the
definitions for the above six models and essentially mimics
the structure of the static x86_def_t x86_defs.

Encoding of cpuid flags names now allows aliases for both the
configuration file and the command line which reconciles some
Intel/AMD/Linux/Qemu naming differences.

This patch was tested relative to qemu.git.

Signed-off-by: john cooper <john.cooper@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
  • Loading branch information
john cooper authored and Anthony Liguori committed Feb 22, 2010
1 parent 4266a13 commit b5ec5ce
Show file tree
Hide file tree
Showing 8 changed files with 556 additions and 72 deletions.
6 changes: 5 additions & 1 deletion Makefile
Expand Up @@ -191,7 +191,11 @@ ifdef CONFIG_POSIX
$(INSTALL_DATA) qemu-nbd.8 "$(DESTDIR)$(mandir)/man8"
endif

install: all $(if $(BUILD_DOCS),install-doc)
install-sysconfig:
$(INSTALL_DIR) "$(sysconfdir)/qemu"
$(INSTALL_DATA) sysconfigs/target/target-x86_64.conf "$(sysconfdir)/qemu"

install: all $(if $(BUILD_DOCS),install-doc) install-sysconfig
$(INSTALL_DIR) "$(DESTDIR)$(bindir)"
ifneq ($(TOOLS),)
$(INSTALL_PROG) $(STRIP_OPT) $(TOOLS) "$(DESTDIR)$(bindir)"
Expand Down
8 changes: 6 additions & 2 deletions linux-user/main.c
Expand Up @@ -2553,6 +2553,10 @@ int main(int argc, char **argv, char **envp)
}

cpu_model = NULL;
#if defined(cpudef_setup)
cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
#endif

optind = 1;
for(;;) {
if (optind >= argc)
Expand Down Expand Up @@ -2624,8 +2628,8 @@ int main(int argc, char **argv, char **envp)
cpu_model = argv[optind++];
if (cpu_model == NULL || strcmp(cpu_model, "?") == 0) {
/* XXX: implement xxx_cpu_list for targets that still miss it */
#if defined(cpu_list)
cpu_list(stdout, &fprintf);
#if defined(cpu_list_id)
cpu_list_id(stdout, &fprintf, "");
#endif
exit(1);
}
Expand Down
49 changes: 49 additions & 0 deletions qemu-config.c
Expand Up @@ -242,6 +242,54 @@ QemuOptsList qemu_mon_opts = {
},
};

QemuOptsList qemu_cpudef_opts = {
.name = "cpudef",
.head = QTAILQ_HEAD_INITIALIZER(qemu_cpudef_opts.head),
.desc = {
{
.name = "name",
.type = QEMU_OPT_STRING,
},{
.name = "level",
.type = QEMU_OPT_NUMBER,
},{
.name = "vendor",
.type = QEMU_OPT_STRING,
},{
.name = "family",
.type = QEMU_OPT_NUMBER,
},{
.name = "model",
.type = QEMU_OPT_NUMBER,
},{
.name = "stepping",
.type = QEMU_OPT_NUMBER,
},{
.name = "feature_edx", /* cpuid 0000_0001.edx */
.type = QEMU_OPT_STRING,
},{
.name = "feature_ecx", /* cpuid 0000_0001.ecx */
.type = QEMU_OPT_STRING,
},{
.name = "extfeature_edx", /* cpuid 8000_0001.edx */
.type = QEMU_OPT_STRING,
},{
.name = "extfeature_ecx", /* cpuid 8000_0001.ecx */
.type = QEMU_OPT_STRING,
},{
.name = "xlevel",
.type = QEMU_OPT_NUMBER,
},{
.name = "model_id",
.type = QEMU_OPT_STRING,
},{
.name = "vendor_override",
.type = QEMU_OPT_NUMBER,
},
{ /* end of list */ }
},
};

static QemuOptsList *lists[] = {
&qemu_drive_opts,
&qemu_chardev_opts,
Expand All @@ -251,6 +299,7 @@ static QemuOptsList *lists[] = {
&qemu_rtc_opts,
&qemu_global_opts,
&qemu_mon_opts,
&qemu_cpudef_opts,
NULL,
};

Expand Down
1 change: 1 addition & 0 deletions qemu-config.h
Expand Up @@ -9,6 +9,7 @@ extern QemuOptsList qemu_net_opts;
extern QemuOptsList qemu_rtc_opts;
extern QemuOptsList qemu_global_opts;
extern QemuOptsList qemu_mon_opts;
extern QemuOptsList qemu_cpudef_opts;

int qemu_set_option(const char *str);
int qemu_global_option(const char *str);
Expand Down
86 changes: 86 additions & 0 deletions sysconfigs/target/target-x86_64.conf
@@ -0,0 +1,86 @@
# x86 CPU MODELS

[cpudef]
name = "Conroe"
level = "2"
vendor = "GenuineIntel"
family = "6"
model = "2"
stepping = "3"
feature_edx = "sse2 sse fxsr mmx pat cmov pge sep apic cx8 mce pae msr tsc pse de fpu mtrr clflush mca pse36"
feature_ecx = "sse3 ssse3"
extfeature_edx = "fxsr mmx pat cmov pge apic cx8 mce pae msr tsc pse de fpu lm syscall nx"
extfeature_ecx = "lahf_lm"
xlevel = "0x8000000A"
model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)"

[cpudef]
name = "Penryn"
level = "2"
vendor = "GenuineIntel"
family = "6"
model = "2"
stepping = "3"
feature_edx = "sse2 sse fxsr mmx pat cmov pge sep apic cx8 mce pae msr tsc pse de fpu mtrr clflush mca pse36"
feature_ecx = "sse3 cx16 ssse3 sse4.1"
extfeature_edx = "fxsr mmx pat cmov pge apic cx8 mce pae msr tsc pse de fpu lm syscall nx"
extfeature_ecx = "lahf_lm"
xlevel = "0x8000000A"
model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)"

[cpudef]
name = "Nehalem"
level = "2"
vendor = "GenuineIntel"
family = "6"
model = "2"
stepping = "3"
feature_edx = "sse2 sse fxsr mmx pat cmov pge sep apic cx8 mce pae msr tsc pse de fpu mtrr clflush mca pse36"
feature_ecx = "sse3 cx16 ssse3 sse4.1 sse4.2 popcnt"
extfeature_edx = "fxsr mmx pat cmov pge apic cx8 mce pae msr tsc pse de fpu lm syscall nx"
extfeature_ecx = "lahf_lm"
xlevel = "0x8000000A"
model_id = "Intel Core i7 9xx (Nehalem Class Core i7)"

[cpudef]
name = "Opteron_G1"
level = "5"
vendor = "AuthenticAMD"
family = "15"
model = "6"
stepping = "1"
feature_edx = "sse2 sse fxsr mmx pat cmov pge sep apic cx8 mce pae msr tsc pse de fpu mtrr clflush mca pse36"
feature_ecx = "sse3"
extfeature_edx = "fxsr mmx pat cmov pge apic cx8 mce pae msr tsc pse de fpu lm syscall nx"
# extfeature_ecx = ""
xlevel = "0x80000008"
model_id = "AMD Opteron 240 (Gen 1 Class Opteron)"

[cpudef]
name = "Opteron_G2"
level = "5"
vendor = "AuthenticAMD"
family = "15"
model = "6"
stepping = "1"
feature_edx = "sse2 sse fxsr mmx pat cmov pge sep apic cx8 mce pae msr tsc pse de fpu mtrr clflush mca pse36"
feature_ecx = "sse3 cx16"
extfeature_edx = "fxsr mmx pat cmov pge apic cx8 mce pae msr tsc pse de fpu lm syscall nx rdtscp"
extfeature_ecx = "svm lahf_lm"
xlevel = "0x80000008"
model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)"

[cpudef]
name = "Opteron_G3"
level = "5"
vendor = "AuthenticAMD"
family = "15"
model = "6"
stepping = "1"
feature_edx = "sse2 sse fxsr mmx pat cmov pge sep apic cx8 mce pae msr tsc pse de fpu mtrr clflush mca pse36"
feature_ecx = "sse3 cx16 monitor popcnt"
extfeature_edx = "fxsr mmx pat cmov pge apic cx8 mce pae msr tsc pse de fpu lm syscall nx rdtscp"
extfeature_ecx = "svm sse4a abm misalignsse lahf_lm"
xlevel = "0x80000008"
model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)"

9 changes: 6 additions & 3 deletions target-i386/cpu.h
Expand Up @@ -723,8 +723,10 @@ typedef struct CPUX86State {
CPUX86State *cpu_x86_init(const char *cpu_model);
int cpu_x86_exec(CPUX86State *s);
void cpu_x86_close(CPUX86State *s);
void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt,
...));
void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
const char *optarg);
void x86_cpudef_setup(void);

int cpu_get_pic_interrupt(CPUX86State *s);
/* MSDOS compatibility mode FPU exception support */
void cpu_set_ferr(CPUX86State *s);
Expand Down Expand Up @@ -876,7 +878,8 @@ uint64_t cpu_get_tsc(CPUX86State *env);
#define cpu_exec cpu_x86_exec
#define cpu_gen_code cpu_x86_gen_code
#define cpu_signal_handler cpu_x86_signal_handler
#define cpu_list x86_cpu_list
#define cpu_list_id x86_cpu_list
#define cpudef_setup x86_cpudef_setup

#define CPU_SAVE_VERSION 11

Expand Down

0 comments on commit b5ec5ce

Please sign in to comment.