From 5e9ea14b7ebc8e4a619c51b1f1daa11b224798fe Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 14 Feb 2018 15:46:12 -0500 Subject: [PATCH] target-i386: add feature flags for CPUID[EAX=0xd,ECX=1] These represent xsave-related capabilities of the processor, and KVM may or may not support them. Add feature bits so that they are considered by "-cpu ...,enforce", and use the new feature work instead of calling kvm_arch_get_supported_cpuid. Bit 3 (XSAVES) is not migratables because it requires saving MSR_IA32_XSS. Neither KVM nor any commonly available hardware supports it anyway. Backports commit 0bb0b2d2fe7f645ddaf1f0ff40ac669c9feb4aa1 from qemu also backports 18cd2c17b5370369a886155c001da0a7f54bbcca --- qemu/target-i386/cpu.c | 58 ++++++++++++++++++++++++++++++++++++++++++ qemu/target-i386/cpu.h | 8 ++++++ 2 files changed, 66 insertions(+) diff --git a/qemu/target-i386/cpu.c b/qemu/target-i386/cpu.c index ebbbff78..baa37ba2 100644 --- a/qemu/target-i386/cpu.c +++ b/qemu/target-i386/cpu.c @@ -241,6 +241,18 @@ static const char *cpuid_apm_edx_feature_name[] = { NULL, NULL, NULL, NULL, }; +static const char *cpuid_xsave_feature_name[] = { + "xsaveopt", "xsavec", "xgetbv1", "xsaves", + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +}; + + #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE) #define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \ CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC) @@ -371,6 +383,15 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { {0}, // FEAT_SVM {0}, + // FEAT_XSAVE + { + cpuid_xsave_feature_name, + 0xd, + true,1, + R_EAX, + 0, + 0, + }, #else [FEAT_1_EDX] = { .feat_names = feature_name, @@ -411,6 +432,13 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { .tcg_features = TCG_APM_FEATURES, .unmigratable_flags = CPUID_APM_INVTSC, }, + [FEAT_XSAVE] = { + .feat_names = cpuid_xsave_feature_name, + .cpuid_eax = 0xd, + .cpuid_needs_ecx = true, .cpuid_ecx = 1, + .cpuid_reg = R_EAX, + .tcg_features = 0, + }, #endif }; @@ -985,6 +1013,16 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT2_SYSCALL, // FEAT_8000_0001_ECX CPUID_EXT3_LAHF_LM, + // FEAT_8000_0007_EDX + 0, + // FEAT_C000_0001_EDX + 0, + // FEAT_KVM + 0, + // FEAT_SVM + 0, + // FEAT_XSAVE + CPUID_XSAVE_XSAVEOPT, }, "Intel Xeon E312xx (Sandy Bridge)", }, @@ -1017,6 +1055,16 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT2_SYSCALL, // FEAT_8000_0001_ECX CPUID_EXT3_LAHF_LM, + // FEAT_8000_0007_EDX + 0, + // FEAT_C000_0001_EDX + 0, + // FEAT_KVM + 0, + // FEAT_SVM + 0, + // FEAT_XSAVE + CPUID_XSAVE_XSAVEOPT, }, "Intel Core Processor (Haswell)", }, @@ -1050,6 +1098,16 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT2_SYSCALL, // FEAT_8000_0001_ECX CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH, + // FEAT_8000_0007_EDX + 0, + // FEAT_C000_0001_EDX + 0, + // FEAT_KVM + 0, + // FEAT_SVM + 0, + // FEAT_XSAVE + CPUID_XSAVE_XSAVEOPT, }, "Intel Core Processor (Broadwell)", }, diff --git a/qemu/target-i386/cpu.h b/qemu/target-i386/cpu.h index c8d5e87d..310ad0cf 100644 --- a/qemu/target-i386/cpu.h +++ b/qemu/target-i386/cpu.h @@ -390,6 +390,7 @@ #define MSR_VM_HSAVE_PA 0xc0010117 #define MSR_IA32_BNDCFGS 0x00000d90 +#define MSR_IA32_XSS 0x00000da0 #define XSTATE_FP (1ULL << 0) #define XSTATE_SSE (1ULL << 1) @@ -412,6 +413,7 @@ typedef enum FeatureWord { FEAT_C000_0001_EDX, /* CPUID[C000_0001].EDX */ FEAT_KVM, /* CPUID[4000_0001].EAX (KVM_CPUID_FEATURES) */ FEAT_SVM, /* CPUID[8000_000A].EDX */ + FEAT_XSAVE, /* CPUID[EAX=0xd,ECX=1].EAX */ FEATURE_WORDS, } FeatureWord; @@ -572,6 +574,11 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS]; #define CPUID_7_0_EBX_AVX512ER (1U << 27) /* AVX-512 Exponential and Reciprocal */ #define CPUID_7_0_EBX_AVX512CD (1U << 28) /* AVX-512 Conflict Detection */ +#define CPUID_XSAVE_XSAVEOPT (1U << 0) +#define CPUID_XSAVE_XSAVEC (1U << 1) +#define CPUID_XSAVE_XGETBV1 (1U << 2) +#define CPUID_XSAVE_XSAVES (1U << 3) + /* CPUID[0x80000007].EDX flags: */ #define CPUID_APM_INVTSC (1U << 8) @@ -970,6 +977,7 @@ typedef struct CPUX86State { uint64_t xstate_bv; uint64_t xcr0; + uint64_t xss; TPRAccess tpr_access_type;