[PATCH] D54896: Introduce control flow speculation tracking pass for AArch64.

Kristof Beyls via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 6 07:27:32 PST 2018


kristof.beyls marked 4 inline comments as done.
kristof.beyls added a comment.

>> There currently isn't even a user interface to reserve X16.
> 
> X16 can be reserved by the user using inline assembly, either with a clobber or named register variable. I can think of a few cases where this might happen in real code:
> 
> D51432 <https://reviews.llvm.org/D51432> uses it in libunwind to implement unwinding through functions using return-address signing.
>  Inline assembly which contains a function call will need to clobber X16 and X17.
>  If moving this pass to before register allocation would add a lot of extra complexity, maybe this could also be solved by copying the taint into SP before each inline asm block, and back out afterwards, like we currently do for calls?

Thanks for pointing out the possibility of X16 and X17 being forced to use by inline assembly code after all.
As we've discussed, we expect very little code to actually go and use X16.

I think there are at least 3 possible solutions to this, each with their set of pros and cons.

1. Change the implementation so that it runs pre register allocation.
  - Cons:
    - Control flow and memory accesses that may be introduced by later passes (e.g. spill/fill code) will not be protected.
    - The implementation will be a lot more complex.
  - Pros:
    - Implementations of SLH on some other architectures may have no choice but to implement this pre register allocation. If it were implemented pre register allocation for all architectures, there might be slightly more consistency in the protection given between architectures. Maybe.

2. Go for the suggestion you've made on storing speculation state in the stack pointer before the inline assembly block and restoring it after.
  - Cons:
    - This would need a code sequence to change the value in SP based on the speculation state in X16. The code sequences used at function entry/exit for this cannot be used here, because those clobber X17 and the flags, which may be live when not at a function boundary. On AArch64, there are only a few instructions that can access that stack pointer, which is why we end up using temporary register X17 in the function boundary sequences. I have come up with a code sequence to encode miss-speculation in the SP that doesn't clobber any other register, nor the flags - but only if the encoding of miss-speculation in the stack pointer is allowed to be different: the least significant bit being set to 1. Obviously, this will not work if code uses a byte aligned stack pointer. I'm afraid I don't have a good insight into whether code would ever use a byte aligned stack pointer.
    - The X16 register may be live across multiple basic blocks/control flow. Applying this technique would remove the miss-speculation tracking from the edges on which the X16 register is live before SLH is applied, resulting in silently dropping some protection the user may expect.
  - Pros:
    - This may be a relatively simple way to still protect the very few functions that absolutely must use X16.

3. Do not apply SLH hardening to a function making hard-coded use of X16, and provide a warning (or error) when a user requests SLH on such a function.
  - Cons:
    - A function will not be protected by SLH, even if it was requested. The warning/error reported will inform the user to either adapt the code in the function to not use X16 or to accept whatever risk there may be in leaving this function unprotected.
  - Pros:
    - A relatively simple implementation, while still keeping the advantages of doing speculation hardening very late (after register allocation).
    - No silent non-protected code.
    - The warning is assumed to trigger to an extremely small amount of code.

Overall, option 3 seems to have the best tradeoffs to me so I'll explore implementing that option further.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54896/new/

https://reviews.llvm.org/D54896





More information about the llvm-commits mailing list