Skip to content

Commit bdcf11d

Browse files
committed
Merge tag 'riscv-for-linus-5.9-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux
Pull RISC-V fixes from Palmer Dabbelt: - A fix for a lockdep issue to avoid an asserting triggering during early boot. There shouldn't be any incorrect behavior as the system isn't concurrent at the time. - The addition of a missing fence when installing early fixmap mappings. - A corretion to the K210 device tree's interrupt map. - A fix for M-mode timer handling on the K210. * tag 'riscv-for-linus-5.9-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: RISC-V: Resurrect the MMIO timer implementation for M-mode systems riscv: Fix Kendryte K210 device tree riscv: Add sfence.vma after early page table changes RISC-V: Take text_mutex in ftrace_init_nop()
2 parents d0373c1 + d5be89a commit bdcf11d

8 files changed

Lines changed: 104 additions & 6 deletions

File tree

arch/riscv/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ config RISCV
3232
select ARCH_WANT_FRAME_POINTERS
3333
select ARCH_WANT_HUGE_PMD_SHARE if 64BIT
3434
select CLONE_BACKWARDS
35+
select CLINT_TIMER if !MMU
3536
select COMMON_CLK
3637
select EDAC_SUPPORT
3738
select GENERIC_ARCH_TOPOLOGY if SMP

arch/riscv/boot/dts/kendryte/k210.dtsi

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,12 @@
9595
#clock-cells = <1>;
9696
};
9797

98-
clint0: interrupt-controller@2000000 {
98+
clint0: clint@2000000 {
99+
#interrupt-cells = <1>;
99100
compatible = "riscv,clint0";
100101
reg = <0x2000000 0xC000>;
101-
interrupts-extended = <&cpu0_intc 3>, <&cpu1_intc 3>;
102+
interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7
103+
&cpu1_intc 3 &cpu1_intc 7>;
102104
clocks = <&sysctl K210_CLK_ACLK>;
103105
};
104106

arch/riscv/include/asm/clint.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Copyright (C) 2020 Google, Inc
4+
*/
5+
6+
#ifndef _ASM_RISCV_CLINT_H
7+
#define _ASM_RISCV_CLINT_H
8+
9+
#include <linux/types.h>
10+
#include <asm/mmio.h>
11+
12+
#ifdef CONFIG_RISCV_M_MODE
13+
/*
14+
* This lives in the CLINT driver, but is accessed directly by timex.h to avoid
15+
* any overhead when accessing the MMIO timer.
16+
*
17+
* The ISA defines mtime as a 64-bit memory-mapped register that increments at
18+
* a constant frequency, but it doesn't define some other constraints we depend
19+
* on (most notably ordering constraints, but also some simpler stuff like the
20+
* memory layout). Thus, this is called "clint_time_val" instead of something
21+
* like "riscv_mtime", to signify that these non-ISA assumptions must hold.
22+
*/
23+
extern u64 __iomem *clint_time_val;
24+
#endif
25+
26+
#endif

arch/riscv/include/asm/ftrace.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ do { \
6666
* Let auipc+jalr be the basic *mcount unit*, so we make it 8 bytes here.
6767
*/
6868
#define MCOUNT_INSN_SIZE 8
69+
70+
#ifndef __ASSEMBLY__
71+
struct dyn_ftrace;
72+
int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
73+
#define ftrace_init_nop ftrace_init_nop
74+
#endif
75+
6976
#endif
7077

7178
#endif /* _ASM_RISCV_FTRACE_H */

arch/riscv/include/asm/timex.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,31 @@
1010

1111
typedef unsigned long cycles_t;
1212

13+
#ifdef CONFIG_RISCV_M_MODE
14+
15+
#include <asm/clint.h>
16+
17+
#ifdef CONFIG_64BIT
18+
static inline cycles_t get_cycles(void)
19+
{
20+
return readq_relaxed(clint_time_val);
21+
}
22+
#else /* !CONFIG_64BIT */
23+
static inline u32 get_cycles(void)
24+
{
25+
return readl_relaxed(((u32 *)clint_time_val));
26+
}
27+
#define get_cycles get_cycles
28+
29+
static inline u32 get_cycles_hi(void)
30+
{
31+
return readl_relaxed(((u32 *)clint_time_val) + 1);
32+
}
33+
#define get_cycles_hi get_cycles_hi
34+
#endif /* CONFIG_64BIT */
35+
36+
#else /* CONFIG_RISCV_M_MODE */
37+
1338
static inline cycles_t get_cycles(void)
1439
{
1540
return csr_read(CSR_TIME);
@@ -41,6 +66,8 @@ static inline u64 get_cycles64(void)
4166
}
4267
#endif /* CONFIG_64BIT */
4368

69+
#endif /* !CONFIG_RISCV_M_MODE */
70+
4471
#define ARCH_HAS_READ_CURRENT_TIMER
4572
static inline int read_current_timer(unsigned long *timer_val)
4673
{

arch/riscv/kernel/ftrace.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,25 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
9797
return __ftrace_modify_call(rec->ip, addr, false);
9898
}
9999

100+
101+
/*
102+
* This is called early on, and isn't wrapped by
103+
* ftrace_arch_code_modify_{prepare,post_process}() and therefor doesn't hold
104+
* text_mutex, which triggers a lockdep failure. SMP isn't running so we could
105+
* just directly poke the text, but it's simpler to just take the lock
106+
* ourselves.
107+
*/
108+
int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
109+
{
110+
int out;
111+
112+
ftrace_arch_code_modify_prepare();
113+
out = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
114+
ftrace_arch_code_modify_post_process();
115+
116+
return out;
117+
}
118+
100119
int ftrace_update_ftrace_func(ftrace_func_t func)
101120
{
102121
int ret = __ftrace_modify_call((unsigned long)&ftrace_call,

arch/riscv/mm/init.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,12 +226,11 @@ void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)
226226

227227
ptep = &fixmap_pte[pte_index(addr)];
228228

229-
if (pgprot_val(prot)) {
229+
if (pgprot_val(prot))
230230
set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));
231-
} else {
231+
else
232232
pte_clear(&init_mm, addr, ptep);
233-
local_flush_tlb_page(addr);
234-
}
233+
local_flush_tlb_page(addr);
235234
}
236235

237236
static pte_t *__init get_pte_virt(phys_addr_t pa)

drivers/clocksource/timer-clint.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
#include <linux/interrupt.h>
2020
#include <linux/of_irq.h>
2121
#include <linux/smp.h>
22+
#include <linux/timex.h>
23+
24+
#ifndef CONFIG_RISCV_M_MODE
25+
#include <asm/clint.h>
26+
#endif
2227

2328
#define CLINT_IPI_OFF 0
2429
#define CLINT_TIMER_CMP_OFF 0x4000
@@ -31,6 +36,10 @@ static u64 __iomem *clint_timer_val;
3136
static unsigned long clint_timer_freq;
3237
static unsigned int clint_timer_irq;
3338

39+
#ifdef CONFIG_RISCV_M_MODE
40+
u64 __iomem *clint_time_val;
41+
#endif
42+
3443
static void clint_send_ipi(const struct cpumask *target)
3544
{
3645
unsigned int cpu;
@@ -184,6 +193,14 @@ static int __init clint_timer_init_dt(struct device_node *np)
184193
clint_timer_val = base + CLINT_TIMER_VAL_OFF;
185194
clint_timer_freq = riscv_timebase;
186195

196+
#ifdef CONFIG_RISCV_M_MODE
197+
/*
198+
* Yes, that's an odd naming scheme. time_val is public, but hopefully
199+
* will die in favor of something cleaner.
200+
*/
201+
clint_time_val = clint_timer_val;
202+
#endif
203+
187204
pr_info("%pOFP: timer running at %ld Hz\n", np, clint_timer_freq);
188205

189206
rc = clocksource_register_hz(&clint_clocksource, clint_timer_freq);

0 commit comments

Comments
 (0)