linux_dsm_epyc7002/arch/nds32/include/asm/futex.h
Greentime Hu 987553894f nds32: fix build error "relocation truncated to fit: R_NDS32_25_PCREL_RELA" when
make allyesconfig

It will cause a linking error because the jump assembly code were using j,
however it may be not enough to jump to the destination. We have to change it
with pseudo instruction b. In that way, assembler will generate a set of safe
assembly codes to make sure the destination is able to jump.

Toolchain:
https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/8.1.0/x86_64-gcc-8.1.0-nolibc-nds32le-linux.tar.gz

Command:
PATH=/NOBACKUP/atcsqa06/greentime/os/toolchain-kernel.org/gcc-8.1.0-nolibc/nds32le-linux/bin:$PATH ARCH=nds32 CROSS_COMPILE=nds32le-linux- make allyesconfig
PATH=/NOBACKUP/atcsqa06/greentime/os/toolchain-kernel.org/gcc-8.1.0-nolibc/nds32le-linux/bin:$PATH ARCH=nds32 CROSS_COMPILE=nds32le-linux- make -j8

  MODPOST vmlinux.o
WARNING: EXPORT symbol "copy_page" [vmlinux] version generation failed, symbol will not be versioned.
WARNING: EXPORT symbol "clear_page" [vmlinux] version generation failed, symbol will not be versioned.
nds32le-linux-ld: kernel/futex.o:(.fixup+0x4): relocation truncated to fit: R_NDS32_25_PCREL_RELA against `.text'
nds32le-linux-ld: kernel/futex.o:(.fixup+0xaa): relocation truncated to fit: R_NDS32_25_PCREL_RELA against `.text'
nds32le-linux-ld: kernel/futex.o:(.fixup+0xb0): relocation truncated to fit: R_NDS32_25_PCREL_RELA against `.text'
nds32le-linux-ld: kernel/futex.o:(.fixup+0xb6): relocation truncated to fit: R_NDS32_25_PCREL_RELA against `.text'
nds32le-linux-ld: kernel/futex.o:(.fixup+0xbc): relocation truncated to fit: R_NDS32_25_PCREL_RELA against `.text'
nds32le-linux-ld: kernel/futex.o:(.fixup+0xc4): relocation truncated to fit: R_NDS32_25_PCREL_RELA against `.text'
Makefile:1010: recipe for target 'vmlinux' failed
make: *** [vmlinux] Error 1

Signed-off-by: Greentime Hu <greentime@andestech.com>
2018-07-05 16:13:47 +08:00

104 lines
2.4 KiB
C

// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2005-2017 Andes Technology Corporation
#ifndef __NDS32_FUTEX_H__
#define __NDS32_FUTEX_H__
#include <linux/futex.h>
#include <linux/uaccess.h>
#include <asm/errno.h>
#define __futex_atomic_ex_table(err_reg) \
" .pushsection __ex_table,\"a\"\n" \
" .align 3\n" \
" .long 1b, 4f\n" \
" .long 2b, 4f\n" \
" .popsection\n" \
" .pushsection .fixup,\"ax\"\n" \
"4: move %0, " err_reg "\n" \
" b 3b\n" \
" .popsection"
#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \
smp_mb(); \
asm volatile( \
" movi $ta, #0\n" \
"1: llw %1, [%2+$ta]\n" \
" " insn "\n" \
"2: scw %0, [%2+$ta]\n" \
" beqz %0, 1b\n" \
" movi %0, #0\n" \
"3:\n" \
__futex_atomic_ex_table("%4") \
: "=&r" (ret), "=&r" (oldval) \
: "r" (uaddr), "r" (oparg), "i" (-EFAULT) \
: "cc", "memory")
static inline int
futex_atomic_cmpxchg_inatomic(u32 * uval, u32 __user * uaddr,
u32 oldval, u32 newval)
{
int ret = 0;
u32 val, tmp, flags;
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
return -EFAULT;
smp_mb();
asm volatile (" movi $ta, #0\n"
"1: llw %1, [%6 + $ta]\n"
" sub %3, %1, %4\n"
" cmovz %2, %5, %3\n"
" cmovn %2, %1, %3\n"
"2: scw %2, [%6 + $ta]\n"
" beqz %2, 1b\n"
"3:\n " __futex_atomic_ex_table("%7")
:"+&r"(ret), "=&r"(val), "=&r"(tmp), "=&r"(flags)
:"r"(oldval), "r"(newval), "r"(uaddr), "i"(-EFAULT)
:"$ta", "memory");
smp_mb();
*uval = val;
return ret;
}
static inline int
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
{
int oldval = 0, ret;
pagefault_disable();
switch (op) {
case FUTEX_OP_SET:
__futex_atomic_op("move %0, %3", ret, oldval, tmp, uaddr,
oparg);
break;
case FUTEX_OP_ADD:
__futex_atomic_op("add %0, %1, %3", ret, oldval, tmp, uaddr,
oparg);
break;
case FUTEX_OP_OR:
__futex_atomic_op("or %0, %1, %3", ret, oldval, tmp, uaddr,
oparg);
break;
case FUTEX_OP_ANDN:
__futex_atomic_op("and %0, %1, %3", ret, oldval, tmp, uaddr,
~oparg);
break;
case FUTEX_OP_XOR:
__futex_atomic_op("xor %0, %1, %3", ret, oldval, tmp, uaddr,
oparg);
break;
default:
ret = -ENOSYS;
}
pagefault_enable();
if (!ret)
*oval = oldval;
return ret;
}
#endif /* __NDS32_FUTEX_H__ */