summary refs log tree commit diff stats
path: root/target-i386/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-i386/cpu.c')
-rw-r--r--target-i386/cpu.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index eee00d6bbd..ddae932ee1 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -361,7 +361,7 @@ static const char *cpuid_6_feature_name[] = {
           CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
           CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
           CPUID_7_0_EBX_RDSEED */
-#define TCG_7_0_ECX_FEATURES 0
+#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE)
 #define TCG_APM_FEATURES 0
 #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT
 #define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1)
@@ -2426,6 +2426,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
             *eax = 0; /* Maximum ECX value for sub-leaves */
             *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
             *ecx = env->features[FEAT_7_0_ECX]; /* Feature flags */
+            if ((*ecx & CPUID_7_0_ECX_PKU) && env->cr[4] & CR4_PKE_MASK) {
+                *ecx |= CPUID_7_0_ECX_OSPKE;
+            }
             *edx = 0; /* Reserved */
         } else {
             *eax = 0;
@@ -2733,9 +2736,13 @@ static void x86_cpu_reset(CPUState *s)
     if (env->features[FEAT_1_EDX] & CPUID_SSE) {
         xcr0 |= XSTATE_SSE_MASK;
     }
-    if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_MPX) {
-        xcr0 |= XSTATE_BNDREGS_MASK | XSTATE_BNDCSR_MASK;
+    for (i = 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
+        const ExtSaveArea *esa = &x86_ext_save_areas[i];
+        if ((env->features[esa->feature] & esa->bits) == esa->bits) {
+            xcr0 |= 1ull << i;
+        }
     }
+
     if (env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) {
         cr4 |= CR4_OSFXSR_MASK | CR4_OSXSAVE_MASK;
     }