Commit dbf83817 authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents e1ec517e 40284a07
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
| openrisc: | TODO | | openrisc: | TODO |
| parisc: | ok | | parisc: | ok |
| powerpc: | ok | | powerpc: | ok |
| riscv: | TODO | | riscv: | ok |
| s390: | ok | | s390: | ok |
| sh: | TODO | | sh: | TODO |
| sparc: | ok | | sparc: | ok |
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
| openrisc: | TODO | | openrisc: | TODO |
| parisc: | TODO | | parisc: | TODO |
| powerpc: | ok | | powerpc: | ok |
| riscv: | TODO | | riscv: | ok |
| s390: | ok | | s390: | ok |
| sh: | TODO | | sh: | TODO |
| sparc: | TODO | | sparc: | TODO |
......
...@@ -13,11 +13,14 @@ config 32BIT ...@@ -13,11 +13,14 @@ config 32BIT
config RISCV config RISCV
def_bool y def_bool y
select ARCH_CLOCKSOURCE_INIT select ARCH_CLOCKSOURCE_INIT
select ARCH_SUPPORTS_ATOMIC_RMW
select ARCH_HAS_BINFMT_FLAT select ARCH_HAS_BINFMT_FLAT
select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DEBUG_VIRTUAL if MMU select ARCH_HAS_DEBUG_VIRTUAL if MMU
select ARCH_HAS_DEBUG_WX select ARCH_HAS_DEBUG_WX
select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_GIGANTIC_PAGE select ARCH_HAS_GIGANTIC_PAGE
select ARCH_HAS_KCOV
select ARCH_HAS_MMIOWB select ARCH_HAS_MMIOWB
select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_PTE_SPECIAL
select ARCH_HAS_SET_DIRECT_MAP select ARCH_HAS_SET_DIRECT_MAP
...@@ -47,6 +50,8 @@ config RISCV ...@@ -47,6 +50,8 @@ config RISCV
select GENERIC_TIME_VSYSCALL if MMU && 64BIT select GENERIC_TIME_VSYSCALL if MMU && 64BIT
select HANDLE_DOMAIN_IRQ select HANDLE_DOMAIN_IRQ
select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_JUMP_LABEL_RELATIVE
select HAVE_ARCH_KASAN if MMU && 64BIT select HAVE_ARCH_KASAN if MMU && 64BIT
select HAVE_ARCH_KGDB select HAVE_ARCH_KGDB
select HAVE_ARCH_KGDB_QXFER_PKT select HAVE_ARCH_KGDB_QXFER_PKT
...@@ -54,14 +59,18 @@ config RISCV ...@@ -54,14 +59,18 @@ config RISCV
select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRACEHOOK
select HAVE_ASM_MODVERSIONS select HAVE_ASM_MODVERSIONS
select HAVE_CONTEXT_TRACKING
select HAVE_DEBUG_KMEMLEAK
select HAVE_DMA_CONTIGUOUS if MMU select HAVE_DMA_CONTIGUOUS if MMU
select HAVE_EBPF_JIT if MMU select HAVE_EBPF_JIT if MMU
select HAVE_FUTEX_CMPXCHG if FUTEX select HAVE_FUTEX_CMPXCHG if FUTEX
select HAVE_GCC_PLUGINS
select HAVE_GENERIC_VDSO if MMU && 64BIT select HAVE_GENERIC_VDSO if MMU && 64BIT
select HAVE_PCI select HAVE_PCI
select HAVE_PERF_EVENTS select HAVE_PERF_EVENTS
select HAVE_PERF_REGS select HAVE_PERF_REGS
select HAVE_PERF_USER_STACK_DUMP select HAVE_PERF_USER_STACK_DUMP
select HAVE_STACKPROTECTOR
select HAVE_SYSCALL_TRACEPOINTS select HAVE_SYSCALL_TRACEPOINTS
select IRQ_DOMAIN select IRQ_DOMAIN
select MODULES_USE_ELF_RELA if MODULES select MODULES_USE_ELF_RELA if MODULES
...@@ -179,6 +188,9 @@ config PGTABLE_LEVELS ...@@ -179,6 +188,9 @@ config PGTABLE_LEVELS
default 3 if 64BIT default 3 if 64BIT
default 2 default 2
config LOCKDEP_SUPPORT
def_bool y
source "arch/riscv/Kconfig.socs" source "arch/riscv/Kconfig.socs"
menu "Platform type" menu "Platform type"
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
# Based on the ia64 and arm64 boot/Makefile. # Based on the ia64 and arm64 boot/Makefile.
# #
KCOV_INSTRUMENT := n
OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
targets := Image loader targets := Image loader
......
...@@ -17,6 +17,7 @@ CONFIG_BPF_SYSCALL=y ...@@ -17,6 +17,7 @@ CONFIG_BPF_SYSCALL=y
CONFIG_SOC_SIFIVE=y CONFIG_SOC_SIFIVE=y
CONFIG_SOC_VIRT=y CONFIG_SOC_VIRT=y
CONFIG_SMP=y CONFIG_SMP=y
CONFIG_JUMP_LABEL=y
CONFIG_MODULES=y CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_UNLOAD=y
CONFIG_NET=y CONFIG_NET=y
......
...@@ -33,6 +33,7 @@ CONFIG_SMP=y ...@@ -33,6 +33,7 @@ CONFIG_SMP=y
CONFIG_NR_CPUS=2 CONFIG_NR_CPUS=2
CONFIG_CMDLINE="earlycon console=ttySIF0" CONFIG_CMDLINE="earlycon console=ttySIF0"
CONFIG_CMDLINE_FORCE=y CONFIG_CMDLINE_FORCE=y
CONFIG_JUMP_LABEL=y
# CONFIG_BLOCK is not set # CONFIG_BLOCK is not set
CONFIG_BINFMT_FLAT=y CONFIG_BINFMT_FLAT=y
# CONFIG_COREDUMP is not set # CONFIG_COREDUMP is not set
......
...@@ -30,6 +30,7 @@ CONFIG_MAXPHYSMEM_2GB=y ...@@ -30,6 +30,7 @@ CONFIG_MAXPHYSMEM_2GB=y
CONFIG_SMP=y CONFIG_SMP=y
CONFIG_CMDLINE="root=/dev/vda rw earlycon=uart8250,mmio,0x10000000,115200n8 console=ttyS0" CONFIG_CMDLINE="root=/dev/vda rw earlycon=uart8250,mmio,0x10000000,115200n8 console=ttyS0"
CONFIG_CMDLINE_FORCE=y CONFIG_CMDLINE_FORCE=y
CONFIG_JUMP_LABEL=y
# CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y CONFIG_PARTITION_ADVANCED=y
# CONFIG_MSDOS_PARTITION is not set # CONFIG_MSDOS_PARTITION is not set
......
...@@ -17,6 +17,7 @@ CONFIG_BPF_SYSCALL=y ...@@ -17,6 +17,7 @@ CONFIG_BPF_SYSCALL=y
CONFIG_SOC_VIRT=y CONFIG_SOC_VIRT=y
CONFIG_ARCH_RV32I=y CONFIG_ARCH_RV32I=y
CONFIG_SMP=y CONFIG_SMP=y
CONFIG_JUMP_LABEL=y
CONFIG_MODULES=y CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_UNLOAD=y
CONFIG_NET=y CONFIG_NET=y
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_RISCV_IRQ_WORK_H
#define _ASM_RISCV_IRQ_WORK_H
static inline bool arch_irq_work_has_interrupt(void)
{
return true;
}
extern void arch_irq_work_raise(void);
#endif /* _ASM_RISCV_IRQ_WORK_H */
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2020 Emil Renner Berthing
*
* Based on arch/arm64/include/asm/jump_label.h
*/
#ifndef __ASM_JUMP_LABEL_H
#define __ASM_JUMP_LABEL_H
#ifndef __ASSEMBLY__
#include <linux/types.h>
#include <asm/asm.h>
#define JUMP_LABEL_NOP_SIZE 4
static __always_inline bool arch_static_branch(struct static_key *key,
bool branch)
{
asm_volatile_goto(
" .option push \n\t"
" .option norelax \n\t"
" .option norvc \n\t"
"1: nop \n\t"
" .option pop \n\t"
" .pushsection __jump_table, \"aw\" \n\t"
" .align " RISCV_LGPTR " \n\t"
" .long 1b - ., %l[label] - . \n\t"
" " RISCV_PTR " %0 - . \n\t"
" .popsection \n\t"
: : "i"(&((char *)key)[branch]) : : label);
return false;
label:
return true;
}
static __always_inline bool arch_static_branch_jump(struct static_key *key,
bool branch)
{
asm_volatile_goto(
" .option push \n\t"
" .option norelax \n\t"
" .option norvc \n\t"
"1: jal zero, %l[label] \n\t"
" .option pop \n\t"
" .pushsection __jump_table, \"aw\" \n\t"
" .align " RISCV_LGPTR " \n\t"
" .long 1b - ., %l[label] - . \n\t"
" " RISCV_PTR " %0 - . \n\t"
" .popsection \n\t"
: : "i"(&((char *)key)[branch]) : : label);
return false;
label:
return true;
}
#endif /* __ASSEMBLY__ */
#endif /* __ASM_JUMP_LABEL_H */
...@@ -14,12 +14,6 @@ ...@@ -14,12 +14,6 @@
#include <linux/types.h> #include <linux/types.h>
#include <asm/mmiowb.h> #include <asm/mmiowb.h>
#ifndef CONFIG_MMU
#define pgprot_noncached(x) (x)
#define pgprot_writecombine(x) (x)
#define pgprot_device(x) (x)
#endif /* CONFIG_MMU */
/* Generic IO read/write. These perform native-endian accesses. */ /* Generic IO read/write. These perform native-endian accesses. */
#define __raw_writeb __raw_writeb #define __raw_writeb __raw_writeb
static inline void __raw_writeb(u8 val, volatile void __iomem *addr) static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
......
...@@ -40,6 +40,9 @@ void arch_send_call_function_single_ipi(int cpu); ...@@ -40,6 +40,9 @@ void arch_send_call_function_single_ipi(int cpu);
int riscv_hartid_to_cpuid(int hartid); int riscv_hartid_to_cpuid(int hartid);
void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out); void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out);
/* Secondary hart entry */
asmlinkage void smp_callin(void);
/* /*
* Obtains the hart ID of the currently executing task. This relies on * Obtains the hart ID of the currently executing task. This relies on
* THREAD_INFO_IN_TASK, but we define that unconditionally. * THREAD_INFO_IN_TASK, but we define that unconditionally.
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_RISCV_STACKPROTECTOR_H
#define _ASM_RISCV_STACKPROTECTOR_H
#include <linux/random.h>
#include <linux/version.h>
#include <asm/timex.h>
extern unsigned long __stack_chk_guard;
/*
* Initialize the stackprotector canary value.
*
* NOTE: this must only be called from functions that never return,
* and it must always be inlined.
*/
static __always_inline void boot_init_stack_canary(void)
{
unsigned long canary;
unsigned long tsc;
/* Try to get a semi random initial value. */
get_random_bytes(&canary, sizeof(canary));
tsc = get_cycles();
canary += tsc + (tsc << BITS_PER_LONG/2);
canary ^= LINUX_VERSION_CODE;
canary &= CANARY_MASK;
current->stack_canary = canary;
__stack_chk_guard = current->stack_canary;
}
#endif /* _ASM_RISCV_STACKPROTECTOR_H */
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
/* /*
* Linux saves the floating-point registers according to the ISA Linux is * Linux saves the floating-point registers according to the ISA Linux is
* executing on, as opposed to the ISA the user program is compiled for. This * executing on, as opposed to the ISA the user program is compiled for. This
* is necessary for a handful of esoteric use cases: for example, userpsace * is necessary for a handful of esoteric use cases: for example, userspace
* threading libraries must be able to examine the actual machine state in * threading libraries must be able to examine the actual machine state in
* order to fully reconstruct the state of a thread. * order to fully reconstruct the state of a thread.
*/ */
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifdef __LP64__ #ifdef __LP64__
......
...@@ -53,4 +53,6 @@ endif ...@@ -53,4 +53,6 @@ endif
obj-$(CONFIG_HOTPLUG_CPU) += cpu-hotplug.o obj-$(CONFIG_HOTPLUG_CPU) += cpu-hotplug.o
obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
clean: clean:
...@@ -27,9 +27,6 @@ void asm_offsets(void) ...@@ -27,9 +27,6 @@ void asm_offsets(void)
OFFSET(TASK_THREAD_S9, task_struct, thread.s[9]); OFFSET(TASK_THREAD_S9, task_struct, thread.s[9]);
OFFSET(TASK_THREAD_S10, task_struct, thread.s[10]); OFFSET(TASK_THREAD_S10, task_struct, thread.s[10]);
OFFSET(TASK_THREAD_S11, task_struct, thread.s[11]); OFFSET(TASK_THREAD_S11, task_struct, thread.s[11]);
OFFSET(TASK_THREAD_SP, task_struct, thread.sp);
OFFSET(TASK_STACK, task_struct, stack);
OFFSET(TASK_TI, task_struct, thread_info);
OFFSET(TASK_TI_FLAGS, task_struct, thread_info.flags); OFFSET(TASK_TI_FLAGS, task_struct, thread_info.flags);
OFFSET(TASK_TI_PREEMPT_COUNT, task_struct, thread_info.preempt_count); OFFSET(TASK_TI_PREEMPT_COUNT, task_struct, thread_info.preempt_count);
OFFSET(TASK_TI_KERNEL_SP, task_struct, thread_info.kernel_sp); OFFSET(TASK_TI_KERNEL_SP, task_struct, thread_info.kernel_sp);
......
...@@ -97,19 +97,36 @@ _save_context: ...@@ -97,19 +97,36 @@ _save_context:
la gp, __global_pointer$ la gp, __global_pointer$
.option pop .option pop
la ra, ret_from_exception #ifdef CONFIG_TRACE_IRQFLAGS
call trace_hardirqs_off
#endif
#ifdef CONFIG_CONTEXT_TRACKING
/* If previous state is in user mode, call context_tracking_user_exit. */
li a0, SR_PP
and a0, s1, a0
bnez a0, skip_context_tracking
call context_tracking_user_exit
skip_context_tracking:
#endif
/* /*
* MSB of cause differentiates between * MSB of cause differentiates between
* interrupts and exceptions * interrupts and exceptions
*/ */
bge s4, zero, 1f bge s4, zero, 1f
la ra, ret_from_exception
/* Handle interrupts */ /* Handle interrupts */
move a0, sp /* pt_regs */ move a0, sp /* pt_regs */
la a1, handle_arch_irq la a1, handle_arch_irq
REG_L a1, (a1) REG_L a1, (a1)
jr a1 jr a1
1: 1:
#ifdef CONFIG_TRACE_IRQFLAGS
call trace_hardirqs_on
#endif
/* /*
* Exceptions run with interrupts enabled or disabled depending on the * Exceptions run with interrupts enabled or disabled depending on the
* state of SR_PIE in m/sstatus. * state of SR_PIE in m/sstatus.
...@@ -119,6 +136,7 @@ _save_context: ...@@ -119,6 +136,7 @@ _save_context:
csrs CSR_STATUS, SR_IE csrs CSR_STATUS, SR_IE
1: 1:
la ra, ret_from_exception
/* Handle syscalls */ /* Handle syscalls */
li t0, EXC_SYSCALL li t0, EXC_SYSCALL
beq s4, t0, handle_syscall beq s4, t0, handle_syscall
...@@ -137,6 +155,17 @@ _save_context: ...@@ -137,6 +155,17 @@ _save_context:
tail do_trap_unknown tail do_trap_unknown
handle_syscall: handle_syscall:
#if defined(CONFIG_TRACE_IRQFLAGS) || defined(CONFIG_CONTEXT_TRACKING)
/* Recover a0 - a7 for system calls */
REG_L a0, PT_A0(sp)
REG_L a1, PT_A1(sp)
REG_L a2, PT_A2(sp)
REG_L a3, PT_A3(sp)
REG_L a4, PT_A4(sp)
REG_L a5, PT_A5(sp)
REG_L a6, PT_A6(sp)
REG_L a7, PT_A7(sp)
#endif
/* save the initial A0 value (needed in signal handlers) */ /* save the initial A0 value (needed in signal handlers) */
REG_S a0, PT_ORIG_A0(sp) REG_S a0, PT_ORIG_A0(sp)
/* /*
...@@ -190,6 +219,9 @@ ret_from_syscall_rejected: ...@@ -190,6 +219,9 @@ ret_from_syscall_rejected:
ret_from_exception: ret_from_exception:
REG_L s0, PT_STATUS(sp) REG_L s0, PT_STATUS(sp)
csrc CSR_STATUS, SR_IE csrc CSR_STATUS, SR_IE
#ifdef CONFIG_TRACE_IRQFLAGS
call trace_hardirqs_off
#endif
#ifdef CONFIG_RISCV_M_MODE #ifdef CONFIG_RISCV_M_MODE
/* the MPP value is too large to be used as an immediate arg for addi */ /* the MPP value is too large to be used as an immediate arg for addi */
li t0, SR_MPP li t0, SR_MPP
...@@ -205,6 +237,10 @@ resume_userspace: ...@@ -205,6 +237,10 @@ resume_userspace:
andi s1, s0, _TIF_WORK_MASK andi s1, s0, _TIF_WORK_MASK
bnez s1, work_pending bnez s1, work_pending
#ifdef CONFIG_CONTEXT_TRACKING
call context_tracking_user_enter
#endif
/* Save unwound kernel stack pointer in thread_info */ /* Save unwound kernel stack pointer in thread_info */
addi s0, sp, PT_SIZE_ON_STACK addi s0, sp, PT_SIZE_ON_STACK
REG_S s0, TASK_TI_KERNEL_SP(tp) REG_S s0, TASK_TI_KERNEL_SP(tp)
...@@ -216,6 +252,16 @@ resume_userspace: ...@@ -216,6 +252,16 @@ resume_userspace:
csrw CSR_SCRATCH, tp csrw CSR_SCRATCH, tp
restore_all: restore_all:
#ifdef CONFIG_TRACE_IRQFLAGS
REG_L s1, PT_STATUS(sp)
andi t0, s1, SR_PIE
beqz t0, 1f
call trace_hardirqs_on
j 2f
1:
call trace_hardirqs_off
2:
#endif
REG_L a0, PT_STATUS(sp) REG_L a0, PT_STATUS(sp)
/* /*
* The current load reservation is effectively part of the processor's * The current load reservation is effectively part of the processor's
...@@ -389,12 +435,8 @@ ENTRY(__switch_to) ...@@ -389,12 +435,8 @@ ENTRY(__switch_to)
lw a4, TASK_TI_CPU(a1) lw a4, TASK_TI_CPU(a1)
sw a3, TASK_TI_CPU(a1) sw a3, TASK_TI_CPU(a1)
sw a4, TASK_TI_CPU(a0) sw a4, TASK_TI_CPU(a0)
#if TASK_TI != 0 /* The offset of thread_info in task_struct is zero. */
#error "TASK_TI != 0: tp will contain a 'struct thread_info', not a 'struct task_struct' so get_current() won't work."
addi tp, a1, TASK_TI
#else
move tp, a1 move tp, a1
#endif
ret ret
ENDPROC(__switch_to) ENDPROC(__switch_to)
......
...@@ -77,10 +77,16 @@ relocate: ...@@ -77,10 +77,16 @@ relocate:
csrw CSR_SATP, a0 csrw CSR_SATP, a0
.align 2 .align 2
1: 1:
/* Set trap vector to spin forever to help debug */ /* Set trap vector to exception handler */
la a0, .Lsecondary_park la a0, handle_exception
csrw CSR_TVEC, a0 csrw CSR_TVEC, a0
/*
* Set sup0 scratch register to 0, indicating to exception vector that
* we are presently executing in kernel.
*/
csrw CSR_SCRATCH, zero
/* Reload the global pointer */ /* Reload the global pointer */
.option push .option push
.option norelax .option norelax
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2020 Emil Renner Berthing
*
* Based on arch/arm64/kernel/jump_label.c
*/
#include <linux/jump_label.h>
#include <linux/kernel.h>
#include <linux/memory.h>
#include <linux/mutex.h>
#include <asm/bug.h>
#include <asm/patch.h>
#define RISCV_INSN_NOP 0x00000013U
#define RISCV_INSN_JAL 0x0000006fU
void arch_jump_label_transform(struct jump_entry *entry,
enum jump_label_type type)
{
void *addr = (void *)jump_entry_code(entry);
u32 insn;
if (type == JUMP_LABEL_JMP) {
long offset = jump_entry_target(entry) - jump_entry_code(entry);
if (WARN_ON(offset & 1 || offset < -524288 || offset >= 524288))
return;
insn = RISCV_INSN_JAL |
(((u32)offset & GENMASK(19, 12)) << (12 - 12)) |
(((u32)offset & GENMASK(11, 11)) << (20 - 11)) |
(((u32)offset & GENMASK(10, 1)) << (21 - 1)) |
(((u32)offset & GENMASK(20, 20)) << (31 - 20));
} else {
insn = RISCV_INSN_NOP;
}
mutex_lock(&text_mutex);
patch_text_nosync(addr, &insn, sizeof(insn));
mutex_unlock(&text_mutex);
}
void arch_jump_label_transform_static(struct jump_entry *entry,
enum jump_label_type type)
{
/*
* We use the same instructions in the arch_static_branch and
* arch_static_branch_jump inline functions, so there's no
* need to patch them up here.
* The core will call arch_jump_label_transform when those
* instructions need to be replaced.
*/
}
...@@ -263,6 +263,13 @@ static int apply_r_riscv_add32_rela(struct module *me, u32 *location, ...@@ -263,6 +263,13 @@ static int apply_r_riscv_add32_rela(struct module *me, u32 *location,
return 0; return 0;
} }
static int apply_r_riscv_add64_rela(struct module *me, u32 *location,
Elf_Addr v)
{
*(u64 *)location += (u64)v;
return 0;
}
static int apply_r_riscv_sub32_rela(struct module *me, u32 *location, static int apply_r_riscv_sub32_rela(struct module *me, u32 *location,
Elf_Addr v) Elf_Addr v)
{ {
...@@ -270,6 +277,13 @@ static int apply_r_riscv_sub32_rela(struct module *me, u32 *location, ...@@ -270,6 +277,13 @@ static int apply_r_riscv_sub32_rela(struct module *me, u32 *location,
return 0; return 0;
} }
static int apply_r_riscv_sub64_rela(struct module *me, u32 *location,
Elf_Addr v)
{
*(u64 *)location -= (u64)v;
return 0;
}
static int (*reloc_handlers_rela[]) (struct module *me, u32 *location, static int (*reloc_handlers_rela[]) (struct module *me, u32 *location,
Elf_Addr v) = { Elf_Addr v) = {
[R_RISCV_32] = apply_r_riscv_32_rela, [R_RISCV_32] = apply_r_riscv_32_rela,
...@@ -290,7 +304,9 @@ static int (*reloc_handlers_rela[]) (struct module *me, u32 *location, ...@@ -290,7 +304,9 @@ static int (*reloc_handlers_rela[]) (struct module *me, u32 *location,
[R_RISCV_RELAX] = apply_r_riscv_relax_rela, [R_RISCV_RELAX] = apply_r_riscv_relax_rela,
[R_RISCV_ALIGN] = apply_r_riscv_align_rela, [R_RISCV_ALIGN] = apply_r_riscv_align_rela,
[R_RISCV_ADD32] = apply_r_riscv_add32_rela, [R_RISCV_ADD32] = apply_r_riscv_add32_rela,
[R_RISCV_ADD64] = apply_r_riscv_add64_rela,
[R_RISCV_SUB32] = apply_r_riscv_sub32_rela, [R_RISCV_SUB32] = apply_r_riscv_sub32_rela,
[R_RISCV_SUB64] = apply_r_riscv_sub64_rela,
}; };
int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
......
...@@ -24,6 +24,12 @@ ...@@ -24,6 +24,12 @@
register unsigned long gp_in_global __asm__("gp"); 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_fork(void);
extern asmlinkage void ret_from_kernel_thread(void); extern asmlinkage void ret_from_kernel_thread(void);
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/irq_work.h>
#include <asm/clint.h> #include <asm/clint.h>
#include <asm/sbi.h> #include <asm/sbi.h>
...@@ -26,6 +27,7 @@ enum ipi_message_type { ...@@ -26,6 +27,7 @@ enum ipi_message_type {
IPI_RESCHEDULE, IPI_RESCHEDULE,
IPI_CALL_FUNC, IPI_CALL_FUNC,
IPI_CPU_STOP, IPI_CPU_STOP,
IPI_IRQ_WORK,
IPI_MAX IPI_MAX
}; };
...@@ -123,6 +125,13 @@ static inline void clear_ipi(void) ...@@ -123,6 +125,13 @@ static inline void clear_ipi(void)
clint_clear_ipi(cpuid_to_hartid_map(smp_processor_id())); clint_clear_ipi(cpuid_to_hartid_map(smp_processor_id()));
} }
#ifdef CONFIG_IRQ_WORK
void arch_irq_work_raise(void)
{
send_ipi_single(smp_processor_id(), IPI_IRQ_WORK);
}
#endif
void handle_IPI(struct pt_regs *regs) void handle_IPI(struct pt_regs *regs)
{ {
struct pt_regs *old_regs = set_irq_regs(regs); struct pt_regs *old_regs = set_irq_regs(regs);
...@@ -158,6 +167,11 @@ void handle_IPI(struct pt_regs *regs) ...@@ -158,6 +167,11 @@ void handle_IPI(struct pt_regs *regs)
ipi_stop(); ipi_stop();
} }
if (ops & (1 << IPI_IRQ_WORK)) {
stats[IPI_IRQ_WORK]++;
irq_work_run();
}
BUG_ON((ops >> IPI_MAX) != 0); BUG_ON((ops >> IPI_MAX) != 0);
/* Order data access and bit testing. */ /* Order data access and bit testing. */
...@@ -173,6 +187,7 @@ static const char * const ipi_names[] = { ...@@ -173,6 +187,7 @@ static const char * const ipi_names[] = {
[IPI_RESCHEDULE] = "Rescheduling interrupts", [IPI_RESCHEDULE] = "Rescheduling interrupts",
[IPI_CALL_FUNC] = "Function call interrupts", [IPI_CALL_FUNC] = "Function call interrupts",
[IPI_CPU_STOP] = "CPU stop interrupts", [IPI_CPU_STOP] = "CPU stop interrupts",
[IPI_IRQ_WORK] = "IRQ work interrupts",
}; };
void show_ipi_stats(struct seq_file *p, int prec) void show_ipi_stats(struct seq_file *p, int prec)
......
...@@ -106,7 +106,7 @@ void __init setup_smp(void) ...@@ -106,7 +106,7 @@ void __init setup_smp(void)
} }
} }
int start_secondary_cpu(int cpu, struct task_struct *tidle) static int start_secondary_cpu(int cpu, struct task_struct *tidle)
{ {
if (cpu_ops[cpu]->cpu_start) if (cpu_ops[cpu]->cpu_start)
return cpu_ops[cpu]->cpu_start(cpu, tidle); return cpu_ops[cpu]->cpu_start(cpu, tidle);
...@@ -121,7 +121,6 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle) ...@@ -121,7 +121,6 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
ret = start_secondary_cpu(cpu, tidle); ret = start_secondary_cpu(cpu, tidle);
if (!ret) { if (!ret) {
lockdep_assert_held(&cpu_running);
wait_for_completion_timeout(&cpu_running, wait_for_completion_timeout(&cpu_running,
msecs_to_jiffies(1000)); msecs_to_jiffies(1000));
...@@ -146,6 +145,7 @@ void __init smp_cpus_done(unsigned int max_cpus) ...@@ -146,6 +145,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
asmlinkage __visible void smp_callin(void) asmlinkage __visible void smp_callin(void)
{ {
struct mm_struct *mm = &init_mm; struct mm_struct *mm = &init_mm;
unsigned int curr_cpuid = smp_processor_id();
if (!IS_ENABLED(CONFIG_RISCV_SBI)) if (!IS_ENABLED(CONFIG_RISCV_SBI))
clint_clear_ipi(cpuid_to_hartid_map(smp_processor_id())); clint_clear_ipi(cpuid_to_hartid_map(smp_processor_id()));
...@@ -154,10 +154,10 @@ asmlinkage __visible void smp_callin(void) ...@@ -154,10 +154,10 @@ asmlinkage __visible void smp_callin(void)
mmgrab(mm); mmgrab(mm);
current->active_mm = mm; current->active_mm = mm;
trap_init(); notify_cpu_starting(curr_cpuid);
notify_cpu_starting(smp_processor_id()); update_siblings_masks(curr_cpuid);
update_siblings_masks(smp_processor_id()); set_cpu_online(curr_cpuid, 1);
set_cpu_online(smp_processor_id(), 1);
/* /*
* Remote TLB flushes are ignored while the CPU is offline, so emit * Remote TLB flushes are ignored while the CPU is offline, so emit
* a local TLB flush right now just in case. * a local TLB flush right now just in case.
......
...@@ -174,13 +174,7 @@ int is_valid_bugaddr(unsigned long pc) ...@@ -174,13 +174,7 @@ int is_valid_bugaddr(unsigned long pc)
} }
#endif /* CONFIG_GENERIC_BUG */ #endif /* CONFIG_GENERIC_BUG */
/* stvec & scratch is already set from head.S */
void trap_init(void) void trap_init(void)
{ {
/*
* Set sup0 scratch register to 0, indicating to exception vector
* that we are presently executing in the kernel
*/
csr_write(CSR_SCRATCH, 0);
/* Set the exception vector address */
csr_write(CSR_TVEC, &handle_exception);
} }
...@@ -16,6 +16,8 @@ vdso-syms += flush_icache ...@@ -16,6 +16,8 @@ vdso-syms += flush_icache
# Files to link into the vdso # Files to link into the vdso
obj-vdso = $(patsubst %, %.o, $(vdso-syms)) note.o obj-vdso = $(patsubst %, %.o, $(vdso-syms)) note.o
ccflags-y := -fno-stack-protector
ifneq ($(c-gettimeofday-y),) ifneq ($(c-gettimeofday-y),)
CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y) CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y)
endif endif
...@@ -32,6 +34,7 @@ CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os ...@@ -32,6 +34,7 @@ CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os
# Disable gcov profiling for VDSO code # Disable gcov profiling for VDSO code
GCOV_PROFILE := n GCOV_PROFILE := n
KCOV_INSTRUMENT := n
# Force dependency # Force dependency
$(obj)/vdso.o: $(obj)/vdso.so $(obj)/vdso.o: $(obj)/vdso.so
......
...@@ -22,6 +22,7 @@ SECTIONS ...@@ -22,6 +22,7 @@ SECTIONS
/* Beginning of code and text segment */ /* Beginning of code and text segment */
. = LOAD_OFFSET; . = LOAD_OFFSET;
_start = .; _start = .;
_stext = .;
HEAD_TEXT_SECTION HEAD_TEXT_SECTION
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);
...@@ -54,7 +55,6 @@ SECTIONS ...@@ -54,7 +55,6 @@ SECTIONS
. = ALIGN(SECTION_ALIGN); . = ALIGN(SECTION_ALIGN);
.text : { .text : {
_text = .; _text = .;
_stext = .;
TEXT_TEXT TEXT_TEXT
SCHED_TEXT SCHED_TEXT
CPUIDLE_TEXT CPUIDLE_TEXT
......
...@@ -5,6 +5,8 @@ ifdef CONFIG_FTRACE ...@@ -5,6 +5,8 @@ ifdef CONFIG_FTRACE
CFLAGS_REMOVE_init.o = -pg CFLAGS_REMOVE_init.o = -pg
endif endif
KCOV_INSTRUMENT_init.o := n
obj-y += init.o obj-y += init.o
obj-y += extable.o obj-y += extable.o
obj-$(CONFIG_MMU) += fault.o pageattr.o obj-$(CONFIG_MMU) += fault.o pageattr.o
......
...@@ -541,6 +541,32 @@ void mark_rodata_ro(void) ...@@ -541,6 +541,32 @@ void mark_rodata_ro(void)
} }
#endif #endif
static void __init resource_init(void)
{
struct memblock_region *region;
for_each_memblock(memory, region) {
struct resource *res;
res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES);
if (!res)
panic("%s: Failed to allocate %zu bytes\n", __func__,
sizeof(struct resource));
if (memblock_is_nomap(region)) {
res->name = "reserved";
res->flags = IORESOURCE_MEM;
} else {
res->name = "System RAM";
res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
}
res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
request_resource(&iomem_resource, res);
}
}
void __init paging_init(void) void __init paging_init(void)
{ {
setup_vm_final(); setup_vm_final();
...@@ -548,6 +574,7 @@ void __init paging_init(void) ...@@ -548,6 +574,7 @@ void __init paging_init(void)
sparse_init(); sparse_init();
setup_zero_page(); setup_zero_page();
zone_sizes_init(); zone_sizes_init();
resource_init();
} }
#ifdef CONFIG_SPARSEMEM_VMEMMAP #ifdef CONFIG_SPARSEMEM_VMEMMAP
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/pgtable.h> #include <linux/pgtable.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/set_memory.h>
struct pageattr_masks { struct pageattr_masks {
pgprot_t set_mask; pgprot_t set_mask;
...@@ -94,7 +95,7 @@ static int pageattr_pte_hole(unsigned long addr, unsigned long next, ...@@ -94,7 +95,7 @@ static int pageattr_pte_hole(unsigned long addr, unsigned long next,
return 0; return 0;
} }
const static struct mm_walk_ops pageattr_ops = { static const struct mm_walk_ops pageattr_ops = {
.pgd_entry = pageattr_pgd_entry, .pgd_entry = pageattr_pgd_entry,
.p4d_entry = pageattr_p4d_entry, .p4d_entry = pageattr_p4d_entry,
.pud_entry = pageattr_pud_entry, .pud_entry = pageattr_pud_entry,
......
...@@ -647,40 +647,6 @@ static inline int arch_unmap_one(struct mm_struct *mm, ...@@ -647,40 +647,6 @@ static inline int arch_unmap_one(struct mm_struct *mm,
#define flush_tlb_fix_spurious_fault(vma, address) flush_tlb_page(vma, address) #define flush_tlb_fix_spurious_fault(vma, address) flush_tlb_page(vma, address)
#endif #endif
#ifndef pgprot_nx
#define pgprot_nx(prot) (prot)
#endif
#ifndef pgprot_noncached
#define pgprot_noncached(prot) (prot)
#endif
#ifndef pgprot_writecombine
#define pgprot_writecombine pgprot_noncached
#endif
#ifndef pgprot_writethrough
#define pgprot_writethrough pgprot_noncached
#endif
#ifndef pgprot_device
#define pgprot_device pgprot_noncached
#endif
#ifndef pgprot_modify
#define pgprot_modify pgprot_modify
static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
{
if (pgprot_val(oldprot) == pgprot_val(pgprot_noncached(oldprot)))
newprot = pgprot_noncached(newprot);
if (pgprot_val(oldprot) == pgprot_val(pgprot_writecombine(oldprot)))
newprot = pgprot_writecombine(newprot);
if (pgprot_val(oldprot) == pgprot_val(pgprot_device(oldprot)))
newprot = pgprot_device(newprot);
return newprot;
}
#endif
/* /*
* When walking page tables, get the address of the next boundary, * When walking page tables, get the address of the next boundary,
* or the end address of the range if that comes earlier. Although no * or the end address of the range if that comes earlier. Although no
...@@ -840,6 +806,43 @@ static inline void ptep_modify_prot_commit(struct vm_area_struct *vma, ...@@ -840,6 +806,43 @@ static inline void ptep_modify_prot_commit(struct vm_area_struct *vma,
* No-op macros that just return the current protection value. Defined here * No-op macros that just return the current protection value. Defined here
* because these macros can be used used even if CONFIG_MMU is not defined. * because these macros can be used used even if CONFIG_MMU is not defined.
*/ */
#ifndef pgprot_nx
#define pgprot_nx(prot) (prot)
#endif
#ifndef pgprot_noncached
#define pgprot_noncached(prot) (prot)
#endif
#ifndef pgprot_writecombine
#define pgprot_writecombine pgprot_noncached
#endif
#ifndef pgprot_writethrough
#define pgprot_writethrough pgprot_noncached
#endif
#ifndef pgprot_device
#define pgprot_device pgprot_noncached
#endif
#ifdef CONFIG_MMU
#ifndef pgprot_modify
#define pgprot_modify pgprot_modify
static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
{
if (pgprot_val(oldprot) == pgprot_val(pgprot_noncached(oldprot)))
newprot = pgprot_noncached(newprot);
if (pgprot_val(oldprot) == pgprot_val(pgprot_writecombine(oldprot)))
newprot = pgprot_writecombine(newprot);
if (pgprot_val(oldprot) == pgprot_val(pgprot_device(oldprot)))
newprot = pgprot_device(newprot);
return newprot;
}
#endif
#endif /* CONFIG_MMU */
#ifndef pgprot_encrypted #ifndef pgprot_encrypted
#define pgprot_encrypted(prot) (prot) #define pgprot_encrypted(prot) (prot)
#endif #endif
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifdef __LP64__ #ifdef __LP64__
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment