ARM: kernel: use relative references for UP/SMP alternatives
authorArd Biesheuvel <ardb@kernel.org>
Mon, 14 Sep 2020 08:48:20 +0000 (11:48 +0300)
committerArd Biesheuvel <ardb@kernel.org>
Wed, 28 Oct 2020 16:05:39 +0000 (17:05 +0100)
Currently, the .alt.smp.init section contains the virtual addresses
of the patch sites. Since patching may occur both before and after
switching into virtual mode, this requires some manual handling of
the address when applying the UP alternative.

Let's simplify this by using relative offsets in the table entries:
this allows us to simply add each entry's address to its contents,
regardless of whether we are running in virtual mode or not.

Reviewed-by: Nicolas Pitre <nico@fluxnic.net>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
arch/arm/include/asm/assembler.h
arch/arm/include/asm/processor.h
arch/arm/kernel/head.S

index 72627c5..6ed3042 100644 (file)
  */
 #define ALT_UP(instr...)                                       \
        .pushsection ".alt.smp.init", "a"                       ;\
-       .long   9998b                                           ;\
+       .long   9998b - .                                       ;\
 9997:  instr                                                   ;\
        .if . - 9997b == 2                                      ;\
                nop                                             ;\
        .popsection
 #define ALT_UP_B(label)                                        \
        .pushsection ".alt.smp.init", "a"                       ;\
-       .long   9998b                                           ;\
+       .long   9998b - .                                       ;\
        W(b)    . + (label - 9998b)                                     ;\
        .popsection
 #else
index b924105..9e6b972 100644 (file)
@@ -96,7 +96,7 @@ unsigned long get_wchan(struct task_struct *p);
 #define __ALT_SMP_ASM(smp, up)                                         \
        "9998:  " smp "\n"                                              \
        "       .pushsection \".alt.smp.init\", \"a\"\n"                \
-       "       .long   9998b\n"                                        \
+       "       .long   9998b - .\n"                                    \
        "       " up "\n"                                               \
        "       .popsection\n"
 #else
index 478506b..cdc79fc 100644 (file)
@@ -546,14 +546,15 @@ smp_on_up:
 __do_fixup_smp_on_up:
        cmp     r4, r5
        reths   lr
-       ldmia   r4!, {r0, r6}
- ARM(  str     r6, [r0, r3]    )
- THUMB(        add     r0, r0, r3      )
+       ldmia   r4, {r0, r6}
+ ARM(  str     r6, [r0, r4]    )
+ THUMB(        add     r0, r0, r4      )
+       add     r4, r4, #8
 #ifdef __ARMEB__
  THUMB(        mov     r6, r6, ror #16 )       @ Convert word order for big-endian.
 #endif
  THUMB(        strh    r6, [r0], #2    )       @ For Thumb-2, store as two halfwords
- THUMB(        mov     r6, r6, lsr #16 )       @ to be robust against misaligned r3.
+ THUMB(        mov     r6, r6, lsr #16 )       @ to be robust against misaligned r0.
  THUMB(        strh    r6, [r0]        )
        b       __do_fixup_smp_on_up
 ENDPROC(__do_fixup_smp_on_up)
@@ -562,7 +563,6 @@ ENTRY(fixup_smp)
        stmfd   sp!, {r4 - r6, lr}
        mov     r4, r0
        add     r5, r0, r1
-       mov     r3, #0
        bl      __do_fixup_smp_on_up
        ldmfd   sp!, {r4 - r6, pc}
 ENDPROC(fixup_smp)