@@ -920,6 +920,22 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
.tcg_features = 0,
.unmigratable_flags = 0,
},
+ [FEAT_8000_0021_EAX] = {
+ .type = CPUID_FEATURE_WORD,
+ .feat_names = {
+ "no-nested-data-bp", NULL, "lfence-always-serializing", NULL,
+ NULL, NULL, "null-sel-clr-base", 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,
+ },
+ .cpuid = { .eax = 0x80000021, .reg = R_EAX, },
+ .tcg_features = 0,
+ .unmigratable_flags = 0,
+ },
[FEAT_XSAVE] = {
.type = CPUID_FEATURE_WORD,
.feat_names = {
@@ -6136,6 +6152,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*ebx |= sev_get_reduced_phys_bits() << 6;
}
break;
+ case 0x80000021:
+ *eax = env->features[FEAT_8000_0021_EAX];
+ *ebx = *ecx = *edx = 0;
+ break;
default:
/* reserved values: zero */
*eax = 0;
@@ -6565,6 +6585,10 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000001F);
}
+ if (env->features[FEAT_8000_0021_EAX]) {
+ x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x80000021);
+ }
+
/* SGX requires CPUID[0x12] for EPC enumeration */
if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SGX) {
x86_cpu_adjust_level(cpu, &env->cpuid_min_level, 0x12);
@@ -600,6 +600,7 @@ typedef enum FeatureWord {
FEAT_8000_0001_ECX, /* CPUID[8000_0001].ECX */
FEAT_8000_0007_EDX, /* CPUID[8000_0007].EDX */
FEAT_8000_0008_EBX, /* CPUID[8000_0008].EBX */
+ FEAT_8000_0021_EAX, /* CPUID[8000_0021].EAX */
FEAT_C000_0001_EDX, /* CPUID[C000_0001].EDX */
FEAT_KVM, /* CPUID[4000_0001].EAX (KVM_CPUID_FEATURES) */
FEAT_KVM_HINTS, /* CPUID[4000_0001].EDX */
@@ -939,6 +940,13 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
/* Predictive Store Forwarding Disable */
#define CPUID_8000_0008_EBX_AMD_PSFD (1U << 28)
+/* Processor ignores nested data breakpoints */
+#define CPUID_8000_0021_EAX_No_NESTED_DATA_BP (1U << 0)
+/* LFENCE is always serializing */
+#define CPUID_8000_0021_EAX_LFENCE_ALWAYS_SERIALIZING (1U << 2)
+/* Null Selector Clears Base */
+#define CPUID_8000_0021_EAX_NULL_SEL_CLR_BASE (1U << 6)
+
#define CPUID_XSAVE_XSAVEOPT (1U << 0)
#define CPUID_XSAVE_XSAVEC (1U << 1)
#define CPUID_XSAVE_XGETBV1 (1U << 2)