[PATCH] D41760: Introduce __builtin_load_no_speculate

Kristof Beyls via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 5 03:02:26 PST 2018

kristof.beyls created this revision.
kristof.beyls added a reviewer: olista01.
Herald added subscribers: aheejin, javed.absar, dschuff, jfb, aemerson.

Recently, Google Project Zero disclosed several classes of attack
against speculative execution. One of these, known as variant-1
(CVE-2017-5753), allows explicit bounds checks to be bypassed under
speculation, providing an arbitrary read gadget. Further details can
be found on the GPZ blog [1].

This patch adds a new builtin function that provides a mechanism for
limiting speculation by a CPU after a bounds-checked memory access.
This patch provides the clang-side of the needed functionality; there is
also an llvm-side patch this patch is dependent on.
We've tried to design this in such a way that it can be used for any
target where this might be necessary.  The patch provides a generic
implementation of the builtin, with most of the target-specific
support in the LLVM counter part to this clang patch.

The signature of the new, polymorphic, builtin is:

T __builtin_load_no_speculate(const volatile T *ptr,

  const volatile void *lower,
  const volatile void *upper,
  T failval,
  const volatile void *cmpptr)

T can be any integral type (signed or unsigned char, int, short, long,
etc) or any pointer type.

The builtin implements the following logical behaviour:

inline T __builtin_load_no_speculate(const volatile T *ptr,

                                     const volatile void *lower,
                                     const volatile void *upper, T failval,
                                     const volatile void *cmpptr) {
  T result;
  if (cmpptr >= lower && cmpptr < upper)
    result = *ptr;
    result = failval;
  return result;


In addition, the builtin ensures that future speculation using *ptr may
only continue iff cmpptr lies within the bounds specified.

To make the builtin easier to use, the final two arguments can both be
omitted: failval will default to 0 in this case and if cmpptr is omitted
ptr will be used for expansions of the range check.  In addition, either
lower or upper (but not both) may be a literal NULL and the expansion
will then ignore that boundary condition when expanding.

This also introduces the predefined pre-processor macro
__HAVE_LOAD_NO_SPECULATE, that allows users to check if their version of
the compiler supports this intrinsic.

The builtin is defined for all architectures, even if they do not
provide a mechanism for inhibiting speculation.  If they do not have
such support the compiler will emit a warning and simply implement the
architectural behavior of the builtin.

This patch can be used with the header file that Arm recently
published here: https://github.com/ARM-software/speculation-barrier.

Kernel patches are also being developed, eg:
https://lkml.org/lkml/2018/1/3/754.  The intent is that eventually
code like this will be able to use support directly from the compiler
in a portable manner.

Similar patches are also being developed for GCC and have been posted to
their development list, see

[1] More information on the topic can be found here:
Arm specific information can be found here:



-------------- next part --------------
A non-text attachment was scrubbed...
Name: D41760.128726.patch
Type: text/x-patch
Size: 40811 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180105/ae5f1a63/attachment-0001.bin>

More information about the cfe-commits mailing list