diff options
Diffstat (limited to 'target')
-rw-r--r-- | target/arm/cpu.c | 8 | ||||
-rw-r--r-- | target/hppa/cpu.c | 17 | ||||
-rw-r--r-- | target/hppa/cpu.h | 2 | ||||
-rw-r--r-- | target/i386/cpu-qom.h | 10 | ||||
-rw-r--r-- | target/i386/cpu.c | 1143 | ||||
-rw-r--r-- | target/i386/cpu.h | 36 | ||||
-rw-r--r-- | target/i386/kvm.c | 12 | ||||
-rw-r--r-- | target/openrisc/sys_helper.c | 6 | ||||
-rw-r--r-- | target/s390x/cpu.c | 3 | ||||
-rw-r--r-- | target/s390x/excp_helper.c | 5 | ||||
-rw-r--r-- | target/s390x/kvm.c | 10 |
11 files changed, 624 insertions, 628 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c index ca718fb..e75a64a 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -31,6 +31,7 @@ #include "hw/qdev-properties.h" #if !defined(CONFIG_USER_ONLY) #include "hw/loader.h" +#include "hw/boards.h" #endif #include "sysemu/sysemu.h" #include "sysemu/tcg.h" @@ -1587,6 +1588,9 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) init_cpreg_list(cpu); #ifndef CONFIG_USER_ONLY + MachineState *ms = MACHINE(qdev_get_machine()); + unsigned int smp_cpus = ms->smp.cpus; + if (cpu->has_el3 || arm_feature(env, ARM_FEATURE_M_SECURITY)) { cs->num_ases = 2; @@ -2127,10 +2131,12 @@ static void cortex_a9_initfn(Object *obj) #ifndef CONFIG_USER_ONLY static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri) { + MachineState *ms = MACHINE(qdev_get_machine()); + /* Linux wants the number of processors from here. * Might as well set the interrupt-controller bit too. */ - return ((smp_cpus - 1) << 24) | (1 << 23); + return ((ms->smp.cpus - 1) << 24) | (1 << 23); } #endif diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c index 368cb71..71b6aca 100644 --- a/target/hppa/cpu.c +++ b/target/hppa/cpu.c @@ -111,23 +111,6 @@ static void hppa_cpu_realizefn(DeviceState *dev, Error **errp) #endif } -static void hppa_cpu_list_entry(gpointer data, gpointer user_data) -{ - ObjectClass *oc = data; - - qemu_printf(" %s\n", object_class_get_name(oc)); -} - -void hppa_cpu_list(void) -{ - GSList *list; - - list = object_class_get_list_sorted(TYPE_HPPA_CPU, false); - qemu_printf("Available CPUs:\n"); - g_slist_foreach(list, hppa_cpu_list_entry, NULL); - g_slist_free(list); -} - static void hppa_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index 2e1f2ac..aab251b 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -241,8 +241,6 @@ void hppa_translate_init(void); #define CPU_RESOLVING_TYPE TYPE_HPPA_CPU -void hppa_cpu_list(void); - static inline target_ulong hppa_form_gva_psw(target_ureg psw, uint64_t spc, target_ureg off) { diff --git a/target/i386/cpu-qom.h b/target/i386/cpu-qom.h index 22f95eb..1a52f02 100644 --- a/target/i386/cpu-qom.h +++ b/target/i386/cpu-qom.h @@ -36,13 +36,7 @@ #define X86_CPU_GET_CLASS(obj) \ OBJECT_GET_CLASS(X86CPUClass, (obj), TYPE_X86_CPU) -/** - * X86CPUDefinition: - * - * CPU model definition data that was not converted to QOM per-subclass - * property defaults yet. - */ -typedef struct X86CPUDefinition X86CPUDefinition; +typedef struct X86CPUModel X86CPUModel; /** * X86CPUClass: @@ -64,7 +58,7 @@ typedef struct X86CPUClass { /* CPU definition, automatically loaded by instance_init if not NULL. * Should be eventually replaced by subclass-specific property defaults. */ - X86CPUDefinition *cpu_def; + X86CPUModel *model; bool host_cpuid_required; int ordering; diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 2a9f4e2..805ce95 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -56,6 +56,7 @@ #include "hw/hw.h" #include "hw/xen/xen.h" #include "hw/i386/apic_internal.h" +#include "hw/boards.h" #endif #include "disas/capstone.h" @@ -1432,7 +1433,18 @@ static char *x86_cpu_class_get_model_name(X86CPUClass *cc) strlen(class_name) - strlen(X86_CPU_TYPE_SUFFIX)); } -struct X86CPUDefinition { +typedef struct PropValue { + const char *prop, *value; +} PropValue; + +typedef struct X86CPUVersionDefinition { + X86CPUVersion version; + const char *alias; + PropValue *props; +} X86CPUVersionDefinition; + +/* Base definition for a CPU model */ +typedef struct X86CPUDefinition { const char *name; uint32_t level; uint32_t xlevel; @@ -1444,8 +1456,46 @@ struct X86CPUDefinition { FeatureWordArray features; const char *model_id; CPUCaches *cache_info; + /* + * Definitions for alternative versions of CPU model. + * List is terminated by item with version == 0. + * If NULL, version 1 will be registered automatically. + */ + const X86CPUVersionDefinition *versions; +} X86CPUDefinition; + +/* Reference to a specific CPU model version */ +struct X86CPUModel { + /* Base CPU definition */ + X86CPUDefinition *cpudef; + /* CPU model version */ + X86CPUVersion version; + /* + * If true, this is an alias CPU model. + * This matters only for "-cpu help" and query-cpu-definitions + */ + bool is_alias; }; +/* Get full model name for CPU version */ +static char *x86_cpu_versioned_model_name(X86CPUDefinition *cpudef, + X86CPUVersion version) +{ + assert(version > 0); + return g_strdup_printf("%s-v%d", cpudef->name, (int)version); +} + +static const X86CPUVersionDefinition *x86_cpu_def_get_versions(X86CPUDefinition *def) +{ + /* When X86CPUDefinition::versions is NULL, we register only v1 */ + static const X86CPUVersionDefinition default_version_list[] = { + { 1 }, + { /* end of list */ } + }; + + return def->versions ?: default_version_list; +} + static CPUCaches epyc_cache_info = { .l1d_cache = &(CPUCacheInfo) { .type = DATA_CACHE, @@ -1807,31 +1857,20 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT3_LAHF_LM, .xlevel = 0x80000008, .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)", - }, - { - .name = "Nehalem-IBRS", - .level = 11, - .vendor = CPUID_VENDOR_INTEL, - .family = 6, - .model = 26, - .stepping = 3, - .features[FEAT_1_EDX] = - CPUID_VME | 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_7_0_EDX] = - CPUID_7_0_EDX_SPEC_CTRL, - .features[FEAT_8000_0001_EDX] = - CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, - .features[FEAT_8000_0001_ECX] = - CPUID_EXT3_LAHF_LM, - .xlevel = 0x80000008, - .model_id = "Intel Core i7 9xx (Nehalem Core i7, IBRS update)", + .versions = (X86CPUVersionDefinition[]) { + { .version = 1 }, + { + .version = 2, + .alias = "Nehalem-IBRS", + .props = (PropValue[]) { + { "spec-ctrl", "on" }, + { "model-id", + "Intel Core i7 9xx (Nehalem Core i7, IBRS update)" }, + { /* end of list */ } + } + }, + { /* end of list */ } + } }, { .name = "Westmere", @@ -1858,34 +1897,20 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_6_EAX_ARAT, .xlevel = 0x80000008, .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)", - }, - { - .name = "Westmere-IBRS", - .level = 11, - .vendor = CPUID_VENDOR_INTEL, - .family = 6, - .model = 44, - .stepping = 1, - .features[FEAT_1_EDX] = - CPUID_VME | 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_PCLMULQDQ | CPUID_EXT_SSE3, - .features[FEAT_8000_0001_EDX] = - CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, - .features[FEAT_8000_0001_ECX] = - CPUID_EXT3_LAHF_LM, - .features[FEAT_7_0_EDX] = - CPUID_7_0_EDX_SPEC_CTRL, - .features[FEAT_6_EAX] = - CPUID_6_EAX_ARAT, - .xlevel = 0x80000008, - .model_id = "Westmere E56xx/L56xx/X56xx (IBRS update)", + .versions = (X86CPUVersionDefinition[]) { + { .version = 1 }, + { + .version = 2, + .alias = "Westmere-IBRS", + .props = (PropValue[]) { + { "spec-ctrl", "on" }, + { "model-id", + "Westmere E56xx/L56xx/X56xx (IBRS update)" }, + { /* end of list */ } + } + }, + { /* end of list */ } + } }, { .name = "SandyBridge", @@ -1917,39 +1942,20 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_6_EAX_ARAT, .xlevel = 0x80000008, .model_id = "Intel Xeon E312xx (Sandy Bridge)", - }, - { - .name = "SandyBridge-IBRS", - .level = 0xd, - .vendor = CPUID_VENDOR_INTEL, - .family = 6, - .model = 42, - .stepping = 1, - .features[FEAT_1_EDX] = - CPUID_VME | 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_8000_0001_EDX] = - CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | - CPUID_EXT2_SYSCALL, - .features[FEAT_8000_0001_ECX] = - CPUID_EXT3_LAHF_LM, - .features[FEAT_7_0_EDX] = - CPUID_7_0_EDX_SPEC_CTRL, - .features[FEAT_XSAVE] = - CPUID_XSAVE_XSAVEOPT, - .features[FEAT_6_EAX] = - CPUID_6_EAX_ARAT, - .xlevel = 0x80000008, - .model_id = "Intel Xeon E312xx (Sandy Bridge, IBRS update)", + .versions = (X86CPUVersionDefinition[]) { + { .version = 1 }, + { + .version = 2, + .alias = "SandyBridge-IBRS", + .props = (PropValue[]) { + { "spec-ctrl", "on" }, + { "model-id", + "Intel Xeon E312xx (Sandy Bridge, IBRS update)" }, + { /* end of list */ } + } + }, + { /* end of list */ } + } }, { .name = "IvyBridge", @@ -1984,116 +1990,20 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_6_EAX_ARAT, .xlevel = 0x80000008, .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge)", - }, - { - .name = "IvyBridge-IBRS", - .level = 0xd, - .vendor = CPUID_VENDOR_INTEL, - .family = 6, - .model = 58, - .stepping = 9, - .features[FEAT_1_EDX] = - CPUID_VME | 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 | CPUID_EXT_F16C | CPUID_EXT_RDRAND, - .features[FEAT_7_0_EBX] = - CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_SMEP | - CPUID_7_0_EBX_ERMS, - .features[FEAT_8000_0001_EDX] = - CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | - CPUID_EXT2_SYSCALL, - .features[FEAT_8000_0001_ECX] = - CPUID_EXT3_LAHF_LM, - .features[FEAT_7_0_EDX] = - CPUID_7_0_EDX_SPEC_CTRL, - .features[FEAT_XSAVE] = - CPUID_XSAVE_XSAVEOPT, - .features[FEAT_6_EAX] = - CPUID_6_EAX_ARAT, - .xlevel = 0x80000008, - .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge, IBRS)", - }, - { - .name = "Haswell-noTSX", - .level = 0xd, - .vendor = CPUID_VENDOR_INTEL, - .family = 6, - .model = 60, - .stepping = 1, - .features[FEAT_1_EDX] = - CPUID_VME | 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 | CPUID_EXT_F16C | CPUID_EXT_RDRAND, - .features[FEAT_8000_0001_EDX] = - CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | - CPUID_EXT2_SYSCALL, - .features[FEAT_8000_0001_ECX] = - CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM, - .features[FEAT_7_0_EBX] = - CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | - 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, - .features[FEAT_XSAVE] = - CPUID_XSAVE_XSAVEOPT, - .features[FEAT_6_EAX] = - CPUID_6_EAX_ARAT, - .xlevel = 0x80000008, - .model_id = "Intel Core Processor (Haswell, no TSX)", - }, - { - .name = "Haswell-noTSX-IBRS", - .level = 0xd, - .vendor = CPUID_VENDOR_INTEL, - .family = 6, - .model = 60, - .stepping = 1, - .features[FEAT_1_EDX] = - CPUID_VME | 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 | CPUID_EXT_F16C | CPUID_EXT_RDRAND, - .features[FEAT_8000_0001_EDX] = - CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | - CPUID_EXT2_SYSCALL, - .features[FEAT_8000_0001_ECX] = - CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM, - .features[FEAT_7_0_EDX] = - CPUID_7_0_EDX_SPEC_CTRL, - .features[FEAT_7_0_EBX] = - CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | - 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, - .features[FEAT_XSAVE] = - CPUID_XSAVE_XSAVEOPT, - .features[FEAT_6_EAX] = - CPUID_6_EAX_ARAT, - .xlevel = 0x80000008, - .model_id = "Intel Core Processor (Haswell, no TSX, IBRS)", + .versions = (X86CPUVersionDefinition[]) { + { .version = 1 }, + { + .version = 2, + .alias = "IvyBridge-IBRS", + .props = (PropValue[]) { + { "spec-ctrl", "on" }, + { "model-id", + "Intel Xeon E3-12xx v2 (Ivy Bridge, IBRS)" }, + { /* end of list */ } + } + }, + { /* end of list */ } + } }, { .name = "Haswell", @@ -2131,123 +2041,52 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_6_EAX_ARAT, .xlevel = 0x80000008, .model_id = "Intel Core Processor (Haswell)", - }, - { - .name = "Haswell-IBRS", - .level = 0xd, - .vendor = CPUID_VENDOR_INTEL, - .family = 6, - .model = 60, - .stepping = 4, - .features[FEAT_1_EDX] = - CPUID_VME | 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 | CPUID_EXT_F16C | CPUID_EXT_RDRAND, - .features[FEAT_8000_0001_EDX] = - CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | - CPUID_EXT2_SYSCALL, - .features[FEAT_8000_0001_ECX] = - CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM, - .features[FEAT_7_0_EDX] = - CPUID_7_0_EDX_SPEC_CTRL, - .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, - .features[FEAT_XSAVE] = - CPUID_XSAVE_XSAVEOPT, - .features[FEAT_6_EAX] = - CPUID_6_EAX_ARAT, - .xlevel = 0x80000008, - .model_id = "Intel Core Processor (Haswell, IBRS)", - }, - { - .name = "Broadwell-noTSX", - .level = 0xd, - .vendor = CPUID_VENDOR_INTEL, - .family = 6, - .model = 61, - .stepping = 2, - .features[FEAT_1_EDX] = - CPUID_VME | 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 | CPUID_EXT_F16C | CPUID_EXT_RDRAND, - .features[FEAT_8000_0001_EDX] = - CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | - CPUID_EXT2_SYSCALL, - .features[FEAT_8000_0001_ECX] = - CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH, - .features[FEAT_7_0_EBX] = - CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | - 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_RDSEED | CPUID_7_0_EBX_ADX | - CPUID_7_0_EBX_SMAP, - .features[FEAT_XSAVE] = - CPUID_XSAVE_XSAVEOPT, - .features[FEAT_6_EAX] = - CPUID_6_EAX_ARAT, - .xlevel = 0x80000008, - .model_id = "Intel Core Processor (Broadwell, no TSX)", - }, - { - .name = "Broadwell-noTSX-IBRS", - .level = 0xd, - .vendor = CPUID_VENDOR_INTEL, - .family = 6, - .model = 61, - .stepping = 2, - .features[FEAT_1_EDX] = - CPUID_VME | 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 | CPUID_EXT_F16C | CPUID_EXT_RDRAND, - .features[FEAT_8000_0001_EDX] = - CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | - CPUID_EXT2_SYSCALL, - .features[FEAT_8000_0001_ECX] = - CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH, - .features[FEAT_7_0_EDX] = - CPUID_7_0_EDX_SPEC_CTRL, - .features[FEAT_7_0_EBX] = - CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | - 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_RDSEED | CPUID_7_0_EBX_ADX | - CPUID_7_0_EBX_SMAP, - .features[FEAT_XSAVE] = - CPUID_XSAVE_XSAVEOPT, - .features[FEAT_6_EAX] = - CPUID_6_EAX_ARAT, - .xlevel = 0x80000008, - .model_id = "Intel Core Processor (Broadwell, no TSX, IBRS)", + .versions = (X86CPUVersionDefinition[]) { + { .version = 1 }, + { + .version = 2, + .alias = "Haswell-noTSX", + .props = (PropValue[]) { + { "hle", "off" }, + { "rtm", "off" }, + { "stepping", "1" }, + { "model-id", "Intel Core Processor (Haswell, no TSX)", }, + { /* end of list */ } + }, + }, + { + .version = 3, + .alias = "Haswell-IBRS", + .props = (PropValue[]) { + /* Restore TSX features removed by -v2 above */ + { "hle", "on" }, + { "rtm", "on" }, + /* + * Haswell and Haswell-IBRS had stepping=4 in + * QEMU 4.0 and older + */ + { "stepping", "4" }, + { "spec-ctrl", "on" }, + { "model-id", + "Intel Core Processor (Haswell, IBRS)" }, + { /* end of list */ } + } + }, + { + .version = 4, + .alias = "Haswell-noTSX-IBRS", + .props = (PropValue[]) { + { "hle", "off" }, + { "rtm", "off" }, + /* spec-ctrl was already enabled by -v3 above */ + { "stepping", "1" }, + { "model-id", + "Intel Core Processor (Haswell, no TSX, IBRS)" }, + { /* end of list */ } + } + }, + { /* end of list */ } + } }, { .name = "Broadwell", @@ -2286,46 +2125,45 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_6_EAX_ARAT, .xlevel = 0x80000008, .model_id = "Intel Core Processor (Broadwell)", - }, - { - .name = "Broadwell-IBRS", - .level = 0xd, - .vendor = CPUID_VENDOR_INTEL, - .family = 6, - .model = 61, - .stepping = 2, - .features[FEAT_1_EDX] = - CPUID_VME | 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 | CPUID_EXT_F16C | CPUID_EXT_RDRAND, - .features[FEAT_8000_0001_EDX] = - CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | - CPUID_EXT2_SYSCALL, - .features[FEAT_8000_0001_ECX] = - CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH, - .features[FEAT_7_0_EDX] = - CPUID_7_0_EDX_SPEC_CTRL, - .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 | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | - CPUID_7_0_EBX_SMAP, - .features[FEAT_XSAVE] = - CPUID_XSAVE_XSAVEOPT, - .features[FEAT_6_EAX] = - CPUID_6_EAX_ARAT, - .xlevel = 0x80000008, - .model_id = "Intel Core Processor (Broadwell, IBRS)", + .versions = (X86CPUVersionDefinition[]) { + { .version = 1 }, + { + .version = 2, + .alias = "Broadwell-noTSX", + .props = (PropValue[]) { + { "hle", "off" }, + { "rtm", "off" }, + { "model-id", "Intel Core Processor (Broadwell, no TSX)", }, + { /* end of list */ } + }, + }, + { + .version = 3, + .alias = "Broadwell-IBRS", + .props = (PropValue[]) { + /* Restore TSX features removed by -v2 above */ + { "hle", "on" }, + { "rtm", "on" }, + { "spec-ctrl", "on" }, + { "model-id", + "Intel Core Processor (Broadwell, IBRS)" }, + { /* end of list */ } + } + }, + { + .version = 4, + .alias = "Broadwell-noTSX-IBRS", + .props = (PropValue[]) { + { "hle", "off" }, + { "rtm", "off" }, + /* spec-ctrl was already enabled by -v3 above */ + { "model-id", + "Intel Core Processor (Broadwell, no TSX, IBRS)" }, + { /* end of list */ } + } + }, + { /* end of list */ } + } }, { .name = "Skylake-Client", @@ -2371,53 +2209,20 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_6_EAX_ARAT, .xlevel = 0x80000008, .model_id = "Intel Core Processor (Skylake)", - }, - { - .name = "Skylake-Client-IBRS", - .level = 0xd, - .vendor = CPUID_VENDOR_INTEL, - .family = 6, - .model = 94, - .stepping = 3, - .features[FEAT_1_EDX] = - CPUID_VME | 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 | CPUID_EXT_F16C | CPUID_EXT_RDRAND, - .features[FEAT_8000_0001_EDX] = - CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | - CPUID_EXT2_SYSCALL, - .features[FEAT_8000_0001_ECX] = - CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH, - .features[FEAT_7_0_EDX] = - CPUID_7_0_EDX_SPEC_CTRL, - .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 | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | - CPUID_7_0_EBX_SMAP, - /* Missing: XSAVES (not supported by some Linux versions, - * including v4.1 to v4.12). - * KVM doesn't yet expose any XSAVES state save component, - * and the only one defined in Skylake (processor tracing) - * probably will block migration anyway. - */ - .features[FEAT_XSAVE] = - CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | - CPUID_XSAVE_XGETBV1, - .features[FEAT_6_EAX] = - CPUID_6_EAX_ARAT, - .xlevel = 0x80000008, - .model_id = "Intel Core Processor (Skylake, IBRS)", + .versions = (X86CPUVersionDefinition[]) { + { .version = 1 }, + { + .version = 2, + .alias = "Skylake-Client-IBRS", + .props = (PropValue[]) { + { "spec-ctrl", "on" }, + { "model-id", + "Intel Core Processor (Skylake, IBRS)" }, + { /* end of list */ } + } + }, + { /* end of list */ } + } }, { .name = "Skylake-Server", @@ -2468,58 +2273,23 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_6_EAX_ARAT, .xlevel = 0x80000008, .model_id = "Intel Xeon Processor (Skylake)", - }, - { - .name = "Skylake-Server-IBRS", - .level = 0xd, - .vendor = CPUID_VENDOR_INTEL, - .family = 6, - .model = 85, - .stepping = 4, - .features[FEAT_1_EDX] = - CPUID_VME | 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 | CPUID_EXT_F16C | CPUID_EXT_RDRAND, - .features[FEAT_8000_0001_EDX] = - CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP | - CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, - .features[FEAT_8000_0001_ECX] = - CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH, - .features[FEAT_7_0_EDX] = - CPUID_7_0_EDX_SPEC_CTRL, - .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 | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | - CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLWB | - CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ | - CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD | - CPUID_7_0_EBX_AVX512VL, - .features[FEAT_7_0_ECX] = - CPUID_7_0_ECX_PKU, - /* Missing: XSAVES (not supported by some Linux versions, - * including v4.1 to v4.12). - * KVM doesn't yet expose any XSAVES state save component, - * and the only one defined in Skylake (processor tracing) - * probably will block migration anyway. - */ - .features[FEAT_XSAVE] = - CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | - CPUID_XSAVE_XGETBV1, - .features[FEAT_6_EAX] = - CPUID_6_EAX_ARAT, - .xlevel = 0x80000008, - .model_id = "Intel Xeon Processor (Skylake, IBRS)", + .versions = (X86CPUVersionDefinition[]) { + { .version = 1 }, + { + .version = 2, + .alias = "Skylake-Server-IBRS", + .props = (PropValue[]) { + /* clflushopt was not added to Skylake-Server-IBRS */ + /* TODO: add -v3 including clflushopt */ + { "clflushopt", "off" }, + { "spec-ctrl", "on" }, + { "model-id", + "Intel Xeon Processor (Skylake, IBRS)" }, + { /* end of list */ } + } + }, + { /* end of list */ } + } }, { .name = "Cascadelake-Server", @@ -2573,6 +2343,20 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_6_EAX_ARAT, .xlevel = 0x80000008, .model_id = "Intel Xeon Processor (Cascadelake)", + .versions = (X86CPUVersionDefinition[]) { + { .version = 1 }, + { .version = 2, + .props = (PropValue[]) { + { "arch-capabilities", "on" }, + { "rdctl-no", "on" }, + { "ibrs-all", "on" }, + { "skip-l1dfl-vmentry", "on" }, + { "mds-no", "on" }, + { /* end of list */ } + }, + }, + { /* end of list */ } + } }, { .name = "Icelake-Client", @@ -2688,6 +2472,77 @@ static X86CPUDefinition builtin_x86_defs[] = { .model_id = "Intel Xeon Processor (Icelake)", }, { + .name = "SnowRidge-Server", + .level = 27, + .vendor = CPUID_VENDOR_INTEL, + .family = 6, + .model = 134, + .stepping = 1, + .features[FEAT_1_EDX] = + /* missing: CPUID_PN CPUID_IA64 */ + /* missing: CPUID_DTS, CPUID_HT, CPUID_TM, CPUID_PBE */ + CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | + CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | + CPUID_CX8 | CPUID_APIC | CPUID_SEP | + CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | + CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH | + CPUID_MMX | + CPUID_FXSR | CPUID_SSE | CPUID_SSE2, + .features[FEAT_1_ECX] = + CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_MONITOR | + CPUID_EXT_VMX | + CPUID_EXT_SSSE3 | + CPUID_EXT_CX16 | + CPUID_EXT_SSE41 | + CPUID_EXT_SSE42 | CPUID_EXT_X2APIC | CPUID_EXT_MOVBE | + CPUID_EXT_POPCNT | + CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_AES | CPUID_EXT_XSAVE | + CPUID_EXT_RDRAND, + .features[FEAT_8000_0001_EDX] = + CPUID_EXT2_SYSCALL | + CPUID_EXT2_NX | + CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP | + CPUID_EXT2_LM, + .features[FEAT_8000_0001_ECX] = + CPUID_EXT3_LAHF_LM | + CPUID_EXT3_3DNOWPREFETCH, + .features[FEAT_7_0_EBX] = + CPUID_7_0_EBX_FSGSBASE | + CPUID_7_0_EBX_SMEP | + CPUID_7_0_EBX_ERMS | + CPUID_7_0_EBX_MPX | /* missing bits 13, 15 */ + CPUID_7_0_EBX_RDSEED | + CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT | + CPUID_7_0_EBX_CLWB | + CPUID_7_0_EBX_SHA_NI, + .features[FEAT_7_0_ECX] = + CPUID_7_0_ECX_UMIP | + /* missing bit 5 */ + CPUID_7_0_ECX_GFNI | + CPUID_7_0_ECX_MOVDIRI | CPUID_7_0_ECX_CLDEMOTE | + CPUID_7_0_ECX_MOVDIR64B, + .features[FEAT_7_0_EDX] = + CPUID_7_0_EDX_SPEC_CTRL | + CPUID_7_0_EDX_ARCH_CAPABILITIES | CPUID_7_0_EDX_SPEC_CTRL_SSBD | + CPUID_7_0_EDX_CORE_CAPABILITY, + .features[FEAT_CORE_CAPABILITY] = + MSR_CORE_CAP_SPLIT_LOCK_DETECT, + /* + * Missing: XSAVES (not supported by some Linux versions, + * including v4.1 to v4.12). + * KVM doesn't yet expose any XSAVES state save component, + * and the only one defined in Skylake (processor tracing) + * probably will block migration anyway. + */ + .features[FEAT_XSAVE] = + CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | + CPUID_XSAVE_XGETBV1, + .features[FEAT_6_EAX] = + CPUID_6_EAX_ARAT, + .xlevel = 0x80000008, + .model_id = "Intel Atom Processor (SnowRidge)", + }, + { .name = "KnightsMill", .level = 0xd, .vendor = CPUID_VENDOR_INTEL, @@ -2907,56 +2762,20 @@ static X86CPUDefinition builtin_x86_defs[] = { .xlevel = 0x8000001E, .model_id = "AMD EPYC Processor", .cache_info = &epyc_cache_info, - }, - { - .name = "EPYC-IBPB", - .level = 0xd, - .vendor = CPUID_VENDOR_AMD, - .family = 23, - .model = 1, - .stepping = 2, - .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_VME | CPUID_FP87, - .features[FEAT_1_ECX] = - CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX | - CPUID_EXT_XSAVE | CPUID_EXT_AES | CPUID_EXT_POPCNT | - CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | - CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 | - CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3, - .features[FEAT_8000_0001_EDX] = - CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB | - CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX | - CPUID_EXT2_SYSCALL, - .features[FEAT_8000_0001_ECX] = - CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH | - CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | - CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM | - CPUID_EXT3_TOPOEXT, - .features[FEAT_8000_0008_EBX] = - CPUID_8000_0008_EBX_IBPB, - .features[FEAT_7_0_EBX] = - CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 | - CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED | - CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT | - CPUID_7_0_EBX_SHA_NI, - /* Missing: XSAVES (not supported by some Linux versions, - * including v4.1 to v4.12). - * KVM doesn't yet expose any XSAVES state save component. - */ - .features[FEAT_XSAVE] = - CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | - CPUID_XSAVE_XGETBV1, - .features[FEAT_6_EAX] = - CPUID_6_EAX_ARAT, - .features[FEAT_SVM] = - CPUID_SVM_NPT | CPUID_SVM_NRIPSAVE, - .xlevel = 0x8000001E, - .model_id = "AMD EPYC Processor (with IBPB)", - .cache_info = &epyc_cache_info, + .versions = (X86CPUVersionDefinition[]) { + { .version = 1 }, + { + .version = 2, + .alias = "EPYC-IBPB", + .props = (PropValue[]) { + { "ibpb", "on" }, + { "model-id", + "AMD EPYC Processor (with IBPB)" }, + { /* end of list */ } + } + }, + { /* end of list */ } + } }, { .name = "Dhyana", @@ -3010,10 +2829,6 @@ static X86CPUDefinition builtin_x86_defs[] = { }, }; -typedef struct PropValue { - const char *prop, *value; -} PropValue; - /* KVM-specific features that are automatically added/removed * from all CPU models when KVM is enabled. */ @@ -3039,6 +2854,40 @@ static PropValue tcg_default_props[] = { }; +X86CPUVersion default_cpu_version = CPU_VERSION_LATEST; + +void x86_cpu_set_default_version(X86CPUVersion version) +{ + /* Translating CPU_VERSION_AUTO to CPU_VERSION_AUTO doesn't make sense */ + assert(version != CPU_VERSION_AUTO); + default_cpu_version = version; +} + +static X86CPUVersion x86_cpu_model_last_version(const X86CPUModel *model) +{ + int v = 0; + const X86CPUVersionDefinition *vdef = + x86_cpu_def_get_versions(model->cpudef); + while (vdef->version) { + v = vdef->version; + vdef++; + } + return v; +} + +/* Return the actual version being used for a specific CPU model */ +static X86CPUVersion x86_cpu_model_resolve_version(const X86CPUModel *model) +{ + X86CPUVersion v = model->version; + if (v == CPU_VERSION_AUTO) { + v = default_cpu_version; + } + if (v == CPU_VERSION_LATEST) { + return x86_cpu_model_last_version(model); + } + return v; +} + void x86_cpu_change_kvm_default(const char *prop, const char *value) { PropValue *pv; @@ -3116,8 +2965,6 @@ static void max_x86_cpu_class_init(ObjectClass *oc, void *data) dc->props = max_x86_cpu_properties; } -static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp); - static void max_x86_cpu_initfn(Object *obj) { X86CPU *cpu = X86_CPU(obj); @@ -3133,14 +2980,8 @@ static void max_x86_cpu_initfn(Object *obj) char vendor[CPUID_VENDOR_SZ + 1] = { 0 }; char model_id[CPUID_MODEL_ID_SZ + 1] = { 0 }; int family, model, stepping; - X86CPUDefinition host_cpudef = { }; - uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0; - - host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx); - x86_cpu_vendor_words2str(host_cpudef.vendor, ebx, edx, ecx); host_vendor_fms(vendor, &family, &model, &stepping); - cpu_x86_fill_model_id(model_id); object_property_set_str(OBJECT(cpu), vendor, "vendor", &error_abort); @@ -3517,46 +3358,6 @@ static void x86_cpu_get_feature_words(Object *obj, Visitor *v, visit_type_X86CPUFeatureWordInfoList(v, "feature-words", &list, errp); } -static void x86_get_hv_spinlocks(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - X86CPU *cpu = X86_CPU(obj); - int64_t value = cpu->hyperv_spinlock_attempts; - - visit_type_int(v, name, &value, errp); -} - -static void x86_set_hv_spinlocks(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - const int64_t min = 0xFFF; - const int64_t max = UINT_MAX; - X86CPU *cpu = X86_CPU(obj); - Error *err = NULL; - int64_t value; - - visit_type_int(v, name, &value, &err); - if (err) { - error_propagate(errp, err); - return; - } - - if (value < min || value > max) { - error_setg(errp, "Property %s.%s doesn't take value %" PRId64 - " (minimum: %" PRId64 ", maximum: %" PRId64 ")", - object_get_typename(obj), name ? name : "null", - value, min, max); - return; - } - cpu->hyperv_spinlock_attempts = value; -} - -static const PropertyInfo qdev_prop_spinlocks = { - .name = "int", - .get = x86_get_hv_spinlocks, - .set = x86_set_hv_spinlocks, -}; - /* Convert all '_' in a feature string option name to '-', to make feature * name conform to QOM property naming rule, which uses '-' instead of '_'. */ @@ -3811,18 +3612,51 @@ static GSList *get_sorted_cpu_model_list(void) return list; } +static char *x86_cpu_class_get_model_id(X86CPUClass *xc) +{ + Object *obj = object_new(object_class_get_name(OBJECT_CLASS(xc))); + char *r = object_property_get_str(obj, "model-id", &error_abort); + object_unref(obj); + return r; +} + +static char *x86_cpu_class_get_alias_of(X86CPUClass *cc) +{ + X86CPUVersion version; + + if (!cc->model || !cc->model->is_alias) { + return NULL; + } + version = x86_cpu_model_resolve_version(cc->model); + if (version <= 0) { + return NULL; + } + return x86_cpu_versioned_model_name(cc->model->cpudef, version); +} + static void x86_cpu_list_entry(gpointer data, gpointer user_data) { ObjectClass *oc = data; X86CPUClass *cc = X86_CPU_CLASS(oc); char *name = x86_cpu_class_get_model_name(cc); - const char *desc = cc->model_description; - if (!desc && cc->cpu_def) { - desc = cc->cpu_def->model_id; + char *desc = g_strdup(cc->model_description); + char *alias_of = x86_cpu_class_get_alias_of(cc); + + if (!desc && alias_of) { + if (cc->model && cc->model->version == CPU_VERSION_AUTO) { + desc = g_strdup("(alias configured by machine type)"); + } else { + desc = g_strdup_printf("(alias of %s)", alias_of); + } + } + if (!desc) { + desc = x86_cpu_class_get_model_id(cc); } qemu_printf("x86 %-20s %-48s\n", name, desc); g_free(name); + g_free(desc); + g_free(alias_of); } /* list available CPU models and flags */ @@ -3871,6 +3705,14 @@ static void x86_cpu_definition_entry(gpointer data, gpointer user_data) info->migration_safe = cc->migration_safe; info->has_migration_safe = true; info->q_static = cc->static_model; + /* + * Old machine types won't report aliases, so that alias translation + * doesn't break compatibility with previous QEMU versions. + */ + if (default_cpu_version != CPU_VERSION_LEGACY) { + info->alias_of = x86_cpu_class_get_alias_of(cc); + info->has_alias_of = !!info->alias_of; + } entry = g_malloc0(sizeof(*entry)); entry->value = info; @@ -3944,10 +3786,40 @@ static void x86_cpu_apply_props(X86CPU *cpu, PropValue *props) } } +/* Apply properties for the CPU model version specified in model */ +static void x86_cpu_apply_version_props(X86CPU *cpu, X86CPUModel *model) +{ + const X86CPUVersionDefinition *vdef; + X86CPUVersion version = x86_cpu_model_resolve_version(model); + + if (version == CPU_VERSION_LEGACY) { + return; + } + + for (vdef = x86_cpu_def_get_versions(model->cpudef); vdef->version; vdef++) { + PropValue *p; + + for (p = vdef->props; p && p->prop; p++) { + object_property_parse(OBJECT(cpu), p->value, p->prop, + &error_abort); + } + + if (vdef->version == version) { + break; + } + } + + /* + * If we reached the end of the list, version number was invalid + */ + assert(vdef->version == version); +} + /* Load data from X86CPUDefinition into a X86CPU object */ -static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp) +static void x86_cpu_load_model(X86CPU *cpu, X86CPUModel *model, Error **errp) { + X86CPUDefinition *def = model->cpudef; CPUX86State *env = &cpu->env; const char *vendor; char host_vendor[CPUID_VENDOR_SZ + 1]; @@ -4004,11 +3876,12 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp) object_property_set_str(OBJECT(cpu), vendor, "vendor", errp); + x86_cpu_apply_version_props(cpu, model); } #ifndef CONFIG_USER_ONLY /* Return a QDict containing keys for all properties that can be included - * in static expansion of CPU models. All properties set by x86_cpu_load_def() + * in static expansion of CPU models. All properties set by x86_cpu_load_model() * must be included in the dictionary. */ static QDict *x86_cpu_static_props(void) @@ -4222,23 +4095,33 @@ static gchar *x86_gdb_arch_name(CPUState *cs) static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data) { - X86CPUDefinition *cpudef = data; + X86CPUModel *model = data; X86CPUClass *xcc = X86_CPU_CLASS(oc); - xcc->cpu_def = cpudef; + xcc->model = model; xcc->migration_safe = true; } -static void x86_register_cpudef_type(X86CPUDefinition *def) +static void x86_register_cpu_model_type(const char *name, X86CPUModel *model) { - char *typename = x86_cpu_type_name(def->name); + char *typename = x86_cpu_type_name(name); TypeInfo ti = { .name = typename, .parent = TYPE_X86_CPU, .class_init = x86_cpu_cpudef_class_init, - .class_data = def, + .class_data = model, }; + type_register(&ti); + g_free(typename); +} + +static void x86_register_cpudef_types(X86CPUDefinition *def) +{ + X86CPUModel *m; + const X86CPUVersionDefinition *vdef; + char *name; + /* AMD aliases are handled at runtime based on CPUID vendor, so * they shouldn't be set on the CPU model table. */ @@ -4246,9 +4129,32 @@ static void x86_register_cpudef_type(X86CPUDefinition *def) /* catch mistakes instead of silently truncating model_id when too long */ assert(def->model_id && strlen(def->model_id) <= 48); + /* Unversioned model: */ + m = g_new0(X86CPUModel, 1); + m->cpudef = def; + m->version = CPU_VERSION_AUTO; + m->is_alias = true; + x86_register_cpu_model_type(def->name, m); + + /* Versioned models: */ + + for (vdef = x86_cpu_def_get_versions(def); vdef->version; vdef++) { + X86CPUModel *m = g_new0(X86CPUModel, 1); + m->cpudef = def; + m->version = vdef->version; + name = x86_cpu_versioned_model_name(def, vdef->version); + x86_register_cpu_model_type(name, m); + g_free(name); + + if (vdef->alias) { + X86CPUModel *am = g_new0(X86CPUModel, 1); + am->cpudef = def; + am->version = vdef->version; + am->is_alias = true; + x86_register_cpu_model_type(vdef->alias, am); + } + } - type_register(&ti); - g_free(typename); } #if !defined(CONFIG_USER_ONLY) @@ -4266,7 +4172,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, { X86CPU *cpu = env_archcpu(env); CPUState *cs = env_cpu(env); - uint32_t pkg_offset; + uint32_t die_offset; uint32_t limit; uint32_t signature[3]; @@ -4355,10 +4261,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, eax, ebx, ecx, edx); break; case 3: /* L3 cache info */ - pkg_offset = apicid_pkg_offset(cs->nr_cores, cs->nr_threads); + die_offset = apicid_die_offset(env->nr_dies, + cs->nr_cores, cs->nr_threads); if (cpu->enable_l3_cache) { encode_cache_cpuid4(env->cache_info_cpuid4.l3_cache, - (1 << pkg_offset), cs->nr_cores, + (1 << die_offset), cs->nr_cores, eax, ebx, ecx, edx); break; } @@ -4440,12 +4347,14 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, switch (count) { case 0: - *eax = apicid_core_offset(cs->nr_cores, cs->nr_threads); + *eax = apicid_core_offset(env->nr_dies, + cs->nr_cores, cs->nr_threads); *ebx = cs->nr_threads; *ecx |= CPUID_TOPOLOGY_LEVEL_SMT; break; case 1: - *eax = apicid_pkg_offset(cs->nr_cores, cs->nr_threads); + *eax = apicid_pkg_offset(env->nr_dies, + cs->nr_cores, cs->nr_threads); *ebx = cs->nr_cores * cs->nr_threads; *ecx |= CPUID_TOPOLOGY_LEVEL_CORE; break; @@ -4458,6 +4367,42 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, assert(!(*eax & ~0x1f)); *ebx &= 0xffff; /* The count doesn't need to be reliable. */ break; + case 0x1F: + /* V2 Extended Topology Enumeration Leaf */ + if (env->nr_dies < 2) { + *eax = *ebx = *ecx = *edx = 0; + break; + } + + *ecx = count & 0xff; + *edx = cpu->apic_id; + switch (count) { + case 0: + *eax = apicid_core_offset(env->nr_dies, cs->nr_cores, + cs->nr_threads); + *ebx = cs->nr_threads; + *ecx |= CPUID_TOPOLOGY_LEVEL_SMT; + break; + case 1: + *eax = apicid_die_offset(env->nr_dies, cs->nr_cores, + cs->nr_threads); + *ebx = cs->nr_cores * cs->nr_threads; + *ecx |= CPUID_TOPOLOGY_LEVEL_CORE; + break; + case 2: + *eax = apicid_pkg_offset(env->nr_dies, cs->nr_cores, + cs->nr_threads); + *ebx = env->nr_dies * cs->nr_cores * cs->nr_threads; + *ecx |= CPUID_TOPOLOGY_LEVEL_DIE; + break; + default: + *eax = 0; + *ebx = 0; + *ecx |= CPUID_TOPOLOGY_LEVEL_INVALID; + } + assert(!(*eax & ~0x1f)); + *ebx &= 0xffff; /* The count doesn't need to be reliable. */ + break; case 0xD: { /* Processor Extended State */ *eax = 0; @@ -5035,7 +4980,7 @@ static void x86_cpu_enable_xsave_components(X86CPU *cpu) * involved in setting up CPUID data are: * * 1) Loading CPU model definition (X86CPUDefinition). This is - * implemented by x86_cpu_load_def() and should be completely + * implemented by x86_cpu_load_model() and should be completely * transparent, as it is done automatically by instance_init. * No code should need to look at X86CPUDefinition structs * outside instance_init. @@ -5136,6 +5081,11 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp) x86_cpu_adjust_level(cpu, &cpu->env.cpuid_min_level, 0x14); } + /* CPU topology with multi-dies support requires CPUID[0x1F] */ + if (env->nr_dies > 1) { + x86_cpu_adjust_level(cpu, &env->cpuid_min_level, 0x1F); + } + /* SVM requires CPUID[0x8000000A] */ if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) { x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000000A); @@ -5180,8 +5130,11 @@ static int x86_cpu_filter_features(X86CPU *cpu) uint32_t host_feat = x86_cpu_get_supported_feature_word(w, false); uint32_t requested_features = env->features[w]; - env->features[w] &= host_feat; - cpu->filtered_features[w] = requested_features & ~env->features[w]; + uint32_t available_features = requested_features & host_feat; + if (!cpu->force_features) { + env->features[w] = available_features; + } + cpu->filtered_features[w] = requested_features & ~available_features; if (cpu->filtered_features[w]) { rv = 1; } @@ -5289,15 +5242,6 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) uint32_t host_phys_bits = x86_host_phys_bits(); static bool warned; - if (cpu->host_phys_bits) { - /* The user asked for us to use the host physical bits */ - cpu->phys_bits = host_phys_bits; - if (cpu->host_phys_bits_limit && - cpu->phys_bits > cpu->host_phys_bits_limit) { - cpu->phys_bits = cpu->host_phys_bits_limit; - } - } - /* Print a warning if the user set it to a value that's not the * host value. */ @@ -5309,6 +5253,15 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) warned = true; } + if (cpu->host_phys_bits) { + /* The user asked for us to use the host physical bits */ + cpu->phys_bits = host_phys_bits; + if (cpu->host_phys_bits_limit && + cpu->phys_bits > cpu->host_phys_bits_limit) { + cpu->phys_bits = cpu->host_phys_bits_limit; + } + } + if (cpu->phys_bits && (cpu->phys_bits > TARGET_PHYS_ADDR_SPACE_BITS || cpu->phys_bits < 32)) { @@ -5349,7 +5302,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) /* Cache information initialization */ if (!cpu->legacy_cache) { - if (!xcc->cpu_def || !xcc->cpu_def->cache_info) { + if (!xcc->model || !xcc->model->cpudef->cache_info) { char *name = x86_cpu_class_get_model_name(xcc); error_setg(errp, "CPU model '%s' doesn't support legacy-cache=off", name); @@ -5357,7 +5310,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) return; } env->cache_info_cpuid2 = env->cache_info_cpuid4 = env->cache_info_amd = - *xcc->cpu_def->cache_info; + *xcc->model->cpudef->cache_info; } else { /* Build legacy cache information */ env->cache_info_cpuid2.l1d_cache = &legacy_l1d_cache; @@ -5384,9 +5337,10 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) } #ifndef CONFIG_USER_ONLY + MachineState *ms = MACHINE(qdev_get_machine()); qemu_register_reset(x86_cpu_machine_reset_cb, cpu); - if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) { + if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || ms->smp.cpus > 1) { x86_cpu_apic_create(cpu, &local_err); if (local_err != NULL) { goto out; @@ -5637,6 +5591,7 @@ static void x86_cpu_initfn(Object *obj) CPUX86State *env = &cpu->env; FeatureWord w; + env->nr_dies = 1; cpu_set_cpustate_pointers(cpu); object_property_add(obj, "family", "int", @@ -5676,8 +5631,6 @@ static void x86_cpu_initfn(Object *obj) object_property_add(obj, "crash-information", "GuestPanicInformation", x86_cpu_get_crash_info_qom, NULL, NULL, NULL, NULL); - cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY; - for (w = 0; w < FEATURE_WORDS; w++) { int bitnr; @@ -5716,8 +5669,8 @@ static void x86_cpu_initfn(Object *obj) object_property_add_alias(obj, "sse4_1", obj, "sse4.1", &error_abort); object_property_add_alias(obj, "sse4_2", obj, "sse4.2", &error_abort); - if (xcc->cpu_def) { - x86_cpu_load_def(cpu, xcc->cpu_def, &error_abort); + if (xcc->model) { + x86_cpu_load_model(cpu, xcc->model, &error_abort); } } @@ -5862,17 +5815,20 @@ static Property x86_cpu_properties[] = { DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, 0), DEFINE_PROP_INT32("thread-id", X86CPU, thread_id, 0), DEFINE_PROP_INT32("core-id", X86CPU, core_id, 0), + DEFINE_PROP_INT32("die-id", X86CPU, die_id, 0), DEFINE_PROP_INT32("socket-id", X86CPU, socket_id, 0), #else DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, UNASSIGNED_APIC_ID), DEFINE_PROP_INT32("thread-id", X86CPU, thread_id, -1), DEFINE_PROP_INT32("core-id", X86CPU, core_id, -1), + DEFINE_PROP_INT32("die-id", X86CPU, die_id, -1), DEFINE_PROP_INT32("socket-id", X86CPU, socket_id, -1), #endif DEFINE_PROP_INT32("node-id", X86CPU, node_id, CPU_UNSET_NUMA_NODE_ID), DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false), - { .name = "hv-spinlocks", .info = &qdev_prop_spinlocks }, + DEFINE_PROP_UINT32("hv-spinlocks", X86CPU, hyperv_spinlock_attempts, + HYPERV_SPINLOCK_NEVER_RETRY), DEFINE_PROP_BIT64("hv-relaxed", X86CPU, hyperv_features, HYPERV_FEAT_RELAXED, 0), DEFINE_PROP_BIT64("hv-vapic", X86CPU, hyperv_features, @@ -5907,6 +5863,7 @@ static Property x86_cpu_properties[] = { DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true), DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false), + DEFINE_PROP_BOOL("x-force-features", X86CPU, force_features, false), DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true), DEFINE_PROP_UINT32("phys-bits", X86CPU, phys_bits, 0), DEFINE_PROP_BOOL("host-phys-bits", X86CPU, host_phys_bits, false), @@ -6052,7 +6009,7 @@ static void x86_cpu_register_types(void) type_register_static(&x86_cpu_type_info); for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) { - x86_register_cpudef_type(&builtin_x86_defs[i]); + x86_register_cpudef_types(&builtin_x86_defs[i]); } type_register_static(&max_x86_cpu_type_info); type_register_static(&x86_base_cpu_type_info); diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 9334579..05393cf 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -736,6 +736,7 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS]; #define CPUID_TOPOLOGY_LEVEL_INVALID (0U << 8) #define CPUID_TOPOLOGY_LEVEL_SMT (1U << 8) #define CPUID_TOPOLOGY_LEVEL_CORE (2U << 8) +#define CPUID_TOPOLOGY_LEVEL_DIE (5U << 8) /* MSR Feature Bits */ #define MSR_ARCH_CAP_RDCL_NO (1U << 0) @@ -1385,6 +1386,8 @@ typedef struct CPUX86State { uint64_t xss; TPRAccess tpr_access_type; + + unsigned nr_dies; } CPUX86State; struct kvm_msrs; @@ -1406,7 +1409,7 @@ struct X86CPU { CPUNegativeOffsetState neg; CPUX86State env; - int hyperv_spinlock_attempts; + uint32_t hyperv_spinlock_attempts; char *hyperv_vendor_id; bool hyperv_synic_kvm_only; uint64_t hyperv_features; @@ -1414,6 +1417,12 @@ struct X86CPU { bool check_cpuid; bool enforce_cpuid; + /* + * Force features to be enabled even if the host doesn't support them. + * This is dangerous and should be done only for testing CPUID + * compatibility. + */ + bool force_features; bool expose_kvm; bool expose_tcg; bool migratable; @@ -1438,7 +1447,7 @@ struct X86CPU { } mwait; /* Features that were filtered out because of missing host capabilities */ - uint32_t filtered_features[FEATURE_WORDS]; + FeatureWordArray filtered_features; /* Enable PMU CPUID bits. This can't be enabled by default yet because * it doesn't have ABI stability guarantees, as it passes all PMU CPUID @@ -1498,6 +1507,7 @@ struct X86CPU { int32_t node_id; /* NUMA node this CPU belongs to */ int32_t socket_id; + int32_t die_id; int32_t core_id; int32_t thread_id; @@ -1919,6 +1929,28 @@ void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip, */ void x86_cpu_change_kvm_default(const char *prop, const char *value); +/* Special values for X86CPUVersion: */ + +/* Resolve to latest CPU version */ +#define CPU_VERSION_LATEST -1 + +/* + * Resolve to version defined by current machine type. + * See x86_cpu_set_default_version() + */ +#define CPU_VERSION_AUTO -2 + +/* Don't resolve to any versioned CPU models, like old QEMU versions */ +#define CPU_VERSION_LEGACY 0 + +typedef int X86CPUVersion; + +/* + * Set default CPU model version for CPU models having + * version == CPU_VERSION_AUTO. + */ +void x86_cpu_set_default_version(X86CPUVersion version); + /* Return name of 32-bit register, from a R_* constant */ const char *get_register_name_32(unsigned int reg); diff --git a/target/i386/kvm.c b/target/i386/kvm.c index e4b4f57..473a17e 100644 --- a/target/i386/kvm.c +++ b/target/i386/kvm.c @@ -1451,6 +1451,10 @@ int kvm_arch_init_vcpu(CPUState *cs) } break; } + case 0x1f: + if (env->nr_dies < 2) { + break; + } case 4: case 0xb: case 0xd: @@ -1458,6 +1462,11 @@ int kvm_arch_init_vcpu(CPUState *cs) if (i == 0xd && j == 64) { break; } + + if (i == 0x1f && j == 64) { + break; + } + c->function = i; c->flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX; c->index = j; @@ -1469,6 +1478,9 @@ int kvm_arch_init_vcpu(CPUState *cs) if (i == 0xb && !(c->ecx & 0xff00)) { break; } + if (i == 0x1f && !(c->ecx & 0xff00)) { + break; + } if (i == 0xd && c->eax == 0) { continue; } diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c index 8f11cb8..1053409 100644 --- a/target/openrisc/sys_helper.c +++ b/target/openrisc/sys_helper.c @@ -24,6 +24,9 @@ #include "exec/helper-proto.h" #include "exception.h" #include "sysemu/sysemu.h" +#ifndef CONFIG_USER_ONLY +#include "hw/boards.h" +#endif #define TO_SPR(group, number) (((group) << 11) + (number)) @@ -194,6 +197,7 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, target_ulong spr) { #ifndef CONFIG_USER_ONLY + MachineState *ms = MACHINE(qdev_get_machine()); OpenRISCCPU *cpu = env_archcpu(env); CPUState *cs = env_cpu(env); int idx; @@ -241,7 +245,7 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, return cpu->parent_obj.cpu_index; case TO_SPR(0, 129): /* NUMCORES */ - return max_cpus; + return ms->smp.max_cpus; case TO_SPR(0, 1024) ... TO_SPR(0, 1024 + (16 * 32)): /* Shadow GPRs */ idx = (spr - 1024); diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index 8540e7a..736a790 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -37,6 +37,7 @@ #include "hw/qdev-properties.h" #ifndef CONFIG_USER_ONLY #include "hw/hw.h" +#include "hw/boards.h" #include "sysemu/arch_init.h" #include "sysemu/sysemu.h" #include "sysemu/tcg.h" @@ -197,6 +198,8 @@ static void s390_cpu_realizefn(DeviceState *dev, Error **errp) } #if !defined(CONFIG_USER_ONLY) + MachineState *ms = MACHINE(qdev_get_machine()); + unsigned int max_cpus = ms->smp.max_cpus; if (cpu->env.core_id >= max_cpus) { error_setg(&err, "Unable to add CPU with core-id: %" PRIu32 ", maximum core-id: %d", cpu->env.core_id, diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c index 202456c..892f659 100644 --- a/target/s390x/excp_helper.c +++ b/target/s390x/excp_helper.c @@ -31,6 +31,7 @@ #ifndef CONFIG_USER_ONLY #include "sysemu/sysemu.h" #include "hw/s390x/s390_flic.h" +#include "hw/boards.h" #endif void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env, uint32_t code, @@ -315,6 +316,10 @@ static void do_ext_interrupt(CPUS390XState *env) g_assert(cpu_addr < S390_MAX_CPUS); lowcore->cpu_addr = cpu_to_be16(cpu_addr); clear_bit(cpu_addr, env->emergency_signals); +#ifndef CONFIG_USER_ONLY + MachineState *ms = MACHINE(qdev_get_machine()); + unsigned int max_cpus = ms->smp.max_cpus; +#endif if (bitmap_empty(env->emergency_signals, max_cpus)) { env->pending_int &= ~INTERRUPT_EMERGENCY_SIGNAL; } diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c index 0267c6c..6e814c2 100644 --- a/target/s390x/kvm.c +++ b/target/s390x/kvm.c @@ -119,8 +119,8 @@ * Needs to be big enough to contain max_cpus emergency signals * and in addition NR_LOCAL_IRQS interrupts */ -#define VCPU_IRQ_BUF_SIZE (sizeof(struct kvm_s390_irq) * \ - (max_cpus + NR_LOCAL_IRQS)) +#define VCPU_IRQ_BUF_SIZE(max_cpus) (sizeof(struct kvm_s390_irq) * \ + (max_cpus + NR_LOCAL_IRQS)) static CPUWatchpoint hw_watchpoint; /* @@ -362,9 +362,10 @@ unsigned long kvm_arch_vcpu_id(CPUState *cpu) int kvm_arch_init_vcpu(CPUState *cs) { + unsigned int max_cpus = MACHINE(qdev_get_machine())->smp.max_cpus; S390CPU *cpu = S390_CPU(cs); kvm_s390_set_cpu_state(cpu, cpu->env.cpu_state); - cpu->irqstate = g_malloc0(VCPU_IRQ_BUF_SIZE); + cpu->irqstate = g_malloc0(VCPU_IRQ_BUF_SIZE(max_cpus)); return 0; } @@ -1950,9 +1951,10 @@ int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state) void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu) { + unsigned int max_cpus = MACHINE(qdev_get_machine())->smp.max_cpus; struct kvm_s390_irq_state irq_state = { .buf = (uint64_t) cpu->irqstate, - .len = VCPU_IRQ_BUF_SIZE, + .len = VCPU_IRQ_BUF_SIZE(max_cpus), }; CPUState *cs = CPU(cpu); int32_t bytes; |