[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen stable-4.6] x86/cpuid: Handling of IBRS/IBPB, STIBP and IBRS for guests



commit 4e1b9e98dffbc2f29a0a90a4ae43b9e19f323089
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Wed Feb 14 13:39:01 2018 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Wed Feb 14 13:39:01 2018 +0100

    x86/cpuid: Handling of IBRS/IBPB, STIBP and IBRS for guests
    
    Intel specifies IBRS/IBPB (combined, in a single bit) and STIBP as a 
separate
    bit.  AMD specifies IBPB alone in a 3rd bit.
    
    AMD's IBPB is a subset of Intel's combined IBRS/IBPB.  For performance
    reasons, administrators might wish to express "IBPB only" even on Intel
    hardware, so we allow the AMD bit to be used for this purpose.
    
    The behaviour of STIBP is more complicated.
    
    It is our current understanding that STIBP will be advertised on HT-capable
    hardware irrespective of whether HT is enabled, but not advertised on
    HT-incapable hardware.  However, for ease of virtualisation, STIBP's
    functionality is ignored rather than reserved by microcode/hardware on
    HT-incapable hardware.
    
    For guest safety, we treat STIBP as special, always override the toolstack
    choice, and always advertise STIBP if IBRS is available.  This removes the
    corner case where STIBP is not advertised, but the guest is running on
    HT-capable hardware where it does matter.
    
    Finally as a bugfix, update the libxc CPUID logic to understand the e8b
    feature leaf, which has the side effect of also offering CLZERO to guests on
    applicable hardware.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Acked-by: Wei Liu <wei.liu2@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
    master commit: d297b56682e730d598e2529cc6998151d3b6f6f8
    master date: 2018-01-26 14:10:21 +0000
---
 xen/arch/x86/hvm/hvm.c | 19 +++++++++++++++++++
 xen/arch/x86/traps.c   | 46 +++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 62 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 35e9449..8fe6fdc 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -4596,6 +4596,20 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, 
unsigned int *ebx,
         /* Don't expose INVPCID to non-hap hvm. */
         if ( (count == 0) && !hap_enabled(d) )
             *ebx &= ~cpufeat_mask(X86_FEATURE_INVPCID);
+
+        if ( count == 0 )
+        {
+            /*
+             * Override STIBP to match IBRS.  Guests can safely use STIBP
+             * functionality on non-HT hardware, but can't necesserily protect
+             * themselves from SP2/Spectre/Branch Target Injection if STIBP is
+             * hidden on HT-capable hardware.
+             */
+            if ( *edx & cpufeat_mask(X86_FEATURE_IBRSB) )
+                *edx |= cpufeat_mask(X86_FEATURE_STIBP);
+            else
+                *edx &= ~cpufeat_mask(X86_FEATURE_STIBP);
+        }
         break;
     case 0xb:
         /* Fix the x2APIC identifier. */
@@ -4650,6 +4664,11 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, 
unsigned int *ebx,
         hvm_cpuid(0x80000001, NULL, NULL, NULL, &_edx);
         *eax = (*eax & ~0xffff00) | (_edx & cpufeat_mask(X86_FEATURE_LM)
                                      ? 0x3000 : 0x2000);
+
+        /* AMD's IBPB is a subset of IBRS/IBPB. */
+        hvm_cpuid(7, NULL, &_ebx, NULL, NULL);
+        if ( _ebx & cpufeat_mask(X86_FEATURE_IBRSB) )
+            *ebx |= cpufeat_mask(X86_FEATURE_IBPB);
         break;
     }
 }
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index cd63a4d..b827f5d 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -843,9 +843,10 @@ void pv_cpuid(struct cpu_user_regs *regs)
 
         switch ( cpuid_leaf )
         {
+            unsigned int _eax, _ebx, _ecx, _edx;
+
         case XSTATE_CPUID:
         {
-            unsigned int _eax, _ebx, _ecx, _edx;
             /* EBX value of main leaf 0 depends on enabled xsave features */
             if ( sub_leaf == 0 && curr->arch.xcr0 )
             {
@@ -863,6 +864,29 @@ void pv_cpuid(struct cpu_user_regs *regs)
             }
             goto xstate;
         }
+
+        case 0x00000007:
+            if ( regs->_ecx == 0 )
+            {
+                /*
+                 * Override STIBP to match IBRS.  Guests can safely use STIBP
+                 * functionality on non-HT hardware, but can't necesserily 
protect
+                 * themselves from SP2/Spectre/Branch Target Injection if 
STIBP is
+                 * hidden on HT-capable hardware.
+                 */
+                if ( d & cpufeat_mask(X86_FEATURE_IBRSB) )
+                    d |= cpufeat_mask(X86_FEATURE_STIBP);
+                else
+                    d &= ~cpufeat_mask(X86_FEATURE_STIBP);
+            }
+            break;
+
+        case 0x80000008:
+            /* AMD's IBPB is a subset of IBRS/IBPB. */
+            domain_cpuid(currd, 7, 0, &_eax, &_ebx, &_ecx, &_edx);
+            if ( _edx & cpufeat_mask(X86_FEATURE_IBRSB) )
+                b |= cpufeat_mask(X86_FEATURE_IBPB);
+            break;
         }
         goto out;
     }
@@ -920,6 +944,7 @@ void pv_cpuid(struct cpu_user_regs *regs)
 
     case 0x00000007:
         if ( regs->_ecx == 0 )
+        {
             b &= (cpufeat_mask(X86_FEATURE_BMI1) |
                   cpufeat_mask(X86_FEATURE_HLE)  |
                   cpufeat_mask(X86_FEATURE_AVX2) |
@@ -929,9 +954,18 @@ void pv_cpuid(struct cpu_user_regs *regs)
                   cpufeat_mask(X86_FEATURE_RDSEED)  |
                   cpufeat_mask(X86_FEATURE_ADX)  |
                   cpufeat_mask(X86_FEATURE_FSGSBASE));
+
+            d &= cpufeat_mask(X86_FEATURE_IBRSB);
+
+            /* Override STIBP to match IBRS (see above). */
+            if ( d & cpufeat_mask(X86_FEATURE_IBRSB) )
+                d |= cpufeat_mask(X86_FEATURE_STIBP);
+            else
+                d &= ~cpufeat_mask(X86_FEATURE_STIBP);
+        }
         else
-            b = 0;
-        a = c = d = 0;
+            b = d = 0;
+        a = c = 0;
         break;
 
     case XSTATE_CPUID:
@@ -975,6 +1009,12 @@ void pv_cpuid(struct cpu_user_regs *regs)
         __clear_bit(X86_FEATURE_MWAITX % 32, &c);
         break;
 
+    case 0x80000008:
+        /* AMD's IBPB is a subset of IBRS/IBPB. */
+        if ( boot_cpu_has(X86_FEATURE_IBRSB) )
+            b |= cpufeat_mask(X86_FEATURE_IBPB);
+        break;
+
     case 0x0000000a: /* Architectural Performance Monitor Features (Intel) */
         break;
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.6

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.