Skip to content

Commit

Permalink
Merge tag 'riscv-for-linus-5.9-rc6' 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 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()
  • Loading branch information
torvalds committed Sep 20, 2020
2 parents d0373c1 + d5be89a commit bdcf11d
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 6 deletions.
1 change: 1 addition & 0 deletions arch/riscv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ config RISCV
select ARCH_WANT_FRAME_POINTERS
select ARCH_WANT_HUGE_PMD_SHARE if 64BIT
select CLONE_BACKWARDS
select CLINT_TIMER if !MMU
select COMMON_CLK
select EDAC_SUPPORT
select GENERIC_ARCH_TOPOLOGY if SMP
Expand Down
6 changes: 4 additions & 2 deletions arch/riscv/boot/dts/kendryte/k210.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,12 @@
#clock-cells = <1>;
};

clint0: interrupt-controller@2000000 {
clint0: clint@2000000 {
#interrupt-cells = <1>;
compatible = "riscv,clint0";
reg = <0x2000000 0xC000>;
interrupts-extended = <&cpu0_intc 3>, <&cpu1_intc 3>;
interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7
&cpu1_intc 3 &cpu1_intc 7>;
clocks = <&sysctl K210_CLK_ACLK>;
};

Expand Down
26 changes: 26 additions & 0 deletions arch/riscv/include/asm/clint.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2020 Google, Inc
*/

#ifndef _ASM_RISCV_CLINT_H
#define _ASM_RISCV_CLINT_H

#include <linux/types.h>
#include <asm/mmio.h>

#ifdef CONFIG_RISCV_M_MODE
/*
* This lives in the CLINT driver, but is accessed directly by timex.h to avoid
* any overhead when accessing the MMIO timer.
*
* The ISA defines mtime as a 64-bit memory-mapped register that increments at
* a constant frequency, but it doesn't define some other constraints we depend
* on (most notably ordering constraints, but also some simpler stuff like the
* memory layout). Thus, this is called "clint_time_val" instead of something
* like "riscv_mtime", to signify that these non-ISA assumptions must hold.
*/
extern u64 __iomem *clint_time_val;
#endif

#endif
7 changes: 7 additions & 0 deletions arch/riscv/include/asm/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ do { \
* Let auipc+jalr be the basic *mcount unit*, so we make it 8 bytes here.
*/
#define MCOUNT_INSN_SIZE 8

#ifndef __ASSEMBLY__
struct dyn_ftrace;
int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
#define ftrace_init_nop ftrace_init_nop
#endif

#endif

#endif /* _ASM_RISCV_FTRACE_H */
27 changes: 27 additions & 0 deletions arch/riscv/include/asm/timex.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,31 @@

typedef unsigned long cycles_t;

#ifdef CONFIG_RISCV_M_MODE

#include <asm/clint.h>

#ifdef CONFIG_64BIT
static inline cycles_t get_cycles(void)
{
return readq_relaxed(clint_time_val);
}
#else /* !CONFIG_64BIT */
static inline u32 get_cycles(void)
{
return readl_relaxed(((u32 *)clint_time_val));
}
#define get_cycles get_cycles

static inline u32 get_cycles_hi(void)
{
return readl_relaxed(((u32 *)clint_time_val) + 1);
}
#define get_cycles_hi get_cycles_hi
#endif /* CONFIG_64BIT */

#else /* CONFIG_RISCV_M_MODE */

static inline cycles_t get_cycles(void)
{
return csr_read(CSR_TIME);
Expand Down Expand Up @@ -41,6 +66,8 @@ static inline u64 get_cycles64(void)
}
#endif /* CONFIG_64BIT */

#endif /* !CONFIG_RISCV_M_MODE */

#define ARCH_HAS_READ_CURRENT_TIMER
static inline int read_current_timer(unsigned long *timer_val)
{
Expand Down
19 changes: 19 additions & 0 deletions arch/riscv/kernel/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,25 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
return __ftrace_modify_call(rec->ip, addr, false);
}


/*
* This is called early on, and isn't wrapped by
* ftrace_arch_code_modify_{prepare,post_process}() and therefor doesn't hold
* text_mutex, which triggers a lockdep failure. SMP isn't running so we could
* just directly poke the text, but it's simpler to just take the lock
* ourselves.
*/
int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
{
int out;

ftrace_arch_code_modify_prepare();
out = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
ftrace_arch_code_modify_post_process();

return out;
}

int ftrace_update_ftrace_func(ftrace_func_t func)
{
int ret = __ftrace_modify_call((unsigned long)&ftrace_call,
Expand Down
7 changes: 3 additions & 4 deletions arch/riscv/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,12 +226,11 @@ void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)

ptep = &fixmap_pte[pte_index(addr)];

if (pgprot_val(prot)) {
if (pgprot_val(prot))
set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));
} else {
else
pte_clear(&init_mm, addr, ptep);
local_flush_tlb_page(addr);
}
local_flush_tlb_page(addr);
}

static pte_t *__init get_pte_virt(phys_addr_t pa)
Expand Down
17 changes: 17 additions & 0 deletions drivers/clocksource/timer-clint.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
#include <linux/interrupt.h>
#include <linux/of_irq.h>
#include <linux/smp.h>
#include <linux/timex.h>

#ifndef CONFIG_RISCV_M_MODE
#include <asm/clint.h>
#endif

#define CLINT_IPI_OFF 0
#define CLINT_TIMER_CMP_OFF 0x4000
Expand All @@ -31,6 +36,10 @@ static u64 __iomem *clint_timer_val;
static unsigned long clint_timer_freq;
static unsigned int clint_timer_irq;

#ifdef CONFIG_RISCV_M_MODE
u64 __iomem *clint_time_val;
#endif

static void clint_send_ipi(const struct cpumask *target)
{
unsigned int cpu;
Expand Down Expand Up @@ -184,6 +193,14 @@ static int __init clint_timer_init_dt(struct device_node *np)
clint_timer_val = base + CLINT_TIMER_VAL_OFF;
clint_timer_freq = riscv_timebase;

#ifdef CONFIG_RISCV_M_MODE
/*
* Yes, that's an odd naming scheme. time_val is public, but hopefully
* will die in favor of something cleaner.
*/
clint_time_val = clint_timer_val;
#endif

pr_info("%pOFP: timer running at %ld Hz\n", np, clint_timer_freq);

rc = clocksource_register_hz(&clint_clocksource, clint_timer_freq);
Expand Down

0 comments on commit bdcf11d

Please sign in to comment.