[PATCH] D41761: Introduce llvm.nospeculateload intrinsic
Kristof Beyls via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 10 07:38:55 PST 2018
kristof.beyls added a comment.
Thanks for the feedback, Chandler and Philip!
Please let me explain how we've ended up with the API design as proposed.
We started from the observation that:
1. We need an API/intrinsic that can be implemented well in all major compilers, including gcc and clang/llvm.
2. We need an API/intrinsic that works well across architectures.
For Arm, the recommended mitigation for protecting against Spectre variant 1 is to generate a LOAD->CSEL->CSDB instruction sequence, where CSDB is a new barrier instruction.
This sequence gives protection on all Arm implementations.
This is explained in far more detail at https://developer.arm.com/support/security-update/download-the-whitepaper, in section "Software mitigations", pages 4-8.
The need to generate the full LOAD->CSEL->CSDB sequence explains why the proposed intrinsic contains the semantics of loading a value, providing it is within bounds.
Being able to generate the LOAD->CSEL->CSDB sequence from the intrinsic is essential for AArch64 and ARM targets.
Hopefully that explains the needs for the ptr, lower_bound and upper_bound parameters.
The cmpptr and failval parameters are there to make it easier to use in certain scenarios, for example:
For failval, the idea is that for code like
if (ptr >= base && ptr < limit) // bounds check
return *ptr;
return FAILVAL;
to be able to be easily rewritten as
return __builtin_load_no_speculate (ptr, base, limit, FAILVAL);
The cmpptr parameter was introduced after hearing a need from the linux kernel. They have some cases where cmpptr may be a pointer to an atomic type and want to do something like
if (cmpptr >= lower && cmpptr < upper)
val = __atomic_read_and_inc (cmpptr);
By separating out cmpptr from ptr you can now write the following, which removes the need to try and wrestle "no-speculate" semantics into the atomic builtins:
if (cmpptr >= lower && cmpptr < upper)
{
T tmp_val = __atomic_read_and_inc (cmpptr);
val = builtin_load_no_speculate (&tmp_val, lower, upper, 0,
cmpptr);
}
There is a bit more explanation on the rationale for the failval and cmpptr parameters at https://gcc.gnu.org/ml/gcc-patches/2018-01/msg00594.html.
Furthermore, there are a few more details on the use of this intrinsic at https://developer.arm.com/support/security-update/compiler-support-for-mitigations
I hope the above helps to explain the rationale for the proposed API design?
https://reviews.llvm.org/D41761
More information about the llvm-commits
mailing list