diff options
author | Palmer Dabbelt <palmerdabbelt@google.com> | 2020-02-27 11:07:28 -0800 |
---|---|---|
committer | Palmer Dabbelt <palmerdabbelt@google.com> | 2020-03-03 10:28:13 -0800 |
commit | 52e7c52d2ded5908e6a4f8a7248e5fa6e0d6809a (patch) | |
tree | 43ea26b8f12ba519ea77b8c83fb9cdefb46e7430 /arch/riscv/kernel/process.c | |
parent | 064223b947a8c3d0b35a4ac9ae6e31e3f77657fd (diff) |
RISC-V: Stop relying on GCC's register allocator's hueristics
GCC allows users to hint to the register allocation that a variable should be
placed in a register by using a syntax along the lines of
function(...) {
register long in_REG __asm__("REG");
}
We've abused this a bit throughout the RISC-V port to access fixed registers
directly as C variables. In practice it's never going to blow up because GCC
isn't going to allocate these registers, but it's not a well defined syntax so
we really shouldn't be relying upon this. Luckily there is a very similar but
well defined syntax that allows us to still access these registers directly as
C variables, which is to simply declare the register variables globally. For
fixed variables this doesn't change the ABI.
LLVM disallows this ambiguous syntax, so this isn't just strictly a formatting
change.
Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
Diffstat (limited to 'arch/riscv/kernel/process.c')
-rw-r--r-- | arch/riscv/kernel/process.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c index 817cf7b0974c..610c11e91606 100644 --- a/arch/riscv/kernel/process.c +++ b/arch/riscv/kernel/process.c @@ -22,6 +22,8 @@ #include <asm/switch_to.h> #include <asm/thread_info.h> +unsigned long gp_in_global __asm__("gp"); + extern asmlinkage void ret_from_fork(void); extern asmlinkage void ret_from_kernel_thread(void); @@ -107,9 +109,8 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long usp, /* p->thread holds context to be restored by __switch_to() */ if (unlikely(p->flags & PF_KTHREAD)) { /* Kernel thread */ - const register unsigned long gp __asm__ ("gp"); memset(childregs, 0, sizeof(struct pt_regs)); - childregs->gp = gp; + childregs->gp = gp_in_global; /* Supervisor/Machine, irqs on: */ childregs->status = SR_PP | SR_PIE; |