x86: Fix "x86: further CPUID handling adjustments"
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 15 May 2018 15:37:59 +0000 (16:37 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 22 May 2018 17:41:33 +0000 (18:41 +0100)
c/s f9616884e (a backport of c/s 0d703a701 "x86/feature: Definitions for
Indirect Branch Controls") missed a CPUID adjustment when calculating the raw
featureset.  This impacts host administrator diagnostics.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
c/s 62b187969 "x86: further CPUID handling adjustments" make some adjustments.
However, it breaks levelling of guests, making it impossible for the toolstack
to hide STIBP or IBPB from guests on hardware with up-to-date microcode.

The dom0 issue referenced in the commit message was fixed by the hunk
adjusting the zeroing alone.  STIBP and IBPB don't need (and indeed, must not
be for levelling purposes) OR'd into the leaf.

One final item which was missed in backport was the need to ignore the
toolstack choice of STIBP, and set it equal to IBRSB.  This needs doing after
the mask has been applied.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Gbp-Pq: Name x86-fix-x86-further-cpuid-handling-adjus.patch

xen/arch/x86/hvm/hvm.c
xen/arch/x86/traps.c

index 4ffa30c1cc8cb4dacc190514b1b2ec63ac4fffac..7c88023c35c6926c267b7718dfed2602b345b592 100644 (file)
@@ -3586,10 +3586,13 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
                      special_features[FEATURESET_7b0]);
 
             *ecx &= hvm_featureset[FEATURESET_7c0];
-
-            *edx |= cpufeat_mask(X86_FEATURE_STIBP);
             *edx &= hvm_featureset[FEATURESET_7d0];
 
+            /* Force STIBP equal to IBRSB */
+            *edx &= ~cpufeat_mask(X86_FEATURE_STIBP);
+            if ( *edx & cpufeat_mask(X86_FEATURE_IBRSB) )
+                *edx |= cpufeat_mask(X86_FEATURE_STIBP);
+
             /* Don't expose HAP-only features to non-hap guests. */
             if ( !hap_enabled(d) )
             {
@@ -3761,7 +3764,6 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
         hvm_cpuid(0x80000001, NULL, NULL, NULL, &_edx);
         *eax |= (_edx & cpufeat_mask(X86_FEATURE_LM) ? vaddr_bits : 32) << 8;
 
-        *ebx |= cpufeat_mask(X86_FEATURE_IBPB);
         *ebx &= hvm_featureset[FEATURESET_e8b];
         break;
     }
index 508c18e1fd290fdd9fc2c1dd57d2c13e0198704e..4a0ad5dc73ba9a19f891b92c0bc4391fe8805c40 100644 (file)
@@ -1155,10 +1155,13 @@ void pv_cpuid(struct cpu_user_regs *regs)
                   special_features[FEATURESET_7b0]);
 
             c &= pv_featureset[FEATURESET_7c0];
-
-            d |= cpufeat_mask(X86_FEATURE_STIBP);
             d &= pv_featureset[FEATURESET_7d0];
 
+            /* Force STIBP equal to IBRSB */
+            d &= ~cpufeat_mask(X86_FEATURE_STIBP);
+            if ( d & cpufeat_mask(X86_FEATURE_IBRSB) )
+                d |= cpufeat_mask(X86_FEATURE_STIBP);
+
             if ( !is_pvh_domain(currd) )
             {
                 /*
@@ -1271,7 +1274,6 @@ void pv_cpuid(struct cpu_user_regs *regs)
 
     case 0x80000008:
         a = paddr_bits | (vaddr_bits << 8);
-        b |= cpufeat_mask(X86_FEATURE_IBPB);
         b &= pv_featureset[FEATURESET_e8b];
         break;