### spec-ctrl (x86)
> `= List of [ <bool>, xen=<bool>, {pv,hvm}=<bool>,
> {msr-sc,rsb,verw,{ibpb,bhb}-entry}=<bool>|{pv,hvm}=<bool>,
-> 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,
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.
*
* 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
int3
.align 64
-2: mov $5, %eax
+2: ALTERNATIVE "mov $5, %eax", "mov $7, %eax", X86_SPEC_BHB_LOOPS_LONG
3: jmp 4f
int3
#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 */
BHB_NONE,
BHB_TSX,
BHB_SHORT,
+ BHB_LONG,
} opt_bhb_seq __initdata;
/* Cmdline controls for Xen's speculative settings. */
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;
}
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-",
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;