Print this page
16413 Post-barrier Return Stack Buffer (consider no-eIBRS cases)
16413 Post-barrier Return Stack Buffer (PBRSB) fixes can be detected in HW
*** 1673,1683 ****
"avx512_bitalg",
"avx512_vbmi2",
"avx512_bf16",
"auto_ibrs",
"rfds_no",
! "rfds_clear"
};
boolean_t
is_x86_feature(void *featureset, uint_t feature)
{
--- 1673,1684 ----
"avx512_bitalg",
"avx512_vbmi2",
"avx512_bf16",
"auto_ibrs",
"rfds_no",
! "rfds_clear",
! "pbrsb_no"
};
boolean_t
is_x86_feature(void *featureset, uint_t feature)
{
*** 2966,3000 ****
}
membar_producer();
}
/*
! * We default to enabling RSB mitigations.
*
! * NOTE: We used to skip RSB mitigations with eIBRS, but developments around
! * post-barrier RSB guessing suggests we should enable RSB mitigations always
! * unless specifically instructed not to.
*
* AMD indicates that when Automatic IBRS is enabled we do not need to implement
* return stack buffer clearing for VMEXIT as it takes care of it. The manual
* also states that as long as SMEP and we maintain at least one page between
* the kernel and user space (we have much more of a red zone), then we do not
* need to clear the RSB. We constrain this to only when Automatic IRBS is
* present.
*/
static void
! cpuid_patch_rsb(x86_spectrev2_mitigation_t mit)
{
const uint8_t ret = RET_INSTR;
uint8_t *stuff = (uint8_t *)x86_rsb_stuff;
switch (mit) {
case X86_SPECTREV2_AUTO_IBRS:
case X86_SPECTREV2_DISABLED:
*stuff = ret;
break;
default:
break;
}
}
static void
--- 2967,3033 ----
}
membar_producer();
}
/*
! * We default to enabling Return Stack Buffer (RSB) mitigations.
*
! * We used to skip RSB mitigations with Intel eIBRS, but developments around
! * post-barrier RSB (PBRSB) guessing suggests we should enable Intel RSB
! * mitigations always unless explicitly bypassed, or unless hardware indicates
! * the bug has been fixed. Intel also says that machines without eIBRS do not
! * have VMEXIT problems with PBRSB. Basically, if we're Intel and have eIBRS,
! * we must stuff the RSB in both context switches AND in VMEXIT, unless the
! * hardware says the PBRSB bug is fixed. If we're Intel but without eIBRS
! * (i.e. using retpolines), we must stuff the RSB in context switches, but we
! * do not have to for VMEXIT.
*
+ * See (pardon broken URL) https://www.intel.com/content/www/us/en/developer \
+ * /articles/technical/software-security-guidance/advisory-guidance
+ * /post-barrier-return-stack-buffer-predictions.html
+ *
* AMD indicates that when Automatic IBRS is enabled we do not need to implement
* return stack buffer clearing for VMEXIT as it takes care of it. The manual
* also states that as long as SMEP and we maintain at least one page between
* the kernel and user space (we have much more of a red zone), then we do not
* need to clear the RSB. We constrain this to only when Automatic IRBS is
* present.
*/
static void
! cpuid_patch_rsb(x86_spectrev2_mitigation_t mit, bool intel_pbrsb_no)
{
const uint8_t ret = RET_INSTR;
uint8_t *stuff = (uint8_t *)x86_rsb_stuff;
+ uint8_t *vmx_stuff = (uint8_t *)x86_rsb_stuff_vmexit;
switch (mit) {
case X86_SPECTREV2_AUTO_IBRS:
case X86_SPECTREV2_DISABLED:
+ /* Don't bother with any RSB stuffing! */
*stuff = ret;
+ *vmx_stuff = ret;
break;
+ case X86_SPECTREV2_RETPOLINE:
+ /*
+ * The Intel document on Post-Barrier RSB says that processors
+ * without eIBRS do not have PBRSB problems upon VMEXIT.
+ */
+ VERIFY(!intel_pbrsb_no);
+ VERIFY3U(*stuff, !=, ret);
+ *vmx_stuff = ret;
+ break;
default:
+ /*
+ * eIBRS is all that's left. If CPU claims PBRSB is fixed,
+ * don't use the RSB mitigation in either case.
+ */
+ if (intel_pbrsb_no) {
+ /* CPU claims PBRSB problems are fixed. */
+ *stuff = ret;
+ *vmx_stuff = ret;
+ }
+ VERIFY3U(*stuff, ==, *vmx_stuff);
break;
}
}
static void
*** 3265,3275 ****
--- 3298,3312 ----
}
if (reg & IA32_ARCH_CAP_RFDS_CLEAR) {
add_x86_feature(featureset,
X86FSET_RFDS_CLEAR);
}
+ if (reg & IA32_ARCH_CAP_PBRSB_NO) {
+ add_x86_feature(featureset,
+ X86FSET_PBRSB_NO);
}
+ }
no_trap();
}
#endif /* !__xpv */
if (ecp->cp_edx & CPUID_INTC_EDX_7_0_SSBD)
*** 3325,3338 ****
} else {
v2mit = X86_SPECTREV2_RETPOLINE;
}
cpuid_patch_retpolines(v2mit);
- cpuid_patch_rsb(v2mit);
x86_spectrev2_mitigation = v2mit;
membar_producer();
/*
* We need to determine what changes are required for mitigating L1TF
* and MDS. If the CPU suffers from either of them, then SMT exclusion
* is required.
*
--- 3362,3382 ----
} else {
v2mit = X86_SPECTREV2_RETPOLINE;
}
cpuid_patch_retpolines(v2mit);
x86_spectrev2_mitigation = v2mit;
membar_producer();
+ /*
+ * Return-stack buffer clearing may need a software-sequence. Discover
+ * and patch as appropriate, after setting the SPECTREv2 global
+ * mitigation level.
+ */
+ cpuid_patch_rsb(v2mit, is_x86_feature(featureset, X86FSET_PBRSB_NO));
+ membar_producer();
+
/*
* We need to determine what changes are required for mitigating L1TF
* and MDS. If the CPU suffers from either of them, then SMT exclusion
* is required.
*