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 72627c5fb3b2cef225d989009f0efe9b9e7c0ff9..6ed30421f697982f6cb58dfc5f2f73673a790d72 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 b9241051e5cb2bfa909334e320f06bba4913a797..9e6b9728630773f445a094e7f9a837d2127a5ce1 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 478506b2d51f762c423b4184da757610937a3dcc..cdc79fcee43eac29c08aa7a19bbbe2eea84cb2d7 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)