Skip to content

Commit

Permalink
Merge tag 'riscv-for-linus-5.8-mw1' of git://git.kernel.org/pub/scm/l…
Browse files Browse the repository at this point in the history
…inux/kernel/git/riscv/linux

Pull more RISC-V updates from Palmer Dabbelt:

 - Kconfig select statements are now sorted alphanumerically

 - first-level interrupts are now handled via a full irqchip driver

 - CPU hotplug is fixed

 - vDSO calls now use the common vDSO infrastructure

* tag 'riscv-for-linus-5.8-mw1' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux:
  riscv: set the permission of vdso_data to read-only
  riscv: use vDSO common flow to reduce the latency of the time-related functions
  riscv: fix build warning of missing prototypes
  RISC-V: Don't mark init section as non-executable
  RISC-V: Force select RISCV_INTC for CONFIG_RISCV
  RISC-V: Remove do_IRQ() function
  clocksource/drivers/timer-riscv: Use per-CPU timer interrupt
  irqchip: RISC-V per-HART local interrupt controller driver
  RISC-V: Rename and move plic_find_hart_id() to arch directory
  RISC-V: self-contained IPI handling routine
  RISC-V: Sort select statements alphanumerically
  • Loading branch information
Linus Torvalds committed Jun 11, 2020
2 parents 55d728b + 01f7638 commit cd16ed3
Show file tree
Hide file tree
Showing 31 changed files with 500 additions and 183 deletions.
74 changes: 40 additions & 34 deletions arch/riscv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,64 +12,70 @@ config 32BIT

config RISCV
def_bool y
select OF
select OF_EARLY_FLATTREE
select OF_IRQ
select ARCH_CLOCKSOURCE_INIT
select ARCH_HAS_BINFMT_FLAT
select ARCH_HAS_DEBUG_VIRTUAL if MMU
select ARCH_HAS_DEBUG_WX
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_GIGANTIC_PAGE
select ARCH_HAS_MMIOWB
select ARCH_HAS_PTE_SPECIAL
select ARCH_HAS_SET_DIRECT_MAP
select ARCH_HAS_SET_MEMORY
select ARCH_HAS_STRICT_KERNEL_RWX if MMU
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
select ARCH_WANT_FRAME_POINTERS
select ARCH_WANT_HUGE_PMD_SHARE if 64BIT
select CLONE_BACKWARDS
select COMMON_CLK
select EDAC_SUPPORT
select GENERIC_ARCH_TOPOLOGY if SMP
select GENERIC_ATOMIC64 if !64BIT
select GENERIC_CLOCKEVENTS
select GENERIC_GETTIMEOFDAY if HAVE_GENERIC_VDSO
select GENERIC_IOREMAP
select GENERIC_IRQ_MULTI_HANDLER
select GENERIC_IRQ_SHOW
select GENERIC_PCI_IOMAP
select GENERIC_PTDUMP if MMU
select GENERIC_SCHED_CLOCK
select GENERIC_SMP_IDLE_THREAD
select GENERIC_STRNCPY_FROM_USER if MMU
select GENERIC_STRNLEN_USER if MMU
select GENERIC_SMP_IDLE_THREAD
select GENERIC_ATOMIC64 if !64BIT
select GENERIC_IOREMAP
select GENERIC_PTDUMP if MMU
select GENERIC_TIME_VSYSCALL if MMU && 64BIT
select HANDLE_DOMAIN_IRQ
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_KASAN if MMU && 64BIT
select HAVE_ARCH_KGDB
select HAVE_ARCH_KGDB_QXFER_PKT
select HAVE_ARCH_MMAP_RND_BITS if MMU
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK
select HAVE_ASM_MODVERSIONS
select HAVE_COPY_THREAD_TLS
select HAVE_DMA_CONTIGUOUS if MMU
select HAVE_EBPF_JIT if MMU
select HAVE_FUTEX_CMPXCHG if FUTEX
select HAVE_GENERIC_VDSO if MMU && 64BIT
select HAVE_PCI
select HAVE_PERF_EVENTS
select HAVE_PERF_REGS
select HAVE_PERF_USER_STACK_DUMP
select HAVE_SYSCALL_TRACEPOINTS
select IRQ_DOMAIN
select SPARSE_IRQ
select SYSCTL_EXCEPTION_TRACE
select HAVE_ARCH_TRACEHOOK
select HAVE_PCI
select MODULES_USE_ELF_RELA if MODULES
select MODULE_SECTIONS if MODULES
select THREAD_INFO_IN_TASK
select OF
select OF_EARLY_FLATTREE
select OF_IRQ
select PCI_DOMAINS_GENERIC if PCI
select PCI_MSI if PCI
select RISCV_INTC
select RISCV_TIMER
select GENERIC_IRQ_MULTI_HANDLER
select GENERIC_ARCH_TOPOLOGY if SMP
select ARCH_HAS_PTE_SPECIAL
select ARCH_HAS_MMIOWB
select ARCH_HAS_DEBUG_VIRTUAL if MMU
select HAVE_EBPF_JIT if MMU
select EDAC_SUPPORT
select ARCH_HAS_GIGANTIC_PAGE
select ARCH_HAS_SET_DIRECT_MAP
select ARCH_HAS_SET_MEMORY
select ARCH_HAS_STRICT_KERNEL_RWX if MMU
select ARCH_WANT_HUGE_PMD_SHARE if 64BIT
select SPARSEMEM_STATIC if 32BIT
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
select HAVE_ARCH_MMAP_RND_BITS if MMU
select ARCH_HAS_GCOV_PROFILE_ALL
select HAVE_COPY_THREAD_TLS
select HAVE_ARCH_KASAN if MMU && 64BIT
select HAVE_ARCH_KGDB
select HAVE_ARCH_KGDB_QXFER_PKT
select SPARSE_IRQ
select SYSCTL_EXCEPTION_TRACE
select THREAD_INFO_IN_TASK

config ARCH_MMAP_RND_BITS_MIN
default 18 if 64BIT
Expand Down Expand Up @@ -196,11 +202,11 @@ config ARCH_RV64I
bool "RV64I"
select 64BIT
select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 && GCC_VERSION >= 50000
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_DYNAMIC_FTRACE if MMU
select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_TRACER
select SWIOTLB if MMU

endchoice
Expand Down
7 changes: 7 additions & 0 deletions arch/riscv/include/asm/clocksource.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_CLOCKSOURCE_H
#define _ASM_CLOCKSOURCE_H

#include <asm/vdso/clocksource.h>

#endif
5 changes: 0 additions & 5 deletions arch/riscv/include/asm/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@
#include <linux/interrupt.h>
#include <linux/linkage.h>

#define NR_IRQS 0

void riscv_timer_interrupt(void);
void riscv_software_interrupt(void);

#include <asm-generic/irq.h>

#endif /* _ASM_RISCV_IRQ_H */
13 changes: 3 additions & 10 deletions arch/riscv/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#include <linux/const.h>

#include <vdso/processor.h>

#include <asm/ptrace.h>

/*
Expand Down Expand Up @@ -58,23 +60,14 @@ static inline void release_thread(struct task_struct *dead_task)
extern unsigned long get_wchan(struct task_struct *p);


static inline void cpu_relax(void)
{
#ifdef __riscv_muldiv
int dummy;
/* In lieu of a halt instruction, induce a long-latency stall. */
__asm__ __volatile__ ("div %0, %0, zero" : "=r" (dummy));
#endif
barrier();
}

static inline void wait_for_interrupt(void)
{
__asm__ __volatile__ ("wfi");
}

struct device_node;
int riscv_of_processor_hartid(struct device_node *node);
int riscv_of_parent_hartid(struct device_node *node);

extern void riscv_fill_hwcap(void);

Expand Down
3 changes: 3 additions & 0 deletions arch/riscv/include/asm/smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ void show_ipi_stats(struct seq_file *p, int prec);
/* SMP initialization hook for setup_arch */
void __init setup_smp(void);

/* Called from C code, this handles an IPI. */
void handle_IPI(struct pt_regs *regs);

/* Hook for the generic smp_call_function_many() routine. */
void arch_send_call_function_ipi_mask(struct cpumask *mask);

Expand Down
2 changes: 2 additions & 0 deletions arch/riscv/include/asm/vdso.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@

#include <linux/types.h>

#ifndef GENERIC_TIME_VSYSCALL
struct vdso_data {
};
#endif

/*
* The VDSO symbols are mapped into Linux so we can just use regular symbol
Expand Down
8 changes: 8 additions & 0 deletions arch/riscv/include/asm/vdso/clocksource.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_VDSOCLOCKSOURCE_H
#define __ASM_VDSOCLOCKSOURCE_H

#define VDSO_ARCH_CLOCKMODES \
VDSO_CLOCKMODE_ARCHTIMER

#endif
79 changes: 79 additions & 0 deletions arch/riscv/include/asm/vdso/gettimeofday.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_VDSO_GETTIMEOFDAY_H
#define __ASM_VDSO_GETTIMEOFDAY_H

#ifndef __ASSEMBLY__

#include <asm/unistd.h>
#include <asm/csr.h>
#include <uapi/linux/time.h>

#define VDSO_HAS_CLOCK_GETRES 1

static __always_inline
int gettimeofday_fallback(struct __kernel_old_timeval *_tv,
struct timezone *_tz)
{
register struct __kernel_old_timeval *tv asm("a0") = _tv;
register struct timezone *tz asm("a1") = _tz;
register long ret asm("a0");
register long nr asm("a7") = __NR_gettimeofday;

asm volatile ("ecall\n"
: "=r" (ret)
: "r"(tv), "r"(tz), "r"(nr)
: "memory");

return ret;
}

static __always_inline
long clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
{
register clockid_t clkid asm("a0") = _clkid;
register struct __kernel_timespec *ts asm("a1") = _ts;
register long ret asm("a0");
register long nr asm("a7") = __NR_clock_gettime;

asm volatile ("ecall\n"
: "=r" (ret)
: "r"(clkid), "r"(ts), "r"(nr)
: "memory");

return ret;
}

static __always_inline
int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
{
register clockid_t clkid asm("a0") = _clkid;
register struct __kernel_timespec *ts asm("a1") = _ts;
register long ret asm("a0");
register long nr asm("a7") = __NR_clock_getres;

asm volatile ("ecall\n"
: "=r" (ret)
: "r"(clkid), "r"(ts), "r"(nr)
: "memory");

return ret;
}

static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
{
/*
* The purpose of csr_read(CSR_TIME) is to trap the system into
* M-mode to obtain the value of CSR_TIME. Hence, unlike other
* architecture, no fence instructions surround the csr_read()
*/
return csr_read(CSR_TIME);
}

static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
{
return _vdso_data;
}

#endif /* !__ASSEMBLY__ */

#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
19 changes: 19 additions & 0 deletions arch/riscv/include/asm/vdso/processor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __ASM_VDSO_PROCESSOR_H
#define __ASM_VDSO_PROCESSOR_H

#ifndef __ASSEMBLY__

static inline void cpu_relax(void)
{
#ifdef __riscv_muldiv
int dummy;
/* In lieu of a halt instruction, induce a long-latency stall. */
__asm__ __volatile__ ("div %0, %0, zero" : "=r" (dummy));
#endif
barrier();
}

#endif /* __ASSEMBLY__ */

#endif /* __ASM_VDSO_PROCESSOR_H */
27 changes: 27 additions & 0 deletions arch/riscv/include/asm/vdso/vsyscall.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_VDSO_VSYSCALL_H
#define __ASM_VDSO_VSYSCALL_H

#ifndef __ASSEMBLY__

#include <linux/timekeeper_internal.h>
#include <vdso/datapage.h>

extern struct vdso_data *vdso_data;

/*
* Update the vDSO data page to keep in sync with kernel timekeeping.
*/
static __always_inline struct vdso_data *__riscv_get_k_vdso_data(void)
{
return vdso_data;
}

#define __arch_get_k_vdso_data __riscv_get_k_vdso_data

/* The asm-generic header needs to be included after the definitions above */
#include <asm-generic/vdso/vsyscall.h>

#endif /* !__ASSEMBLY__ */

#endif /* __ASM_VDSO_VSYSCALL_H */
16 changes: 16 additions & 0 deletions arch/riscv/kernel/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@ int riscv_of_processor_hartid(struct device_node *node)
return hart;
}

/*
* Find hart ID of the CPU DT node under which given DT node falls.
*
* To achieve this, we walk up the DT tree until we find an active
* RISC-V core (HART) node and extract the cpuid from it.
*/
int riscv_of_parent_hartid(struct device_node *node)
{
for (; node; node = node->parent) {
if (of_device_is_compatible(node, "riscv"))
return riscv_of_processor_hartid(node);
}

return -1;
}

#ifdef CONFIG_PROC_FS

static void print_isa(struct seq_file *f, const char *isa)
Expand Down
4 changes: 3 additions & 1 deletion arch/riscv/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ _save_context:

/* Handle interrupts */
move a0, sp /* pt_regs */
tail do_IRQ
la a1, handle_arch_irq
REG_L a1, (a1)
jr a1
1:
/*
* Exceptions run with interrupts enabled or disabled depending on the
Expand Down
Loading

0 comments on commit cd16ed3

Please sign in to comment.