diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc index 9cbbffc818..2dad1edd59 100644 --- a/docs/misc/xen-command-line.pandoc +++ b/docs/misc/xen-command-line.pandoc @@ -2187,7 +2187,7 @@ By default SSBD will be mitigated at runtime (i.e `ssbd=runtime`). ### spec-ctrl (x86) > `= List of [ , xen=, {pv,hvm}=, > {msr-sc,rsb,verw,{ibpb,bhb}-entry}=|{pv,hvm}=, -> bti-thunk=retpoline|lfence|jmp,bhb-seq=short|tsx, +> bti-thunk=retpoline|lfence|jmp,bhb-seq=short|tsx|long, > {ibrs,ibpb,ssbd,psfd, > eager-fpu,l1d-flush,branch-harden,srb-lock, > unpriv-mmio,gds-mit,div-scrub,lock-harden, @@ -2259,7 +2259,7 @@ On all hardware, `bhb-seq=` can be used to select which of the BHB-clearing sequences gets used. This interacts with the `bhb-entry=` and `bhi-dis-s=` options in order to mitigate Branch History Injection on affected hardware. The default sequence is `short`, with `tsx` as an alternative available -capable hardware that can be opted in to. +capable hardware, and `long` that can be opted in to. On hardware supporting IBRS (Indirect Branch Restricted Speculation), the `ibrs=` option can be used to force or prevent Xen using the feature itself. diff --git a/xen/arch/x86/bhb-thunk.S b/xen/arch/x86/bhb-thunk.S index f52cfb9bc2..7e866784f7 100644 --- a/xen/arch/x86/bhb-thunk.S +++ b/xen/arch/x86/bhb-thunk.S @@ -56,9 +56,13 @@ ENTRY(clear_bhb_tsx) * * The "short" sequence (5 and 5) is for CPUs prior to Alder Lake / Sapphire * Rapids (i.e. Cores prior to Golden Cove and/or Gracemont). + * + * The "long" sequence (12 and 7) is for Alder Lake / Sapphire Rapids + * (i.e. Golden Cove and/or Gracemont cores). However, such CPUs are expected + * to use BHI_DIS_S in preference. */ ENTRY(clear_bhb_loops) - mov $5, %ecx + ALTERNATIVE "mov $5, %ecx", "mov $12, %ecx", X86_SPEC_BHB_LOOPS_LONG call 1f jmp 5f @@ -70,7 +74,7 @@ ENTRY(clear_bhb_loops) int3 .align 64 -2: mov $5, %eax +2: ALTERNATIVE "mov $5, %eax", "mov $7, %eax", X86_SPEC_BHB_LOOPS_LONG 3: jmp 4f int3 diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c index 555d86882e..6ce2815746 100644 --- a/xen/arch/x86/spec_ctrl.c +++ b/xen/arch/x86/spec_ctrl.c @@ -52,6 +52,7 @@ static enum bhb_thunk { BHB_NONE, BHB_TSX, BHB_SHORT, + BHB_LONG, } opt_bhb_seq __initdata; /* Cmdline controls for Xen's speculative settings. */ @@ -313,6 +314,8 @@ static int __init parse_spec_ctrl(const char *s) opt_bhb_seq = BHB_TSX; else if ( !cmdline_strcmp(s, "short") ) opt_bhb_seq = BHB_SHORT; + else if ( !cmdline_strcmp(s, "long") ) + opt_bhb_seq = BHB_LONG; else rc = -EINVAL; } @@ -570,7 +573,8 @@ static void __init print_details(enum ind_thunk thunk) opt_bhb_seq != BHB_NONE ? "BHB-Seq: " : "", opt_bhb_seq == BHB_NONE ? "" : opt_bhb_seq == BHB_TSX ? "TSX, " : - opt_bhb_seq == BHB_SHORT ? "SHORT, " : "?, ", + opt_bhb_seq == BHB_SHORT ? "SHORT, " : + opt_bhb_seq == BHB_LONG ? "LONG, " : "?, ", (!boot_cpu_has(X86_FEATURE_IBRSB) && !boot_cpu_has(X86_FEATURE_IBRS)) ? "No" : (default_xen_spec_ctrl & SPEC_CTRL_IBRS) ? "IBRS+" : "IBRS-", @@ -1678,6 +1682,10 @@ static void __init bhi_calculations(void) switch ( opt_bhb_seq ) { + case BHB_LONG: + setup_force_cpu_cap(X86_SPEC_BHB_LOOPS_LONG); + fallthrough; + case BHB_SHORT: setup_force_cpu_cap(X86_SPEC_BHB_LOOPS); break; diff --git a/xen/include/asm-x86/cpufeatures.h b/xen/include/asm-x86/cpufeatures.h index 4df8f19d8a..6a9df4ae0c 100644 --- a/xen/include/asm-x86/cpufeatures.h +++ b/xen/include/asm-x86/cpufeatures.h @@ -57,6 +57,7 @@ XEN_CPUFEATURE(IBPB_ENTRY_HVM, X86_SYNTH(29)) /* MSR_PRED_CMD used by Xen for #define X86_SPEC_BHB_TSX X86_BUG(19) /* Use clear_bhb_tsx for BHI mitigation. */ #define X86_SPEC_BHB_LOOPS X86_BUG(20) /* Use clear_bhb_loops for BHI mitigation.*/ +#define X86_SPEC_BHB_LOOPS_LONG X86_BUG(21) /* Upgrade clear_bhb_loops to the "long" sequence. */ /* Total number of capability words, inc synth and bug words. */ #define NCAPINTS (FSCAPINTS + X86_NR_SYNTH + X86_NR_BUG) /* N 32-bit words worth of info */