aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2019-04-14 15:18:37 +1000
committerStewart Smith <stewart@linux.ibm.com>2019-04-17 15:56:34 +1000
commit32a23ae6b0d3549bec7338e439e504db263dc390 (patch)
treed44f4dd228c97cce2a1f39579de684226baf7883
parentf244f3e1b679a1a45b5a5165543ce0c9c86a93ce (diff)
downloadskiboot-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.S7
1 files changed, 6 insertions, 1 deletions
diff --git a/asm/head.S b/asm/head.S
index 916b22c..bd06149 100644
--- a/asm/head.S
+++ b/asm/head.S
@@ -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: