* [Qemu-devel] [PATCH 0/3] replace cpuid_*features fields with a featue word array (v2) @ 2012-12-12 22:22 Eduardo Habkost 2012-12-12 22:22 ` [Qemu-devel] [PATCH 1/3] target-i386: add EXT2_PPRO_FEATURES #define Eduardo Habkost ` (2 more replies) 0 siblings, 3 replies; 22+ messages in thread From: Eduardo Habkost @ 2012-12-12 22:22 UTC (permalink / raw) To: qemu-devel; +Cc: Igor Mammedov, Andreas Färber Changes in v2: - Rebased on top of: Subject: [PATCH 0/2] target-i386: move CPU object creation to cpu.c (v2) - Wrote a sed script that can be used to reproduce exactly the same changes from patch 3: https://gist.github.com/4271991 Git tree for testing: git://github.com/ehabkost/qemu-hacks.git x86-cpu-feature-array.v2 https://github.com/ehabkost/qemu-hacks/tree/x86-cpu-feature-array.v2 Original description: I was planning to implement this only after we finished the rest of the work, the changes are a bit intrusive. But now it looks like the CPUID feature bits are getting into our way (e.g. the feature word array will allow us to simplify the -cpu host and -cpu check/enforce code a lot, making it easier to convert that code to use CPU subclasses), so I decided to submit it now. Eduardo Habkost (3): target-i386: add EXT2_PPRO_FEATURES #define target-i386/cpu.c: coding style fix target-i386: replace cpuid_*features fields with a feature word array hw/kvm/clock.c | 2 +- linux-user/elfload.c | 2 +- linux-user/main.c | 4 +- target-i386/cpu.c | 582 +++++++++++++++++++++++----------------------- target-i386/cpu.h | 30 +-- target-i386/helper.c | 4 +- target-i386/kvm.c | 5 +- target-i386/misc_helper.c | 14 +- target-i386/translate.c | 10 +- 9 files changed, 334 insertions(+), 319 deletions(-) -- 1.7.11.7 ^ permalink raw reply [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 1/3] target-i386: add EXT2_PPRO_FEATURES #define 2012-12-12 22:22 [Qemu-devel] [PATCH 0/3] replace cpuid_*features fields with a featue word array (v2) Eduardo Habkost @ 2012-12-12 22:22 ` Eduardo Habkost 2012-12-14 9:44 ` Igor Mammedov 2012-12-14 11:44 ` Andreas Färber 2012-12-12 22:22 ` [Qemu-devel] [PATCH 2/3] target-i386/cpu.c: coding style fix Eduardo Habkost 2012-12-12 22:22 ` [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array Eduardo Habkost 2 siblings, 2 replies; 22+ messages in thread From: Eduardo Habkost @ 2012-12-12 22:22 UTC (permalink / raw) To: qemu-devel; +Cc: Igor Mammedov, Andreas Färber Instead of repeating the (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) expression everywhere, use EXT2_PPRO_FEATURES. Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- target-i386/cpu.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 546c86a..a2ee8bb 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -303,6 +303,7 @@ typedef struct x86_def_t { CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \ CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \ CPUID_PAE | CPUID_SEP | CPUID_APIC) +#define EXT2_PPRO_FEATURES (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) #define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \ CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \ @@ -350,7 +351,7 @@ static x86_def_t builtin_x86_defs[] = { CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36, .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT, - .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | + .ext2_features = EXT2_PPRO_FEATURES | CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A, @@ -370,7 +371,7 @@ static x86_def_t builtin_x86_defs[] = { CPUID_PSE36 | CPUID_VME | CPUID_HT, .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 | CPUID_EXT_POPCNT, - .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | + .ext2_features = EXT2_PPRO_FEATURES | CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT | CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP, @@ -421,7 +422,7 @@ static x86_def_t builtin_x86_defs[] = { /* 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 & CPUID_EXT2_AMD_ALIASES) | + .ext2_features = EXT2_PPRO_FEATURES | 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, @@ -456,7 +457,7 @@ static x86_def_t builtin_x86_defs[] = { .features = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36, .ext_features = CPUID_EXT_SSE3, - .ext2_features = PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES, + .ext2_features = EXT2_PPRO_FEATURES, .ext3_features = 0, .xlevel = 0x80000008, .model_id = "Common 32-bit KVM processor" @@ -538,7 +539,7 @@ static x86_def_t builtin_x86_defs[] = { .stepping = 3, .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA, - .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | + .ext2_features = EXT2_PPRO_FEATURES | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT, .xlevel = 0x80000008, }, @@ -558,7 +559,7 @@ static x86_def_t builtin_x86_defs[] = { /* Some CPUs got no CPUID_SEP */ .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR, - .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | + .ext2_features = EXT2_PPRO_FEATURES | CPUID_EXT2_NX, .ext3_features = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, -- 1.7.11.7 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 1/3] target-i386: add EXT2_PPRO_FEATURES #define 2012-12-12 22:22 ` [Qemu-devel] [PATCH 1/3] target-i386: add EXT2_PPRO_FEATURES #define Eduardo Habkost @ 2012-12-14 9:44 ` Igor Mammedov 2012-12-14 11:44 ` Andreas Färber 1 sibling, 0 replies; 22+ messages in thread From: Igor Mammedov @ 2012-12-14 9:44 UTC (permalink / raw) To: Eduardo Habkost; +Cc: qemu-devel, Andreas Färber On Wed, 12 Dec 2012 20:22:24 -0200 Eduardo Habkost <ehabkost@redhat.com> wrote: > Instead of repeating the (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) > expression everywhere, use EXT2_PPRO_FEATURES. > > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> > --- > target-i386/cpu.c | 13 +++++++------ > 1 file changed, 7 insertions(+), 6 deletions(-) Reviewed-by: Igor Mammedov <imammedo@redhat.com> > > diff --git a/target-i386/cpu.c b/target-i386/cpu.c > index 546c86a..a2ee8bb 100644 > --- a/target-i386/cpu.c > +++ b/target-i386/cpu.c > @@ -303,6 +303,7 @@ typedef struct x86_def_t { > CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \ > CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \ > CPUID_PAE | CPUID_SEP | CPUID_APIC) > +#define EXT2_PPRO_FEATURES (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) > > #define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \ > CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \ > @@ -350,7 +351,7 @@ static x86_def_t builtin_x86_defs[] = { > CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | > CPUID_PSE36, > .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT, > - .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | > + .ext2_features = EXT2_PPRO_FEATURES | > CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, > .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | > CPUID_EXT3_ABM | CPUID_EXT3_SSE4A, > @@ -370,7 +371,7 @@ static x86_def_t builtin_x86_defs[] = { > CPUID_PSE36 | CPUID_VME | CPUID_HT, > .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 | > CPUID_EXT_POPCNT, > - .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | > + .ext2_features = EXT2_PPRO_FEATURES | > CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | > CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT | > CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP, > @@ -421,7 +422,7 @@ static x86_def_t builtin_x86_defs[] = { > /* 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 & CPUID_EXT2_AMD_ALIASES) | > + .ext2_features = EXT2_PPRO_FEATURES | > 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, > @@ -456,7 +457,7 @@ static x86_def_t builtin_x86_defs[] = { > .features = PPRO_FEATURES | > CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36, > .ext_features = CPUID_EXT_SSE3, > - .ext2_features = PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES, > + .ext2_features = EXT2_PPRO_FEATURES, > .ext3_features = 0, > .xlevel = 0x80000008, > .model_id = "Common 32-bit KVM processor" > @@ -538,7 +539,7 @@ static x86_def_t builtin_x86_defs[] = { > .stepping = 3, > .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | > CPUID_MCA, > - .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | > + .ext2_features = EXT2_PPRO_FEATURES | > CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT, > .xlevel = 0x80000008, > }, > @@ -558,7 +559,7 @@ static x86_def_t builtin_x86_defs[] = { > /* Some CPUs got no CPUID_SEP */ > .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | > CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR, > - .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | > + .ext2_features = EXT2_PPRO_FEATURES | > CPUID_EXT2_NX, > .ext3_features = CPUID_EXT3_LAHF_LM, > .xlevel = 0x8000000A, > -- > 1.7.11.7 > > -- Regards, Igor ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 1/3] target-i386: add EXT2_PPRO_FEATURES #define 2012-12-12 22:22 ` [Qemu-devel] [PATCH 1/3] target-i386: add EXT2_PPRO_FEATURES #define Eduardo Habkost 2012-12-14 9:44 ` Igor Mammedov @ 2012-12-14 11:44 ` Andreas Färber 2012-12-14 12:15 ` Eduardo Habkost 1 sibling, 1 reply; 22+ messages in thread From: Andreas Färber @ 2012-12-14 11:44 UTC (permalink / raw) To: Eduardo Habkost; +Cc: Igor Mammedov, qemu-devel Am 12.12.2012 23:22, schrieb Eduardo Habkost: > Instead of repeating the (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) > expression everywhere, use EXT2_PPRO_FEATURES. > > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> Technically this patch looks fine. My dislike for these defines aside, I have doubts about the semantics: This is masking out "AMD_ALIASES" (whatever that is exactly I still need to look up) - doesn't that rather call for EXT2_PPRO_INTEL_FEATURES or so? (But then again the Pentium Pro was an Intel chip so AMD sounds confusing...) Or does no AMD model actually inherit those AMD aliases? This at least deserves a mention in the commit message (no need to resend then). Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 1/3] target-i386: add EXT2_PPRO_FEATURES #define 2012-12-14 11:44 ` Andreas Färber @ 2012-12-14 12:15 ` Eduardo Habkost 0 siblings, 0 replies; 22+ messages in thread From: Eduardo Habkost @ 2012-12-14 12:15 UTC (permalink / raw) To: Andreas Färber; +Cc: Igor Mammedov, qemu-devel On Fri, Dec 14, 2012 at 12:44:43PM +0100, Andreas Färber wrote: > Am 12.12.2012 23:22, schrieb Eduardo Habkost: > > Instead of repeating the (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) > > expression everywhere, use EXT2_PPRO_FEATURES. > > > > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> > > Technically this patch looks fine. My dislike for these defines aside, I > have doubts about the semantics: This is masking out "AMD_ALIASES" > (whatever that is exactly I still need to look up) - doesn't that rather > call for EXT2_PPRO_INTEL_FEATURES or so? (But then again the Pentium Pro > was an Intel chip so AMD sounds confusing...) Or does no AMD model > actually inherit those AMD aliases? This at least deserves a mention in > the commit message (no need to resend then). The code is not masking out AMD_ALIASES, it is is the opposite: it's keeping only the AMD_ALIASES bits. CPUID_EXT2_AMD_ALIASES are the bits in cpuid_ext2_features that have to be directly duplicated from cpuid_features, but only on AMD CPUs. Intel CPUs don't have those bit aliases. Anyway, you have a point: I think the #define could be named PPRO_EXT2_FEATURES_AMD instead, to make it clear that those bits make sense only on AMD CPU models. Also: on the models that actually have vendor=AMD, we can probably remove those bits entirely from the table, as we now have code that makes sure the feature aliases on cpuid_ext2_features are consistent with cpuid_features. But we still have a few exceptions that have vendor=Intel (kvm64, kvm32, and n270), that have to be (carefully) fixed later. The main reason I sent this change was to make it easier to automatically line-wrap the feature lists in the code to 80-columns on patch 3/3. I think I will reorder and send the feature-array patch first, and fix the CPUID_EXT2_AMD_ALIASES mess later. -- Eduardo ^ permalink raw reply [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 2/3] target-i386/cpu.c: coding style fix 2012-12-12 22:22 [Qemu-devel] [PATCH 0/3] replace cpuid_*features fields with a featue word array (v2) Eduardo Habkost 2012-12-12 22:22 ` [Qemu-devel] [PATCH 1/3] target-i386: add EXT2_PPRO_FEATURES #define Eduardo Habkost @ 2012-12-12 22:22 ` Eduardo Habkost 2012-12-12 23:36 ` Igor Mammedov 2012-12-12 22:22 ` [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array Eduardo Habkost 2 siblings, 1 reply; 22+ messages in thread From: Eduardo Habkost @ 2012-12-12 22:22 UTC (permalink / raw) To: qemu-devel; +Cc: Igor Mammedov, Andreas Färber Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- target-i386/cpu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index a2ee8bb..25f7500 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -1865,10 +1865,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, /* 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) + if (env->cpuid_features & CPUID_PSE36) { *eax = 0x00000024; /* 36 bits physical */ - else + } else { *eax = 0x00000020; /* 32 bits physical */ + } } *ebx = 0; *ecx = 0; -- 1.7.11.7 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 2/3] target-i386/cpu.c: coding style fix 2012-12-12 22:22 ` [Qemu-devel] [PATCH 2/3] target-i386/cpu.c: coding style fix Eduardo Habkost @ 2012-12-12 23:36 ` Igor Mammedov 2012-12-13 13:16 ` Eduardo Habkost 0 siblings, 1 reply; 22+ messages in thread From: Igor Mammedov @ 2012-12-12 23:36 UTC (permalink / raw) To: Eduardo Habkost; +Cc: qemu-devel, Andreas Färber On Wed, 12 Dec 2012 20:22:25 -0200 Eduardo Habkost <ehabkost@redhat.com> wrote: While at it, could you remove the last <TAB> as well? > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> > --- > target-i386/cpu.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/target-i386/cpu.c b/target-i386/cpu.c > index a2ee8bb..25f7500 100644 > --- a/target-i386/cpu.c > +++ b/target-i386/cpu.c > @@ -1865,10 +1865,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, > /* 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) > + if (env->cpuid_features & CPUID_PSE36) { > *eax = 0x00000024; /* 36 bits physical */ > - else > + } else { > *eax = 0x00000020; /* 32 bits physical */ > + } > } > *ebx = 0; > *ecx = 0; > -- > 1.7.11.7 > -- Regards, Igor ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 2/3] target-i386/cpu.c: coding style fix 2012-12-12 23:36 ` Igor Mammedov @ 2012-12-13 13:16 ` Eduardo Habkost 0 siblings, 0 replies; 22+ messages in thread From: Eduardo Habkost @ 2012-12-13 13:16 UTC (permalink / raw) To: Igor Mammedov; +Cc: qemu-devel, Andreas Färber On Thu, Dec 13, 2012 at 12:36:02AM +0100, Igor Mammedov wrote: > On Wed, 12 Dec 2012 20:22:25 -0200 > Eduardo Habkost <ehabkost@redhat.com> wrote: > > While at it, could you remove the last <TAB> as well? I didn't even notice it was there. I will do that in case I have to resubmit this series, or send a separate patch to qemu-trivial later, in case this version gets included. > > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> > > --- > > target-i386/cpu.c | 5 +++-- > > 1 file changed, 3 insertions(+), 2 deletions(-) > > > > diff --git a/target-i386/cpu.c b/target-i386/cpu.c > > index a2ee8bb..25f7500 100644 > > --- a/target-i386/cpu.c > > +++ b/target-i386/cpu.c > > @@ -1865,10 +1865,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, > > /* 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) > > + if (env->cpuid_features & CPUID_PSE36) { > > *eax = 0x00000024; /* 36 bits physical */ > > - else > > + } else { > > *eax = 0x00000020; /* 32 bits physical */ > > + } > > } > > *ebx = 0; > > *ecx = 0; > > -- > > 1.7.11.7 > > > > > -- > Regards, > Igor -- Eduardo ^ permalink raw reply [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array 2012-12-12 22:22 [Qemu-devel] [PATCH 0/3] replace cpuid_*features fields with a featue word array (v2) Eduardo Habkost 2012-12-12 22:22 ` [Qemu-devel] [PATCH 1/3] target-i386: add EXT2_PPRO_FEATURES #define Eduardo Habkost 2012-12-12 22:22 ` [Qemu-devel] [PATCH 2/3] target-i386/cpu.c: coding style fix Eduardo Habkost @ 2012-12-12 22:22 ` Eduardo Habkost 2012-12-14 9:38 ` Igor Mammedov 2012-12-14 15:14 ` Andreas Färber 2 siblings, 2 replies; 22+ messages in thread From: Eduardo Habkost @ 2012-12-12 22:22 UTC (permalink / raw) To: qemu-devel; +Cc: Igor Mammedov, Andreas Färber This replaces the feature-bit fields on both X86CPU and x86_def_t structs with an array. With this, we will be able to simplify code that simply does the same operation on all feature words (e.g. kvm_check_features_against_host(), filter_features_for_kvm(), add_flagname_to_bitmaps(), and CPU feature-bit property lookup/registration). Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- This patch was created solely using a sed script and no manual changes, to try to avoid mistakes while converting the code, and make it easier to rebase if necessary. The sed script can be seen at: https://gist.github.com/4271991 --- hw/kvm/clock.c | 2 +- linux-user/elfload.c | 2 +- linux-user/main.c | 4 +- target-i386/cpu.c | 578 +++++++++++++++++++++++----------------------- target-i386/cpu.h | 30 +-- target-i386/helper.c | 4 +- target-i386/kvm.c | 5 +- target-i386/misc_helper.c | 14 +- target-i386/translate.c | 10 +- 9 files changed, 331 insertions(+), 318 deletions(-) diff --git a/hw/kvm/clock.c b/hw/kvm/clock.c index 824b978..11af665 100644 --- a/hw/kvm/clock.c +++ b/hw/kvm/clock.c @@ -129,7 +129,7 @@ static TypeInfo kvmclock_info = { void kvmclock_create(void) { if (kvm_enabled() && - first_cpu->cpuid_kvm_features & ((1ULL << KVM_FEATURE_CLOCKSOURCE) | + first_cpu->features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) | (1ULL << KVM_FEATURE_CLOCKSOURCE2))) { sysbus_create_simple("kvmclock", -1, NULL); } diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 1d8bcb4..71156af 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -130,7 +130,7 @@ static const char *get_elf_platform(void) static uint32_t get_elf_hwcap(void) { - return thread_env->cpuid_features; + return thread_env->features[FEAT_1_EDX]; } #ifdef TARGET_X86_64 diff --git a/linux-user/main.c b/linux-user/main.c index 25e35cd..5e847dd 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3625,13 +3625,13 @@ int main(int argc, char **argv, char **envp) env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK; env->hflags |= HF_PE_MASK; - if (env->cpuid_features & CPUID_SSE) { + if (env->features[FEAT_1_EDX] & CPUID_SSE) { env->cr[4] |= CR4_OSFXSR_MASK; env->hflags |= HF_OSFXSR_MASK; } #ifndef TARGET_ABI32 /* enable 64 bit mode if possible */ - if (!(env->cpuid_ext2_features & CPUID_EXT2_LM)) { + if (!(env->features[FEAT_80000001_EDX] & CPUID_EXT2_LM)) { fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n"); exit(1); } diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 25f7500..f73583d 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -274,22 +274,15 @@ static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features, typedef struct x86_def_t { struct x86_def_t *next; const char *name; - uint32_t level; + uint32_t level, xlevel, xlevel2; + X86CPUFeatureWords features; uint32_t vendor1, vendor2, vendor3; int family; int model; int stepping; int tsc_khz; - uint32_t features, ext_features, ext2_features, ext3_features; - uint32_t kvm_features, svm_features; - uint32_t xlevel; char model_id[48]; int vendor_override; - /* Store the results of Centaur's CPUID instructions */ - uint32_t ext4_features; - uint32_t xlevel2; - /* The feature bits on CPUID[EAX=7,ECX=0].EBX */ - uint32_t cpuid_7_0_ebx_features; } x86_def_t; #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE) @@ -347,13 +340,13 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 2, .stepping = 3, - .features = PPRO_FEATURES | - CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | - CPUID_PSE36, - .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT, - .ext2_features = EXT2_PPRO_FEATURES | - CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, - .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH | + CPUID_MCA | CPUID_PSE36, + .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | + CPUID_EXT_POPCNT, + .features[FEAT_80000001_EDX] = EXT2_PPRO_FEATURES | CPUID_EXT2_LM | + CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A, .xlevel = 0x8000000A, }, @@ -366,22 +359,21 @@ static x86_def_t builtin_x86_defs[] = { .family = 16, .model = 2, .stepping = 3, - .features = PPRO_FEATURES | - CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | - CPUID_PSE36 | CPUID_VME | CPUID_HT, - .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 | - CPUID_EXT_POPCNT, - .ext2_features = EXT2_PPRO_FEATURES | - CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | - CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT | - CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP, + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH | + CPUID_MCA | CPUID_PSE36 | CPUID_VME | CPUID_HT, + .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | + CPUID_EXT_CX16 | CPUID_EXT_POPCNT, + .features[FEAT_80000001_EDX] = EXT2_PPRO_FEATURES | CPUID_EXT2_LM | + CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_3DNOW | + CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT | CPUID_EXT2_FFXSR | + CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP, /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC, CPUID_EXT3_CR8LEG, CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH, CPUID_EXT3_OSVW, CPUID_EXT3_IBS */ - .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A, - .svm_features = CPUID_SVM_NPT | CPUID_SVM_LBRV, + .features[FEAT_SVM] = CPUID_SVM_NPT | CPUID_SVM_LBRV, .xlevel = 0x8000001A, .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor" }, @@ -394,15 +386,16 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 15, .stepping = 11, - .features = PPRO_FEATURES | - CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | - CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS | - CPUID_HT | CPUID_TM | CPUID_PBE, - .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | - CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | CPUID_EXT_VMX | CPUID_EXT_EST | - CPUID_EXT_TM2 | CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, - .ext3_features = CPUID_EXT3_LAHF_LM, + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH | + CPUID_MCA | CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | + CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE, + .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | + CPUID_EXT_SSSE3 | CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | + CPUID_EXT_VMX | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_CX16 | + CPUID_EXT_XTPR | CPUID_EXT_PDCM, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | + CPUID_EXT2_NX, + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x80000008, .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz", }, @@ -416,19 +409,18 @@ static x86_def_t builtin_x86_defs[] = { .model = 6, .stepping = 1, /* Missing: CPUID_VME, CPUID_HT */ - .features = PPRO_FEATURES | - CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | - CPUID_PSE36, + .features[FEAT_1_EDX] = 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, + .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_CX16, /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */ - .ext2_features = EXT2_PPRO_FEATURES | - CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, + .features[FEAT_80000001_EDX] = EXT2_PPRO_FEATURES | 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, + .features[FEAT_80000001_ECX] = 0, .xlevel = 0x80000008, .model_id = "Common KVM processor" }, @@ -441,8 +433,8 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 3, .stepping = 3, - .features = PPRO_FEATURES, - .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT, + .features[FEAT_1_EDX] = PPRO_FEATURES, + .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT, .xlevel = 0x80000004, }, { @@ -454,11 +446,11 @@ static x86_def_t builtin_x86_defs[] = { .family = 15, .model = 6, .stepping = 1, - .features = PPRO_FEATURES | - CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36, - .ext_features = CPUID_EXT_SSE3, - .ext2_features = EXT2_PPRO_FEATURES, - .ext3_features = 0, + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH | + CPUID_MCA | CPUID_PSE36, + .features[FEAT_1_ECX] = CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = EXT2_PPRO_FEATURES, + .features[FEAT_80000001_ECX] = 0, .xlevel = 0x80000008, .model_id = "Common 32-bit KVM processor" }, @@ -471,12 +463,13 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 14, .stepping = 8, - .features = PPRO_FEATURES | CPUID_VME | - CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI | - CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE, - .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_VMX | - CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | CPUID_EXT_PDCM, - .ext2_features = CPUID_EXT2_NX, + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_VME | CPUID_MTRR | + CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI | CPUID_SS | + CPUID_HT | CPUID_TM | CPUID_PBE, + .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | + CPUID_EXT_VMX | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | + CPUID_EXT_PDCM, + .features[FEAT_80000001_EDX] = CPUID_EXT2_NX, .xlevel = 0x80000008, .model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz", }, @@ -489,7 +482,7 @@ static x86_def_t builtin_x86_defs[] = { .family = 4, .model = 0, .stepping = 0, - .features = I486_FEATURES, + .features[FEAT_1_EDX] = I486_FEATURES, .xlevel = 0, }, { @@ -501,7 +494,7 @@ static x86_def_t builtin_x86_defs[] = { .family = 5, .model = 4, .stepping = 3, - .features = PENTIUM_FEATURES, + .features[FEAT_1_EDX] = PENTIUM_FEATURES, .xlevel = 0, }, { @@ -513,7 +506,7 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 5, .stepping = 2, - .features = PENTIUM2_FEATURES, + .features[FEAT_1_EDX] = PENTIUM2_FEATURES, .xlevel = 0, }, { @@ -525,7 +518,7 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 7, .stepping = 3, - .features = PENTIUM3_FEATURES, + .features[FEAT_1_EDX] = PENTIUM3_FEATURES, .xlevel = 0, }, { @@ -537,10 +530,10 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 2, .stepping = 3, - .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | - CPUID_MCA, - .ext2_features = EXT2_PPRO_FEATURES | - CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT, + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | + CPUID_MTRR | CPUID_MCA, + .features[FEAT_80000001_EDX] = EXT2_PPRO_FEATURES | CPUID_EXT2_MMXEXT | + CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT, .xlevel = 0x80000008, }, { @@ -553,15 +546,15 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 28, .stepping = 2, - .features = PPRO_FEATURES | - CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME | CPUID_DTS | - CPUID_ACPI | CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE, + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH | + CPUID_MCA | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS | + CPUID_HT | CPUID_TM | CPUID_PBE, /* Some CPUs got no CPUID_SEP */ - .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | - CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR, - .ext2_features = EXT2_PPRO_FEATURES | - CPUID_EXT2_NX, - .ext3_features = CPUID_EXT3_LAHF_LM, + .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | + CPUID_EXT_SSSE3 | CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | + CPUID_EXT_XTPR, + .features[FEAT_80000001_EDX] = EXT2_PPRO_FEATURES | CPUID_EXT2_NX, + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, .model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz", }, @@ -574,14 +567,15 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 2, .stepping = 3, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_SSSE3 | CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, - .ext3_features = CPUID_EXT3_LAHF_LM, + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_SSSE3 | CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_NX | + CPUID_EXT2_SYSCALL, + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)", }, @@ -594,15 +588,16 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 2, .stepping = 3, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | - CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, - .ext3_features = CPUID_EXT3_LAHF_LM, + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_SSE41 | CPUID_EXT_CX16 | + CPUID_EXT_SSSE3 | CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_NX | + CPUID_EXT2_SYSCALL, + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)", }, @@ -615,15 +610,17 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 2, .stepping = 3, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | - CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, - .ext3_features = CPUID_EXT3_LAHF_LM, + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | + CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | + CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | + CPUID_EXT2_NX, + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)", }, @@ -636,16 +633,17 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 44, .stepping = 1, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | - CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | - CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, - .ext3_features = CPUID_EXT3_LAHF_LM, + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_AES | CPUID_EXT_POPCNT | + CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | CPUID_EXT_CX16 | + CPUID_EXT_SSSE3 | CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | + CPUID_EXT2_NX, + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)", }, @@ -658,19 +656,19 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 42, .stepping = 1, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES | - CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT | - CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | - CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | - CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | - CPUID_EXT2_SYSCALL, - .ext3_features = CPUID_EXT3_LAHF_LM, + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_AVX | CPUID_EXT_XSAVE | + CPUID_EXT_AES | CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT | + CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | + CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | + CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | + CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, .model_id = "Intel Xeon E312xx (Sandy Bridge)", }, @@ -683,21 +681,21 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 60, .stepping = 1, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES | - CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | - CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | - CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 | - CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE | - CPUID_EXT_PCID, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | - CPUID_EXT2_SYSCALL, - .ext3_features = CPUID_EXT3_LAHF_LM, - .cpuid_7_0_ebx_features = CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_AVX | CPUID_EXT_XSAVE | + CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | + CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | CPUID_EXT_CX16 | + CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 | + CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE | + CPUID_EXT_PCID, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | + CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM, + .features[FEAT_7_0_EBX] = CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_RTM, @@ -713,18 +711,18 @@ static x86_def_t builtin_x86_defs[] = { .family = 15, .model = 6, .stepping = 1, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX | - CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_FXSR | + CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE | - CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | - CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | - CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, + CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | + CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | + CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, .xlevel = 0x80000008, .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)", }, @@ -737,20 +735,20 @@ static x86_def_t builtin_x86_defs[] = { .family = 15, .model = 6, .stepping = 1, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_CX16 | CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR | - CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 | - CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA | - CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | - CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE | - CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE | - CPUID_EXT2_DE | CPUID_EXT2_FPU, - .ext3_features = CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM, + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_CX16 | CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | + CPUID_EXT2_FXSR | CPUID_EXT2_MMX | CPUID_EXT2_NX | + CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | CPUID_EXT2_CMOV | + CPUID_EXT2_MCA | CPUID_EXT2_PGE | CPUID_EXT2_MTRR | + CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | CPUID_EXT2_CX8 | + CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | + CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, + .features[FEAT_80000001_ECX] = CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM, .xlevel = 0x80000008, .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)", }, @@ -763,22 +761,23 @@ static x86_def_t builtin_x86_defs[] = { .family = 15, .model = 6, .stepping = 1, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR | - CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR | - CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 | - CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA | - CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | - CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE | - CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE | - CPUID_EXT2_DE | CPUID_EXT2_FPU, - .ext3_features = CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | - CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM, + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_POPCNT | CPUID_EXT_CX16 | + CPUID_EXT_MONITOR | CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | + CPUID_EXT2_FXSR | CPUID_EXT2_MMX | CPUID_EXT2_NX | + CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | CPUID_EXT2_CMOV | + CPUID_EXT2_MCA | CPUID_EXT2_PGE | CPUID_EXT2_MTRR | + CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | CPUID_EXT2_CX8 | + CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | + CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, + .features[FEAT_80000001_ECX] = CPUID_EXT3_MISALIGNSSE | + CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM | + CPUID_EXT3_LAHF_LM, .xlevel = 0x80000008, .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)", }, @@ -791,26 +790,26 @@ static x86_def_t builtin_x86_defs[] = { .family = 21, .model = 1, .stepping = 2, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES | - CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | - CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | - CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | - CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX | - CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | - CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE | - CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | - CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | - CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, - .ext3_features = CPUID_EXT3_FMA4 | CPUID_EXT3_XOP | - CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE | - CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM | - CPUID_EXT3_LAHF_LM, + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_AVX | CPUID_EXT_XSAVE | + CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | + CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | + CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | + CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX | + CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | + CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE | + CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | + CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | + CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, + .features[FEAT_80000001_ECX] = CPUID_EXT3_FMA4 | CPUID_EXT3_XOP | + CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE | + CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM | + CPUID_EXT3_LAHF_LM, .xlevel = 0x8000001A, .model_id = "AMD Opteron 62xx class CPU", }, @@ -823,26 +822,26 @@ static x86_def_t builtin_x86_defs[] = { .family = 21, .model = 2, .stepping = 0, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE | - CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | - CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA | + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_F16C | CPUID_EXT_AVX | + CPUID_EXT_XSAVE | CPUID_EXT_AES | CPUID_EXT_POPCNT | + CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | - CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX | - CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | - CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE | - CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | - CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | - CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, - .ext3_features = CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP | - CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE | + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | + CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX | + CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | + CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE | + CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | + CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | + CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, + .features[FEAT_80000001_ECX] = CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | + CPUID_EXT3_XOP | CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM | - CPUID_EXT3_LAHF_LM, + CPUID_EXT3_LAHF_LM, .xlevel = 0x8000001A, .model_id = "AMD Opteron 63xx class CPU", }, @@ -890,20 +889,22 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def) x86_cpu_def->stepping = eax & 0x0F; x86_cpu_def->level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX); - x86_cpu_def->features = kvm_arch_get_supported_cpuid(s, 0x1, 0, R_EDX); - x86_cpu_def->ext_features = kvm_arch_get_supported_cpuid(s, 0x1, 0, R_ECX); + x86_cpu_def->features[FEAT_1_EDX] = + kvm_arch_get_supported_cpuid(s, 0x1, 0, R_EDX); + x86_cpu_def->features[FEAT_1_ECX] = + kvm_arch_get_supported_cpuid(s, 0x1, 0, R_ECX); if (x86_cpu_def->level >= 7) { - x86_cpu_def->cpuid_7_0_ebx_features = + x86_cpu_def->features[FEAT_7_0_EBX] = kvm_arch_get_supported_cpuid(s, 0x7, 0, R_EBX); } else { - x86_cpu_def->cpuid_7_0_ebx_features = 0; + x86_cpu_def->features[FEAT_7_0_EBX] = 0; } x86_cpu_def->xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX); - x86_cpu_def->ext2_features = + x86_cpu_def->features[FEAT_80000001_EDX] = kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX); - x86_cpu_def->ext3_features = + x86_cpu_def->features[FEAT_80000001_ECX] = kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_ECX); cpu_x86_fill_model_id(x86_cpu_def->model_id); @@ -919,7 +920,7 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def) /* Support VIA max extended level */ x86_cpu_def->xlevel2 = eax; host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx); - x86_cpu_def->ext4_features = + x86_cpu_def->features[FEAT_C0000001_EDX] = kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX); } } @@ -930,7 +931,7 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def) * available on the host hardware. Just set all bits and mask out the * unsupported ones later. */ - x86_cpu_def->svm_features = -1; + x86_cpu_def->features[FEAT_SVM] = -1; #endif /* CONFIG_KVM */ } @@ -961,13 +962,17 @@ static int kvm_check_features_against_host(x86_def_t *guest_def) uint32_t mask; int rv, i; struct model_features_t ft[] = { - {&guest_def->features, &host_def.features, + {&guest_def->features[FEAT_1_EDX], + &host_def.features[FEAT_1_EDX], ~0, feature_name, 0x00000000}, - {&guest_def->ext_features, &host_def.ext_features, + {&guest_def->features[FEAT_1_ECX], + &host_def.features[FEAT_1_ECX], ~CPUID_EXT_HYPERVISOR, ext_feature_name, 0x00000001}, - {&guest_def->ext2_features, &host_def.ext2_features, + {&guest_def->features[FEAT_80000001_EDX], + &host_def.features[FEAT_80000001_EDX], ~PPRO_FEATURES, ext2_feature_name, 0x80000000}, - {&guest_def->ext3_features, &host_def.ext3_features, + {&guest_def->features[FEAT_80000001_ECX], + &host_def.features[FEAT_80000001_ECX], ~CPUID_EXT3_SVM, ext3_feature_name, 0x80000001}}; assert(kvm_enabled()); @@ -1249,15 +1254,15 @@ static void cpudef_2_x86_cpu(X86CPU *cpu, x86_def_t *def, Error **errp) object_property_set_int(OBJECT(cpu), def->family, "family", errp); object_property_set_int(OBJECT(cpu), def->model, "model", errp); object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp); - env->cpuid_features = def->features; - env->cpuid_ext_features = def->ext_features; - env->cpuid_ext2_features = def->ext2_features; - env->cpuid_ext3_features = def->ext3_features; + env->features[FEAT_1_EDX] = def->features[FEAT_1_EDX]; + env->features[FEAT_1_ECX] = def->features[FEAT_1_ECX]; + env->features[FEAT_80000001_EDX] = def->features[FEAT_80000001_EDX]; + env->features[FEAT_80000001_ECX] = def->features[FEAT_80000001_ECX]; object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", errp); - env->cpuid_kvm_features = def->kvm_features; - env->cpuid_svm_features = def->svm_features; - env->cpuid_ext4_features = def->ext4_features; - env->cpuid_7_0_ebx_features = def->cpuid_7_0_ebx_features; + env->features[FEAT_KVM] = def->features[FEAT_KVM]; + env->features[FEAT_SVM] = def->features[FEAT_SVM]; + env->features[FEAT_C0000001_EDX] = def->features[FEAT_C0000001_EDX]; + env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX]; env->cpuid_xlevel2 = def->xlevel2; object_property_set_int(OBJECT(cpu), (int64_t)def->tsc_khz * 1000, "tsc-frequency", errp); @@ -1415,20 +1420,20 @@ static int cpu_x86_parse_featurestr(x86_def_t *x86_cpu_def, char *features) } 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->kvm_features |= plus_kvm_features; - x86_cpu_def->svm_features |= plus_svm_features; - x86_cpu_def->cpuid_7_0_ebx_features |= plus_7_0_ebx_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; - x86_cpu_def->kvm_features &= ~minus_kvm_features; - x86_cpu_def->svm_features &= ~minus_svm_features; - x86_cpu_def->cpuid_7_0_ebx_features &= ~minus_7_0_ebx_features; + x86_cpu_def->features[FEAT_1_EDX] |= plus_features; + x86_cpu_def->features[FEAT_1_ECX] |= plus_ext_features; + x86_cpu_def->features[FEAT_80000001_EDX] |= plus_ext2_features; + x86_cpu_def->features[FEAT_80000001_ECX] |= plus_ext3_features; + x86_cpu_def->features[FEAT_KVM] |= plus_kvm_features; + x86_cpu_def->features[FEAT_SVM] |= plus_svm_features; + x86_cpu_def->features[FEAT_7_0_EBX] |= plus_7_0_ebx_features; + x86_cpu_def->features[FEAT_1_EDX] &= ~minus_features; + x86_cpu_def->features[FEAT_1_ECX] &= ~minus_ext_features; + x86_cpu_def->features[FEAT_80000001_EDX] &= ~minus_ext2_features; + x86_cpu_def->features[FEAT_80000001_ECX] &= ~minus_ext3_features; + x86_cpu_def->features[FEAT_KVM] &= ~minus_kvm_features; + x86_cpu_def->features[FEAT_SVM] &= ~minus_svm_features; + x86_cpu_def->features[FEAT_7_0_EBX] &= ~minus_7_0_ebx_features; if (check_cpuid && kvm_enabled()) { if (kvm_check_features_against_host(x86_cpu_def) && enforce_cpuid) goto error; @@ -1520,21 +1525,21 @@ static void filter_features_for_kvm(X86CPU *cpu) CPUX86State *env = &cpu->env; KVMState *s = kvm_state; - env->cpuid_features &= + env->features[FEAT_1_EDX] &= kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX); - env->cpuid_ext_features &= + env->features[FEAT_1_ECX] &= kvm_arch_get_supported_cpuid(s, 1, 0, R_ECX); - env->cpuid_ext2_features &= + env->features[FEAT_80000001_EDX] &= kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX); - env->cpuid_ext3_features &= + env->features[FEAT_80000001_ECX] &= kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_ECX); - env->cpuid_svm_features &= + env->features[FEAT_SVM] &= kvm_arch_get_supported_cpuid(s, 0x8000000A, 0, R_EDX); - env->cpuid_7_0_ebx_features &= + env->features[FEAT_7_0_EBX] &= kvm_arch_get_supported_cpuid(s, 7, 0, R_EBX); - env->cpuid_kvm_features &= + env->features[FEAT_KVM] &= kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX); - env->cpuid_ext4_features &= + env->features[FEAT_C0000001_EDX] &= kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX); } @@ -1571,11 +1576,14 @@ X86CPU *cpu_x86_create(const char *cpu_model, Error **errp) goto error; } - def->kvm_features |= kvm_default_features; - add_flagname_to_bitmaps("hypervisor", &def->features, - &def->ext_features, &def->ext2_features, - &def->ext3_features, &def->kvm_features, - &def->svm_features, &def->cpuid_7_0_ebx_features); + def->features[FEAT_KVM] |= kvm_default_features; + add_flagname_to_bitmaps("hypervisor", &def->features[FEAT_1_EDX], + &def->features[FEAT_1_ECX], + &def->features[FEAT_80000001_EDX], + &def->features[FEAT_80000001_ECX], + &def->features[FEAT_KVM], + &def->features[FEAT_SVM], + &def->features[FEAT_7_0_EBX]); if (cpu_x86_parse_featurestr(def, features) < 0) { error_setg(errp, "Error parsing feature string: %s", @@ -1603,7 +1611,7 @@ error: void cpu_clear_apic_feature(CPUX86State *env) { - env->cpuid_features &= ~CPUID_APIC; + env->features[FEAT_1_EDX] &= ~CPUID_APIC; } #endif /* !CONFIG_USER_ONLY */ @@ -1684,8 +1692,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, 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; + *ecx = env->features[FEAT_1_ECX]; + *edx = env->features[FEAT_1_EDX]; if (env->nr_cores * env->nr_threads > 1) { *ebx |= (env->nr_cores * env->nr_threads) << 16; *edx |= 1 << 28; /* HTT bit */ @@ -1753,7 +1761,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, /* Structured Extended Feature Flags Enumeration Leaf */ if (count == 0) { *eax = 0; /* Maximum ECX value for sub-leaves */ - *ebx = env->cpuid_7_0_ebx_features; /* Feature flags */ + *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */ *ecx = 0; /* Reserved */ *edx = 0; /* Reserved */ } else { @@ -1788,7 +1796,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, break; case 0xD: /* Processor Extended State */ - if (!(env->cpuid_ext_features & CPUID_EXT_XSAVE)) { + if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) { *eax = 0; *ebx = 0; *ecx = 0; @@ -1818,8 +1826,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, case 0x80000001: *eax = env->cpuid_version; *ebx = 0; - *ecx = env->cpuid_ext3_features; - *edx = env->cpuid_ext2_features; + *ecx = env->features[FEAT_80000001_ECX]; + *edx = env->features[FEAT_80000001_EDX]; /* The Linux kernel checks for the CMPLegacy bit and * discards multiple thread information if it is set. @@ -1860,12 +1868,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, 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) { + if (env->features[FEAT_80000001_EDX] & 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) { + if (env->features[FEAT_1_EDX] & CPUID_PSE36) { *eax = 0x00000024; /* 36 bits physical */ } else { *eax = 0x00000020; /* 32 bits physical */ @@ -1879,11 +1887,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, } break; case 0x8000000A: - if (env->cpuid_ext3_features & CPUID_EXT3_SVM) { + if (env->features[FEAT_80000001_ECX] & CPUID_EXT3_SVM) { *eax = 0x00000001; /* SVM Revision */ *ebx = 0x00000010; /* nr of ASIDs */ *ecx = 0; - *edx = env->cpuid_svm_features; /* optional features */ + *edx = env->features[FEAT_SVM]; /* optional features */ } else { *eax = 0; *ebx = 0; @@ -1902,7 +1910,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *eax = env->cpuid_version; *ebx = 0; *ecx = 0; - *edx = env->cpuid_ext4_features; + *edx = env->features[FEAT_C0000001_EDX]; break; case 0xC0000002: case 0xC0000003: @@ -2034,7 +2042,7 @@ static void mce_init(X86CPU *cpu) unsigned int bank; if (((cenv->cpuid_version >> 8) & 0xf) >= 6 - && (cenv->cpuid_features & (CPUID_MCE | CPUID_MCA)) == + && (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) == (CPUID_MCE | CPUID_MCA)) { cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF; cenv->mcg_ctl = ~(uint64_t)0; @@ -2095,7 +2103,7 @@ void x86_cpu_realize(Object *obj, Error **errp) X86CPU *cpu = X86_CPU(obj); CPUX86State *env = &cpu->env; - if (env->cpuid_7_0_ebx_features && env->cpuid_level < 7) { + if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) { env->cpuid_level = 7; } @@ -2105,21 +2113,21 @@ void x86_cpu_realize(Object *obj, Error **errp) if (env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 && env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 && env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) { - env->cpuid_ext2_features &= ~CPUID_EXT2_AMD_ALIASES; - env->cpuid_ext2_features |= (env->cpuid_features & - CPUID_EXT2_AMD_ALIASES); + env->features[FEAT_80000001_EDX] &= ~CPUID_EXT2_AMD_ALIASES; + env->features[FEAT_80000001_EDX] |= (env->features[FEAT_1_EDX] & + CPUID_EXT2_AMD_ALIASES); } if (!kvm_enabled()) { - env->cpuid_features &= TCG_FEATURES; - env->cpuid_ext_features &= TCG_EXT_FEATURES; - env->cpuid_ext2_features &= (TCG_EXT2_FEATURES + env->features[FEAT_1_EDX] &= TCG_FEATURES; + env->features[FEAT_1_ECX] &= TCG_EXT_FEATURES; + env->features[FEAT_80000001_EDX] &= (TCG_EXT2_FEATURES #ifdef TARGET_X86_64 | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM #endif ); - env->cpuid_ext3_features &= TCG_EXT3_FEATURES; - env->cpuid_svm_features &= TCG_SVM_FEATURES; + env->features[FEAT_80000001_ECX] &= TCG_EXT3_FEATURES; + env->features[FEAT_SVM] &= TCG_SVM_FEATURES; } else { #ifdef CONFIG_KVM filter_features_for_kvm(cpu); @@ -2129,7 +2137,7 @@ void x86_cpu_realize(Object *obj, Error **errp) #ifndef CONFIG_USER_ONLY qemu_register_reset(x86_cpu_machine_reset_cb, cpu); - if (cpu->env.cpuid_features & CPUID_APIC || smp_cpus > 1) { + if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) { x86_cpu_apic_init(cpu, errp); if (error_is_set(errp)) { return; diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 8ce9b9f..76f0d27 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -694,6 +694,21 @@ typedef enum TPRAccess { TPR_ACCESS_WRITE, } TPRAccess; +typedef enum X86CPUFeatureWord { + FEAT_1_EDX, /* CPUID[1].EDX */ + FEAT_1_ECX, /* CPUID[1].ECX */ + FEAT_7_0_EBX, /* CPUID[EAX=7,ECX=0].EBX */ + FEAT_80000001_EDX, /* CPUID[8000_0001].EDX */ + FEAT_80000001_ECX, /* CPUID[8000_0001].ECX */ + FEAT_C0000001_EDX, /* CPUID[C000_0001].EDX */ + FEAT_KVM, /* CPUID[4000_0001].EAX (KVM_CPUID_FEATURES) */ + FEAT_SVM, /* CPUID[8000_000A].EDX */ + FEATURE_WORDS, /* Size of the features arrays */ +} FeatureWord; + +/* An array of feature words */ +typedef uint32_t X86CPUFeatureWords[FEATURE_WORDS]; + typedef struct CPUX86State { /* standard registers */ target_ulong regs[CPU_NB_REGS]; @@ -800,24 +815,15 @@ typedef struct CPUX86State { uint64_t pat; /* processor features (e.g. for CPUID insn) */ - uint32_t cpuid_level; + uint32_t cpuid_level, cpuid_xlevel, cpuid_xlevel2; + X86CPUFeatureWords features; uint32_t cpuid_vendor1; uint32_t cpuid_vendor2; uint32_t cpuid_vendor3; uint32_t cpuid_version; - uint32_t cpuid_features; - uint32_t cpuid_ext_features; - uint32_t cpuid_xlevel; uint32_t cpuid_model[12]; - uint32_t cpuid_ext2_features; - uint32_t cpuid_ext3_features; uint32_t cpuid_apic_id; int cpuid_vendor_override; - /* Store the results of Centaur's CPUID instructions */ - uint32_t cpuid_xlevel2; - uint32_t cpuid_ext4_features; - /* Flags from CPUID[EAX=7,ECX=0].EBX */ - uint32_t cpuid_7_0_ebx_features; /* MTRRs */ uint64_t mtrr_fixed[11]; @@ -831,8 +837,6 @@ typedef struct CPUX86State { uint8_t soft_interrupt; uint8_t has_error_code; uint32_t sipi_vector; - uint32_t cpuid_kvm_features; - uint32_t cpuid_svm_features; bool tsc_valid; int tsc_khz; void *kvm_xsave_buf; diff --git a/target-i386/helper.c b/target-i386/helper.c index dafa666..a1b25b6 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -450,7 +450,7 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4) tlb_flush(env, 1); } /* SSE handling */ - if (!(env->cpuid_features & CPUID_SSE)) { + if (!(env->features[FEAT_1_EDX] & CPUID_SSE)) { new_cr4 &= ~CR4_OSFXSR_MASK; } env->hflags &= ~HF_OSFXSR_MASK; @@ -458,7 +458,7 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4) env->hflags |= HF_OSFXSR_MASK; } - if (!(env->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)) { + if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SMAP)) { new_cr4 &= ~CR4_SMAP_MASK; } env->hflags &= ~HF_SMAP_MASK; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index f669281..5b614fa 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -438,7 +438,7 @@ int kvm_arch_init_vcpu(CPUX86State *env) c = &cpuid_data.entries[cpuid_i++]; memset(c, 0, sizeof(*c)); c->function = KVM_CPUID_FEATURES; - c->eax = env->cpuid_kvm_features; + c->eax = env->features[FEAT_KVM]; if (hyperv_enabled()) { memcpy(signature, "Hv#1\0\0\0\0\0\0\0\0", 12); @@ -573,7 +573,8 @@ int kvm_arch_init_vcpu(CPUX86State *env) cpuid_data.cpuid.nent = cpuid_i; if (((env->cpuid_version >> 8)&0xF) >= 6 - && (env->cpuid_features&(CPUID_MCE|CPUID_MCA)) == (CPUID_MCE|CPUID_MCA) + && (env->features[FEAT_1_EDX] & (CPUID_MCE|CPUID_MCA)) == + (CPUID_MCE|CPUID_MCA) && kvm_check_extension(env->kvm_state, KVM_CAP_MCE) > 0) { uint64_t mcg_cap; int banks; diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c index a020379..546b8b9 100644 --- a/target-i386/misc_helper.c +++ b/target-i386/misc_helper.c @@ -291,22 +291,22 @@ void helper_wrmsr(CPUX86State *env) uint64_t update_mask; update_mask = 0; - if (env->cpuid_ext2_features & CPUID_EXT2_SYSCALL) { + if (env->features[FEAT_80000001_EDX] & CPUID_EXT2_SYSCALL) { update_mask |= MSR_EFER_SCE; } - if (env->cpuid_ext2_features & CPUID_EXT2_LM) { + if (env->features[FEAT_80000001_EDX] & CPUID_EXT2_LM) { update_mask |= MSR_EFER_LME; } - if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR) { + if (env->features[FEAT_80000001_EDX] & CPUID_EXT2_FFXSR) { update_mask |= MSR_EFER_FFXSR; } - if (env->cpuid_ext2_features & CPUID_EXT2_NX) { + if (env->features[FEAT_80000001_EDX] & CPUID_EXT2_NX) { update_mask |= MSR_EFER_NXE; } - if (env->cpuid_ext3_features & CPUID_EXT3_SVM) { + if (env->features[FEAT_80000001_ECX] & CPUID_EXT3_SVM) { update_mask |= MSR_EFER_SVME; } - if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR) { + if (env->features[FEAT_80000001_EDX] & CPUID_EXT2_FFXSR) { update_mask |= MSR_EFER_FFXSR; } cpu_load_efer(env, (env->efer & ~update_mask) | @@ -513,7 +513,7 @@ void helper_rdmsr(CPUX86State *env) val = env->mtrr_deftype; break; case MSR_MTRRcap: - if (env->cpuid_features & CPUID_MTRR) { + if (env->features[FEAT_1_EDX] & CPUID_MTRR) { val = MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT | MSR_MTRRcap_WC_SUPPORTED; } else { diff --git a/target-i386/translate.c b/target-i386/translate.c index f394ea6..8ff4af9 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -7926,11 +7926,11 @@ static inline void gen_intermediate_code_internal(CPUX86State *env, if (flags & HF_SOFTMMU_MASK) { dc->mem_index = (cpu_mmu_index(env) + 1) << 2; } - dc->cpuid_features = env->cpuid_features; - dc->cpuid_ext_features = env->cpuid_ext_features; - dc->cpuid_ext2_features = env->cpuid_ext2_features; - dc->cpuid_ext3_features = env->cpuid_ext3_features; - dc->cpuid_7_0_ebx_features = env->cpuid_7_0_ebx_features; + dc->cpuid_features = env->features[FEAT_1_EDX]; + dc->cpuid_ext_features = env->features[FEAT_1_ECX]; + dc->cpuid_ext2_features = env->features[FEAT_80000001_EDX]; + dc->cpuid_ext3_features = env->features[FEAT_80000001_ECX]; + dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX]; #ifdef TARGET_X86_64 dc->lma = (flags >> HF_LMA_SHIFT) & 1; dc->code64 = (flags >> HF_CS64_SHIFT) & 1; -- 1.7.11.7 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array 2012-12-12 22:22 ` [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array Eduardo Habkost @ 2012-12-14 9:38 ` Igor Mammedov 2012-12-14 12:27 ` Eduardo Habkost 2012-12-14 15:14 ` Andreas Färber 1 sibling, 1 reply; 22+ messages in thread From: Igor Mammedov @ 2012-12-14 9:38 UTC (permalink / raw) To: Eduardo Habkost; +Cc: qemu-devel, Andreas Färber On Wed, 12 Dec 2012 20:22:26 -0200 Eduardo Habkost <ehabkost@redhat.com> wrote: > This replaces the feature-bit fields on both X86CPU and x86_def_t > structs with an array. > > With this, we will be able to simplify code that simply does the same > operation on all feature words (e.g. kvm_check_features_against_host(), > filter_features_for_kvm(), add_flagname_to_bitmaps(), and CPU > feature-bit property lookup/registration). > do you have a patch that simplifies kvm_check_features_against_host() using this? > -- > 1.7.11.7 > -- Regards, Igor ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array 2012-12-14 9:38 ` Igor Mammedov @ 2012-12-14 12:27 ` Eduardo Habkost 2012-12-14 13:52 ` Igor Mammedov 2012-12-14 14:53 ` Andreas Färber 0 siblings, 2 replies; 22+ messages in thread From: Eduardo Habkost @ 2012-12-14 12:27 UTC (permalink / raw) To: Igor Mammedov; +Cc: qemu-devel, Andreas Färber On Fri, Dec 14, 2012 at 10:38:50AM +0100, Igor Mammedov wrote: > On Wed, 12 Dec 2012 20:22:26 -0200 > Eduardo Habkost <ehabkost@redhat.com> wrote: > > > This replaces the feature-bit fields on both X86CPU and x86_def_t > > structs with an array. > > > > With this, we will be able to simplify code that simply does the same > > operation on all feature words (e.g. kvm_check_features_against_host(), > > filter_features_for_kvm(), add_flagname_to_bitmaps(), and CPU > > feature-bit property lookup/registration). > > > > do you have a patch that simplifies kvm_check_features_against_host() using > this? I have a very old one, based on an older (and more complex) version of this series: https://github.com/ehabkost/qemu-hacks/commit/eb01d374baecf6df26fd6f0d0bb23f2e1547f499 It's in the work/cpuid-refactor-v0.22-2012-08-31 branch in my git repository. That branch also has some patches to merge kvm_check_features_against_host() and filter_features_for_kvm() (because the purpose of kvm_check_features_against_host() is simply to check if anything is going to be filtered out by filter_features_for_kvm()). If people are happy with the approach in this series, I plan to write and submit cleanups for kvm_cpu_fill_host(), kvm_check_features_against_host(), filter_features_for_kvm(), add_flagname_to_bitmaps(), and the cpudef -> CPU feature copying code. There's so much code that could be cleaned up using the array, that I am afraid that it would cause too much conflicts in the CPU properties work. So I can wait until the CPU properties series are submitted before making the cleanups, if necessary. -- Eduardo ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array 2012-12-14 12:27 ` Eduardo Habkost @ 2012-12-14 13:52 ` Igor Mammedov 2012-12-14 14:02 ` Eduardo Habkost 2012-12-14 14:53 ` Andreas Färber 1 sibling, 1 reply; 22+ messages in thread From: Igor Mammedov @ 2012-12-14 13:52 UTC (permalink / raw) To: Eduardo Habkost; +Cc: qemu-devel, Andreas Färber On Fri, 14 Dec 2012 10:27:34 -0200 Eduardo Habkost <ehabkost@redhat.com> wrote: > On Fri, Dec 14, 2012 at 10:38:50AM +0100, Igor Mammedov wrote: > > On Wed, 12 Dec 2012 20:22:26 -0200 > > Eduardo Habkost <ehabkost@redhat.com> wrote: > > > > > This replaces the feature-bit fields on both X86CPU and x86_def_t > > > structs with an array. > > > > > > With this, we will be able to simplify code that simply does the same > > > operation on all feature words (e.g. kvm_check_features_against_host(), > > > filter_features_for_kvm(), add_flagname_to_bitmaps(), and CPU > > > feature-bit property lookup/registration). > > > > > > > do you have a patch that simplifies kvm_check_features_against_host() using > > this? > > I have a very old one, based on an older (and more complex) version of > this series: > https://github.com/ehabkost/qemu-hacks/commit/eb01d374baecf6df26fd6f0d0bb23f2e1547f499 > > It's in the work/cpuid-refactor-v0.22-2012-08-31 branch in my git > repository. > > That branch also has some patches to merge kvm_check_features_against_host() > and filter_features_for_kvm() (because the purpose of > kvm_check_features_against_host() is simply to check if anything is > going to be filtered out by filter_features_for_kvm()). > > If people are happy with the approach in this series, I plan to write > and submit cleanups for kvm_cpu_fill_host(), > kvm_check_features_against_host(), filter_features_for_kvm(), > add_flagname_to_bitmaps(), and the cpudef -> CPU feature copying code. > > There's so much code that could be cleaned up using the array, that I am > afraid that it would cause too much conflicts in the CPU properties > work. So I can wait until the CPU properties series are submitted before > making the cleanups, if necessary. with cpu properties and subclasses in place, kvm_check_features_against_host() could be expressed as simple subtraction of host subclass features list from guest cpu features list. Which won't require access to feature words at all. Just iterating over properties of both to build lists and then do subtraction and print difference if any, it could be eventially generalized to other kvm supported targets since it won't use any x86 specific fields. > -- > Eduardo > -- Regards, Igor ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array 2012-12-14 13:52 ` Igor Mammedov @ 2012-12-14 14:02 ` Eduardo Habkost 0 siblings, 0 replies; 22+ messages in thread From: Eduardo Habkost @ 2012-12-14 14:02 UTC (permalink / raw) To: Igor Mammedov; +Cc: qemu-devel, Andreas Färber On Fri, Dec 14, 2012 at 02:52:50PM +0100, Igor Mammedov wrote: > On Fri, 14 Dec 2012 10:27:34 -0200 > Eduardo Habkost <ehabkost@redhat.com> wrote: > > > On Fri, Dec 14, 2012 at 10:38:50AM +0100, Igor Mammedov wrote: > > > On Wed, 12 Dec 2012 20:22:26 -0200 > > > Eduardo Habkost <ehabkost@redhat.com> wrote: > > > > > > > This replaces the feature-bit fields on both X86CPU and x86_def_t > > > > structs with an array. > > > > > > > > With this, we will be able to simplify code that simply does the same > > > > operation on all feature words (e.g. kvm_check_features_against_host(), > > > > filter_features_for_kvm(), add_flagname_to_bitmaps(), and CPU > > > > feature-bit property lookup/registration). > > > > > > > > > > do you have a patch that simplifies kvm_check_features_against_host() using > > > this? > > > > I have a very old one, based on an older (and more complex) version of > > this series: > > https://github.com/ehabkost/qemu-hacks/commit/eb01d374baecf6df26fd6f0d0bb23f2e1547f499 > > > > It's in the work/cpuid-refactor-v0.22-2012-08-31 branch in my git > > repository. > > > > That branch also has some patches to merge kvm_check_features_against_host() > > and filter_features_for_kvm() (because the purpose of > > kvm_check_features_against_host() is simply to check if anything is > > going to be filtered out by filter_features_for_kvm()). > > > > If people are happy with the approach in this series, I plan to write > > and submit cleanups for kvm_cpu_fill_host(), > > kvm_check_features_against_host(), filter_features_for_kvm(), > > add_flagname_to_bitmaps(), and the cpudef -> CPU feature copying code. > > > > There's so much code that could be cleaned up using the array, that I am > > afraid that it would cause too much conflicts in the CPU properties > > work. So I can wait until the CPU properties series are submitted before > > making the cleanups, if necessary. > with cpu properties and subclasses in place, > kvm_check_features_against_host() could be expressed as simple subtraction of > host subclass features list from guest cpu features list. Which won't require > access to feature words at all. Just iterating over properties of both to > build lists and then do subtraction and print difference if any, it could be > eventially generalized to other kvm supported targets since it won't use any > x86 specific fields. Once we have the CPU properties code, maybe we could do that. I find the idea a bit confusing (I would like to avoid coupling the "check" code to the "host" CPU class directly), but may be doeable. We also have one problem: the host class class_init method may be called before KVM is initialized, so I don't know if we can really use the class instrospection system to find out which flags are supported by the host by looking at the "host" class. Considering the complexity of what you suggest, I think there's value in cleaning up that code first (and use the array to allow us to clean up other code as well), and try to use the solution you suggest later, after we actually have working CPU properties and subclasses. -- Eduardo ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array 2012-12-14 12:27 ` Eduardo Habkost 2012-12-14 13:52 ` Igor Mammedov @ 2012-12-14 14:53 ` Andreas Färber 2012-12-14 17:16 ` Eduardo Habkost 1 sibling, 1 reply; 22+ messages in thread From: Andreas Färber @ 2012-12-14 14:53 UTC (permalink / raw) To: Eduardo Habkost; +Cc: Igor Mammedov, qemu-devel Am 14.12.2012 13:27, schrieb Eduardo Habkost: > On Fri, Dec 14, 2012 at 10:38:50AM +0100, Igor Mammedov wrote: >> On Wed, 12 Dec 2012 20:22:26 -0200 >> Eduardo Habkost <ehabkost@redhat.com> wrote: >> >>> This replaces the feature-bit fields on both X86CPU and x86_def_t >>> structs with an array. >>> >>> With this, we will be able to simplify code that simply does the same >>> operation on all feature words (e.g. kvm_check_features_against_host(), >>> filter_features_for_kvm(), add_flagname_to_bitmaps(), and CPU >>> feature-bit property lookup/registration). >>> >> >> do you have a patch that simplifies kvm_check_features_against_host() using >> this? > > I have a very old one, based on an older (and more complex) version of > this series: > https://github.com/ehabkost/qemu-hacks/commit/eb01d374baecf6df26fd6f0d0bb23f2e1547f499 > > It's in the work/cpuid-refactor-v0.22-2012-08-31 branch in my git > repository. > > That branch also has some patches to merge kvm_check_features_against_host() > and filter_features_for_kvm() (because the purpose of > kvm_check_features_against_host() is simply to check if anything is > going to be filtered out by filter_features_for_kvm()). > > If people are happy with the approach in this series, I plan to write > and submit cleanups for kvm_cpu_fill_host(), > kvm_check_features_against_host(), filter_features_for_kvm(), > add_flagname_to_bitmaps(), and the cpudef -> CPU feature copying code. > > There's so much code that could be cleaned up using the array, that I am > afraid that it would cause too much conflicts in the CPU properties > work. So I can wait until the CPU properties series are submitted before > making the cleanups, if necessary. As stated elsewhere, for me a proper way to define new CPU models has higher priority than feature properties, especially now that we're headed for a class_init based approach where properties cannot be used for original initialization. As suggested with my RFC I would like to take a quick, simplistic route to subclasses where no major refactoring of data fields happens. If we prepend a couple coding style and function movement patches, that's fine with me. But if we do large functional refactorings > 10 patches that change history will be clobbered by the touch-all conversion and we need to do intensive functional testing, for which I don't see sufficient time before the Soft Freeze, given the holidays. When the feature bits are stored in the classes, setting them via properties in instance_init seems like overkill (visitor overhead); we no longer dump them in -cpu ?foo; only +feature/-feature would benefit. Thus I assume them to mainly conflict where function signatures change and trivially where def changes to env, making them rather orthogonal to each other. Regards, Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array 2012-12-14 14:53 ` Andreas Färber @ 2012-12-14 17:16 ` Eduardo Habkost 0 siblings, 0 replies; 22+ messages in thread From: Eduardo Habkost @ 2012-12-14 17:16 UTC (permalink / raw) To: Andreas Färber; +Cc: Igor Mammedov, qemu-devel On Fri, Dec 14, 2012 at 03:53:58PM +0100, Andreas Färber wrote: > Am 14.12.2012 13:27, schrieb Eduardo Habkost: > > On Fri, Dec 14, 2012 at 10:38:50AM +0100, Igor Mammedov wrote: > >> On Wed, 12 Dec 2012 20:22:26 -0200 > >> Eduardo Habkost <ehabkost@redhat.com> wrote: > >> > >>> This replaces the feature-bit fields on both X86CPU and x86_def_t > >>> structs with an array. > >>> > >>> With this, we will be able to simplify code that simply does the same > >>> operation on all feature words (e.g. kvm_check_features_against_host(), > >>> filter_features_for_kvm(), add_flagname_to_bitmaps(), and CPU > >>> feature-bit property lookup/registration). > >>> > >> > >> do you have a patch that simplifies kvm_check_features_against_host() using > >> this? > > > > I have a very old one, based on an older (and more complex) version of > > this series: > > https://github.com/ehabkost/qemu-hacks/commit/eb01d374baecf6df26fd6f0d0bb23f2e1547f499 > > > > It's in the work/cpuid-refactor-v0.22-2012-08-31 branch in my git > > repository. > > > > That branch also has some patches to merge kvm_check_features_against_host() > > and filter_features_for_kvm() (because the purpose of > > kvm_check_features_against_host() is simply to check if anything is > > going to be filtered out by filter_features_for_kvm()). > > > > If people are happy with the approach in this series, I plan to write > > and submit cleanups for kvm_cpu_fill_host(), > > kvm_check_features_against_host(), filter_features_for_kvm(), > > add_flagname_to_bitmaps(), and the cpudef -> CPU feature copying code. > > > > There's so much code that could be cleaned up using the array, that I am > > afraid that it would cause too much conflicts in the CPU properties > > work. So I can wait until the CPU properties series are submitted before > > making the cleanups, if necessary. > > As stated elsewhere, for me a proper way to define new CPU models has > higher priority than feature properties, especially now that we're > headed for a class_init based approach where properties cannot be used > for original initialization. We can go that way. But then I still strongly suggest we add the feature array before doing that, because it will help a lot to simplify the "host" CPU subclass code, and kvm_check_features_against_host() and kvm_cpu_fill_host(). (The main change I see is that kvm_check_features_against_host() won't need to fill a full x86_def_t struct from the host, just a local in-stack feature array. Also, kvm_check_features_against_host() and filter_features_for_kvm() could be unified as well) (Maybe I can work around the lack of feature array by keeping an embedded x86_def_t struct inside CPUClass (so kvm_cpu_fill_host() don't need a full CPUClass struct like in your RFC). I will try and see what's possible) > > As suggested with my RFC I would like to take a quick, simplistic route > to subclasses where no major refactoring of data fields happens. If we > prepend a couple coding style and function movement patches, that's fine > with me. But if we do large functional refactorings > 10 patches that > change history will be clobbered by the touch-all conversion and we need > to do intensive functional testing, for which I don't see sufficient > time before the Soft Freeze, given the holidays. I thought we would be in the "we can't introduce major changes" mode _after_ the soft freeze, not before the soft freeze. ;-) So, are we already in soft freeze in practice? > > When the feature bits are stored in the classes, setting them via > properties in instance_init seems like overkill (visitor overhead); If performance is an issue (I doubt it would be), we could still keep the array inside the model/class, and copy it on instance_init. But we still need a per-instance array as well, in addition to the per-model data (see below). > we > no longer dump them in -cpu ?foo; only +feature/-feature would benefit. > Thus I assume them to mainly conflict where function signatures change > and trivially where def changes to env, making them rather orthogonal to > each other. We can't just change "env" to "def", because "def" is static and "env" contains the result of the "<model>,+feature,-feature" parsing. We could try to go through a route where there's no def->env copy in the code, but then I believe this would be the opposite of the quick simplistic route you're trying to take. -- Eduardo ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array 2012-12-12 22:22 ` [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array Eduardo Habkost 2012-12-14 9:38 ` Igor Mammedov @ 2012-12-14 15:14 ` Andreas Färber 2012-12-14 16:52 ` Eduardo Habkost 1 sibling, 1 reply; 22+ messages in thread From: Andreas Färber @ 2012-12-14 15:14 UTC (permalink / raw) To: Eduardo Habkost; +Cc: Igor Mammedov, qemu-devel Am 12.12.2012 23:22, schrieb Eduardo Habkost: > This replaces the feature-bit fields on both X86CPU and x86_def_t > structs with an array. > > With this, we will be able to simplify code that simply does the same > operation on all feature words (e.g. kvm_check_features_against_host(), > filter_features_for_kvm(), add_flagname_to_bitmaps(), and CPU > feature-bit property lookup/registration). > > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> > --- > This patch was created solely using a sed script and no manual changes, > to try to avoid mistakes while converting the code, and make it easier > to rebase if necessary. The sed script can be seen at: > https://gist.github.com/4271991 > --- > hw/kvm/clock.c | 2 +- > linux-user/elfload.c | 2 +- > linux-user/main.c | 4 +- > target-i386/cpu.c | 578 +++++++++++++++++++++++----------------------- > target-i386/cpu.h | 30 +-- > target-i386/helper.c | 4 +- > target-i386/kvm.c | 5 +- > target-i386/misc_helper.c | 14 +- > target-i386/translate.c | 10 +- > 9 files changed, 331 insertions(+), 318 deletions(-) I wonder, if we're touching all these lines anyway, can't we place the new feature array directly into X86CPU? As far as I see the features are never changed at runtime, so the only reason to have them in the instance is the command-line-supplied overrides. The clock code using first_cpu looks solvable; what about CR4 and MSR helpers, how performance-sensitive are they? (if they're not yet using X86CPU for something else) With the proposed variable change env -> cpu it would not be fully sed'able, but as a maintainer I need to review the whole patch anyway. Either way since this change affects not just the core CPU that I have started to maintain I feel I should give other target-i386 stakeholders (Blue, Aurélien, malc, ...) sufficient time to object, so not before Christmas realistically. Regards, Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array 2012-12-14 15:14 ` Andreas Färber @ 2012-12-14 16:52 ` Eduardo Habkost 2012-12-14 17:20 ` Andreas Färber 0 siblings, 1 reply; 22+ messages in thread From: Eduardo Habkost @ 2012-12-14 16:52 UTC (permalink / raw) To: Andreas Färber; +Cc: Igor Mammedov, qemu-devel On Fri, Dec 14, 2012 at 04:14:32PM +0100, Andreas Färber wrote: > Am 12.12.2012 23:22, schrieb Eduardo Habkost: > > This replaces the feature-bit fields on both X86CPU and x86_def_t > > structs with an array. > > > > With this, we will be able to simplify code that simply does the same > > operation on all feature words (e.g. kvm_check_features_against_host(), > > filter_features_for_kvm(), add_flagname_to_bitmaps(), and CPU > > feature-bit property lookup/registration). > > > > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> > > --- > > This patch was created solely using a sed script and no manual changes, > > to try to avoid mistakes while converting the code, and make it easier > > to rebase if necessary. The sed script can be seen at: > > https://gist.github.com/4271991 > > --- > > hw/kvm/clock.c | 2 +- > > linux-user/elfload.c | 2 +- > > linux-user/main.c | 4 +- > > target-i386/cpu.c | 578 +++++++++++++++++++++++----------------------- > > target-i386/cpu.h | 30 +-- > > target-i386/helper.c | 4 +- > > target-i386/kvm.c | 5 +- > > target-i386/misc_helper.c | 14 +- > > target-i386/translate.c | 10 +- > > 9 files changed, 331 insertions(+), 318 deletions(-) > > I wonder, if we're touching all these lines anyway, can't we place the > new feature array directly into X86CPU? As far as I see the features are > never changed at runtime, so the only reason to have them in the > instance is the command-line-supplied overrides. You mean directly into X86CPUClass? No, we can't: the features are changed at the CPU instance at runtime, when based in the +feature,-feature feature string. We also do some extra filtering based on KVM capabilities at filter_features_for_kvm(). I believe we're moving towards another direction: making the feature bits live only in the X86CPU object, and they will be initialized based on the default property values of each CPU class. Probably we won't do that in the first version of CPU subclasses/properties, but we are trying to reach that point. > > The clock code using first_cpu looks solvable; what about CR4 and MSR > helpers, how performance-sensitive are they? (if they're not yet using > X86CPU for something else) I guess any CPU-state code inside QEMU is not performance-sensitive, as it woud already require switching between KVM kernelspace and QEMU userspace. > > With the proposed variable change env -> cpu it would not be fully > sed'able, but as a maintainer I need to review the whole patch anyway. On the other hand, this cleanup will allow us to easily convert some code to deal with the feature array only (not requiring the full X86CPU or x86_def_t struct), making it easier to have only one feature array, in only one place, in the future. > > Either way since this change affects not just the core CPU that I have > started to maintain I feel I should give other target-i386 stakeholders > (Blue, Aurélien, malc, ...) sufficient time to object, so not before > Christmas realistically. OK. -- Eduardo ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array 2012-12-14 16:52 ` Eduardo Habkost @ 2012-12-14 17:20 ` Andreas Färber 2012-12-14 17:36 ` Eduardo Habkost 0 siblings, 1 reply; 22+ messages in thread From: Andreas Färber @ 2012-12-14 17:20 UTC (permalink / raw) To: Eduardo Habkost; +Cc: Igor Mammedov, qemu-devel Am 14.12.2012 17:52, schrieb Eduardo Habkost: > On Fri, Dec 14, 2012 at 04:14:32PM +0100, Andreas Färber wrote: >> Am 12.12.2012 23:22, schrieb Eduardo Habkost: >>> This replaces the feature-bit fields on both X86CPU and x86_def_t >>> structs with an array. >>> >>> With this, we will be able to simplify code that simply does the same >>> operation on all feature words (e.g. kvm_check_features_against_host(), >>> filter_features_for_kvm(), add_flagname_to_bitmaps(), and CPU >>> feature-bit property lookup/registration). >>> >>> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> >>> --- >>> This patch was created solely using a sed script and no manual changes, >>> to try to avoid mistakes while converting the code, and make it easier >>> to rebase if necessary. The sed script can be seen at: >>> https://gist.github.com/4271991 >>> --- >>> hw/kvm/clock.c | 2 +- >>> linux-user/elfload.c | 2 +- >>> linux-user/main.c | 4 +- >>> target-i386/cpu.c | 578 +++++++++++++++++++++++----------------------- >>> target-i386/cpu.h | 30 +-- >>> target-i386/helper.c | 4 +- >>> target-i386/kvm.c | 5 +- >>> target-i386/misc_helper.c | 14 +- >>> target-i386/translate.c | 10 +- >>> 9 files changed, 331 insertions(+), 318 deletions(-) >> >> I wonder, if we're touching all these lines anyway, can't we place the >> new feature array directly into X86CPU? As far as I see the features are >> never changed at runtime, so the only reason to have them in the >> instance is the command-line-supplied overrides. > > You mean directly into X86CPUClass? [...] No, I literally meant X86CPU rather than CPUX86State (i.e., the place within the instance). >> The clock code using first_cpu looks solvable; what about CR4 and MSR >> helpers, how performance-sensitive are they? (if they're not yet using >> X86CPU for something else) > > I guess any CPU-state code inside QEMU is not performance-sensitive, as > it woud already require switching between KVM kernelspace and QEMU > userspace. I mean target-i386/[misc_]helper.c and thus TCG, IIUC. :) > On the other hand, this cleanup will allow us to easily convert some > code to deal with the feature array only (not requiring the full X86CPU > or x86_def_t struct), making it easier to have only one feature array, > in only one place, in the future. The alternative line of thought is whether to group KVM stuff together. Tying it into an array makes that harder. But personally I'm not opposed to this array proposal. Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array 2012-12-14 17:20 ` Andreas Färber @ 2012-12-14 17:36 ` Eduardo Habkost 2012-12-14 17:47 ` Igor Mammedov 0 siblings, 1 reply; 22+ messages in thread From: Eduardo Habkost @ 2012-12-14 17:36 UTC (permalink / raw) To: Andreas Färber; +Cc: Igor Mammedov, qemu-devel On Fri, Dec 14, 2012 at 06:20:41PM +0100, Andreas Färber wrote: > Am 14.12.2012 17:52, schrieb Eduardo Habkost: > > On Fri, Dec 14, 2012 at 04:14:32PM +0100, Andreas Färber wrote: > >> Am 12.12.2012 23:22, schrieb Eduardo Habkost: > >>> This replaces the feature-bit fields on both X86CPU and x86_def_t > >>> structs with an array. > >>> > >>> With this, we will be able to simplify code that simply does the same > >>> operation on all feature words (e.g. kvm_check_features_against_host(), > >>> filter_features_for_kvm(), add_flagname_to_bitmaps(), and CPU > >>> feature-bit property lookup/registration). > >>> > >>> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> > >>> --- > >>> This patch was created solely using a sed script and no manual changes, > >>> to try to avoid mistakes while converting the code, and make it easier > >>> to rebase if necessary. The sed script can be seen at: > >>> https://gist.github.com/4271991 > >>> --- > >>> hw/kvm/clock.c | 2 +- > >>> linux-user/elfload.c | 2 +- > >>> linux-user/main.c | 4 +- > >>> target-i386/cpu.c | 578 +++++++++++++++++++++++----------------------- > >>> target-i386/cpu.h | 30 +-- > >>> target-i386/helper.c | 4 +- > >>> target-i386/kvm.c | 5 +- > >>> target-i386/misc_helper.c | 14 +- > >>> target-i386/translate.c | 10 +- > >>> 9 files changed, 331 insertions(+), 318 deletions(-) > >> > >> I wonder, if we're touching all these lines anyway, can't we place the > >> new feature array directly into X86CPU? As far as I see the features are > >> never changed at runtime, so the only reason to have them in the > >> instance is the command-line-supplied overrides. > > > > You mean directly into X86CPUClass? [...] > > No, I literally meant X86CPU rather than CPUX86State (i.e., the place > within the instance). OK. That makes sense. I believe that moving fields to X86CPU would be much easier if we change the code that will actually use those fields to use the QOM CPU class. > > >> The clock code using first_cpu looks solvable; what about CR4 and MSR > >> helpers, how performance-sensitive are they? (if they're not yet using > >> X86CPU for something else) > > > > I guess any CPU-state code inside QEMU is not performance-sensitive, as > > it woud already require switching between KVM kernelspace and QEMU > > userspace. > > I mean target-i386/[misc_]helper.c and thus TCG, IIUC. :) Oh, right. I wonder how much performance impact it would have, if people are already using TCG. Anyway, would this really have any impact at all? I mean: ENV_GET_CPU(env) is basically subtracing an constant offset from 'env'. So I expect similar code to be generated, just using a different offset from 'env' to get the cpuid_features field. > > > On the other hand, this cleanup will allow us to easily convert some > > code to deal with the feature array only (not requiring the full X86CPU > > or x86_def_t struct), making it easier to have only one feature array, > > in only one place, in the future. > > The alternative line of thought is whether to group KVM stuff together. > Tying it into an array makes that harder. But personally I'm not opposed > to this array proposal. I don't think we would gain much from grouping KVM stuff together. It would just force us to add KVM special-cases to code that deal with feature bits. KVM feature bits are CPUID bits that work like all others. -- Eduardo ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array 2012-12-14 17:36 ` Eduardo Habkost @ 2012-12-14 17:47 ` Igor Mammedov 2012-12-14 18:32 ` Eduardo Habkost 0 siblings, 1 reply; 22+ messages in thread From: Igor Mammedov @ 2012-12-14 17:47 UTC (permalink / raw) To: Eduardo Habkost; +Cc: Andreas Färber, qemu-devel On Fri, 14 Dec 2012 15:36:22 -0200 Eduardo Habkost <ehabkost@redhat.com> wrote: > On Fri, Dec 14, 2012 at 06:20:41PM +0100, Andreas Färber wrote: > > Am 14.12.2012 17:52, schrieb Eduardo Habkost: > > > On Fri, Dec 14, 2012 at 04:14:32PM +0100, Andreas Färber wrote: > > >> Am 12.12.2012 23:22, schrieb Eduardo Habkost: [...] > > > > >> The clock code using first_cpu looks solvable; what about CR4 and MSR > > >> helpers, how performance-sensitive are they? (if they're not yet using > > >> X86CPU for something else) > > > > > > I guess any CPU-state code inside QEMU is not performance-sensitive, as > > > it woud already require switching between KVM kernelspace and QEMU > > > userspace. > > > > I mean target-i386/[misc_]helper.c and thus TCG, IIUC. :) > > Oh, right. I wonder how much performance impact it would have, if people > are already using TCG. > > Anyway, would this really have any impact at all? I mean: > ENV_GET_CPU(env) is basically subtracing an constant offset from 'env'. > So I expect similar code to be generated, just using a different offset > from 'env' to get the cpuid_features field. ENV_GET_CPU(env) does dynamic_cast which is expensive. > > -- > Eduardo -- Regards, Igor ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array 2012-12-14 17:47 ` Igor Mammedov @ 2012-12-14 18:32 ` Eduardo Habkost 0 siblings, 0 replies; 22+ messages in thread From: Eduardo Habkost @ 2012-12-14 18:32 UTC (permalink / raw) To: Igor Mammedov; +Cc: Andreas Färber, qemu-devel On Fri, Dec 14, 2012 at 06:47:20PM +0100, Igor Mammedov wrote: > On Fri, 14 Dec 2012 15:36:22 -0200 > Eduardo Habkost <ehabkost@redhat.com> wrote: > > > On Fri, Dec 14, 2012 at 06:20:41PM +0100, Andreas Färber wrote: > > > Am 14.12.2012 17:52, schrieb Eduardo Habkost: > > > > On Fri, Dec 14, 2012 at 04:14:32PM +0100, Andreas Färber wrote: > > > >> Am 12.12.2012 23:22, schrieb Eduardo Habkost: > [...] > > > > > > >> The clock code using first_cpu looks solvable; what about CR4 and MSR > > > >> helpers, how performance-sensitive are they? (if they're not yet using > > > >> X86CPU for something else) > > > > > > > > I guess any CPU-state code inside QEMU is not performance-sensitive, as > > > > it woud already require switching between KVM kernelspace and QEMU > > > > userspace. > > > > > > I mean target-i386/[misc_]helper.c and thus TCG, IIUC. :) > > > > Oh, right. I wonder how much performance impact it would have, if people > > are already using TCG. > > > > Anyway, would this really have any impact at all? I mean: > > ENV_GET_CPU(env) is basically subtracing an constant offset from 'env'. > > So I expect similar code to be generated, just using a different offset > > from 'env' to get the cpuid_features field. > ENV_GET_CPU(env) does dynamic_cast which is expensive. Oh, I didn't notice that. So the alternatives I see are: - Use ENV_GET_CPU() and risk performance problems; - Write a FAST_ENV_GET_CPU() macro for performance-sensitive code, that doesn't use dynamic_cast; - Keep the fields on CPUX86State and move them only after we change the TCG code to use the QOM CPU object. Personally, I prefer the third option. Moving fields from CPUArchState before making most code use the CPU QOM objects instead of CPUArchState sounds like a painful task. -- Eduardo ^ permalink raw reply [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 0/3] replace cpuid_*features fields with a featue word array (v3) @ 2012-12-18 16:29 Eduardo Habkost 2012-12-18 16:29 ` [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array Eduardo Habkost 0 siblings, 1 reply; 22+ messages in thread From: Eduardo Habkost @ 2012-12-18 16:29 UTC (permalink / raw) To: qemu-devel Cc: Riku Voipio, Blue Swirl, malc, Igor Mammedov, Andreas Färber, Aurelien Jarno I would like to give emphasis to the following, from description of patch 3: This should also help avoid bugs like the ones introduced when we added cpuid_7_0_ebx_features. Today, adding a new feature word to the code requires chaning 5 or 6 different places in the code, and it's very easy to miss a problem when we forget to update one of those parts. See, for example: * The bug solved by commit ffa8c11f0bbf47e1b7a3a62f97bc1da591c6734a; * The fact that check_features_against_host() still doesn't check all feature words as it is supposed to. Changes in v3: - Removed the EXT2_PPRO_FEATURES patch - Rebased on top of: - afaerber's qom-cpu-next (commit cb97b7f), plus - Igor's "[PATCH 00/20 v2] x86 CPU cleanup (wave 2)" (but only patches 1-6 and 12) (See git tree below) - I tried to choose the patches that I find likely to be included soon, to try to reduce the need to rebase this patch again, but I know I probably haven't guessed correctly and a new rebase is probably going to be necessary. - Added "target-i386/cpu.c: remove last TAB character from the source" Changes in v2: - Rebased on top of: Subject: [PATCH 0/2] target-i386: move CPU object creation to cpu.c (v2) - Wrote a sed script that can be used to reproduce exactly the same changes from patch 3: https://gist.github.com/4271991 Git tree for testing: git://github.com/ehabkost/qemu-hacks.git x86-cpu-feature-array.v3 https://github.com/ehabkost/qemu-hacks/tree/x86-cpu-feature-array.v3 Original description: I was planning to implement this only after we finished the rest of the work, the changes are a bit intrusive. But now it looks like the CPUID feature bits are getting into our way (e.g. the feature word array will allow us to simplify the -cpu host and -cpu check/enforce code a lot, making it easier to convert that code to use CPU subclasses), so I decided to submit it now. Eduardo Habkost (3): target-i386/cpu.c: coding style fix target-i386/cpu.c: remove last TAB character from the source target-i386: replace cpuid_*features fields with a feature word array hw/kvm/clock.c | 2 +- linux-user/elfload.c | 2 +- linux-user/main.c | 4 +- target-i386/cpu.c | 586 ++++++++++++++++++++++++---------------------- target-i386/cpu.h | 30 ++- target-i386/helper.c | 4 +- target-i386/kvm.c | 5 +- target-i386/misc_helper.c | 14 +- target-i386/translate.c | 10 +- 9 files changed, 338 insertions(+), 319 deletions(-) -- 1.7.11.7 ^ permalink raw reply [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array 2012-12-18 16:29 [Qemu-devel] [PATCH 0/3] replace cpuid_*features fields with a featue word array (v3) Eduardo Habkost @ 2012-12-18 16:29 ` Eduardo Habkost 0 siblings, 0 replies; 22+ messages in thread From: Eduardo Habkost @ 2012-12-18 16:29 UTC (permalink / raw) To: qemu-devel; +Cc: Igor Mammedov, Andreas Färber This replaces the feature-bit fields on both X86CPU and x86_def_t structs with an array. With this, we will be able to simplify code that simply does the same operation on all feature words (e.g. kvm_check_features_against_host(), filter_features_for_kvm(), add_flagname_to_bitmaps(), and CPU feature-bit property lookup/registration). This should also help avoid bugs like the ones introduced when we added cpuid_7_0_ebx_features. Today, adding a new feature word to the code requires chaning 5 or 6 different places in the code, and it's very easy to miss a problem when we forget to update one of those parts. See, for example: * The bug solved by commit ffa8c11f0bbf47e1b7a3a62f97bc1da591c6734a; * The fact that check_features_against_host() still doesn't check all feature words as it is supposed to. Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- This patch was created solely using a sed script and no manual changes, to try to avoid mistakes while converting the code, and make it easier to rebase if necessary. The sed script can be seen at: https://gist.github.com/4271991 --- hw/kvm/clock.c | 2 +- linux-user/elfload.c | 2 +- linux-user/main.c | 4 +- target-i386/cpu.c | 581 ++++++++++++++++++++++++---------------------- target-i386/cpu.h | 30 +-- target-i386/helper.c | 4 +- target-i386/kvm.c | 5 +- target-i386/misc_helper.c | 14 +- target-i386/translate.c | 10 +- 9 files changed, 335 insertions(+), 317 deletions(-) diff --git a/hw/kvm/clock.c b/hw/kvm/clock.c index 824b978..11af665 100644 --- a/hw/kvm/clock.c +++ b/hw/kvm/clock.c @@ -129,7 +129,7 @@ static TypeInfo kvmclock_info = { void kvmclock_create(void) { if (kvm_enabled() && - first_cpu->cpuid_kvm_features & ((1ULL << KVM_FEATURE_CLOCKSOURCE) | + first_cpu->features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) | (1ULL << KVM_FEATURE_CLOCKSOURCE2))) { sysbus_create_simple("kvmclock", -1, NULL); } diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 1d8bcb4..71156af 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -130,7 +130,7 @@ static const char *get_elf_platform(void) static uint32_t get_elf_hwcap(void) { - return thread_env->cpuid_features; + return thread_env->features[FEAT_1_EDX]; } #ifdef TARGET_X86_64 diff --git a/linux-user/main.c b/linux-user/main.c index 25e35cd..5e847dd 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3625,13 +3625,13 @@ int main(int argc, char **argv, char **envp) env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK; env->hflags |= HF_PE_MASK; - if (env->cpuid_features & CPUID_SSE) { + if (env->features[FEAT_1_EDX] & CPUID_SSE) { env->cr[4] |= CR4_OSFXSR_MASK; env->hflags |= HF_OSFXSR_MASK; } #ifndef TARGET_ABI32 /* enable 64 bit mode if possible */ - if (!(env->cpuid_ext2_features & CPUID_EXT2_LM)) { + if (!(env->features[FEAT_80000001_EDX] & CPUID_EXT2_LM)) { fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n"); exit(1); } diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 6bfc8cc..58b3676 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -274,22 +274,15 @@ static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features, typedef struct x86_def_t { struct x86_def_t *next; const char *name; - uint32_t level; + uint32_t level, xlevel, xlevel2; + X86CPUFeatureWords features; char vendor[CPUID_VENDOR_SZ + 1]; int family; int model; int stepping; int tsc_khz; - uint32_t features, ext_features, ext2_features, ext3_features; - uint32_t kvm_features, svm_features; - uint32_t xlevel; char model_id[48]; int vendor_override; - /* Store the results of Centaur's CPUID instructions */ - uint32_t ext4_features; - uint32_t xlevel2; - /* The feature bits on CPUID[EAX=7,ECX=0].EBX */ - uint32_t cpuid_7_0_ebx_features; } x86_def_t; #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE) @@ -344,13 +337,14 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 2, .stepping = 3, - .features = PPRO_FEATURES | - CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | - CPUID_PSE36, - .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT, - .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | - CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, - .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH | + CPUID_MCA | CPUID_PSE36, + .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | + CPUID_EXT_POPCNT, + .features[FEAT_80000001_EDX] = + (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | CPUID_EXT2_LM | + CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A, .xlevel = 0x8000000A, }, @@ -361,22 +355,22 @@ static x86_def_t builtin_x86_defs[] = { .family = 16, .model = 2, .stepping = 3, - .features = PPRO_FEATURES | - CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | - CPUID_PSE36 | CPUID_VME | CPUID_HT, - .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 | - CPUID_EXT_POPCNT, - .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | - CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | - CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT | - CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP, + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH | + CPUID_MCA | CPUID_PSE36 | CPUID_VME | CPUID_HT, + .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | + CPUID_EXT_CX16 | CPUID_EXT_POPCNT, + .features[FEAT_80000001_EDX] = + (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | CPUID_EXT2_LM | + CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_3DNOW | + CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT | CPUID_EXT2_FFXSR | + CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP, /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC, CPUID_EXT3_CR8LEG, CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH, CPUID_EXT3_OSVW, CPUID_EXT3_IBS */ - .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A, - .svm_features = CPUID_SVM_NPT | CPUID_SVM_LBRV, + .features[FEAT_SVM] = CPUID_SVM_NPT | CPUID_SVM_LBRV, .xlevel = 0x8000001A, .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor" }, @@ -387,15 +381,16 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 15, .stepping = 11, - .features = PPRO_FEATURES | - CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | - CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS | - CPUID_HT | CPUID_TM | CPUID_PBE, - .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | - CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | CPUID_EXT_VMX | CPUID_EXT_EST | - CPUID_EXT_TM2 | CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, - .ext3_features = CPUID_EXT3_LAHF_LM, + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH | + CPUID_MCA | CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | + CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE, + .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | + CPUID_EXT_SSSE3 | CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | + CPUID_EXT_VMX | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_CX16 | + CPUID_EXT_XTPR | CPUID_EXT_PDCM, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | + CPUID_EXT2_NX, + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x80000008, .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz", }, @@ -407,19 +402,19 @@ static x86_def_t builtin_x86_defs[] = { .model = 6, .stepping = 1, /* Missing: CPUID_VME, CPUID_HT */ - .features = PPRO_FEATURES | - CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | - CPUID_PSE36, + .features[FEAT_1_EDX] = 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, + .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_CX16, /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */ - .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | - CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, + .features[FEAT_80000001_EDX] = + (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | 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, + .features[FEAT_80000001_ECX] = 0, .xlevel = 0x80000008, .model_id = "Common KVM processor" }, @@ -430,8 +425,8 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 3, .stepping = 3, - .features = PPRO_FEATURES, - .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT, + .features[FEAT_1_EDX] = PPRO_FEATURES, + .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT, .xlevel = 0x80000004, }, { @@ -441,11 +436,11 @@ static x86_def_t builtin_x86_defs[] = { .family = 15, .model = 6, .stepping = 1, - .features = PPRO_FEATURES | - CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36, - .ext_features = CPUID_EXT_SSE3, - .ext2_features = PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES, - .ext3_features = 0, + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH | + CPUID_MCA | CPUID_PSE36, + .features[FEAT_1_ECX] = CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES, + .features[FEAT_80000001_ECX] = 0, .xlevel = 0x80000008, .model_id = "Common 32-bit KVM processor" }, @@ -456,12 +451,13 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 14, .stepping = 8, - .features = PPRO_FEATURES | CPUID_VME | - CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI | - CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE, - .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_VMX | - CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | CPUID_EXT_PDCM, - .ext2_features = CPUID_EXT2_NX, + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_VME | CPUID_MTRR | + CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI | CPUID_SS | + CPUID_HT | CPUID_TM | CPUID_PBE, + .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | + CPUID_EXT_VMX | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | + CPUID_EXT_PDCM, + .features[FEAT_80000001_EDX] = CPUID_EXT2_NX, .xlevel = 0x80000008, .model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz", }, @@ -472,7 +468,7 @@ static x86_def_t builtin_x86_defs[] = { .family = 4, .model = 0, .stepping = 0, - .features = I486_FEATURES, + .features[FEAT_1_EDX] = I486_FEATURES, .xlevel = 0, }, { @@ -482,7 +478,7 @@ static x86_def_t builtin_x86_defs[] = { .family = 5, .model = 4, .stepping = 3, - .features = PENTIUM_FEATURES, + .features[FEAT_1_EDX] = PENTIUM_FEATURES, .xlevel = 0, }, { @@ -492,7 +488,7 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 5, .stepping = 2, - .features = PENTIUM2_FEATURES, + .features[FEAT_1_EDX] = PENTIUM2_FEATURES, .xlevel = 0, }, { @@ -502,7 +498,7 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 7, .stepping = 3, - .features = PENTIUM3_FEATURES, + .features[FEAT_1_EDX] = PENTIUM3_FEATURES, .xlevel = 0, }, { @@ -512,10 +508,11 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 2, .stepping = 3, - .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | - CPUID_MCA, - .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | - CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT, + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | + CPUID_MTRR | CPUID_MCA, + .features[FEAT_80000001_EDX] = + (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | CPUID_EXT2_MMXEXT | + CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT, .xlevel = 0x80000008, }, { @@ -526,15 +523,16 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 28, .stepping = 2, - .features = PPRO_FEATURES | - CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME | CPUID_DTS | - CPUID_ACPI | CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE, + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH | + CPUID_MCA | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS | + CPUID_HT | CPUID_TM | CPUID_PBE, /* Some CPUs got no CPUID_SEP */ - .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | - CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR, - .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | - CPUID_EXT2_NX, - .ext3_features = CPUID_EXT3_LAHF_LM, + .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | + CPUID_EXT_SSSE3 | CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | + CPUID_EXT_XTPR, + .features[FEAT_80000001_EDX] = + (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | CPUID_EXT2_NX, + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, .model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz", }, @@ -545,14 +543,15 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 2, .stepping = 3, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_SSSE3 | CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, - .ext3_features = CPUID_EXT3_LAHF_LM, + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_SSSE3 | CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_NX | + CPUID_EXT2_SYSCALL, + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)", }, @@ -563,15 +562,16 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 2, .stepping = 3, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | - CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, - .ext3_features = CPUID_EXT3_LAHF_LM, + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_SSE41 | CPUID_EXT_CX16 | + CPUID_EXT_SSSE3 | CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_NX | + CPUID_EXT2_SYSCALL, + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)", }, @@ -582,15 +582,17 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 2, .stepping = 3, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | - CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, - .ext3_features = CPUID_EXT3_LAHF_LM, + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | + CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | + CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | + CPUID_EXT2_NX, + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)", }, @@ -601,16 +603,17 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 44, .stepping = 1, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | - CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | - CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, - .ext3_features = CPUID_EXT3_LAHF_LM, + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_AES | CPUID_EXT_POPCNT | + CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | CPUID_EXT_CX16 | + CPUID_EXT_SSSE3 | CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | + CPUID_EXT2_NX, + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)", }, @@ -621,19 +624,19 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 42, .stepping = 1, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES | - CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT | - CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | - CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | - CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | - CPUID_EXT2_SYSCALL, - .ext3_features = CPUID_EXT3_LAHF_LM, + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_AVX | CPUID_EXT_XSAVE | + CPUID_EXT_AES | CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT | + CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | + CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | + CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | + CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, .model_id = "Intel Xeon E312xx (Sandy Bridge)", }, @@ -644,21 +647,21 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 60, .stepping = 1, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES | - CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | - CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | - CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 | - CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE | - CPUID_EXT_PCID, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | - CPUID_EXT2_SYSCALL, - .ext3_features = CPUID_EXT3_LAHF_LM, - .cpuid_7_0_ebx_features = CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_AVX | CPUID_EXT_XSAVE | + CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | + CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | CPUID_EXT_CX16 | + CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 | + CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE | + CPUID_EXT_PCID, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | + CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, + .features[FEAT_80000001_ECX] = CPUID_EXT3_LAHF_LM, + .features[FEAT_7_0_EBX] = CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_RTM, @@ -672,18 +675,18 @@ static x86_def_t builtin_x86_defs[] = { .family = 15, .model = 6, .stepping = 1, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX | - CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_FXSR | + CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE | - CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | - CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | - CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, + CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | + CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | + CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, .xlevel = 0x80000008, .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)", }, @@ -694,20 +697,20 @@ static x86_def_t builtin_x86_defs[] = { .family = 15, .model = 6, .stepping = 1, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_CX16 | CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR | - CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 | - CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA | - CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | - CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE | - CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE | - CPUID_EXT2_DE | CPUID_EXT2_FPU, - .ext3_features = CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM, + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_CX16 | CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | + CPUID_EXT2_FXSR | CPUID_EXT2_MMX | CPUID_EXT2_NX | + CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | CPUID_EXT2_CMOV | + CPUID_EXT2_MCA | CPUID_EXT2_PGE | CPUID_EXT2_MTRR | + CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | CPUID_EXT2_CX8 | + CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | + CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, + .features[FEAT_80000001_ECX] = CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM, .xlevel = 0x80000008, .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)", }, @@ -718,22 +721,23 @@ static x86_def_t builtin_x86_defs[] = { .family = 15, .model = 6, .stepping = 1, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR | - CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR | - CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 | - CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA | - CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | - CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE | - CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE | - CPUID_EXT2_DE | CPUID_EXT2_FPU, - .ext3_features = CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | - CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM, + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_POPCNT | CPUID_EXT_CX16 | + CPUID_EXT_MONITOR | CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | + CPUID_EXT2_FXSR | CPUID_EXT2_MMX | CPUID_EXT2_NX | + CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | CPUID_EXT2_CMOV | + CPUID_EXT2_MCA | CPUID_EXT2_PGE | CPUID_EXT2_MTRR | + CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | CPUID_EXT2_CX8 | + CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | + CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, + .features[FEAT_80000001_ECX] = CPUID_EXT3_MISALIGNSSE | + CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM | + CPUID_EXT3_LAHF_LM, .xlevel = 0x80000008, .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)", }, @@ -744,26 +748,26 @@ static x86_def_t builtin_x86_defs[] = { .family = 21, .model = 1, .stepping = 2, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES | - CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | - CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | - CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | - CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX | - CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | - CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE | - CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | - CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | - CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, - .ext3_features = CPUID_EXT3_FMA4 | CPUID_EXT3_XOP | - CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE | - CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM | - CPUID_EXT3_LAHF_LM, + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_AVX | CPUID_EXT_XSAVE | + CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | + CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | + CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3, + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | + CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX | + CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | + CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE | + CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | + CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | + CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, + .features[FEAT_80000001_ECX] = CPUID_EXT3_FMA4 | CPUID_EXT3_XOP | + CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE | + CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM | + CPUID_EXT3_LAHF_LM, .xlevel = 0x8000001A, .model_id = "AMD Opteron 62xx class CPU", }, @@ -774,26 +778,26 @@ static x86_def_t builtin_x86_defs[] = { .family = 21, .model = 2, .stepping = 0, - .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | - CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | - CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | - CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | - CPUID_DE | CPUID_FP87, - .ext_features = CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE | - CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | - CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA | + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | + CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | + CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | + CPUID_PSE | CPUID_DE | CPUID_FP87, + .features[FEAT_1_ECX] = CPUID_EXT_F16C | CPUID_EXT_AVX | + CPUID_EXT_XSAVE | CPUID_EXT_AES | CPUID_EXT_POPCNT | + CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3, - .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | - CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX | - CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | - CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE | - CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | - CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | - CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, - .ext3_features = CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP | - CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE | + .features[FEAT_80000001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | + CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX | + CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | + CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE | + CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | + CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | + CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, + .features[FEAT_80000001_ECX] = CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | + CPUID_EXT3_XOP | CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM | - CPUID_EXT3_LAHF_LM, + CPUID_EXT3_LAHF_LM, .xlevel = 0x8000001A, .model_id = "AMD Opteron 63xx class CPU", }, @@ -844,20 +848,22 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def) x86_cpu_def->stepping = eax & 0x0F; x86_cpu_def->level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX); - x86_cpu_def->features = kvm_arch_get_supported_cpuid(s, 0x1, 0, R_EDX); - x86_cpu_def->ext_features = kvm_arch_get_supported_cpuid(s, 0x1, 0, R_ECX); + x86_cpu_def->features[FEAT_1_EDX] = + kvm_arch_get_supported_cpuid(s, 0x1, 0, R_EDX); + x86_cpu_def->features[FEAT_1_ECX] = + kvm_arch_get_supported_cpuid(s, 0x1, 0, R_ECX); if (x86_cpu_def->level >= 7) { - x86_cpu_def->cpuid_7_0_ebx_features = + x86_cpu_def->features[FEAT_7_0_EBX] = kvm_arch_get_supported_cpuid(s, 0x7, 0, R_EBX); } else { - x86_cpu_def->cpuid_7_0_ebx_features = 0; + x86_cpu_def->features[FEAT_7_0_EBX] = 0; } x86_cpu_def->xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX); - x86_cpu_def->ext2_features = + x86_cpu_def->features[FEAT_80000001_EDX] = kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX); - x86_cpu_def->ext3_features = + x86_cpu_def->features[FEAT_80000001_ECX] = kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_ECX); cpu_x86_fill_model_id(x86_cpu_def->model_id); @@ -871,7 +877,7 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def) /* Support VIA max extended level */ x86_cpu_def->xlevel2 = eax; host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx); - x86_cpu_def->ext4_features = + x86_cpu_def->features[FEAT_C0000001_EDX] = kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX); } } @@ -882,7 +888,7 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def) * available on the host hardware. Just set all bits and mask out the * unsupported ones later. */ - x86_cpu_def->svm_features = -1; + x86_cpu_def->features[FEAT_SVM] = -1; #endif /* CONFIG_KVM */ } @@ -913,13 +919,17 @@ static int kvm_check_features_against_host(x86_def_t *guest_def) uint32_t mask; int rv, i; struct model_features_t ft[] = { - {&guest_def->features, &host_def.features, + {&guest_def->features[FEAT_1_EDX], + &host_def.features[FEAT_1_EDX], ~0, feature_name, 0x00000000}, - {&guest_def->ext_features, &host_def.ext_features, + {&guest_def->features[FEAT_1_ECX], + &host_def.features[FEAT_1_ECX], ~CPUID_EXT_HYPERVISOR, ext_feature_name, 0x00000001}, - {&guest_def->ext2_features, &host_def.ext2_features, + {&guest_def->features[FEAT_80000001_EDX], + &host_def.features[FEAT_80000001_EDX], ~PPRO_FEATURES, ext2_feature_name, 0x80000000}, - {&guest_def->ext3_features, &host_def.ext3_features, + {&guest_def->features[FEAT_80000001_ECX], + &host_def.features[FEAT_80000001_ECX], ~CPUID_EXT3_SVM, ext3_feature_name, 0x80000001}}; assert(kvm_enabled()); @@ -1199,15 +1209,15 @@ static void cpudef_2_x86_cpu(X86CPU *cpu, x86_def_t *def, Error **errp) object_property_set_int(OBJECT(cpu), def->family, "family", errp); object_property_set_int(OBJECT(cpu), def->model, "model", errp); object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp); - env->cpuid_features = def->features; - env->cpuid_ext_features = def->ext_features; - env->cpuid_ext2_features = def->ext2_features; - env->cpuid_ext3_features = def->ext3_features; + env->features[FEAT_1_EDX] = def->features[FEAT_1_EDX]; + env->features[FEAT_1_ECX] = def->features[FEAT_1_ECX]; + env->features[FEAT_80000001_EDX] = def->features[FEAT_80000001_EDX]; + env->features[FEAT_80000001_ECX] = def->features[FEAT_80000001_ECX]; object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", errp); - env->cpuid_kvm_features = def->kvm_features; - env->cpuid_svm_features = def->svm_features; - env->cpuid_ext4_features = def->ext4_features; - env->cpuid_7_0_ebx_features = def->cpuid_7_0_ebx_features; + env->features[FEAT_KVM] = def->features[FEAT_KVM]; + env->features[FEAT_SVM] = def->features[FEAT_SVM]; + env->features[FEAT_C0000001_EDX] = def->features[FEAT_C0000001_EDX]; + env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX]; env->cpuid_xlevel2 = def->xlevel2; object_property_set_int(OBJECT(cpu), (int64_t)def->tsc_khz * 1000, "tsc-frequency", errp); @@ -1353,20 +1363,20 @@ static int cpu_x86_parse_featurestr(x86_def_t *x86_cpu_def, char *features) } 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->kvm_features |= plus_kvm_features; - x86_cpu_def->svm_features |= plus_svm_features; - x86_cpu_def->cpuid_7_0_ebx_features |= plus_7_0_ebx_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; - x86_cpu_def->kvm_features &= ~minus_kvm_features; - x86_cpu_def->svm_features &= ~minus_svm_features; - x86_cpu_def->cpuid_7_0_ebx_features &= ~minus_7_0_ebx_features; + x86_cpu_def->features[FEAT_1_EDX] |= plus_features; + x86_cpu_def->features[FEAT_1_ECX] |= plus_ext_features; + x86_cpu_def->features[FEAT_80000001_EDX] |= plus_ext2_features; + x86_cpu_def->features[FEAT_80000001_ECX] |= plus_ext3_features; + x86_cpu_def->features[FEAT_KVM] |= plus_kvm_features; + x86_cpu_def->features[FEAT_SVM] |= plus_svm_features; + x86_cpu_def->features[FEAT_7_0_EBX] |= plus_7_0_ebx_features; + x86_cpu_def->features[FEAT_1_EDX] &= ~minus_features; + x86_cpu_def->features[FEAT_1_ECX] &= ~minus_ext_features; + x86_cpu_def->features[FEAT_80000001_EDX] &= ~minus_ext2_features; + x86_cpu_def->features[FEAT_80000001_ECX] &= ~minus_ext3_features; + x86_cpu_def->features[FEAT_KVM] &= ~minus_kvm_features; + x86_cpu_def->features[FEAT_SVM] &= ~minus_svm_features; + x86_cpu_def->features[FEAT_7_0_EBX] &= ~minus_7_0_ebx_features; if (check_cpuid && kvm_enabled()) { if (kvm_check_features_against_host(x86_cpu_def) && enforce_cpuid) goto error; @@ -1458,21 +1468,21 @@ static void filter_features_for_kvm(X86CPU *cpu) CPUX86State *env = &cpu->env; KVMState *s = kvm_state; - env->cpuid_features &= + env->features[FEAT_1_EDX] &= kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX); - env->cpuid_ext_features &= + env->features[FEAT_1_ECX] &= kvm_arch_get_supported_cpuid(s, 1, 0, R_ECX); - env->cpuid_ext2_features &= + env->features[FEAT_80000001_EDX] &= kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX); - env->cpuid_ext3_features &= + env->features[FEAT_80000001_ECX] &= kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_ECX); - env->cpuid_svm_features &= + env->features[FEAT_SVM] &= kvm_arch_get_supported_cpuid(s, 0x8000000A, 0, R_EDX); - env->cpuid_7_0_ebx_features &= + env->features[FEAT_7_0_EBX] &= kvm_arch_get_supported_cpuid(s, 7, 0, R_EBX); - env->cpuid_kvm_features &= + env->features[FEAT_KVM] &= kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX); - env->cpuid_ext4_features &= + env->features[FEAT_C0000001_EDX] &= kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX); } @@ -1498,11 +1508,14 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model) goto error; } - def->kvm_features |= kvm_default_features; - add_flagname_to_bitmaps("hypervisor", &def->features, - &def->ext_features, &def->ext2_features, - &def->ext3_features, &def->kvm_features, - &def->svm_features, &def->cpuid_7_0_ebx_features); + def->features[FEAT_KVM] |= kvm_default_features; + add_flagname_to_bitmaps("hypervisor", &def->features[FEAT_1_EDX], + &def->features[FEAT_1_ECX], + &def->features[FEAT_80000001_EDX], + &def->features[FEAT_80000001_ECX], + &def->features[FEAT_KVM], + &def->features[FEAT_SVM], + &def->features[FEAT_7_0_EBX]); if (cpu_x86_parse_featurestr(def, features) < 0) { goto error; @@ -1527,7 +1540,7 @@ error: void cpu_clear_apic_feature(CPUX86State *env) { - env->cpuid_features &= ~CPUID_APIC; + env->features[FEAT_1_EDX] &= ~CPUID_APIC; } #endif /* !CONFIG_USER_ONLY */ @@ -1608,8 +1621,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, 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; + *ecx = env->features[FEAT_1_ECX]; + *edx = env->features[FEAT_1_EDX]; if (env->nr_cores * env->nr_threads > 1) { *ebx |= (env->nr_cores * env->nr_threads) << 16; *edx |= 1 << 28; /* HTT bit */ @@ -1677,7 +1690,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, /* Structured Extended Feature Flags Enumeration Leaf */ if (count == 0) { *eax = 0; /* Maximum ECX value for sub-leaves */ - *ebx = env->cpuid_7_0_ebx_features; /* Feature flags */ + *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */ *ecx = 0; /* Reserved */ *edx = 0; /* Reserved */ } else { @@ -1712,7 +1725,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, break; case 0xD: /* Processor Extended State */ - if (!(env->cpuid_ext_features & CPUID_EXT_XSAVE)) { + if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) { *eax = 0; *ebx = 0; *ecx = 0; @@ -1742,8 +1755,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, case 0x80000001: *eax = env->cpuid_version; *ebx = 0; - *ecx = env->cpuid_ext3_features; - *edx = env->cpuid_ext2_features; + *ecx = env->features[FEAT_80000001_ECX]; + *edx = env->features[FEAT_80000001_EDX]; /* The Linux kernel checks for the CMPLegacy bit and * discards multiple thread information if it is set. @@ -1784,12 +1797,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, 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) { + if (env->features[FEAT_80000001_EDX] & 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) { + if (env->features[FEAT_1_EDX] & CPUID_PSE36) { *eax = 0x00000024; /* 36 bits physical */ } else { *eax = 0x00000020; /* 32 bits physical */ @@ -1803,11 +1816,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, } break; case 0x8000000A: - if (env->cpuid_ext3_features & CPUID_EXT3_SVM) { + if (env->features[FEAT_80000001_ECX] & CPUID_EXT3_SVM) { *eax = 0x00000001; /* SVM Revision */ *ebx = 0x00000010; /* nr of ASIDs */ *ecx = 0; - *edx = env->cpuid_svm_features; /* optional features */ + *edx = env->features[FEAT_SVM]; /* optional features */ } else { *eax = 0; *ebx = 0; @@ -1826,7 +1839,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *eax = env->cpuid_version; *ebx = 0; *ecx = 0; - *edx = env->cpuid_ext4_features; + *edx = env->features[FEAT_C0000001_EDX]; break; case 0xC0000002: case 0xC0000003: @@ -1958,7 +1971,7 @@ static void mce_init(X86CPU *cpu) unsigned int bank; if (((cenv->cpuid_version >> 8) & 0xf) >= 6 - && (cenv->cpuid_features & (CPUID_MCE | CPUID_MCA)) == + && (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) == (CPUID_MCE | CPUID_MCA)) { cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF; cenv->mcg_ctl = ~(uint64_t)0; @@ -2019,7 +2032,7 @@ void x86_cpu_realize(Object *obj, Error **errp) X86CPU *cpu = X86_CPU(obj); CPUX86State *env = &cpu->env; - if (env->cpuid_7_0_ebx_features && env->cpuid_level < 7) { + if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) { env->cpuid_level = 7; } @@ -2029,21 +2042,21 @@ void x86_cpu_realize(Object *obj, Error **errp) if (env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 && env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 && env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) { - env->cpuid_ext2_features &= ~CPUID_EXT2_AMD_ALIASES; - env->cpuid_ext2_features |= (env->cpuid_features + env->features[FEAT_80000001_EDX] &= ~CPUID_EXT2_AMD_ALIASES; + env->features[FEAT_80000001_EDX] |= (env->features[FEAT_1_EDX] & CPUID_EXT2_AMD_ALIASES); } if (!kvm_enabled()) { - env->cpuid_features &= TCG_FEATURES; - env->cpuid_ext_features &= TCG_EXT_FEATURES; - env->cpuid_ext2_features &= (TCG_EXT2_FEATURES + env->features[FEAT_1_EDX] &= TCG_FEATURES; + env->features[FEAT_1_ECX] &= TCG_EXT_FEATURES; + env->features[FEAT_80000001_EDX] &= (TCG_EXT2_FEATURES #ifdef TARGET_X86_64 | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM #endif ); - env->cpuid_ext3_features &= TCG_EXT3_FEATURES; - env->cpuid_svm_features &= TCG_SVM_FEATURES; + env->features[FEAT_80000001_ECX] &= TCG_EXT3_FEATURES; + env->features[FEAT_SVM] &= TCG_SVM_FEATURES; } else { #ifdef CONFIG_KVM filter_features_for_kvm(cpu); @@ -2053,7 +2066,7 @@ void x86_cpu_realize(Object *obj, Error **errp) #ifndef CONFIG_USER_ONLY qemu_register_reset(x86_cpu_machine_reset_cb, cpu); - if (cpu->env.cpuid_features & CPUID_APIC || smp_cpus > 1) { + if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) { x86_cpu_apic_init(cpu, errp); if (error_is_set(errp)) { return; diff --git a/target-i386/cpu.h b/target-i386/cpu.h index fbbe730..5f3d272 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -694,6 +694,21 @@ typedef enum TPRAccess { TPR_ACCESS_WRITE, } TPRAccess; +typedef enum X86CPUFeatureWord { + FEAT_1_EDX, /* CPUID[1].EDX */ + FEAT_1_ECX, /* CPUID[1].ECX */ + FEAT_7_0_EBX, /* CPUID[EAX=7,ECX=0].EBX */ + FEAT_80000001_EDX, /* CPUID[8000_0001].EDX */ + FEAT_80000001_ECX, /* CPUID[8000_0001].ECX */ + FEAT_C0000001_EDX, /* CPUID[C000_0001].EDX */ + FEAT_KVM, /* CPUID[4000_0001].EAX (KVM_CPUID_FEATURES) */ + FEAT_SVM, /* CPUID[8000_000A].EDX */ + FEATURE_WORDS, /* Size of the features arrays */ +} FeatureWord; + +/* An array of feature words */ +typedef uint32_t X86CPUFeatureWords[FEATURE_WORDS]; + typedef struct CPUX86State { /* standard registers */ target_ulong regs[CPU_NB_REGS]; @@ -800,24 +815,15 @@ typedef struct CPUX86State { uint64_t pat; /* processor features (e.g. for CPUID insn) */ - uint32_t cpuid_level; + uint32_t cpuid_level, cpuid_xlevel, cpuid_xlevel2; + X86CPUFeatureWords features; uint32_t cpuid_vendor1; uint32_t cpuid_vendor2; uint32_t cpuid_vendor3; uint32_t cpuid_version; - uint32_t cpuid_features; - uint32_t cpuid_ext_features; - uint32_t cpuid_xlevel; uint32_t cpuid_model[12]; - uint32_t cpuid_ext2_features; - uint32_t cpuid_ext3_features; uint32_t cpuid_apic_id; int cpuid_vendor_override; - /* Store the results of Centaur's CPUID instructions */ - uint32_t cpuid_xlevel2; - uint32_t cpuid_ext4_features; - /* Flags from CPUID[EAX=7,ECX=0].EBX */ - uint32_t cpuid_7_0_ebx_features; /* MTRRs */ uint64_t mtrr_fixed[11]; @@ -831,8 +837,6 @@ typedef struct CPUX86State { uint8_t soft_interrupt; uint8_t has_error_code; uint32_t sipi_vector; - uint32_t cpuid_kvm_features; - uint32_t cpuid_svm_features; bool tsc_valid; int tsc_khz; void *kvm_xsave_buf; diff --git a/target-i386/helper.c b/target-i386/helper.c index 00341c5..7453d4b 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -449,7 +449,7 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4) tlb_flush(env, 1); } /* SSE handling */ - if (!(env->cpuid_features & CPUID_SSE)) { + if (!(env->features[FEAT_1_EDX] & CPUID_SSE)) { new_cr4 &= ~CR4_OSFXSR_MASK; } env->hflags &= ~HF_OSFXSR_MASK; @@ -457,7 +457,7 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4) env->hflags |= HF_OSFXSR_MASK; } - if (!(env->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)) { + if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SMAP)) { new_cr4 &= ~CR4_SMAP_MASK; } env->hflags &= ~HF_SMAP_MASK; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index f669281..5b614fa 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -438,7 +438,7 @@ int kvm_arch_init_vcpu(CPUX86State *env) c = &cpuid_data.entries[cpuid_i++]; memset(c, 0, sizeof(*c)); c->function = KVM_CPUID_FEATURES; - c->eax = env->cpuid_kvm_features; + c->eax = env->features[FEAT_KVM]; if (hyperv_enabled()) { memcpy(signature, "Hv#1\0\0\0\0\0\0\0\0", 12); @@ -573,7 +573,8 @@ int kvm_arch_init_vcpu(CPUX86State *env) cpuid_data.cpuid.nent = cpuid_i; if (((env->cpuid_version >> 8)&0xF) >= 6 - && (env->cpuid_features&(CPUID_MCE|CPUID_MCA)) == (CPUID_MCE|CPUID_MCA) + && (env->features[FEAT_1_EDX] & (CPUID_MCE|CPUID_MCA)) == + (CPUID_MCE|CPUID_MCA) && kvm_check_extension(env->kvm_state, KVM_CAP_MCE) > 0) { uint64_t mcg_cap; int banks; diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c index a020379..546b8b9 100644 --- a/target-i386/misc_helper.c +++ b/target-i386/misc_helper.c @@ -291,22 +291,22 @@ void helper_wrmsr(CPUX86State *env) uint64_t update_mask; update_mask = 0; - if (env->cpuid_ext2_features & CPUID_EXT2_SYSCALL) { + if (env->features[FEAT_80000001_EDX] & CPUID_EXT2_SYSCALL) { update_mask |= MSR_EFER_SCE; } - if (env->cpuid_ext2_features & CPUID_EXT2_LM) { + if (env->features[FEAT_80000001_EDX] & CPUID_EXT2_LM) { update_mask |= MSR_EFER_LME; } - if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR) { + if (env->features[FEAT_80000001_EDX] & CPUID_EXT2_FFXSR) { update_mask |= MSR_EFER_FFXSR; } - if (env->cpuid_ext2_features & CPUID_EXT2_NX) { + if (env->features[FEAT_80000001_EDX] & CPUID_EXT2_NX) { update_mask |= MSR_EFER_NXE; } - if (env->cpuid_ext3_features & CPUID_EXT3_SVM) { + if (env->features[FEAT_80000001_ECX] & CPUID_EXT3_SVM) { update_mask |= MSR_EFER_SVME; } - if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR) { + if (env->features[FEAT_80000001_EDX] & CPUID_EXT2_FFXSR) { update_mask |= MSR_EFER_FFXSR; } cpu_load_efer(env, (env->efer & ~update_mask) | @@ -513,7 +513,7 @@ void helper_rdmsr(CPUX86State *env) val = env->mtrr_deftype; break; case MSR_MTRRcap: - if (env->cpuid_features & CPUID_MTRR) { + if (env->features[FEAT_1_EDX] & CPUID_MTRR) { val = MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT | MSR_MTRRcap_WC_SUPPORTED; } else { diff --git a/target-i386/translate.c b/target-i386/translate.c index f394ea6..8ff4af9 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -7926,11 +7926,11 @@ static inline void gen_intermediate_code_internal(CPUX86State *env, if (flags & HF_SOFTMMU_MASK) { dc->mem_index = (cpu_mmu_index(env) + 1) << 2; } - dc->cpuid_features = env->cpuid_features; - dc->cpuid_ext_features = env->cpuid_ext_features; - dc->cpuid_ext2_features = env->cpuid_ext2_features; - dc->cpuid_ext3_features = env->cpuid_ext3_features; - dc->cpuid_7_0_ebx_features = env->cpuid_7_0_ebx_features; + dc->cpuid_features = env->features[FEAT_1_EDX]; + dc->cpuid_ext_features = env->features[FEAT_1_ECX]; + dc->cpuid_ext2_features = env->features[FEAT_80000001_EDX]; + dc->cpuid_ext3_features = env->features[FEAT_80000001_ECX]; + dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX]; #ifdef TARGET_X86_64 dc->lma = (flags >> HF_LMA_SHIFT) & 1; dc->code64 = (flags >> HF_CS64_SHIFT) & 1; -- 1.7.11.7 ^ permalink raw reply related [flat|nested] 22+ messages in thread
end of thread, other threads:[~2012-12-18 16:28 UTC | newest] Thread overview: 22+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-12-12 22:22 [Qemu-devel] [PATCH 0/3] replace cpuid_*features fields with a featue word array (v2) Eduardo Habkost 2012-12-12 22:22 ` [Qemu-devel] [PATCH 1/3] target-i386: add EXT2_PPRO_FEATURES #define Eduardo Habkost 2012-12-14 9:44 ` Igor Mammedov 2012-12-14 11:44 ` Andreas Färber 2012-12-14 12:15 ` Eduardo Habkost 2012-12-12 22:22 ` [Qemu-devel] [PATCH 2/3] target-i386/cpu.c: coding style fix Eduardo Habkost 2012-12-12 23:36 ` Igor Mammedov 2012-12-13 13:16 ` Eduardo Habkost 2012-12-12 22:22 ` [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array Eduardo Habkost 2012-12-14 9:38 ` Igor Mammedov 2012-12-14 12:27 ` Eduardo Habkost 2012-12-14 13:52 ` Igor Mammedov 2012-12-14 14:02 ` Eduardo Habkost 2012-12-14 14:53 ` Andreas Färber 2012-12-14 17:16 ` Eduardo Habkost 2012-12-14 15:14 ` Andreas Färber 2012-12-14 16:52 ` Eduardo Habkost 2012-12-14 17:20 ` Andreas Färber 2012-12-14 17:36 ` Eduardo Habkost 2012-12-14 17:47 ` Igor Mammedov 2012-12-14 18:32 ` Eduardo Habkost -- strict thread matches above, loose matches on Subject: below -- 2012-12-18 16:29 [Qemu-devel] [PATCH 0/3] replace cpuid_*features fields with a featue word array (v3) Eduardo Habkost 2012-12-18 16:29 ` [Qemu-devel] [PATCH 3/3] target-i386: replace cpuid_*features fields with a feature word array Eduardo Habkost
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).