Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
xen.6712
5a6b36cd-1-x86-cpuid-handling-of-IBRS-IBPB-STIB...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 5a6b36cd-1-x86-cpuid-handling-of-IBRS-IBPB-STIBP-and-IBRS-for-guests.patch of Package xen.6712
# Commit d297b56682e730d598e2529cc6998151d3b6f6f8 # Date 2018-01-26 14:10:21 +0000 # Author Andrew Cooper <andrew.cooper3@citrix.com> # Committer Andrew Cooper <andrew.cooper3@citrix.com> 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@citrix.com> Acked-by: Wei Liu <wei.liu2@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -4346,6 +4346,20 @@ void hvm_cpuid(unsigned int input, unsig /* 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. */ @@ -4400,6 +4414,11 @@ void hvm_cpuid(unsigned int input, unsig 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; } } --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -777,9 +777,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 ) { @@ -797,6 +798,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(curr->domain, 7, 0, &_eax, &_ebx, &_ecx, &_edx); + if ( _edx & cpufeat_mask(X86_FEATURE_IBRSB) ) + b |= cpufeat_mask(X86_FEATURE_IBPB); + break; } goto out; } @@ -857,6 +881,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) | @@ -866,9 +891,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: @@ -912,6 +946,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 0x00000005: /* MONITOR/MWAIT */ case 0x0000000a: /* Architectural Performance Monitor Features */ case 0x0000000b: /* Extended Topology Enumeration */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor