]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
powerpc/64e: provide an addressing macro for use with TOC in alternate register
authorNicholas Piggin <npiggin@gmail.com>
Mon, 26 Sep 2022 03:40:57 +0000 (13:40 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 28 Sep 2022 09:22:12 +0000 (19:22 +1000)
The interrupt entry code carefully saves a minimal number of registers,
so in some places the TOC is required, it is loaded into a different
register, so provide a macro that can supply an alternate TOC register.

This continues to use got addressing because TOC-relative results in
"got/toc optimization is not supported" messages by the linker. Having
r2 be one of the saved registers and using that for TOC addressing may
be the best way to avoid that and switch this to TOC addressing.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20220926034057.2360083-6-npiggin@gmail.com
arch/powerpc/include/asm/ppc_asm.h
arch/powerpc/kernel/exceptions-64e.S
arch/powerpc/mm/nohash/tlb_low_64e.S

index cf6bec9770d62f4b82116ca56d2f088963d94006..753a2757bcd4f3c78927a0b5ded949d6c5d3b19a 100644 (file)
@@ -346,6 +346,17 @@ n:
        addis   reg,r2,name@toc@ha;             \
        addi    reg,reg,name@toc@l
 
+#ifdef CONFIG_PPC_BOOK3E_64
+/*
+ * This is used in register-constrained interrupt handlers. Not to be used
+ * by BOOK3S. ld complains with "got/toc optimization is not supported" if r2
+ * is not used for the TOC offset, so use @got(tocreg). If the interrupt
+ * handlers saved r2 instead, LOAD_REG_ADDR could be used.
+ */
+#define LOAD_REG_ADDR_ALTTOC(reg,tocreg,name)  \
+       ld      reg,name@got(tocreg)
+#endif
+
 #define LOAD_REG_ADDRBASE(reg,name)    LOAD_REG_ADDR(reg,name)
 #define ADDROFF(name)                  0
 
index ece1bd2a4a395c42ae95ab52afcb6810d574de54..930e360990152ef8677df2279a048b7e616455f0 100644 (file)
@@ -688,8 +688,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 
 #ifdef CONFIG_RELOCATABLE
        __LOAD_PACA_TOC(r15)
-       ld      r14,interrupt_base_book3e@got(r15)
-       ld      r15,__end_interrupts@got(r15)
+       LOAD_REG_ADDR_ALTTOC(r14, r15, interrupt_base_book3e)
+       LOAD_REG_ADDR_ALTTOC(r15, r15, __end_interrupts)
        cmpld   cr0,r10,r14
        cmpld   cr1,r10,r15
 #else
@@ -759,8 +759,8 @@ kernel_dbg_exc:
 
 #ifdef CONFIG_RELOCATABLE
        __LOAD_PACA_TOC(r15)
-       ld      r14,interrupt_base_book3e@got(r15)
-       ld      r15,__end_interrupts@got(r15)
+       LOAD_REG_ADDR_ALTTOC(r14, r15, interrupt_base_book3e)
+       LOAD_REG_ADDR_ALTTOC(r15, r15, __end_interrupts)
        cmpld   cr0,r10,r14
        cmpld   cr1,r10,r15
 #else
@@ -884,8 +884,8 @@ kernel_dbg_exc:
 .macro SEARCH_RESTART_TABLE
 #ifdef CONFIG_RELOCATABLE
        __LOAD_PACA_TOC(r11)
-       ld      r14,__start___restart_table@got(r11)
-       ld      r15,__stop___restart_table@got(r11)
+       LOAD_REG_ADDR_ALTTOC(r14, r11, __start___restart_table)
+       LOAD_REG_ADDR_ALTTOC(r15, r11, __stop___restart_table)
 #else
        LOAD_REG_IMMEDIATE_SYM(r14, r11, __start___restart_table)
        LOAD_REG_IMMEDIATE_SYM(r15, r11, __stop___restart_table)
@@ -1303,7 +1303,7 @@ a2_tlbinit_after_linear_map:
        /* Now we branch the new virtual address mapped by this entry */
 #ifdef CONFIG_RELOCATABLE
        __LOAD_PACA_TOC(r5)
-       ld      r3,1f@got(r5)
+       LOAD_REG_ADDR_ALTTOC(r3, r5, 1f)
 #else
        LOAD_REG_IMMEDIATE_SYM(r3, r5, 1f)
 #endif
index b3b3dfeec8f57a9841b81386d650b3c8fd11c5d9..76cf456d797624b37147d63a36af1b90dd8cc27a 100644 (file)
@@ -1119,7 +1119,7 @@ tlb_load_linear:
         * final implementation, especially when dealing with hypervisors
         */
        __LOAD_PACA_TOC(r11)
-       ld      r11,linear_map_top@got(r11)
+       LOAD_REG_ADDR_ALTTOC(r11, r11, linear_map_top)
        ld      r10,0(r11)
        tovirt(10,10)
        cmpld   cr0,r16,r10