diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2019-04-14 15:18:37 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.ibm.com> | 2019-04-17 15:56:34 +1000 |
commit | 32a23ae6b0d3549bec7338e439e504db263dc390 (patch) | |
tree | d44f4dd228c97cce2a1f39579de684226baf7883 | |
parent | f244f3e1b679a1a45b5a5165543ce0c9c86a93ce (diff) | |
download | skiboot-32a23ae6b0d3549bec7338e439e504db263dc390.zip skiboot-32a23ae6b0d3549bec7338e439e504db263dc390.tar.gz skiboot-32a23ae6b0d3549bec7338e439e504db263dc390.tar.bz2 |
asm/head: balance branches to avoid link stack predictor mispredicts
The Linux wrapper for OPAL call and return is arranged like this:
__opal_call:
mflr r0
std r0,PPC_STK_LROFF(r1)
LOAD_REG_ADDR(r11, opal_return)
mtlr r11
hrfid -> OPAL
opal_return:
ld r0,PPC_STK_LROFF(r1)
mtlr r0
blr
When skiboot returns to Linux, it branches to LR (i.e., opal_return)
with a blr. This unbalances the link stack predictor and will cause
mispredicts back up the return stack.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
-rw-r--r-- | asm/head.S | 7 |
1 files changed, 6 insertions, 1 deletions
@@ -1090,7 +1090,12 @@ opal_entry: lwz %r11,CPUTHREAD_IN_OPAL_CALL(%r12) subi %r11,%r11,1 stw %r11,CPUTHREAD_IN_OPAL_CALL(%r12) - blr + /* + * blr with BH=01b means it's not a function return, OPAL was entered + * via (h)rfid not bl, so we don't have a corresponding link stack + * prediction to return to here. + */ + bclr 20,0,1 .global start_kernel start_kernel: |