Skip to content

Commit

Permalink
LoongArch: Adjust symbol addressing for CONFIG_AS_HAS_EXPLICIT_RELOCS
Browse files Browse the repository at this point in the history
If explicit relocation hints is used by the toolchain, -Wa,-mla-*
options will be useless for C code.  Only use them for
!CONFIG_AS_HAS_EXPLICIT_RELOCS.

Replace "la" with "la.pcrel" in head.S to keep the semantic consistent
with new and old toolchains for the low level startup code.

For per-CPU variables, the "address" of the symbol is actually an
offset from $r21.  The value is nearing the loading address of main
kernel image, but far from the address of modules.  Use model("extreme")
attibute to tell the compiler that a  a PC-relative addressing with
32-bit offset is not sufficient for local per-CPU variables.

The behavior with different assemblers and compilers are summarized in
the following table:

AS has            CC has
explicit reloc    explicit reloc *  Behavior
==============================================================
No                No                Use la.* macros.
                                    No change from Linux 6.0.
--------------------------------------------------------------
No                Yes               Disable explicit reloc.
                                    No change from Linux 6.0.
--------------------------------------------------------------
Yes               No                Not supported.
--------------------------------------------------------------
Yes               Yes               Use explicit relocs.
                                    No -Wa,-mla* options.
==============================================================
*: We assume CC must have model attribute if it has explicit reloc.
   Both features are added in GCC 13 development cycle, so any GCC
   release >= 13 should be OK.  Using early GCC 13 development snapshots
   may produce modules with unsupported relocations.

Link: https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=f09482a
Link: https://gcc.gnu.org/r13-1834
Link: https://gcc.gnu.org/r13-2199
Signed-off-by: Xi Ruoyao <[email protected]>
  • Loading branch information
xry111 committed Sep 2, 2022
1 parent 47b09be commit 3d71f0a
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 5 deletions.
17 changes: 17 additions & 0 deletions arch/loongarch/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,27 @@ endif

cflags-y += -G0 -pipe -msoft-float
LDFLAGS_vmlinux += -G0 -static -n -nostdlib

# When the assembler supports explicit relocation hint, we must use it.
# GCC may have -mexplicit-relocs off by default if it was built with an old
# assembler, so we force it via an option.
#
# When the assembler does not supports explicit relocation hint, we can't use
# it. Disable it if the compiler supports it.
#
# If you've seen "unknown reloc hint" message building the kernel and you are
# now wondering why "-mexplicit-relocs" is not wrapped with cc-option: the
# combination of a "new" assembler and "old" compiler is not supported. Either
# upgrade the compiler or downgrade the assembler.
ifdef CONFIG_AS_HAS_EXPLICIT_RELOCS
cflags-y += -mexplicit-relocs
else
cflags-y += $(call cc-option,-mno-explicit-relocs)
KBUILD_AFLAGS_KERNEL += -Wa,-mla-global-with-pcrel
KBUILD_CFLAGS_KERNEL += -Wa,-mla-global-with-pcrel
KBUILD_AFLAGS_MODULE += -Wa,-mla-global-with-abs
KBUILD_CFLAGS_MODULE += -fplt -Wa,-mla-global-with-abs,-mla-local-with-abs
endif

cflags-y += -ffreestanding
cflags-y += $(call cc-option, -mno-check-zero-division)
Expand Down
8 changes: 8 additions & 0 deletions arch/loongarch/include/asm/percpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@
#include <asm/cmpxchg.h>
#include <asm/loongarch.h>

#if defined(MODULE) && defined(CONFIG_AS_HAS_EXPLICIT_RELOCS)
/* The "address" (in fact, offset from $r21) of a per-CPU variable is close
* to the load address of main kernel image, but far from where the modules are
* loaded. Tell the compiler this fact.
*/
# define PER_CPU_ATTRIBUTES __attribute__((model("extreme")))
#endif

/* Use r21 for fast access */
register unsigned long __my_cpu_offset __asm__("$r21");

Expand Down
10 changes: 5 additions & 5 deletions arch/loongarch/kernel/head.S
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,25 @@ SYM_CODE_START(kernel_entry) # kernel entry point
li.w t0, 0x00 # FPE=0, SXE=0, ASXE=0, BTE=0
csrwr t0, LOONGARCH_CSR_EUEN

la t0, __bss_start # clear .bss
la.pcrel t0, __bss_start # clear .bss
st.d zero, t0, 0
la t1, __bss_stop - LONGSIZE
la.pcrel t1, __bss_stop - LONGSIZE
1:
addi.d t0, t0, LONGSIZE
st.d zero, t0, 0
bne t0, t1, 1b

la t0, fw_arg0
la.pcrel t0, fw_arg0
st.d a0, t0, 0 # firmware arguments
la t0, fw_arg1
la.pcrel t0, fw_arg1
st.d a1, t0, 0

/* KSave3 used for percpu base, initialized as 0 */
csrwr zero, PERCPU_BASE_KS
/* GPR21 used for percpu base (runtime), initialized as 0 */
move u0, zero

la tp, init_thread_union
la.pcrel tp, init_thread_union
/* Set the SP after an empty pt_regs. */
PTR_LI sp, (_THREAD_SIZE - 32 - PT_SIZE)
PTR_ADD sp, sp, tp
Expand Down

0 comments on commit 3d71f0a

Please sign in to comment.