From patchwork Tue Apr 16 16:12:04 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eduardo Habkost X-Patchwork-Id: 237032 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id B56CA2C011D for ; Wed, 17 Apr 2013 02:14:42 +1000 (EST) Received: from localhost ([::1]:43922 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1US8Wm-0001e2-SG for incoming@patchwork.ozlabs.org; Tue, 16 Apr 2013 12:14:40 -0400 Received: from eggs.gnu.org ([208.118.235.92]:41460) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1US8UX-0006rs-IY for qemu-devel@nongnu.org; Tue, 16 Apr 2013 12:12:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1US8UQ-00010p-O7 for qemu-devel@nongnu.org; Tue, 16 Apr 2013 12:12:21 -0400 Received: from mx1.redhat.com ([209.132.183.28]:3562) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1US8UQ-00010X-3b for qemu-devel@nongnu.org; Tue, 16 Apr 2013 12:12:14 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r3GGCDgW003420 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 16 Apr 2013 12:12:13 -0400 Received: from localhost (vpn1-7-91.gru2.redhat.com [10.97.7.91]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r3GGCBTx020005; Tue, 16 Apr 2013 12:12:12 -0400 From: Eduardo Habkost To: qemu-devel@nongnu.org, =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Tue, 16 Apr 2013 13:12:04 -0300 Message-Id: <1366128724-31860-5-git-send-email-ehabkost@redhat.com> In-Reply-To: <1366128724-31860-1-git-send-email-ehabkost@redhat.com> References: <1366128724-31860-1-git-send-email-ehabkost@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Igor Mammedov Subject: [Qemu-devel] [PATCH qom-cpu 4/4] target-i386: Replace cpuid_*features fields with a feature word array X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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(), CPU feature-bit property lookup/registration, and the proposed "feature-words" property) The following field replacements were made on X86CPU and x86_def_t: (cpuid_)features -> features[FEAT_1_EDX] (cpuid_)ext_features -> features[FEAT_1_ECX] (cpuid_)ext2_features -> features[FEAT_8000_0001_EDX] (cpuid_)ext3_features -> features[FEAT_8000_0001_ECX] (cpuid_)ext4_features -> features[FEAT_C000_0001_EDX] (cpuid_)kvm_features -> features[FEAT_KVM] (cpuid_)svm_features -> features[FEAT_SVM] (cpuid_)7_0_ebx_features -> features[FEAT_7_0_EBX] Signed-off-by: Eduardo Habkost --- This should help us 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; (CPUID 7 leaf was not being filtered based on host capabilities) * The bug solved by commit 07ca59450c9a0c5df65665ce46aa8487af59a1dd (check/enforce flags were not checking all feature flags) 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 The script is a lot simpler now, it is basically 8 s/.../.../ commands and a few insert/delete commands to change the cpu.h and cpu.c structs. Changes v9: * commit message changes: move some text below "---", add table showing how each field was replaced Changes v8: * Move line-breaking and code-formatting changes to separate patches * Rebase on top of qom-cpu commit b4d31f73 (qdev: Set device's parent before calling realize() down inheritance chain) Changes v7: * Rebase on top qom-cpu-next (commit 3755f0a9d48da07258f4a0ef5e883272799e47b9) Changes v7: * Rebase on top of Andreas' qom-cpu tree (commit 9260944307077b93a66bf861a467107af986fe47) * Break lines on kvm_check_features_against_host() * Break the lines on builtin_x86_defs just after the "=". This way the feature lists stay on separate lines, this patch gets easier to review, and future patches that touches the code around builtin_x86_defs will be even easier to review (as they won't need to touch the lines containing the fature lists again) Signed-off-by: Eduardo Habkost Conflicts: target-i386/kvm.c --- bsd-user/elfload.c | 2 +- bsd-user/main.c | 4 +- hw/i386/kvm/clock.c | 2 +- linux-user/elfload.c | 2 +- linux-user/main.c | 4 +- target-i386/cpu.c | 329 +++++++++++++++++++++++----------------------- target-i386/cpu.h | 11 +- target-i386/helper.c | 4 +- target-i386/kvm.c | 4 +- target-i386/misc_helper.c | 14 +- target-i386/translate.c | 10 +- 11 files changed, 186 insertions(+), 200 deletions(-) diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c index a6cd3ab..44e1568 100644 --- a/bsd-user/elfload.c +++ b/bsd-user/elfload.c @@ -110,7 +110,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/bsd-user/main.c b/bsd-user/main.c index cc84981..0da3ab9 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -1004,13 +1004,13 @@ int main(int argc, char **argv) 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_8000_0001_EDX] & CPUID_EXT2_LM)) { fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n"); exit(1); } diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c index fa40e28..87d4d0f 100644 --- a/hw/i386/kvm/clock.c +++ b/hw/i386/kvm/clock.c @@ -129,7 +129,7 @@ static const 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 89db49c..04755de 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 4e92a0b..b97b8cf 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3764,13 +3764,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_8000_0001_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 73ae2ef..110ef98 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -356,13 +356,8 @@ typedef struct x86_def_t { int family; int model; int stepping; - uint32_t features, ext_features, ext2_features, ext3_features; - uint32_t kvm_features, svm_features; + FeatureWordArray features; char model_id[48]; - /* Store the results of Centaur's CPUID instructions */ - uint32_t ext4_features; - /* 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) @@ -423,16 +418,16 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 2, .stepping = 3, - .features = + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36, - .ext_features = + .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT, - .ext2_features = + .features[FEAT_8000_0001_EDX] = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, - .ext3_features = + .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A, .xlevel = 0x8000000A, @@ -444,14 +439,14 @@ static x86_def_t builtin_x86_defs[] = { .family = 16, .model = 2, .stepping = 3, - .features = + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36 | CPUID_VME | CPUID_HT, - .ext_features = + .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 | CPUID_EXT_POPCNT, - .ext2_features = + .features[FEAT_8000_0001_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 | @@ -460,10 +455,10 @@ static x86_def_t builtin_x86_defs[] = { CPUID_EXT3_CR8LEG, CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH, CPUID_EXT3_OSVW, CPUID_EXT3_IBS */ - .ext3_features = + .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A, - .svm_features = + .features[FEAT_SVM] = CPUID_SVM_NPT | CPUID_SVM_LBRV, .xlevel = 0x8000001A, .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor" @@ -475,18 +470,18 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 15, .stepping = 11, - .features = + .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, - .ext_features = + .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, - .ext2_features = + .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, - .ext3_features = + .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x80000008, .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz", @@ -499,22 +494,22 @@ static x86_def_t builtin_x86_defs[] = { .model = 6, .stepping = 1, /* Missing: CPUID_VME, CPUID_HT */ - .features = + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36, /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */ - .ext_features = + .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_CX16, /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */ - .ext2_features = + .features[FEAT_8000_0001_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 = + .features[FEAT_8000_0001_ECX] = 0, .xlevel = 0x80000008, .model_id = "Common KVM processor" @@ -526,9 +521,9 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 3, .stepping = 3, - .features = + .features[FEAT_1_EDX] = PPRO_FEATURES, - .ext_features = + .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT, .xlevel = 0x80000004, }, @@ -539,14 +534,14 @@ static x86_def_t builtin_x86_defs[] = { .family = 15, .model = 6, .stepping = 1, - .features = + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36, - .ext_features = + .features[FEAT_1_ECX] = CPUID_EXT_SSE3, - .ext2_features = + .features[FEAT_8000_0001_EDX] = PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES, - .ext3_features = + .features[FEAT_8000_0001_ECX] = 0, .xlevel = 0x80000008, .model_id = "Common 32-bit KVM processor" @@ -558,14 +553,14 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 14, .stepping = 8, - .features = + .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, - .ext_features = + .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, - .ext2_features = + .features[FEAT_8000_0001_EDX] = CPUID_EXT2_NX, .xlevel = 0x80000008, .model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz", @@ -577,7 +572,7 @@ static x86_def_t builtin_x86_defs[] = { .family = 4, .model = 0, .stepping = 0, - .features = + .features[FEAT_1_EDX] = I486_FEATURES, .xlevel = 0, }, @@ -588,7 +583,7 @@ static x86_def_t builtin_x86_defs[] = { .family = 5, .model = 4, .stepping = 3, - .features = + .features[FEAT_1_EDX] = PENTIUM_FEATURES, .xlevel = 0, }, @@ -599,7 +594,7 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 5, .stepping = 2, - .features = + .features[FEAT_1_EDX] = PENTIUM2_FEATURES, .xlevel = 0, }, @@ -610,7 +605,7 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 7, .stepping = 3, - .features = + .features[FEAT_1_EDX] = PENTIUM3_FEATURES, .xlevel = 0, }, @@ -621,10 +616,10 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 2, .stepping = 3, - .features = + .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA, - .ext2_features = + .features[FEAT_8000_0001_EDX] = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT, .xlevel = 0x80000008, @@ -637,18 +632,18 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 28, .stepping = 2, - .features = + .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 = + .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, - .ext2_features = + .features[FEAT_8000_0001_EDX] = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | CPUID_EXT2_NX, - .ext3_features = + .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, .model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz", @@ -660,17 +655,17 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 2, .stepping = 3, - .features = + .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, - .ext_features = + .features[FEAT_1_ECX] = CPUID_EXT_SSSE3 | CPUID_EXT_SSE3, - .ext2_features = + .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, - .ext3_features = + .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)", @@ -682,18 +677,18 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 2, .stepping = 3, - .features = + .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, - .ext_features = + .features[FEAT_1_ECX] = CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3, - .ext2_features = + .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, - .ext3_features = + .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)", @@ -705,18 +700,18 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 2, .stepping = 3, - .features = + .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, - .ext_features = + .features[FEAT_1_ECX] = CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3, - .ext2_features = + .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, - .ext3_features = + .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)", @@ -728,19 +723,19 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 44, .stepping = 1, - .features = + .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, - .ext_features = + .features[FEAT_1_ECX] = 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 = + .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, - .ext3_features = + .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)", @@ -752,22 +747,22 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 42, .stepping = 1, - .features = + .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, - .ext_features = + .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, - .ext2_features = + .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, - .ext3_features = + .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM, .xlevel = 0x8000000A, .model_id = "Intel Xeon E312xx (Sandy Bridge)", @@ -779,25 +774,25 @@ static x86_def_t builtin_x86_defs[] = { .family = 6, .model = 60, .stepping = 1, - .features = + .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, - .ext_features = + .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, - .ext2_features = + .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, - .ext3_features = + .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM, - .cpuid_7_0_ebx_features = + .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 | @@ -812,15 +807,15 @@ static x86_def_t builtin_x86_defs[] = { .family = 15, .model = 6, .stepping = 1, - .features = + .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, - .ext_features = + .features[FEAT_1_ECX] = CPUID_EXT_SSE3, - .ext2_features = + .features[FEAT_8000_0001_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 | @@ -837,15 +832,15 @@ static x86_def_t builtin_x86_defs[] = { .family = 15, .model = 6, .stepping = 1, - .features = + .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, - .ext_features = + .features[FEAT_1_ECX] = CPUID_EXT_CX16 | CPUID_EXT_SSE3, - .ext2_features = + .features[FEAT_8000_0001_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 | @@ -853,7 +848,7 @@ static x86_def_t builtin_x86_defs[] = { 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 = + .features[FEAT_8000_0001_ECX] = CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM, .xlevel = 0x80000008, .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)", @@ -865,16 +860,16 @@ static x86_def_t builtin_x86_defs[] = { .family = 15, .model = 6, .stepping = 1, - .features = + .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, - .ext_features = + .features[FEAT_1_ECX] = CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR | CPUID_EXT_SSE3, - .ext2_features = + .features[FEAT_8000_0001_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 | @@ -882,7 +877,7 @@ static x86_def_t builtin_x86_defs[] = { 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 = + .features[FEAT_8000_0001_ECX] = CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM, .xlevel = 0x80000008, @@ -895,18 +890,18 @@ static x86_def_t builtin_x86_defs[] = { .family = 21, .model = 1, .stepping = 2, - .features = + .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, - .ext_features = + .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, - .ext2_features = + .features[FEAT_8000_0001_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 | @@ -914,7 +909,7 @@ static x86_def_t builtin_x86_defs[] = { 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 = + .features[FEAT_8000_0001_ECX] = CPUID_EXT3_FMA4 | CPUID_EXT3_XOP | CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM | @@ -929,18 +924,18 @@ static x86_def_t builtin_x86_defs[] = { .family = 21, .model = 2, .stepping = 0, - .features = + .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, - .ext_features = + .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 = + .features[FEAT_8000_0001_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 | @@ -948,7 +943,7 @@ static x86_def_t builtin_x86_defs[] = { 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 = + .features[FEAT_8000_0001_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 | @@ -998,22 +993,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 = + x86_cpu_def->features[FEAT_1_EDX] = kvm_arch_get_supported_cpuid(s, 0x1, 0, R_EDX); - x86_cpu_def->ext_features = + 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_8000_0001_EDX] = kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX); - x86_cpu_def->ext3_features = + x86_cpu_def->features[FEAT_8000_0001_ECX] = kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_ECX); cpu_x86_fill_model_id(x86_cpu_def->model_id); @@ -1026,15 +1021,15 @@ 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_C000_0001_EDX] = kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX); } } /* Other KVM-specific feature fields: */ - x86_cpu_def->svm_features = + x86_cpu_def->features[FEAT_SVM] = kvm_arch_get_supported_cpuid(s, 0x8000000A, 0, R_EDX); - x86_cpu_def->kvm_features = + x86_cpu_def->features[FEAT_KVM] = kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX); #endif /* CONFIG_KVM */ @@ -1071,29 +1066,29 @@ static int kvm_check_features_against_host(X86CPU *cpu) uint32_t mask; int rv, i; struct model_features_t ft[] = { - {&env->cpuid_features, - &host_def.features, + {&env->features[FEAT_1_EDX], + &host_def.features[FEAT_1_EDX], FEAT_1_EDX }, - {&env->cpuid_ext_features, - &host_def.ext_features, + {&env->features[FEAT_1_ECX], + &host_def.features[FEAT_1_ECX], FEAT_1_ECX }, - {&env->cpuid_ext2_features, - &host_def.ext2_features, + {&env->features[FEAT_8000_0001_EDX], + &host_def.features[FEAT_8000_0001_EDX], FEAT_8000_0001_EDX }, - {&env->cpuid_ext3_features, - &host_def.ext3_features, + {&env->features[FEAT_8000_0001_ECX], + &host_def.features[FEAT_8000_0001_ECX], FEAT_8000_0001_ECX }, - {&env->cpuid_ext4_features, - &host_def.ext4_features, + {&env->features[FEAT_C000_0001_EDX], + &host_def.features[FEAT_C000_0001_EDX], FEAT_C000_0001_EDX }, - {&env->cpuid_7_0_ebx_features, - &host_def.cpuid_7_0_ebx_features, + {&env->features[FEAT_7_0_EBX], + &host_def.features[FEAT_7_0_EBX], FEAT_7_0_EBX }, - {&env->cpuid_svm_features, - &host_def.svm_features, + {&env->features[FEAT_SVM], + &host_def.features[FEAT_SVM], FEAT_SVM }, - {&env->cpuid_kvm_features, - &host_def.kvm_features, + {&env->features[FEAT_KVM], + &host_def.features[FEAT_KVM], FEAT_KVM }, }; @@ -1490,22 +1485,22 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp) } featurestr = strtok(NULL, ","); } - env->cpuid_features |= plus_features[FEAT_1_EDX]; - env->cpuid_ext_features |= plus_features[FEAT_1_ECX]; - env->cpuid_ext2_features |= plus_features[FEAT_8000_0001_EDX]; - env->cpuid_ext3_features |= plus_features[FEAT_8000_0001_ECX]; - env->cpuid_ext4_features |= plus_features[FEAT_C000_0001_EDX]; - env->cpuid_kvm_features |= plus_features[FEAT_KVM]; - env->cpuid_svm_features |= plus_features[FEAT_SVM]; - env->cpuid_7_0_ebx_features |= plus_features[FEAT_7_0_EBX]; - env->cpuid_features &= ~minus_features[FEAT_1_EDX]; - env->cpuid_ext_features &= ~minus_features[FEAT_1_ECX]; - env->cpuid_ext2_features &= ~minus_features[FEAT_8000_0001_EDX]; - env->cpuid_ext3_features &= ~minus_features[FEAT_8000_0001_ECX]; - env->cpuid_ext4_features &= ~minus_features[FEAT_C000_0001_EDX]; - env->cpuid_kvm_features &= ~minus_features[FEAT_KVM]; - env->cpuid_svm_features &= ~minus_features[FEAT_SVM]; - env->cpuid_7_0_ebx_features &= ~minus_features[FEAT_7_0_EBX]; + env->features[FEAT_1_EDX] |= plus_features[FEAT_1_EDX]; + env->features[FEAT_1_ECX] |= plus_features[FEAT_1_ECX]; + env->features[FEAT_8000_0001_EDX] |= plus_features[FEAT_8000_0001_EDX]; + env->features[FEAT_8000_0001_ECX] |= plus_features[FEAT_8000_0001_ECX]; + env->features[FEAT_C000_0001_EDX] |= plus_features[FEAT_C000_0001_EDX]; + env->features[FEAT_KVM] |= plus_features[FEAT_KVM]; + env->features[FEAT_SVM] |= plus_features[FEAT_SVM]; + env->features[FEAT_7_0_EBX] |= plus_features[FEAT_7_0_EBX]; + env->features[FEAT_1_EDX] &= ~minus_features[FEAT_1_EDX]; + env->features[FEAT_1_ECX] &= ~minus_features[FEAT_1_ECX]; + env->features[FEAT_8000_0001_EDX] &= ~minus_features[FEAT_8000_0001_EDX]; + env->features[FEAT_8000_0001_ECX] &= ~minus_features[FEAT_8000_0001_ECX]; + env->features[FEAT_C000_0001_EDX] &= ~minus_features[FEAT_C000_0001_EDX]; + env->features[FEAT_KVM] &= ~minus_features[FEAT_KVM]; + env->features[FEAT_SVM] &= ~minus_features[FEAT_SVM]; + env->features[FEAT_7_0_EBX] &= ~minus_features[FEAT_7_0_EBX]; out: return; @@ -1597,21 +1592,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_8000_0001_EDX] &= kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX); - env->cpuid_ext3_features &= + env->features[FEAT_8000_0001_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_C000_0001_EDX] &= kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX); } @@ -1630,24 +1625,24 @@ static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp) } if (kvm_enabled()) { - def->kvm_features |= kvm_default_features; + def->features[FEAT_KVM] |= kvm_default_features; } - def->ext_features |= CPUID_EXT_HYPERVISOR; + def->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR; object_property_set_str(OBJECT(cpu), def->vendor, "vendor", errp); object_property_set_int(OBJECT(cpu), def->level, "level", 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_8000_0001_EDX] = def->features[FEAT_8000_0001_EDX]; + env->features[FEAT_8000_0001_ECX] = def->features[FEAT_8000_0001_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_C000_0001_EDX] = def->features[FEAT_C000_0001_EDX]; + env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX]; env->cpuid_xlevel2 = def->xlevel2; object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp); @@ -1717,7 +1712,7 @@ out: void cpu_clear_apic_feature(CPUX86State *env) { - env->cpuid_features &= ~CPUID_APIC; + env->features[FEAT_1_EDX] &= ~CPUID_APIC; } #endif /* !CONFIG_USER_ONLY */ @@ -1792,8 +1787,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 (cs->nr_cores * cs->nr_threads > 1) { *ebx |= (cs->nr_cores * cs->nr_threads) << 16; *edx |= 1 << 28; /* HTT bit */ @@ -1861,7 +1856,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 { @@ -1896,7 +1891,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; @@ -1926,8 +1921,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_8000_0001_ECX]; + *edx = env->features[FEAT_8000_0001_EDX]; /* The Linux kernel checks for the CMPLegacy bit and * discards multiple thread information if it is set. @@ -1968,12 +1963,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_8000_0001_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 */ @@ -1987,11 +1982,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_8000_0001_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; @@ -2010,7 +2005,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_C000_0001_EDX]; break; case 0xC0000002: case 0xC0000003: @@ -2142,7 +2137,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; @@ -2217,7 +2212,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) CPUX86State *env = &cpu->env; Error *local_err = NULL; - 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; } @@ -2227,21 +2222,21 @@ static void x86_cpu_realizefn(DeviceState *dev, 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_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES; + env->features[FEAT_8000_0001_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_8000_0001_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_8000_0001_ECX] &= TCG_EXT3_FEATURES; + env->features[FEAT_SVM] &= TCG_SVM_FEATURES; } else { if (check_cpuid && kvm_check_features_against_host(cpu) && enforce_cpuid) { @@ -2257,7 +2252,7 @@ static void x86_cpu_realizefn(DeviceState *dev, 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_create(cpu, &local_err); if (local_err != NULL) { goto out; diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 500fe93..e812335 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -841,16 +841,9 @@ typedef struct CPUX86State { uint32_t cpuid_vendor2; uint32_t cpuid_vendor3; uint32_t cpuid_version; - uint32_t cpuid_features; - uint32_t cpuid_ext_features; + FeatureWordArray features; uint32_t cpuid_model[12]; - uint32_t cpuid_ext2_features; - uint32_t cpuid_ext3_features; uint32_t cpuid_apic_id; - /* Store the results of Centaur's CPUID instructions */ - 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]; @@ -864,8 +857,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 282494f..158710a 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -463,7 +463,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; @@ -471,7 +471,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 e650900..98e8474 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -453,7 +453,7 @@ int kvm_arch_init_vcpu(CPUState *cs) 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); @@ -610,7 +610,7 @@ int kvm_arch_init_vcpu(CPUState *cs) cpuid_data.cpuid.nent = cpuid_i; if (((env->cpuid_version >> 8)&0xF) >= 6 - && (env->cpuid_features & (CPUID_MCE|CPUID_MCA)) == + && (env->features[FEAT_1_EDX] & (CPUID_MCE|CPUID_MCA)) == (CPUID_MCE|CPUID_MCA) && kvm_check_extension(cs->kvm_state, KVM_CAP_MCE) > 0) { uint64_t mcg_cap; diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c index dfbc07b..ec834fc 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_8000_0001_EDX] & CPUID_EXT2_SYSCALL) { update_mask |= MSR_EFER_SCE; } - if (env->cpuid_ext2_features & CPUID_EXT2_LM) { + if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) { update_mask |= MSR_EFER_LME; } - if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR) { + if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) { update_mask |= MSR_EFER_FFXSR; } - if (env->cpuid_ext2_features & CPUID_EXT2_NX) { + if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_NX) { update_mask |= MSR_EFER_NXE; } - if (env->cpuid_ext3_features & CPUID_EXT3_SVM) { + if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) { update_mask |= MSR_EFER_SVME; } - if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR) { + if (env->features[FEAT_8000_0001_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 233f24f..ae77b16 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -8289,11 +8289,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_8000_0001_EDX]; + dc->cpuid_ext3_features = env->features[FEAT_8000_0001_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;