dbf8381731
We have a lot of new kernel features for this merge window: * ARCH_SUPPORTS_ATOMIC_RMW, to allow OSQ locks to be enabled. * The ability to enable NO_HZ_FULL * Support for enabling kcov, kmemleak, stack protector, and VM debugging. * JUMP_LABEL support. There are also a handful of cleanups. next points out a trivial Kconfig merge conflict. I don't see any way to have done this better: the symbols are sorted, it just happens that HAVE_COPY_THREAD_TLS was in the middle of two new symbols. In case it helps any, here's a pretty current conflict resolution: diff --cc arch/riscv/Kconfig index bc37241a6875,6c4bce7cad8a..7b5905529146 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@@ -57,9 -54,6 +59,8 @@@ config RISC select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK select HAVE_ASM_MODVERSIONS + select HAVE_CONTEXT_TRACKING - select HAVE_COPY_THREAD_TLS + select HAVE_DEBUG_KMEMLEAK select HAVE_DMA_CONTIGUOUS if MMU select HAVE_EBPF_JIT if MMU select HAVE_FUTEX_CMPXCHG if FUTEX -----BEGIN PGP SIGNATURE----- iQJHBAABCgAxFiEEKzw3R0RoQ7JKlDp6LhMZ81+7GIkFAl8sa2YTHHBhbG1lckBk YWJiZWx0LmNvbQAKCRAuExnzX7sYieFTD/0RlhicBrn5UGpaUwtgwuMENYOrb3pn 5SsPzhCni3/8HvMzr/gOGHWM2YOQZkY5FReIqy1IdbPSe/exjv6DyKMdZr+OI+3+ 232TAwAtILGlKB+zBMJWA3eLah0pbDvs7RpuhiPfWSzzWUrAMHcGSq0TzM2pYe1r KPOLj6bSKpnZO+Dto80V8w4ZeWmtAArVDiujIy8zlvgpM1Z66C2SazloQH7HkPS7 D2hvLZZU00etyAZI/aJJsemCBRg9nsVoqGTBSXWpUPATBRMZFfHovbh7AUJlqY5E HPHBSf3KDeOjoF8EXkvT/6z5Q6+LUpRyK+KKwWCs/337i1652P31nczDps9J6Eq0 IC3J/YWcy4eZ7pMEps0vQmr9aX+FusOCJUmJqJW77Uzi0fHHTXa+O3olwiz/JqYz c3yIihVAvtw9eCSoqlL7YoL9HNyfrXKCtZ4l/DLjwGG5WJw7C7mGMbBMClcD4ytU /Z91ON/UgWFW5805dBaajp72SStp1FP54HsAH5E12XYZSiepnu70G3BUNJHvDJT5 QOKkrhOswwit5DW30Celh6kmtidAWiavy6R0AbbpcqI+bItkEZWD1BSStTc0WdhV JgOp0ieCzu5Jyw03KC1nZA8VgM3zrAmU0moSDqirddzNYuuBTqt39doZOEs1MS2W TiR1JSnGNaKl4Q== =asH5 -----END PGP SIGNATURE----- Merge tag 'riscv-for-linus-5.9-mw0' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux Pull RISC-V updates from Palmer Dabbelt: "We have a lot of new kernel features for this merge window: - ARCH_SUPPORTS_ATOMIC_RMW, to allow OSQ locks to be enabled - The ability to enable NO_HZ_FULL - Support for enabling kcov, kmemleak, stack protector, and VM debugging - JUMP_LABEL support There are also a handful of cleanups" * tag 'riscv-for-linus-5.9-mw0' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: (24 commits) riscv: disable stack-protector for vDSO RISC-V: Fix build warning for smpboot.c riscv: fix build warning of mm/pageattr riscv: Fix build warning for mm/init RISC-V: Setup exception vector early riscv: Select ARCH_HAS_DEBUG_VM_PGTABLE riscv: Use generic pgprot_* macros from <linux/pgtable.h> mm: pgtable: Make generic pgprot_* macros available for no-MMU riscv: Cleanup unnecessary define in asm-offset.c riscv: Add jump-label implementation riscv: Support R_RISCV_ADD64 and R_RISCV_SUB64 relocs Replace HTTP links with HTTPS ones: RISC-V riscv: Add STACKPROTECTOR supported riscv: Fix typo in asm/hwcap.h uapi header riscv: Add kmemleak support riscv: Allow building with kcov coverage riscv: Enable context tracking riscv: Support irq_work via self IPIs riscv: Enable LOCKDEP_SUPPORT & fixup TRACE_IRQFLAGS_SUPPORT riscv: Fixup lockdep_assert_held with wrong param cpu_running ...
138 lines
3.9 KiB
C
138 lines
3.9 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
|
|
* Chen Liqin <liqin.chen@sunplusct.com>
|
|
* Lennox Wu <lennox.wu@sunplusct.com>
|
|
* Copyright (C) 2012 Regents of the University of California
|
|
* Copyright (C) 2017 SiFive
|
|
*/
|
|
|
|
#include <linux/cpu.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/sched/task_stack.h>
|
|
#include <linux/tick.h>
|
|
#include <linux/ptrace.h>
|
|
#include <linux/uaccess.h>
|
|
|
|
#include <asm/unistd.h>
|
|
#include <asm/processor.h>
|
|
#include <asm/csr.h>
|
|
#include <asm/string.h>
|
|
#include <asm/switch_to.h>
|
|
#include <asm/thread_info.h>
|
|
|
|
register unsigned long gp_in_global __asm__("gp");
|
|
|
|
#ifdef CONFIG_STACKPROTECTOR
|
|
#include <linux/stackprotector.h>
|
|
unsigned long __stack_chk_guard __read_mostly;
|
|
EXPORT_SYMBOL(__stack_chk_guard);
|
|
#endif
|
|
|
|
extern asmlinkage void ret_from_fork(void);
|
|
extern asmlinkage void ret_from_kernel_thread(void);
|
|
|
|
void arch_cpu_idle(void)
|
|
{
|
|
wait_for_interrupt();
|
|
local_irq_enable();
|
|
}
|
|
|
|
void show_regs(struct pt_regs *regs)
|
|
{
|
|
show_regs_print_info(KERN_DEFAULT);
|
|
|
|
pr_cont("epc: " REG_FMT " ra : " REG_FMT " sp : " REG_FMT "\n",
|
|
regs->epc, regs->ra, regs->sp);
|
|
pr_cont(" gp : " REG_FMT " tp : " REG_FMT " t0 : " REG_FMT "\n",
|
|
regs->gp, regs->tp, regs->t0);
|
|
pr_cont(" t1 : " REG_FMT " t2 : " REG_FMT " s0 : " REG_FMT "\n",
|
|
regs->t1, regs->t2, regs->s0);
|
|
pr_cont(" s1 : " REG_FMT " a0 : " REG_FMT " a1 : " REG_FMT "\n",
|
|
regs->s1, regs->a0, regs->a1);
|
|
pr_cont(" a2 : " REG_FMT " a3 : " REG_FMT " a4 : " REG_FMT "\n",
|
|
regs->a2, regs->a3, regs->a4);
|
|
pr_cont(" a5 : " REG_FMT " a6 : " REG_FMT " a7 : " REG_FMT "\n",
|
|
regs->a5, regs->a6, regs->a7);
|
|
pr_cont(" s2 : " REG_FMT " s3 : " REG_FMT " s4 : " REG_FMT "\n",
|
|
regs->s2, regs->s3, regs->s4);
|
|
pr_cont(" s5 : " REG_FMT " s6 : " REG_FMT " s7 : " REG_FMT "\n",
|
|
regs->s5, regs->s6, regs->s7);
|
|
pr_cont(" s8 : " REG_FMT " s9 : " REG_FMT " s10: " REG_FMT "\n",
|
|
regs->s8, regs->s9, regs->s10);
|
|
pr_cont(" s11: " REG_FMT " t3 : " REG_FMT " t4 : " REG_FMT "\n",
|
|
regs->s11, regs->t3, regs->t4);
|
|
pr_cont(" t5 : " REG_FMT " t6 : " REG_FMT "\n",
|
|
regs->t5, regs->t6);
|
|
|
|
pr_cont("status: " REG_FMT " badaddr: " REG_FMT " cause: " REG_FMT "\n",
|
|
regs->status, regs->badaddr, regs->cause);
|
|
}
|
|
|
|
void start_thread(struct pt_regs *regs, unsigned long pc,
|
|
unsigned long sp)
|
|
{
|
|
regs->status = SR_PIE;
|
|
if (has_fpu) {
|
|
regs->status |= SR_FS_INITIAL;
|
|
/*
|
|
* Restore the initial value to the FP register
|
|
* before starting the user program.
|
|
*/
|
|
fstate_restore(current, regs);
|
|
}
|
|
regs->epc = pc;
|
|
regs->sp = sp;
|
|
set_fs(USER_DS);
|
|
}
|
|
|
|
void flush_thread(void)
|
|
{
|
|
#ifdef CONFIG_FPU
|
|
/*
|
|
* Reset FPU state and context
|
|
* frm: round to nearest, ties to even (IEEE default)
|
|
* fflags: accrued exceptions cleared
|
|
*/
|
|
fstate_off(current, task_pt_regs(current));
|
|
memset(¤t->thread.fstate, 0, sizeof(current->thread.fstate));
|
|
#endif
|
|
}
|
|
|
|
int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
|
|
{
|
|
fstate_save(src, task_pt_regs(src));
|
|
*dst = *src;
|
|
return 0;
|
|
}
|
|
|
|
int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg,
|
|
struct task_struct *p, unsigned long tls)
|
|
{
|
|
struct pt_regs *childregs = task_pt_regs(p);
|
|
|
|
/* p->thread holds context to be restored by __switch_to() */
|
|
if (unlikely(p->flags & PF_KTHREAD)) {
|
|
/* Kernel thread */
|
|
memset(childregs, 0, sizeof(struct pt_regs));
|
|
childregs->gp = gp_in_global;
|
|
/* Supervisor/Machine, irqs on: */
|
|
childregs->status = SR_PP | SR_PIE;
|
|
|
|
p->thread.ra = (unsigned long)ret_from_kernel_thread;
|
|
p->thread.s[0] = usp; /* fn */
|
|
p->thread.s[1] = arg;
|
|
} else {
|
|
*childregs = *(current_pt_regs());
|
|
if (usp) /* User fork */
|
|
childregs->sp = usp;
|
|
if (clone_flags & CLONE_SETTLS)
|
|
childregs->tp = tls;
|
|
childregs->a0 = 0; /* Return value of fork() */
|
|
p->thread.ra = (unsigned long)ret_from_fork;
|
|
}
|
|
p->thread.sp = (unsigned long)childregs; /* kernel sp */
|
|
return 0;
|
|
}
|