mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 02:39:48 +00:00
RISC-V Fixes for 6.5-rc7
* A fix to avoid excessive rejections from seccomp RET_ERRNO rules. * A fix for compressed jal/jalr decoding. * A pair of fixes for independent irq/softirq stacks on kernels built with CONFIG_FRAME_POINTER=n. * A fix to avoid a hang handling uaccess fixups. * Another build fix for toolchain ISA strings, this time for Zicsr and Zifenci on old GNU toolchains. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEKzw3R0RoQ7JKlDp6LhMZ81+7GIkFAmTfa34THHBhbG1lckBk YWJiZWx0LmNvbQAKCRAuExnzX7sYidwxD/9EeVWNnjAzZyz6dKtQRFe4czuQepXI 5Apcc8UKUs2vFfWybAAL8ICyzZ0ME8Vc+UfAZkFhouCBHpxMWmPDpkGiGxwKYw+E hWZeyIC8Vn/3mmdEvUVrFU37uyndhRaej6sJQb8tj2SLo4K3PvUELl6fhnSs2ESk EaSaOtTnC3DLKpJTup0jvCa1T9aGwVpEVuc7yjARiAxAquxH5ky6N5/l3gCGTQzJ Yph/llxhwmR83zwqto5kHS9nCWi6noammBCYl+Kbb7jMg6UMMBK6T3Dube5rvyqd 7ZEQNWAQ2RDs5pQJklutYjSCE+5LjONMX7IlrBR3plAMfXiLx+K3FhuMizHKD0YZ EIQ1QtsEuu6xPPZXig4KViEp75fRGnV6xJApAE0o0fUCJ7r77vddUJQDQdN3HhGe qfo8sEub8eWZ/IklkVhr6zsZAqMx6srb9r+T/iT+9KW9HKDNfNdEHc8FLuMjzm+C tIrrcZE40N7d37KVB/myWeDBrYAx6Bd6YaJOnuAR8H2t1dSj9rvxi7XFHfVdyRTs SUBQ0BCdMV+1UYmU1qtqWpti06nepeY3EMm4JLUFvKP+7jHBEcEwoye6/hGiTu7d rNsh6kB1Qq29JNQSn5HsOl89QRfz7orRGVZhTW9clhxrgV9fmy+pW9UG564NSSKI tBQGCt7OvXVMsQ== =LtPj -----END PGP SIGNATURE----- Merge tag 'riscv-for-linus-6.5-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux Pull RISC-V fixes from Palmer Dabbelt: - avoid excessive rejections from seccomp RET_ERRNO rules - compressed jal/jalr decoding fix - fixes for independent irq/softirq stacks on kernels built with CONFIG_FRAME_POINTER=n - avoid a hang handling uaccess fixups - another build fix for toolchain ISA strings, this time for Zicsr and Zifenci on old GNU toolchains * tag 'riscv-for-linus-6.5-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: riscv: Handle zicsr/zifencei issue between gcc and binutils riscv: uaccess: Return the number of bytes effectively not copied riscv: stack: Fixup independent softirq stack for CONFIG_FRAME_POINTER=n riscv: stack: Fixup independent irq stack for CONFIG_FRAME_POINTER=n riscv: correct riscv_insn_is_c_jr() and riscv_insn_is_c_jalr() riscv: entry: set a0 = -ENOSYS only when syscall != -1
This commit is contained in:
commit
cd479d9c72
6 changed files with 53 additions and 21 deletions
|
@ -570,24 +570,30 @@ config TOOLCHAIN_HAS_ZIHINTPAUSE
|
|||
config TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI
|
||||
def_bool y
|
||||
# https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=aed44286efa8ae8717a77d94b51ac3614e2ca6dc
|
||||
depends on AS_IS_GNU && AS_VERSION >= 23800
|
||||
# https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=98416dbb0a62579d4a7a4a76bab51b5b52fec2cd
|
||||
depends on AS_IS_GNU && AS_VERSION >= 23600
|
||||
help
|
||||
Newer binutils versions default to ISA spec version 20191213 which
|
||||
moves some instructions from the I extension to the Zicsr and Zifencei
|
||||
extensions.
|
||||
Binutils-2.38 and GCC-12.1.0 bumped the default ISA spec to the newer
|
||||
20191213 version, which moves some instructions from the I extension to
|
||||
the Zicsr and Zifencei extensions. This requires explicitly specifying
|
||||
Zicsr and Zifencei when binutils >= 2.38 or GCC >= 12.1.0. Zicsr
|
||||
and Zifencei are supported in binutils from version 2.36 onwards.
|
||||
To make life easier, and avoid forcing toolchains that default to a
|
||||
newer ISA spec to version 2.2, relax the check to binutils >= 2.36.
|
||||
For clang < 17 or GCC < 11.1.0, for which this is not possible, this is
|
||||
dealt with in CONFIG_TOOLCHAIN_NEEDS_OLD_ISA_SPEC.
|
||||
|
||||
config TOOLCHAIN_NEEDS_OLD_ISA_SPEC
|
||||
def_bool y
|
||||
depends on TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI
|
||||
# https://github.com/llvm/llvm-project/commit/22e199e6afb1263c943c0c0d4498694e15bf8a16
|
||||
depends on CC_IS_CLANG && CLANG_VERSION < 170000
|
||||
# https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=b03be74bad08c382da47e048007a78fa3fb4ef49
|
||||
depends on (CC_IS_CLANG && CLANG_VERSION < 170000) || (CC_IS_GCC && GCC_VERSION < 110100)
|
||||
help
|
||||
Certain versions of clang do not support zicsr and zifencei via -march
|
||||
but newer versions of binutils require it for the reasons noted in the
|
||||
help text of CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI. This
|
||||
option causes an older ISA spec compatible with these older versions
|
||||
of clang to be passed to GAS, which has the same result as passing zicsr
|
||||
and zifencei to -march.
|
||||
Certain versions of clang and GCC do not support zicsr and zifencei via
|
||||
-march. This option causes an older ISA spec compatible with these older
|
||||
versions of clang and GCC to be passed to GAS, which has the same result
|
||||
as passing zicsr and zifencei to -march.
|
||||
|
||||
config FPU
|
||||
bool "FPU support"
|
||||
|
|
|
@ -110,6 +110,7 @@
|
|||
#define RVC_INSN_FUNCT4_OPOFF 12
|
||||
#define RVC_INSN_FUNCT3_MASK GENMASK(15, 13)
|
||||
#define RVC_INSN_FUNCT3_OPOFF 13
|
||||
#define RVC_INSN_J_RS1_MASK GENMASK(11, 7)
|
||||
#define RVC_INSN_J_RS2_MASK GENMASK(6, 2)
|
||||
#define RVC_INSN_OPCODE_MASK GENMASK(1, 0)
|
||||
#define RVC_ENCODE_FUNCT3(f_) (RVC_FUNCT3_##f_ << RVC_INSN_FUNCT3_OPOFF)
|
||||
|
@ -245,8 +246,6 @@ __RISCV_INSN_FUNCS(c_jal, RVC_MASK_C_JAL, RVC_MATCH_C_JAL)
|
|||
__RISCV_INSN_FUNCS(auipc, RVG_MASK_AUIPC, RVG_MATCH_AUIPC)
|
||||
__RISCV_INSN_FUNCS(jalr, RVG_MASK_JALR, RVG_MATCH_JALR)
|
||||
__RISCV_INSN_FUNCS(jal, RVG_MASK_JAL, RVG_MATCH_JAL)
|
||||
__RISCV_INSN_FUNCS(c_jr, RVC_MASK_C_JR, RVC_MATCH_C_JR)
|
||||
__RISCV_INSN_FUNCS(c_jalr, RVC_MASK_C_JALR, RVC_MATCH_C_JALR)
|
||||
__RISCV_INSN_FUNCS(c_j, RVC_MASK_C_J, RVC_MATCH_C_J)
|
||||
__RISCV_INSN_FUNCS(beq, RVG_MASK_BEQ, RVG_MATCH_BEQ)
|
||||
__RISCV_INSN_FUNCS(bne, RVG_MASK_BNE, RVG_MATCH_BNE)
|
||||
|
@ -273,6 +272,18 @@ static __always_inline bool riscv_insn_is_branch(u32 code)
|
|||
return (code & RV_INSN_OPCODE_MASK) == RVG_OPCODE_BRANCH;
|
||||
}
|
||||
|
||||
static __always_inline bool riscv_insn_is_c_jr(u32 code)
|
||||
{
|
||||
return (code & RVC_MASK_C_JR) == RVC_MATCH_C_JR &&
|
||||
(code & RVC_INSN_J_RS1_MASK) != 0;
|
||||
}
|
||||
|
||||
static __always_inline bool riscv_insn_is_c_jalr(u32 code)
|
||||
{
|
||||
return (code & RVC_MASK_C_JALR) == RVC_MATCH_C_JALR &&
|
||||
(code & RVC_INSN_J_RS1_MASK) != 0;
|
||||
}
|
||||
|
||||
#define RV_IMM_SIGN(x) (-(((x) >> 31) & 1))
|
||||
#define RVC_IMM_SIGN(x) (-(((x) >> 12) & 1))
|
||||
#define RV_X(X, s, mask) (((X) >> (s)) & (mask))
|
||||
|
|
|
@ -11,7 +11,13 @@ compat_vdso-syms += flush_icache
|
|||
COMPAT_CC := $(CC)
|
||||
COMPAT_LD := $(LD)
|
||||
|
||||
COMPAT_CC_FLAGS := -march=rv32g -mabi=ilp32
|
||||
# binutils 2.35 does not support the zifencei extension, but in the ISA
|
||||
# spec 20191213, G stands for IMAFD_ZICSR_ZIFENCEI.
|
||||
ifdef CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI
|
||||
COMPAT_CC_FLAGS := -march=rv32g -mabi=ilp32
|
||||
else
|
||||
COMPAT_CC_FLAGS := -march=rv32imafd -mabi=ilp32
|
||||
endif
|
||||
COMPAT_LD_FLAGS := -melf32lriscv
|
||||
|
||||
# Disable attributes, as they're useless and break the build.
|
||||
|
|
|
@ -84,6 +84,9 @@ void do_softirq_own_stack(void)
|
|||
: [sp] "r" (sp)
|
||||
: "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
|
||||
"t0", "t1", "t2", "t3", "t4", "t5", "t6",
|
||||
#ifndef CONFIG_FRAME_POINTER
|
||||
"s0",
|
||||
#endif
|
||||
"memory");
|
||||
} else
|
||||
#endif
|
||||
|
|
|
@ -297,7 +297,7 @@ asmlinkage __visible __trap_section void do_trap_break(struct pt_regs *regs)
|
|||
asmlinkage __visible __trap_section void do_trap_ecall_u(struct pt_regs *regs)
|
||||
{
|
||||
if (user_mode(regs)) {
|
||||
ulong syscall = regs->a7;
|
||||
long syscall = regs->a7;
|
||||
|
||||
regs->epc += 4;
|
||||
regs->orig_a0 = regs->a0;
|
||||
|
@ -306,9 +306,9 @@ asmlinkage __visible __trap_section void do_trap_ecall_u(struct pt_regs *regs)
|
|||
|
||||
syscall = syscall_enter_from_user_mode(regs, syscall);
|
||||
|
||||
if (syscall < NR_syscalls)
|
||||
if (syscall >= 0 && syscall < NR_syscalls)
|
||||
syscall_handler(regs, syscall);
|
||||
else
|
||||
else if (syscall != -1)
|
||||
regs->a0 = -ENOSYS;
|
||||
|
||||
syscall_exit_to_user_mode(regs);
|
||||
|
@ -372,6 +372,9 @@ asmlinkage void noinstr do_irq(struct pt_regs *regs)
|
|||
: [sp] "r" (sp), [regs] "r" (regs)
|
||||
: "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
|
||||
"t0", "t1", "t2", "t3", "t4", "t5", "t6",
|
||||
#ifndef CONFIG_FRAME_POINTER
|
||||
"s0",
|
||||
#endif
|
||||
"memory");
|
||||
} else
|
||||
#endif
|
||||
|
|
|
@ -17,8 +17,11 @@ ENTRY(__asm_copy_from_user)
|
|||
li t6, SR_SUM
|
||||
csrs CSR_STATUS, t6
|
||||
|
||||
/* Save for return value */
|
||||
mv t5, a2
|
||||
/*
|
||||
* Save the terminal address which will be used to compute the number
|
||||
* of bytes copied in case of a fixup exception.
|
||||
*/
|
||||
add t5, a0, a2
|
||||
|
||||
/*
|
||||
* Register allocation for code below:
|
||||
|
@ -176,7 +179,7 @@ ENTRY(__asm_copy_from_user)
|
|||
10:
|
||||
/* Disable access to user memory */
|
||||
csrc CSR_STATUS, t6
|
||||
mv a0, t5
|
||||
sub a0, t5, a0
|
||||
ret
|
||||
ENDPROC(__asm_copy_to_user)
|
||||
ENDPROC(__asm_copy_from_user)
|
||||
|
@ -228,7 +231,7 @@ ENTRY(__clear_user)
|
|||
11:
|
||||
/* Disable access to user memory */
|
||||
csrc CSR_STATUS, t6
|
||||
mv a0, a1
|
||||
sub a0, a3, a0
|
||||
ret
|
||||
ENDPROC(__clear_user)
|
||||
EXPORT_SYMBOL(__clear_user)
|
||||
|
|
Loading…
Reference in a new issue