This is part of implementing a technique to mitigate against Spectre v1,
similar in spirit to what has been proposed by Chandler for X86_64 at
http://lists.llvm.org/pipermail/llvm-dev/2018-March/122085.html.
This patch introduces the AArch64SpeculationHardeningPass. The pass
modifies code to track whether any previously executed direct
conditional branch has been mispredicted. The command line argument to
do so is -aarch64-track-speculation.
As is, the patch makes use of the AArch64 ABI convention that X16 and
X17 can be clobbered on function call boundaries to store the
miss-speculation state in register X16 and on function call boundaries
temporarily use X17 to help encode this information in the stack pointer
register.
Register X16 contains value 0 when any misprediction has been detected,
and otherwise contains value 0xFFF..FFF. This makes it easy to use it as
a mask for any value that needs to be nullified when miss-speculation
has happened. This patch only implements this tracking of
miss-speculation in register X16. Actually using the value in X16 to
protect specific values against leaking under miss-speculation is
implemented in follow-on patches.
On a function call, control flow miss-speculation is encoded by making
the stack pointer have value 0. On correct control flow speculation, the
value of the stack pointer remains unchanged. Since 0 is not a value the
stack pointer should have on any valid function call, this is a reliable
backwards ABI-compatible way to encode the miss-speculation information.
In between function calls, as implied above, the information is encoded
in register X16 as value 0, so that it is cheap to use that value
(implemented in a later patch) to nullify values that must not be used
on a miss-speculated execution path.
I hope that splitting the patches this way makes it easier to review
them.