linux-riscv.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* RISC-V nommu support v5
@ 2019-10-17 17:37 Christoph Hellwig
  2019-10-17 17:37 ` [PATCH 01/15] riscv: cleanup <asm/bug.h> Christoph Hellwig
                   ` (15 more replies)
  0 siblings, 16 replies; 41+ messages in thread
From: Christoph Hellwig @ 2019-10-17 17:37 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley; +Cc: Damien Le Moal, linux-riscv, linux-kernel

Hi all,

below is a series to support nommu mode on RISC-V.  For now this series
just works under qemu with the qemu-virt platform, but Damien has also
been able to get kernel based on this tree with additional driver hacks
to work on the Kendryte KD210, but that will take a while to cleanup
an upstream.

A git tree is available here:

    git://git.infradead.org/users/hch/riscv.git riscv-nommu.5

Gitweb:

    http://git.infradead.org/users/hch/riscv.git/shortlog/refs/heads/riscv-nommu.5

I've also pushed out a builtroot branch that can build a RISC-V nommu
root filesystem here:

   git://git.infradead.org/users/hch/buildroot.git riscv-nommu.2

Gitweb:

   http://git.infradead.org/users/hch/buildroot.git/shortlog/refs/heads/riscv-nommu.2


Changes since v4:
 - rebased to 5.4-rc + latest riscv fixes
 - clean up do_trap_break
 - fix an SR_XPIE issue (Paul Walmsley)
 - use the symbolic PAGE_OFFSET value in the flat loader
   (Aurabindo Jayamohanan)

Changes since v3:
 - improve a few commit message
 - cleanup riscv_cpuid_to_hartid_mask
 - cleanup the timer handling
 - cleanup the IPI handling a little more
 - renamed CONFIG_M_MODE to CONFIG_RISCV_M_MODE
 - split out CONFIG_RISCV_SBI to make some of the ifdefs more obbious
 - use IS_ENABLED wherever possible instead of if ifdefs to make the
   code more readable

Changes since v2:
 - rebased to 5.3-rc
 - remove the EFI image header for nommu builds
 - set ARCH_SLAB_MINALIGN to ensure stack alignment in the flat binary
   loader
 - minor comment improvement
 - use #defines for more CSRs

Changes since v1:
 - fixes so that a kernel with this series still work on builds with an
   IOMMU
 - small clint cleanups
 - the binfmt_flat base and buildroot now don't put arguments on the stack

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 01/15] riscv: cleanup <asm/bug.h>
  2019-10-17 17:37 RISC-V nommu support v5 Christoph Hellwig
@ 2019-10-17 17:37 ` Christoph Hellwig
  2019-10-18  2:50   ` Anup Patel
  2019-10-23 22:04   ` Paul Walmsley
  2019-10-17 17:37 ` [PATCH 02/15] riscv: cleanup do_trap_break Christoph Hellwig
                   ` (14 subsequent siblings)
  15 siblings, 2 replies; 41+ messages in thread
From: Christoph Hellwig @ 2019-10-17 17:37 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley; +Cc: Damien Le Moal, linux-riscv, linux-kernel

Remove various not required ifdefs and externs.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/riscv/include/asm/bug.h | 16 +++-------------
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/arch/riscv/include/asm/bug.h b/arch/riscv/include/asm/bug.h
index 07ceee8b1747..75604fec1b1b 100644
--- a/arch/riscv/include/asm/bug.h
+++ b/arch/riscv/include/asm/bug.h
@@ -12,7 +12,6 @@
 
 #include <asm/asm.h>
 
-#ifdef CONFIG_GENERIC_BUG
 #define __INSN_LENGTH_MASK  _UL(0x3)
 #define __INSN_LENGTH_32    _UL(0x3)
 #define __COMPRESSED_INSN_MASK	_UL(0xffff)
@@ -20,7 +19,6 @@
 #define __BUG_INSN_32	_UL(0x00100073) /* ebreak */
 #define __BUG_INSN_16	_UL(0x9002) /* c.ebreak */
 
-#ifndef __ASSEMBLY__
 typedef u32 bug_insn_t;
 
 #ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
@@ -43,6 +41,7 @@ typedef u32 bug_insn_t;
 	RISCV_SHORT " %2"
 #endif
 
+#ifdef CONFIG_GENERIC_BUG
 #define __BUG_FLAGS(flags)					\
 do {								\
 	__asm__ __volatile__ (					\
@@ -58,14 +57,10 @@ do {								\
 		  "i" (flags),					\
 		  "i" (sizeof(struct bug_entry)));              \
 } while (0)
-
-#endif /* !__ASSEMBLY__ */
 #else /* CONFIG_GENERIC_BUG */
-#ifndef __ASSEMBLY__
 #define __BUG_FLAGS(flags) do {					\
 	__asm__ __volatile__ ("ebreak\n");			\
 } while (0)
-#endif /* !__ASSEMBLY__ */
 #endif /* CONFIG_GENERIC_BUG */
 
 #define BUG() do {						\
@@ -79,15 +74,10 @@ do {								\
 
 #include <asm-generic/bug.h>
 
-#ifndef __ASSEMBLY__
-
 struct pt_regs;
 struct task_struct;
 
-extern void die(struct pt_regs *regs, const char *str);
-extern void do_trap(struct pt_regs *regs, int signo, int code,
-	unsigned long addr);
-
-#endif /* !__ASSEMBLY__ */
+void die(struct pt_regs *regs, const char *str);
+void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr);
 
 #endif /* _ASM_RISCV_BUG_H */
-- 
2.20.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 02/15] riscv: cleanup do_trap_break
  2019-10-17 17:37 RISC-V nommu support v5 Christoph Hellwig
  2019-10-17 17:37 ` [PATCH 01/15] riscv: cleanup <asm/bug.h> Christoph Hellwig
@ 2019-10-17 17:37 ` Christoph Hellwig
  2019-10-18  2:51   ` Anup Patel
  2019-10-23 22:05   ` Paul Walmsley
  2019-10-17 17:37 ` [PATCH 03/15] riscv: abstract out CSR names for supervisor vs machine mode Christoph Hellwig
                   ` (13 subsequent siblings)
  15 siblings, 2 replies; 41+ messages in thread
From: Christoph Hellwig @ 2019-10-17 17:37 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley; +Cc: Damien Le Moal, linux-riscv, linux-kernel

If we always compile the get_break_insn_length inline function we can
remove the ifdefs and let dead code elimination take care of the warn
branch that is now unreadable because the report_bug stub always
returns BUG_TRAP_TYPE_BUG.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/riscv/kernel/traps.c | 26 ++++++--------------------
 1 file changed, 6 insertions(+), 20 deletions(-)

diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 1ac75f7d0bff..10a17e545f43 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -111,7 +111,6 @@ DO_ERROR_INFO(do_trap_ecall_s,
 DO_ERROR_INFO(do_trap_ecall_m,
 	SIGILL, ILL_ILLTRP, "environment call from M-mode");
 
-#ifdef CONFIG_GENERIC_BUG
 static inline unsigned long get_break_insn_length(unsigned long pc)
 {
 	bug_insn_t insn;
@@ -120,28 +119,15 @@ static inline unsigned long get_break_insn_length(unsigned long pc)
 		return 0;
 	return (((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) ? 4UL : 2UL);
 }
-#endif /* CONFIG_GENERIC_BUG */
 
 asmlinkage void do_trap_break(struct pt_regs *regs)
 {
-	if (user_mode(regs)) {
-		force_sig_fault(SIGTRAP, TRAP_BRKPT,
-				(void __user *)(regs->sepc));
-		return;
-	}
-#ifdef CONFIG_GENERIC_BUG
-	{
-		enum bug_trap_type type;
-
-		type = report_bug(regs->sepc, regs);
-		if (type == BUG_TRAP_TYPE_WARN) {
-			regs->sepc += get_break_insn_length(regs->sepc);
-			return;
-		}
-	}
-#endif /* CONFIG_GENERIC_BUG */
-
-	die(regs, "Kernel BUG");
+	if (user_mode(regs))
+		force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->sepc);
+	else if (report_bug(regs->sepc, regs) == BUG_TRAP_TYPE_WARN)
+		regs->sepc += get_break_insn_length(regs->sepc);
+	else
+		die(regs, "Kernel BUG");
 }
 
 #ifdef CONFIG_GENERIC_BUG
-- 
2.20.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 03/15] riscv: abstract out CSR names for supervisor vs machine mode
  2019-10-17 17:37 RISC-V nommu support v5 Christoph Hellwig
  2019-10-17 17:37 ` [PATCH 01/15] riscv: cleanup <asm/bug.h> Christoph Hellwig
  2019-10-17 17:37 ` [PATCH 02/15] riscv: cleanup do_trap_break Christoph Hellwig
@ 2019-10-17 17:37 ` Christoph Hellwig
  2019-10-18  2:51   ` Anup Patel
  2019-10-18 23:55   ` Paul Walmsley
  2019-10-17 17:37 ` [PATCH 04/15] riscv: don't allow selecting SBI based drivers for M-mode Christoph Hellwig
                   ` (12 subsequent siblings)
  15 siblings, 2 replies; 41+ messages in thread
From: Christoph Hellwig @ 2019-10-17 17:37 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley
  Cc: Atish Patra, Damien Le Moal, linux-riscv, linux-kernel

Many of the privileged CSRs exist in a supervisor and machine version
that are used very similarly.  Provide a new X-naming layer so that
we don't have to ifdef everywhere for M-mode Linux support.

Contains contributions from Damien Le Moal <Damien.LeMoal@wdc.com>.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
---
 arch/riscv/Kconfig                 |  4 ++
 arch/riscv/include/asm/asm.h       |  6 +++
 arch/riscv/include/asm/csr.h       | 58 +++++++++++++++++++++++--
 arch/riscv/include/asm/irqflags.h  | 12 +++---
 arch/riscv/include/asm/processor.h |  2 +-
 arch/riscv/include/asm/ptrace.h    | 16 +++----
 arch/riscv/include/asm/switch_to.h | 10 ++---
 arch/riscv/kernel/asm-offsets.c    |  8 ++--
 arch/riscv/kernel/entry.S          | 68 ++++++++++++++++--------------
 arch/riscv/kernel/fpu.S            |  8 ++--
 arch/riscv/kernel/head.S           | 12 +++---
 arch/riscv/kernel/irq.c            |  4 +-
 arch/riscv/kernel/process.c        | 15 ++++---
 arch/riscv/kernel/signal.c         | 21 +++++----
 arch/riscv/kernel/traps.c          | 16 +++----
 arch/riscv/lib/uaccess.S           | 12 +++---
 arch/riscv/mm/extable.c            |  4 +-
 arch/riscv/mm/fault.c              |  6 +--
 drivers/clocksource/timer-riscv.c  |  8 ++--
 drivers/irqchip/irq-sifive-plic.c  |  4 +-
 20 files changed, 181 insertions(+), 113 deletions(-)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 8eebbc8860bb..86b7e8b0471c 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -72,6 +72,10 @@ config ARCH_MMAP_RND_BITS_MAX
 	default 24 if 64BIT # SV39 based
 	default 17
 
+# set if we run in machine mode, cleared if we run in supervisor mode
+config RISCV_M_MODE
+	bool
+
 config MMU
 	def_bool y
 
diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
index 9c992a88d858..e362fb741c76 100644
--- a/arch/riscv/include/asm/asm.h
+++ b/arch/riscv/include/asm/asm.h
@@ -66,4 +66,10 @@
 #error "Unexpected __SIZEOF_SHORT__"
 #endif
 
+#ifdef CONFIG_RISCV_M_MODE
+# define Xret		mret
+#else
+# define Xret		sret
+#endif
+
 #endif /* _ASM_RISCV_ASM_H */
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index a18923fa23c8..0dae5c361f29 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -11,8 +11,11 @@
 
 /* Status register flags */
 #define SR_SIE		_AC(0x00000002, UL) /* Supervisor Interrupt Enable */
+#define SR_MIE		_AC(0x00000008, UL) /* Machine Interrupt Enable */
 #define SR_SPIE		_AC(0x00000020, UL) /* Previous Supervisor IE */
+#define SR_MPIE		_AC(0x00000080, UL) /* Previous Machine IE */
 #define SR_SPP		_AC(0x00000100, UL) /* Previously Supervisor */
+#define SR_MPP		_AC(0x00001800, UL) /* Previously Machine */
 #define SR_SUM		_AC(0x00040000, UL) /* Supervisor User Memory Access */
 
 #define SR_FS		_AC(0x00006000, UL) /* Floating-point Status */
@@ -44,8 +47,8 @@
 #define SATP_MODE	SATP_MODE_39
 #endif
 
-/* SCAUSE */
-#define SCAUSE_IRQ_FLAG		(_AC(1, UL) << (__riscv_xlen - 1))
+/* *CAUSE */
+#define XCAUSE_IRQ_FLAG		(_AC(1, UL) << (__riscv_xlen - 1))
 
 #define IRQ_U_SOFT		0
 #define IRQ_S_SOFT		1
@@ -67,11 +70,26 @@
 #define EXC_LOAD_PAGE_FAULT	13
 #define EXC_STORE_PAGE_FAULT	15
 
-/* SIE (Interrupt Enable) and SIP (Interrupt Pending) flags */
+/* SIE/SIP (Machine Interrupt Enable/Pending) flags */
+#define MIE_MSIE		(_AC(0x1, UL) << IRQ_M_SOFT)
+#define MIE_MTIE		(_AC(0x1, UL) << IRQ_M_TIMER)
+#define MIE_MEIE		(_AC(0x1, UL) << IRQ_M_EXT)
+
+/* SIE/SIP (Supervisor Interrupt Enable/Pending) flags */
 #define SIE_SSIE		(_AC(0x1, UL) << IRQ_S_SOFT)
 #define SIE_STIE		(_AC(0x1, UL) << IRQ_S_TIMER)
 #define SIE_SEIE		(_AC(0x1, UL) << IRQ_S_EXT)
 
+/* symbolic CSR names: */
+#define CSR_MSTATUS		0x300
+#define CSR_MIE			0x304
+#define CSR_MTVEC		0x305
+#define CSR_MSCRATCH		0x340
+#define CSR_MEPC		0x341
+#define CSR_MCAUSE		0x342
+#define CSR_MTVAL		0x343
+#define CSR_MIP			0x344
+
 #define CSR_CYCLE		0xc00
 #define CSR_TIME		0xc01
 #define CSR_INSTRET		0xc02
@@ -89,6 +107,40 @@
 #define CSR_TIMEH		0xc81
 #define CSR_INSTRETH		0xc82
 
+#ifdef CONFIG_RISCV_M_MODE
+# define CSR_XSTATUS	CSR_MSTATUS
+# define CSR_XIE	CSR_MIE
+# define CSR_XTVEC	CSR_MTVEC
+# define CSR_XSCRATCH	CSR_MSCRATCH
+# define CSR_XEPC	CSR_MEPC
+# define CSR_XCAUSE	CSR_MCAUSE
+# define CSR_XTVAL	CSR_MTVAL
+# define CSR_XIP	CSR_MIP
+
+# define SR_XIE		SR_MIE
+# define SR_XPIE	SR_MPIE
+# define SR_XPP		SR_MPP
+
+# define XIE_XTIE	MIE_MTIE
+# define XIE_XEIE	MIE_MEIE
+#else /* CONFIG_RISCV_M_MODE */
+# define CSR_XSTATUS	CSR_SSTATUS
+# define CSR_XIE	CSR_SIE
+# define CSR_XTVEC	CSR_STVEC
+# define CSR_XSCRATCH	CSR_SSCRATCH
+# define CSR_XEPC	CSR_SEPC
+# define CSR_XCAUSE	CSR_SCAUSE
+# define CSR_XTVAL	CSR_STVAL
+# define CSR_XIP	CSR_SIP
+
+# define SR_XIE		SR_SIE
+# define SR_XPIE	SR_SPIE
+# define SR_XPP		SR_SPP
+
+# define XIE_XTIE	SIE_STIE
+# define XIE_XEIE	SIE_SEIE
+#endif /* CONFIG_RISCV_M_MODE */
+
 #ifndef __ASSEMBLY__
 
 #define csr_swap(csr, val)					\
diff --git a/arch/riscv/include/asm/irqflags.h b/arch/riscv/include/asm/irqflags.h
index e70f647ce3b7..ba2828a37d72 100644
--- a/arch/riscv/include/asm/irqflags.h
+++ b/arch/riscv/include/asm/irqflags.h
@@ -13,31 +13,31 @@
 /* read interrupt enabled status */
 static inline unsigned long arch_local_save_flags(void)
 {
-	return csr_read(CSR_SSTATUS);
+	return csr_read(CSR_XSTATUS);
 }
 
 /* unconditionally enable interrupts */
 static inline void arch_local_irq_enable(void)
 {
-	csr_set(CSR_SSTATUS, SR_SIE);
+	csr_set(CSR_XSTATUS, SR_XIE);
 }
 
 /* unconditionally disable interrupts */
 static inline void arch_local_irq_disable(void)
 {
-	csr_clear(CSR_SSTATUS, SR_SIE);
+	csr_clear(CSR_XSTATUS, SR_XIE);
 }
 
 /* get status and disable interrupts */
 static inline unsigned long arch_local_irq_save(void)
 {
-	return csr_read_clear(CSR_SSTATUS, SR_SIE);
+	return csr_read_clear(CSR_XSTATUS, SR_XIE);
 }
 
 /* test flags */
 static inline int arch_irqs_disabled_flags(unsigned long flags)
 {
-	return !(flags & SR_SIE);
+	return !(flags & SR_XIE);
 }
 
 /* test hardware interrupt enable bit */
@@ -49,7 +49,7 @@ static inline int arch_irqs_disabled(void)
 /* set interrupt enabled status */
 static inline void arch_local_irq_restore(unsigned long flags)
 {
-	csr_set(CSR_SSTATUS, flags & SR_SIE);
+	csr_set(CSR_XSTATUS, flags & SR_XIE);
 }
 
 #endif /* _ASM_RISCV_IRQFLAGS_H */
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index f539149d04c2..46f825e34575 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -42,7 +42,7 @@ struct thread_struct {
 	((struct pt_regs *)(task_stack_page(tsk) + THREAD_SIZE		\
 			    - ALIGN(sizeof(struct pt_regs), STACK_ALIGN)))
 
-#define KSTK_EIP(tsk)		(task_pt_regs(tsk)->sepc)
+#define KSTK_EIP(tsk)		(task_pt_regs(tsk)->xepc)
 #define KSTK_ESP(tsk)		(task_pt_regs(tsk)->sp)
 
 
diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h
index d48d1e13973c..7684d81d0e84 100644
--- a/arch/riscv/include/asm/ptrace.h
+++ b/arch/riscv/include/asm/ptrace.h
@@ -12,7 +12,7 @@
 #ifndef __ASSEMBLY__
 
 struct pt_regs {
-	unsigned long sepc;
+	unsigned long xepc;
 	unsigned long ra;
 	unsigned long sp;
 	unsigned long gp;
@@ -44,10 +44,10 @@ struct pt_regs {
 	unsigned long t4;
 	unsigned long t5;
 	unsigned long t6;
-	/* Supervisor CSRs */
-	unsigned long sstatus;
-	unsigned long sbadaddr;
-	unsigned long scause;
+	/* Supervisor/Machine CSRs */
+	unsigned long xstatus;
+	unsigned long xbadaddr;
+	unsigned long xcause;
 	/* a0 value before the syscall */
 	unsigned long orig_a0;
 };
@@ -58,18 +58,18 @@ struct pt_regs {
 #define REG_FMT "%08lx"
 #endif
 
-#define user_mode(regs) (((regs)->sstatus & SR_SPP) == 0)
+#define user_mode(regs) (((regs)->xstatus & SR_XPP) == 0)
 
 
 /* Helpers for working with the instruction pointer */
 static inline unsigned long instruction_pointer(struct pt_regs *regs)
 {
-	return regs->sepc;
+	return regs->xepc;
 }
 static inline void instruction_pointer_set(struct pt_regs *regs,
 					   unsigned long val)
 {
-	regs->sepc = val;
+	regs->xepc = val;
 }
 
 #define profile_pc(regs) instruction_pointer(regs)
diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
index f0227bdce0f0..77593105b367 100644
--- a/arch/riscv/include/asm/switch_to.h
+++ b/arch/riscv/include/asm/switch_to.h
@@ -16,19 +16,19 @@ extern void __fstate_restore(struct task_struct *restore_from);
 
 static inline void __fstate_clean(struct pt_regs *regs)
 {
-	regs->sstatus = (regs->sstatus & ~SR_FS) | SR_FS_CLEAN;
+	regs->xstatus = (regs->xstatus & ~SR_FS) | SR_FS_CLEAN;
 }
 
 static inline void fstate_off(struct task_struct *task,
 			      struct pt_regs *regs)
 {
-	regs->sstatus = (regs->sstatus & ~SR_FS) | SR_FS_OFF;
+	regs->xstatus = (regs->xstatus & ~SR_FS) | SR_FS_OFF;
 }
 
 static inline void fstate_save(struct task_struct *task,
 			       struct pt_regs *regs)
 {
-	if ((regs->sstatus & SR_FS) == SR_FS_DIRTY) {
+	if ((regs->xstatus & SR_FS) == SR_FS_DIRTY) {
 		__fstate_save(task);
 		__fstate_clean(regs);
 	}
@@ -37,7 +37,7 @@ static inline void fstate_save(struct task_struct *task,
 static inline void fstate_restore(struct task_struct *task,
 				  struct pt_regs *regs)
 {
-	if ((regs->sstatus & SR_FS) != SR_FS_OFF) {
+	if ((regs->xstatus & SR_FS) != SR_FS_OFF) {
 		__fstate_restore(task);
 		__fstate_clean(regs);
 	}
@@ -49,7 +49,7 @@ static inline void __switch_to_aux(struct task_struct *prev,
 	struct pt_regs *regs;
 
 	regs = task_pt_regs(prev);
-	if (unlikely(regs->sstatus & SR_SD))
+	if (unlikely(regs->xstatus & SR_SD))
 		fstate_save(prev, regs);
 	fstate_restore(next, task_pt_regs(next));
 }
diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
index 9f5628c38ac9..d631ad41917b 100644
--- a/arch/riscv/kernel/asm-offsets.c
+++ b/arch/riscv/kernel/asm-offsets.c
@@ -71,7 +71,7 @@ void asm_offsets(void)
 	OFFSET(TASK_THREAD_FCSR, task_struct, thread.fstate.fcsr);
 
 	DEFINE(PT_SIZE, sizeof(struct pt_regs));
-	OFFSET(PT_SEPC, pt_regs, sepc);
+	OFFSET(PT_XEPC, pt_regs, xepc);
 	OFFSET(PT_RA, pt_regs, ra);
 	OFFSET(PT_FP, pt_regs, s0);
 	OFFSET(PT_S0, pt_regs, s0);
@@ -105,9 +105,9 @@ void asm_offsets(void)
 	OFFSET(PT_T6, pt_regs, t6);
 	OFFSET(PT_GP, pt_regs, gp);
 	OFFSET(PT_ORIG_A0, pt_regs, orig_a0);
-	OFFSET(PT_SSTATUS, pt_regs, sstatus);
-	OFFSET(PT_SBADADDR, pt_regs, sbadaddr);
-	OFFSET(PT_SCAUSE, pt_regs, scause);
+	OFFSET(PT_XSTATUS, pt_regs, xstatus);
+	OFFSET(PT_XBADADDR, pt_regs, xbadaddr);
+	OFFSET(PT_XCAUSE, pt_regs, xcause);
 
 	/*
 	 * THREAD_{F,X}* might be larger than a S-type offset can handle, but
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 8ca479831142..c0b3732af1ea 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -26,14 +26,14 @@
 
 	/*
 	 * If coming from userspace, preserve the user thread pointer and load
-	 * the kernel thread pointer.  If we came from the kernel, sscratch
-	 * will contain 0, and we should continue on the current TP.
+	 * the kernel thread pointer.  If we came from the kernel, the scratch
+	 * register will contain 0, and we should continue on the current TP.
 	 */
-	csrrw tp, CSR_SSCRATCH, tp
+	csrrw tp, CSR_XSCRATCH, tp
 	bnez tp, _save_context
 
 _restore_kernel_tpsp:
-	csrr tp, CSR_SSCRATCH
+	csrr tp, CSR_XSCRATCH
 	REG_S sp, TASK_TI_KERNEL_SP(tp)
 _save_context:
 	REG_S sp, TASK_TI_USER_SP(tp)
@@ -79,16 +79,16 @@ _save_context:
 	li t0, SR_SUM | SR_FS
 
 	REG_L s0, TASK_TI_USER_SP(tp)
-	csrrc s1, CSR_SSTATUS, t0
-	csrr s2, CSR_SEPC
-	csrr s3, CSR_STVAL
-	csrr s4, CSR_SCAUSE
-	csrr s5, CSR_SSCRATCH
+	csrrc s1, CSR_XSTATUS, t0
+	csrr s2, CSR_XEPC
+	csrr s3, CSR_XTVAL
+	csrr s4, CSR_XCAUSE
+	csrr s5, CSR_XSCRATCH
 	REG_S s0, PT_SP(sp)
-	REG_S s1, PT_SSTATUS(sp)
-	REG_S s2, PT_SEPC(sp)
-	REG_S s3, PT_SBADADDR(sp)
-	REG_S s4, PT_SCAUSE(sp)
+	REG_S s1, PT_XSTATUS(sp)
+	REG_S s2, PT_XEPC(sp)
+	REG_S s3, PT_XBADADDR(sp)
+	REG_S s4, PT_XCAUSE(sp)
 	REG_S s5, PT_TP(sp)
 	.endm
 
@@ -97,7 +97,7 @@ _save_context:
  * registers from the stack.
  */
 	.macro RESTORE_ALL
-	REG_L a0, PT_SSTATUS(sp)
+	REG_L a0, PT_XSTATUS(sp)
 	/*
 	 * The current load reservation is effectively part of the processor's
 	 * state, in the sense that load reservations cannot be shared between
@@ -115,11 +115,11 @@ _save_context:
 	 * completes, implementations are allowed to expand reservations to be
 	 * arbitrarily large.
 	 */
-	REG_L  a2, PT_SEPC(sp)
-	REG_SC x0, a2, PT_SEPC(sp)
+	REG_L  a2, PT_XEPC(sp)
+	REG_SC x0, a2, PT_XEPC(sp)
 
-	csrw CSR_SSTATUS, a0
-	csrw CSR_SEPC, a2
+	csrw CSR_XSTATUS, a0
+	csrw CSR_XEPC, a2
 
 	REG_L x1,  PT_RA(sp)
 	REG_L x3,  PT_GP(sp)
@@ -163,10 +163,10 @@ ENTRY(handle_exception)
 	SAVE_ALL
 
 	/*
-	 * Set sscratch register to 0, so that if a recursive exception
+	 * Set the scratch register to 0, so that if a recursive exception
 	 * occurs, the exception vector knows it came from the kernel
 	 */
-	csrw CSR_SSCRATCH, x0
+	csrw CSR_XSCRATCH, x0
 
 	/* Load the global pointer */
 .option push
@@ -186,10 +186,10 @@ ENTRY(handle_exception)
 	tail do_IRQ
 1:
 	/* Exceptions run with interrupts enabled or disabled
-	   depending on the state of sstatus.SR_SPIE */
-	andi t0, s1, SR_SPIE
+	   depending on the state of xstatus.SR_XPIE */
+	andi t0, s1, SR_XPIE
 	beqz t0, 1f
-	csrs CSR_SSTATUS, SR_SIE
+	csrs CSR_XSTATUS, SR_XIE
 
 1:
 	/* Handle syscalls */
@@ -217,7 +217,7 @@ handle_syscall:
 	 * scall instruction on sret
 	 */
 	addi s2, s2, 0x4
-	REG_S s2, PT_SEPC(sp)
+	REG_S s2, PT_XEPC(sp)
 	/* Trace syscalls, but only if requested by the user. */
 	REG_L t0, TASK_TI_FLAGS(tp)
 	andi t0, t0, _TIF_SYSCALL_WORK
@@ -244,9 +244,15 @@ ret_from_syscall:
 	bnez t0, handle_syscall_trace_exit
 
 ret_from_exception:
-	REG_L s0, PT_SSTATUS(sp)
-	csrc CSR_SSTATUS, SR_SIE
+	REG_L s0, PT_XSTATUS(sp)
+	csrc CSR_XSTATUS, SR_XIE
+#ifdef CONFIG_RISCV_M_MODE
+	/* the MPP value is too large to be used as an immediate arg for addi */
+	li t0, SR_MPP
+	and s0, s0, t0
+#else
 	andi s0, s0, SR_SPP
+#endif
 	bnez s0, resume_kernel
 
 resume_userspace:
@@ -260,14 +266,14 @@ resume_userspace:
 	REG_S s0, TASK_TI_KERNEL_SP(tp)
 
 	/*
-	 * Save TP into sscratch, so we can find the kernel data structures
-	 * again.
+	 * Save TP into the scratch register , so we can find the kernel data
+	 * structures again.
 	 */
-	csrw CSR_SSCRATCH, tp
+	csrw CSR_XSCRATCH, tp
 
 restore_all:
 	RESTORE_ALL
-	sret
+	Xret
 
 #if IS_ENABLED(CONFIG_PREEMPT)
 resume_kernel:
@@ -287,7 +293,7 @@ work_pending:
 	bnez s1, work_resched
 work_notifysig:
 	/* Handle pending signals and notify-resume requests */
-	csrs CSR_SSTATUS, SR_SIE /* Enable interrupts for do_notify_resume() */
+	csrs CSR_XSTATUS, SR_XIE /* Enable interrupts for do_notify_resume() */
 	move a0, sp /* pt_regs */
 	move a1, s0 /* current_thread_info->flags */
 	tail do_notify_resume
diff --git a/arch/riscv/kernel/fpu.S b/arch/riscv/kernel/fpu.S
index 631d31540660..1dade31f4564 100644
--- a/arch/riscv/kernel/fpu.S
+++ b/arch/riscv/kernel/fpu.S
@@ -23,7 +23,7 @@ ENTRY(__fstate_save)
 	li  a2,  TASK_THREAD_F0
 	add a0, a0, a2
 	li t1, SR_FS
-	csrs CSR_SSTATUS, t1
+	csrs CSR_XSTATUS, t1
 	frcsr t0
 	fsd f0,  TASK_THREAD_F0_F0(a0)
 	fsd f1,  TASK_THREAD_F1_F0(a0)
@@ -58,7 +58,7 @@ ENTRY(__fstate_save)
 	fsd f30, TASK_THREAD_F30_F0(a0)
 	fsd f31, TASK_THREAD_F31_F0(a0)
 	sw t0, TASK_THREAD_FCSR_F0(a0)
-	csrc CSR_SSTATUS, t1
+	csrc CSR_XSTATUS, t1
 	ret
 ENDPROC(__fstate_save)
 
@@ -67,7 +67,7 @@ ENTRY(__fstate_restore)
 	add a0, a0, a2
 	li t1, SR_FS
 	lw t0, TASK_THREAD_FCSR_F0(a0)
-	csrs CSR_SSTATUS, t1
+	csrs CSR_XSTATUS, t1
 	fld f0,  TASK_THREAD_F0_F0(a0)
 	fld f1,  TASK_THREAD_F1_F0(a0)
 	fld f2,  TASK_THREAD_F2_F0(a0)
@@ -101,6 +101,6 @@ ENTRY(__fstate_restore)
 	fld f30, TASK_THREAD_F30_F0(a0)
 	fld f31, TASK_THREAD_F31_F0(a0)
 	fscsr t0
-	csrc CSR_SSTATUS, t1
+	csrc CSR_XSTATUS, t1
 	ret
 ENDPROC(__fstate_restore)
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 72f89b7590dd..679e63d29edb 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -47,8 +47,8 @@ ENTRY(_start)
 .global _start_kernel
 _start_kernel:
 	/* Mask all interrupts */
-	csrw CSR_SIE, zero
-	csrw CSR_SIP, zero
+	csrw CSR_XIE, zero
+	csrw CSR_XIP, zero
 
 	/* Load the global pointer */
 .option push
@@ -61,7 +61,7 @@ _start_kernel:
 	 * floating point in kernel space
 	 */
 	li t0, SR_FS
-	csrc CSR_SSTATUS, t0
+	csrc CSR_XSTATUS, t0
 
 #ifdef CONFIG_SMP
 	li t0, CONFIG_NR_CPUS
@@ -116,7 +116,7 @@ relocate:
 	/* Point stvec to virtual address of intruction after satp write */
 	la a2, 1f
 	add a2, a2, a1
-	csrw CSR_STVEC, a2
+	csrw CSR_XTVEC, a2
 
 	/* Compute satp for kernel page tables, but don't load it yet */
 	srl a2, a0, PAGE_SHIFT
@@ -138,7 +138,7 @@ relocate:
 1:
 	/* Set trap vector to spin forever to help debug */
 	la a0, .Lsecondary_park
-	csrw CSR_STVEC, a0
+	csrw CSR_XTVEC, a0
 
 	/* Reload the global pointer */
 .option push
@@ -161,7 +161,7 @@ relocate:
 #ifdef CONFIG_SMP
 	/* Set trap vector to spin forever to help debug */
 	la a3, .Lsecondary_park
-	csrw CSR_STVEC, a3
+	csrw CSR_XTVEC, a3
 
 	slli a3, a0, LGREG
 	la a1, __cpu_up_stack_pointer
diff --git a/arch/riscv/kernel/irq.c b/arch/riscv/kernel/irq.c
index 6d8659388c49..804ff70bb853 100644
--- a/arch/riscv/kernel/irq.c
+++ b/arch/riscv/kernel/irq.c
@@ -29,7 +29,7 @@ asmlinkage void __irq_entry do_IRQ(struct pt_regs *regs)
 	struct pt_regs *old_regs = set_irq_regs(regs);
 
 	irq_enter();
-	switch (regs->scause & ~SCAUSE_IRQ_FLAG) {
+	switch (regs->xcause & ~XCAUSE_IRQ_FLAG) {
 	case INTERRUPT_CAUSE_TIMER:
 		riscv_timer_interrupt();
 		break;
@@ -46,7 +46,7 @@ asmlinkage void __irq_entry do_IRQ(struct pt_regs *regs)
 		handle_arch_irq(regs);
 		break;
 	default:
-		pr_alert("unexpected interrupt cause 0x%lx", regs->scause);
+		pr_alert("unexpected interrupt cause 0x%lx", regs->xcause);
 		BUG();
 	}
 	irq_exit();
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index fb3a082362eb..b318f7ff740b 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -34,7 +34,7 @@ void show_regs(struct pt_regs *regs)
 	show_regs_print_info(KERN_DEFAULT);
 
 	pr_cont("sepc: " REG_FMT " ra : " REG_FMT " sp : " REG_FMT "\n",
-		regs->sepc, regs->ra, regs->sp);
+		regs->xepc, 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",
@@ -56,23 +56,23 @@ void show_regs(struct pt_regs *regs)
 	pr_cont(" t5 : " REG_FMT " t6 : " REG_FMT "\n",
 		regs->t5, regs->t6);
 
-	pr_cont("sstatus: " REG_FMT " sbadaddr: " REG_FMT " scause: " REG_FMT "\n",
-		regs->sstatus, regs->sbadaddr, regs->scause);
+	pr_cont("status: " REG_FMT " badaddr: " REG_FMT " cause: " REG_FMT "\n",
+		regs->xstatus, regs->xbadaddr, regs->xcause);
 }
 
 void start_thread(struct pt_regs *regs, unsigned long pc,
 	unsigned long sp)
 {
-	regs->sstatus = SR_SPIE;
+	regs->xstatus = SR_XPIE;
 	if (has_fpu) {
-		regs->sstatus |= SR_FS_INITIAL;
+		regs->xstatus |= SR_FS_INITIAL;
 		/*
 		 * Restore the initial value to the FP register
 		 * before starting the user program.
 		 */
 		fstate_restore(current, regs);
 	}
-	regs->sepc = pc;
+	regs->xepc = pc;
 	regs->sp = sp;
 	set_fs(USER_DS);
 }
@@ -108,7 +108,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
 		const register unsigned long gp __asm__ ("gp");
 		memset(childregs, 0, sizeof(struct pt_regs));
 		childregs->gp = gp;
-		childregs->sstatus = SR_SPP | SR_SPIE; /* Supervisor, irqs on */
+		/* Supervisor/Machine, irqs on: */
+		childregs->xstatus = SR_XPP | SR_XPIE;
 
 		p->thread.ra = (unsigned long)ret_from_kernel_thread;
 		p->thread.s[0] = usp; /* fn */
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index b14d7647d800..e1a2cee340f7 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -124,7 +124,7 @@ SYSCALL_DEFINE0(rt_sigreturn)
 		pr_info_ratelimited(
 			"%s[%d]: bad frame in %s: frame=%p pc=%p sp=%p\n",
 			task->comm, task_pid_nr(task), __func__,
-			frame, (void *)regs->sepc, (void *)regs->sp);
+			frame, (void *)regs->xepc, (void *)regs->sp);
 	}
 	force_sig(SIGSEGV);
 	return 0;
@@ -199,7 +199,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 	 * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
 	 * since some things rely on this (e.g. glibc's debug/segfault.c).
 	 */
-	regs->sepc = (unsigned long)ksig->ka.sa.sa_handler;
+	regs->xepc = (unsigned long)ksig->ka.sa.sa_handler;
 	regs->sp = (unsigned long)frame;
 	regs->a0 = ksig->sig;                     /* a0: signal number */
 	regs->a1 = (unsigned long)(&frame->info); /* a1: siginfo pointer */
@@ -208,7 +208,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 #if DEBUG_SIG
 	pr_info("SIG deliver (%s:%d): sig=%d pc=%p ra=%p sp=%p\n",
 		current->comm, task_pid_nr(current), ksig->sig,
-		(void *)regs->sepc, (void *)regs->ra, frame);
+		(void *)regs->xepc, (void *)regs->ra, frame);
 #endif
 
 	return 0;
@@ -220,10 +220,9 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 	int ret;
 
 	/* Are we from a system call? */
-	if (regs->scause == EXC_SYSCALL) {
+	if (regs->xcause == EXC_SYSCALL) {
 		/* Avoid additional syscall restarting via ret_from_exception */
-		regs->scause = -1UL;
-
+		regs->xcause = -1UL;
 		/* If so, check system call restarting.. */
 		switch (regs->a0) {
 		case -ERESTART_RESTARTBLOCK:
@@ -239,7 +238,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 			/* fallthrough */
 		case -ERESTARTNOINTR:
                         regs->a0 = regs->orig_a0;
-			regs->sepc -= 0x4;
+			regs->xepc -= 0x4;
 			break;
 		}
 	}
@@ -261,9 +260,9 @@ static void do_signal(struct pt_regs *regs)
 	}
 
 	/* Did we come from a system call? */
-	if (regs->scause == EXC_SYSCALL) {
+	if (regs->xcause == EXC_SYSCALL) {
 		/* Avoid additional syscall restarting via ret_from_exception */
-		regs->scause = -1UL;
+		regs->xcause = -1UL;
 
 		/* Restart the system call - no handlers present */
 		switch (regs->a0) {
@@ -271,12 +270,12 @@ static void do_signal(struct pt_regs *regs)
 		case -ERESTARTSYS:
 		case -ERESTARTNOINTR:
                         regs->a0 = regs->orig_a0;
-			regs->sepc -= 0x4;
+			regs->xepc -= 0x4;
 			break;
 		case -ERESTART_RESTARTBLOCK:
                         regs->a0 = regs->orig_a0;
 			regs->a7 = __NR_restart_syscall;
-			regs->sepc -= 0x4;
+			regs->xepc -= 0x4;
 			break;
 		}
 	}
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 10a17e545f43..2cf1f0f3871e 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -40,7 +40,7 @@ void die(struct pt_regs *regs, const char *str)
 	print_modules();
 	show_regs(regs);
 
-	ret = notify_die(DIE_OOPS, str, regs, 0, regs->scause, SIGSEGV);
+	ret = notify_die(DIE_OOPS, str, regs, 0, regs->xcause, SIGSEGV);
 
 	bust_spinlocks(0);
 	add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
@@ -85,7 +85,7 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code,
 #define DO_ERROR_INFO(name, signo, code, str)				\
 asmlinkage void name(struct pt_regs *regs)				\
 {									\
-	do_trap_error(regs, signo, code, regs->sepc, "Oops - " str);	\
+	do_trap_error(regs, signo, code, regs->xepc, "Oops - " str);	\
 }
 
 DO_ERROR_INFO(do_trap_unknown,
@@ -123,9 +123,9 @@ static inline unsigned long get_break_insn_length(unsigned long pc)
 asmlinkage void do_trap_break(struct pt_regs *regs)
 {
 	if (user_mode(regs))
-		force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->sepc);
-	else if (report_bug(regs->sepc, regs) == BUG_TRAP_TYPE_WARN)
-		regs->sepc += get_break_insn_length(regs->sepc);
+		force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->xepc);
+	else if (report_bug(regs->xepc, regs) == BUG_TRAP_TYPE_WARN)
+		regs->xepc += get_break_insn_length(regs->xepc);
 	else
 		die(regs, "Kernel BUG");
 }
@@ -152,9 +152,9 @@ void __init trap_init(void)
 	 * Set sup0 scratch register to 0, indicating to exception vector
 	 * that we are presently executing in the kernel
 	 */
-	csr_write(CSR_SSCRATCH, 0);
+	csr_write(CSR_XSCRATCH, 0);
 	/* Set the exception vector address */
-	csr_write(CSR_STVEC, &handle_exception);
+	csr_write(CSR_XTVEC, &handle_exception);
 	/* Enable all interrupts */
-	csr_write(CSR_SIE, -1);
+	csr_write(CSR_XIE, -1);
 }
diff --git a/arch/riscv/lib/uaccess.S b/arch/riscv/lib/uaccess.S
index ed2696c0143d..f47a2ea4dc89 100644
--- a/arch/riscv/lib/uaccess.S
+++ b/arch/riscv/lib/uaccess.S
@@ -18,7 +18,7 @@ ENTRY(__asm_copy_from_user)
 
 	/* Enable access to user memory */
 	li t6, SR_SUM
-	csrs CSR_SSTATUS, t6
+	csrs CSR_XSTATUS, t6
 
 	add a3, a1, a2
 	/* Use word-oriented copy only if low-order bits match */
@@ -47,7 +47,7 @@ ENTRY(__asm_copy_from_user)
 
 3:
 	/* Disable access to user memory */
-	csrc CSR_SSTATUS, t6
+	csrc CSR_XSTATUS, t6
 	li a0, 0
 	ret
 4: /* Edge case: unalignment */
@@ -72,7 +72,7 @@ ENTRY(__clear_user)
 
 	/* Enable access to user memory */
 	li t6, SR_SUM
-	csrs CSR_SSTATUS, t6
+	csrs CSR_XSTATUS, t6
 
 	add a3, a0, a1
 	addi t0, a0, SZREG-1
@@ -94,7 +94,7 @@ ENTRY(__clear_user)
 
 3:
 	/* Disable access to user memory */
-	csrc CSR_SSTATUS, t6
+	csrc CSR_XSTATUS, t6
 	li a0, 0
 	ret
 4: /* Edge case: unalignment */
@@ -114,11 +114,11 @@ ENDPROC(__clear_user)
 	/* Fixup code for __copy_user(10) and __clear_user(11) */
 10:
 	/* Disable access to user memory */
-	csrs CSR_SSTATUS, t6
+	csrs CSR_XSTATUS, t6
 	mv a0, a2
 	ret
 11:
-	csrs CSR_SSTATUS, t6
+	csrs CSR_XSTATUS, t6
 	mv a0, a1
 	ret
 	.previous
diff --git a/arch/riscv/mm/extable.c b/arch/riscv/mm/extable.c
index 7aed9178d365..e0659deeb16b 100644
--- a/arch/riscv/mm/extable.c
+++ b/arch/riscv/mm/extable.c
@@ -15,9 +15,9 @@ int fixup_exception(struct pt_regs *regs)
 {
 	const struct exception_table_entry *fixup;
 
-	fixup = search_exception_tables(regs->sepc);
+	fixup = search_exception_tables(regs->xepc);
 	if (fixup) {
-		regs->sepc = fixup->fixup;
+		regs->xepc = fixup->fixup;
 		return 1;
 	}
 	return 0;
diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c
index 96add1427a75..10a8ce38ac7a 100644
--- a/arch/riscv/mm/fault.c
+++ b/arch/riscv/mm/fault.c
@@ -32,8 +32,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs)
 	int code = SEGV_MAPERR;
 	vm_fault_t fault;
 
-	cause = regs->scause;
-	addr = regs->sbadaddr;
+	cause = regs->xcause;
+	addr = regs->xbadaddr;
 
 	tsk = current;
 	mm = tsk->mm;
@@ -51,7 +51,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs)
 		goto vmalloc_fault;
 
 	/* Enable interrupts if they were enabled in the parent context. */
-	if (likely(regs->sstatus & SR_SPIE))
+	if (likely(regs->xstatus & SR_XPIE))
 		local_irq_enable();
 
 	/*
diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
index 470c7ef02ea4..5d2fdc3e28a9 100644
--- a/drivers/clocksource/timer-riscv.c
+++ b/drivers/clocksource/timer-riscv.c
@@ -19,7 +19,7 @@
 static int riscv_clock_next_event(unsigned long delta,
 		struct clock_event_device *ce)
 {
-	csr_set(sie, SIE_STIE);
+	csr_set(CSR_XIE, XIE_XTIE);
 	sbi_set_timer(get_cycles64() + delta);
 	return 0;
 }
@@ -61,13 +61,13 @@ static int riscv_timer_starting_cpu(unsigned int cpu)
 	ce->cpumask = cpumask_of(cpu);
 	clockevents_config_and_register(ce, riscv_timebase, 100, 0x7fffffff);
 
-	csr_set(sie, SIE_STIE);
+	csr_set(CSR_XIE, XIE_XTIE);
 	return 0;
 }
 
 static int riscv_timer_dying_cpu(unsigned int cpu)
 {
-	csr_clear(sie, SIE_STIE);
+	csr_clear(CSR_XIE, XIE_XTIE);
 	return 0;
 }
 
@@ -76,7 +76,7 @@ void riscv_timer_interrupt(void)
 {
 	struct clock_event_device *evdev = this_cpu_ptr(&riscv_clock_event);
 
-	csr_clear(sie, SIE_STIE);
+	csr_clear(CSR_XIE, XIE_XTIE);
 	evdev->event_handler(evdev);
 }
 
diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index c72c036aea76..4ee96ac90ea4 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -179,7 +179,7 @@ static void plic_handle_irq(struct pt_regs *regs)
 
 	WARN_ON_ONCE(!handler->present);
 
-	csr_clear(sie, SIE_SEIE);
+	csr_clear(CSR_XIE, XIE_XEIE);
 	while ((hwirq = readl(claim))) {
 		int irq = irq_find_mapping(plic_irqdomain, hwirq);
 
@@ -190,7 +190,7 @@ static void plic_handle_irq(struct pt_regs *regs)
 			generic_handle_irq(irq);
 		writel(hwirq, claim);
 	}
-	csr_set(sie, SIE_SEIE);
+	csr_set(CSR_XIE, XIE_XEIE);
 }
 
 /*
-- 
2.20.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 04/15] riscv: don't allow selecting SBI based drivers for M-mode
  2019-10-17 17:37 RISC-V nommu support v5 Christoph Hellwig
                   ` (2 preceding siblings ...)
  2019-10-17 17:37 ` [PATCH 03/15] riscv: abstract out CSR names for supervisor vs machine mode Christoph Hellwig
@ 2019-10-17 17:37 ` Christoph Hellwig
  2019-10-18  2:52   ` Anup Patel
  2019-10-17 17:37 ` [PATCH 05/15] riscv: poison SBI calls " Christoph Hellwig
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 41+ messages in thread
From: Christoph Hellwig @ 2019-10-17 17:37 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley; +Cc: Damien Le Moal, linux-riscv, linux-kernel

From: Damien Le Moal <damien.lemoal@wdc.com>

When running in M-mode we can't use SBI based drivers.  Add a new
CONFIG_RISCV_SBI that drivers that do SBI calls can depend on
instead.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/riscv/Kconfig         | 6 ++++++
 drivers/tty/hvc/Kconfig    | 2 +-
 drivers/tty/serial/Kconfig | 2 +-
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 86b7e8b0471c..b85492c42ccb 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -76,6 +76,12 @@ config ARCH_MMAP_RND_BITS_MAX
 config RISCV_M_MODE
 	bool
 
+# set if we are running in S-mode and can use SBI calls
+config RISCV_SBI
+	bool
+	depends on !RISCV_M_MODE
+	default y
+
 config MMU
 	def_bool y
 
diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig
index 4d22b911111f..4487a6b9acc8 100644
--- a/drivers/tty/hvc/Kconfig
+++ b/drivers/tty/hvc/Kconfig
@@ -89,7 +89,7 @@ config HVC_DCC
 
 config HVC_RISCV_SBI
 	bool "RISC-V SBI console support"
-	depends on RISCV
+	depends on RISCV_SBI
 	select HVC_DRIVER
 	help
 	  This enables support for console output via RISC-V SBI calls, which
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 67a9eb3f94ce..540142c5b7b3 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -88,7 +88,7 @@ config SERIAL_EARLYCON_ARM_SEMIHOST
 
 config SERIAL_EARLYCON_RISCV_SBI
 	bool "Early console using RISC-V SBI"
-	depends on RISCV
+	depends on RISCV_SBI
 	select SERIAL_CORE
 	select SERIAL_CORE_CONSOLE
 	select SERIAL_EARLYCON
-- 
2.20.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 05/15] riscv: poison SBI calls for M-mode
  2019-10-17 17:37 RISC-V nommu support v5 Christoph Hellwig
                   ` (3 preceding siblings ...)
  2019-10-17 17:37 ` [PATCH 04/15] riscv: don't allow selecting SBI based drivers for M-mode Christoph Hellwig
@ 2019-10-17 17:37 ` Christoph Hellwig
  2019-10-18  2:53   ` Anup Patel
  2019-10-17 17:37 ` [PATCH 06/15] riscv: cleanup the default power off implementation Christoph Hellwig
                   ` (10 subsequent siblings)
  15 siblings, 1 reply; 41+ messages in thread
From: Christoph Hellwig @ 2019-10-17 17:37 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley; +Cc: Damien Le Moal, linux-riscv, linux-kernel

There is no SBI when we run in M-mode, so fail the compile for any code
trying to use SBI calls.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/riscv/include/asm/sbi.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index 21134b3ef404..b167af3e7470 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -8,6 +8,7 @@
 
 #include <linux/types.h>
 
+#ifdef CONFIG_RISCV_SBI
 #define SBI_SET_TIMER 0
 #define SBI_CONSOLE_PUTCHAR 1
 #define SBI_CONSOLE_GETCHAR 2
@@ -93,5 +94,5 @@ static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
 {
 	SBI_CALL_4(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask, start, size, asid);
 }
-
-#endif
+#endif /* CONFIG_RISCV_SBI */
+#endif /* _ASM_RISCV_SBI_H */
-- 
2.20.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 06/15] riscv: cleanup the default power off implementation
  2019-10-17 17:37 RISC-V nommu support v5 Christoph Hellwig
                   ` (4 preceding siblings ...)
  2019-10-17 17:37 ` [PATCH 05/15] riscv: poison SBI calls " Christoph Hellwig
@ 2019-10-17 17:37 ` Christoph Hellwig
  2019-10-18  2:53   ` Anup Patel
  2019-10-17 17:37 ` [PATCH 07/15] riscv: implement remote sfence.i using IPIs Christoph Hellwig
                   ` (9 subsequent siblings)
  15 siblings, 1 reply; 41+ messages in thread
From: Christoph Hellwig @ 2019-10-17 17:37 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley
  Cc: Atish Patra, Damien Le Moal, linux-riscv, linux-kernel

Move the sbi poweroff to a separate function and file that is only
compiled if CONFIG_SBI is set.  Provide a new default fallback
power off that just sits in a wfi loop to save some power.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
---
 arch/riscv/kernel/Makefile |  1 +
 arch/riscv/kernel/reset.c  |  5 ++---
 arch/riscv/kernel/sbi.c    | 17 +++++++++++++++++
 3 files changed, 20 insertions(+), 3 deletions(-)
 create mode 100644 arch/riscv/kernel/sbi.c

diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 696020ff72db..d8c35fa93cc6 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -41,5 +41,6 @@ obj-$(CONFIG_DYNAMIC_FTRACE)	+= mcount-dyn.o
 obj-$(CONFIG_PERF_EVENTS)	+= perf_event.o
 obj-$(CONFIG_PERF_EVENTS)	+= perf_callchain.o
 obj-$(CONFIG_HAVE_PERF_REGS)	+= perf_regs.o
+obj-$(CONFIG_RISCV_SBI)		+= sbi.o
 
 clean:
diff --git a/arch/riscv/kernel/reset.c b/arch/riscv/kernel/reset.c
index d0fe623bfb8f..5e4e69859af1 100644
--- a/arch/riscv/kernel/reset.c
+++ b/arch/riscv/kernel/reset.c
@@ -4,12 +4,11 @@
  */
 
 #include <linux/reboot.h>
-#include <asm/sbi.h>
 
 static void default_power_off(void)
 {
-	sbi_shutdown();
-	while (1);
+	while (1)
+		wait_for_interrupt();
 }
 
 void (*pm_power_off)(void) = default_power_off;
diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c
new file mode 100644
index 000000000000..f6c7c3e82d28
--- /dev/null
+++ b/arch/riscv/kernel/sbi.c
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <asm/sbi.h>
+
+static void sbi_power_off(void)
+{
+	sbi_shutdown();
+}
+
+static int __init sbi_init(void)
+{
+	pm_power_off = sbi_power_off;
+	return 0;
+}
+early_initcall(sbi_init);
-- 
2.20.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 07/15] riscv: implement remote sfence.i using IPIs
  2019-10-17 17:37 RISC-V nommu support v5 Christoph Hellwig
                   ` (5 preceding siblings ...)
  2019-10-17 17:37 ` [PATCH 06/15] riscv: cleanup the default power off implementation Christoph Hellwig
@ 2019-10-17 17:37 ` Christoph Hellwig
  2019-10-18  2:55   ` Anup Patel
  2019-10-17 17:37 ` [PATCH 08/15] riscv: add support for MMIO access to the timer registers Christoph Hellwig
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 41+ messages in thread
From: Christoph Hellwig @ 2019-10-17 17:37 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley; +Cc: Damien Le Moal, linux-riscv, linux-kernel

The RISC-V ISA only supports flushing the instruction cache for the
local CPU core.  Currently we always offload the remote TLB flushing to
the SBI, which then issues an IPI under the hoods.  But with M-mode
we do not have an SBI so we have to do it ourselves.   IPI to the
other nodes using the existing kernel helpers instead if we have
native clint support and thus can IPI directly from the kernel.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/riscv/include/asm/sbi.h |  3 +++
 arch/riscv/mm/cacheflush.c   | 24 ++++++++++++++++++------
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index b167af3e7470..0cb74eccc73f 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -94,5 +94,8 @@ static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
 {
 	SBI_CALL_4(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask, start, size, asid);
 }
+#else /* CONFIG_RISCV_SBI */
+/* stub to for code is only reachable under IS_ENABLED(CONFIG_RISCV_SBI): */
+void sbi_remote_fence_i(const unsigned long *hart_mask);
 #endif /* CONFIG_RISCV_SBI */
 #endif /* _ASM_RISCV_SBI_H */
diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c
index 3f15938dec89..794c9ab256eb 100644
--- a/arch/riscv/mm/cacheflush.c
+++ b/arch/riscv/mm/cacheflush.c
@@ -10,9 +10,17 @@
 
 #include <asm/sbi.h>
 
+static void ipi_remote_fence_i(void *info)
+{
+	return local_flush_icache_all();
+}
+
 void flush_icache_all(void)
 {
-	sbi_remote_fence_i(NULL);
+	if (IS_ENABLED(CONFIG_RISCV_SBI))
+		sbi_remote_fence_i(NULL);
+	else
+		on_each_cpu(ipi_remote_fence_i, NULL, 1);
 }
 
 /*
@@ -28,7 +36,7 @@ void flush_icache_all(void)
 void flush_icache_mm(struct mm_struct *mm, bool local)
 {
 	unsigned int cpu;
-	cpumask_t others, hmask, *mask;
+	cpumask_t others, *mask;
 
 	preempt_disable();
 
@@ -46,10 +54,7 @@ void flush_icache_mm(struct mm_struct *mm, bool local)
 	 */
 	cpumask_andnot(&others, mm_cpumask(mm), cpumask_of(cpu));
 	local |= cpumask_empty(&others);
-	if (mm != current->active_mm || !local) {
-		riscv_cpuid_to_hartid_mask(&others, &hmask);
-		sbi_remote_fence_i(hmask.bits);
-	} else {
+	if (mm == current->active_mm && local) {
 		/*
 		 * It's assumed that at least one strongly ordered operation is
 		 * performed on this hart between setting a hart's cpumask bit
@@ -59,6 +64,13 @@ void flush_icache_mm(struct mm_struct *mm, bool local)
 		 * with flush_icache_deferred().
 		 */
 		smp_mb();
+	} else if (IS_ENABLED(CONFIG_RISCV_SBI)) {
+		cpumask_t hartid_mask;
+
+		riscv_cpuid_to_hartid_mask(&others, &hartid_mask);
+		sbi_remote_fence_i(cpumask_bits(&hartid_mask));
+	} else {
+		on_each_cpu_mask(&others, ipi_remote_fence_i, NULL, 1);
 	}
 
 	preempt_enable();
-- 
2.20.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 08/15] riscv: add support for MMIO access to the timer registers
  2019-10-17 17:37 RISC-V nommu support v5 Christoph Hellwig
                   ` (6 preceding siblings ...)
  2019-10-17 17:37 ` [PATCH 07/15] riscv: implement remote sfence.i using IPIs Christoph Hellwig
@ 2019-10-17 17:37 ` Christoph Hellwig
  2019-10-18  2:57   ` Anup Patel
  2019-10-17 17:37 ` [PATCH 09/15] riscv: provide native clint access for M-mode Christoph Hellwig
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 41+ messages in thread
From: Christoph Hellwig @ 2019-10-17 17:37 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley; +Cc: Damien Le Moal, linux-riscv, linux-kernel

When running in M-mode we can't use the SBI to set the timer, and
don't have access to the time CSR as that usually is emulated by
M-mode.  Instead provide code that directly accesses the MMIO for
the timer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/riscv/include/asm/sbi.h      |  3 ++-
 arch/riscv/include/asm/timex.h    | 19 +++++++++++++++++--
 drivers/clocksource/timer-riscv.c | 21 +++++++++++++++++----
 3 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index 0cb74eccc73f..a4774bafe033 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -95,7 +95,8 @@ static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
 	SBI_CALL_4(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask, start, size, asid);
 }
 #else /* CONFIG_RISCV_SBI */
-/* stub to for code is only reachable under IS_ENABLED(CONFIG_RISCV_SBI): */
+/* stubs to for code is only reachable under IS_ENABLED(CONFIG_RISCV_SBI): */
+void sbi_set_timer(uint64_t stime_value);
 void sbi_remote_fence_i(const unsigned long *hart_mask);
 #endif /* CONFIG_RISCV_SBI */
 #endif /* _ASM_RISCV_SBI_H */
diff --git a/arch/riscv/include/asm/timex.h b/arch/riscv/include/asm/timex.h
index c7ef131b9e4c..e17837d61667 100644
--- a/arch/riscv/include/asm/timex.h
+++ b/arch/riscv/include/asm/timex.h
@@ -7,12 +7,25 @@
 #define _ASM_RISCV_TIMEX_H
 
 #include <asm/csr.h>
+#include <asm/io.h>
 
 typedef unsigned long cycles_t;
 
+extern u64 __iomem *riscv_time_val;
+extern u64 __iomem *riscv_time_cmp;
+
+#ifdef CONFIG_64BIT
+#define mmio_get_cycles()	readq_relaxed(riscv_time_val)
+#else
+#define mmio_get_cycles()	readl_relaxed(riscv_time_val)
+#define mmio_get_cycles_hi()	readl_relaxed(((u32 *)riscv_time_val) + 1)
+#endif
+
 static inline cycles_t get_cycles(void)
 {
-	return csr_read(CSR_TIME);
+	if (IS_ENABLED(CONFIG_RISCV_SBI))
+		return csr_read(CSR_TIME);
+	return mmio_get_cycles();
 }
 #define get_cycles get_cycles
 
@@ -24,7 +37,9 @@ static inline u64 get_cycles64(void)
 #else /* CONFIG_64BIT */
 static inline u32 get_cycles_hi(void)
 {
-	return csr_read(CSR_TIMEH);
+	if (IS_ENABLED(CONFIG_RISCV_SBI))
+		return csr_read(CSR_TIMEH);
+	return mmio_get_cycles_hi();
 }
 
 static inline u64 get_cycles64(void)
diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
index 5d2fdc3e28a9..2b9fbc4ebe49 100644
--- a/drivers/clocksource/timer-riscv.c
+++ b/drivers/clocksource/timer-riscv.c
@@ -3,9 +3,9 @@
  * Copyright (C) 2012 Regents of the University of California
  * Copyright (C) 2017 SiFive
  *
- * All RISC-V systems have a timer attached to every hart.  These timers can be
- * read from the "time" and "timeh" CSRs, and can use the SBI to setup
- * events.
+ * All RISC-V systems have a timer attached to every hart.  These timers can
+ * either be read from the "time" and "timeh" CSRs, and can use the SBI to
+ * setup events, or directly accessed using MMIO registers.
  */
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
@@ -13,14 +13,27 @@
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/sched_clock.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
 #include <asm/smp.h>
 #include <asm/sbi.h>
 
+u64 __iomem *riscv_time_cmp;
+u64 __iomem *riscv_time_val;
+
+static inline void mmio_set_timer(u64 val)
+{
+	writeq_relaxed(val,
+		riscv_time_cmp + cpuid_to_hartid_map(smp_processor_id()));
+}
+
 static int riscv_clock_next_event(unsigned long delta,
 		struct clock_event_device *ce)
 {
 	csr_set(CSR_XIE, XIE_XTIE);
-	sbi_set_timer(get_cycles64() + delta);
+	if (IS_ENABLED(CONFIG_RISCV_SBI))
+		sbi_set_timer(get_cycles64() + delta);
+	else
+		mmio_set_timer(get_cycles64() + delta);
 	return 0;
 }
 
-- 
2.20.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 09/15] riscv: provide native clint access for M-mode
  2019-10-17 17:37 RISC-V nommu support v5 Christoph Hellwig
                   ` (7 preceding siblings ...)
  2019-10-17 17:37 ` [PATCH 08/15] riscv: add support for MMIO access to the timer registers Christoph Hellwig
@ 2019-10-17 17:37 ` Christoph Hellwig
  2019-10-18  3:00   ` Anup Patel
  2019-11-14  7:39   ` Paul Walmsley
  2019-10-17 17:37 ` [PATCH 10/15] riscv: read the hart ID from mhartid on boot Christoph Hellwig
                   ` (6 subsequent siblings)
  15 siblings, 2 replies; 41+ messages in thread
From: Christoph Hellwig @ 2019-10-17 17:37 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley; +Cc: Damien Le Moal, linux-riscv, linux-kernel

RISC-V has the concept of a cpu level interrupt controller.  The
interface for it is split between a standardized part that is exposed
as bits in the mstatus/sstatus register and the mie/mip/sie/sip
CRS.  But the bit to actually trigger IPIs is not standardized and
just mentioned as implementable using MMIO.

Add support for IPIs using MMIO using the SiFive clint layout (which is
also shared by Ariane, Kendrye and the Qemu virt platform).  Additional
the MMIO block also support the time value and timer compare registers,
so they are also set up using the same OF node.  Support for other
layouts should also be relatively easy to add in the future.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/riscv/include/asm/clint.h | 39 ++++++++++++++++++++++++++++++
 arch/riscv/include/asm/sbi.h   |  2 ++
 arch/riscv/kernel/Makefile     |  1 +
 arch/riscv/kernel/clint.c      | 44 ++++++++++++++++++++++++++++++++++
 arch/riscv/kernel/setup.c      |  2 ++
 arch/riscv/kernel/smp.c        | 16 ++++++++++---
 arch/riscv/kernel/smpboot.c    |  4 ++++
 7 files changed, 105 insertions(+), 3 deletions(-)
 create mode 100644 arch/riscv/include/asm/clint.h
 create mode 100644 arch/riscv/kernel/clint.c

diff --git a/arch/riscv/include/asm/clint.h b/arch/riscv/include/asm/clint.h
new file mode 100644
index 000000000000..02a26b68f21d
--- /dev/null
+++ b/arch/riscv/include/asm/clint.h
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+#ifndef _ASM_CLINT_H
+#define _ASM_CLINT_H 1
+
+#include <linux/io.h>
+#include <linux/smp.h>
+
+#ifdef CONFIG_RISCV_M_MODE
+extern u32 __iomem *clint_ipi_base;
+
+void clint_init_boot_cpu(void);
+
+static inline void clint_send_ipi_single(unsigned long hartid)
+{
+	writel(1, clint_ipi_base + hartid);
+}
+
+static inline void clint_send_ipi_mask(const struct cpumask *hartid_mask)
+{
+	int hartid;
+
+	for_each_cpu(hartid, hartid_mask)
+		clint_send_ipi_single(hartid);
+}
+
+static inline void clint_clear_ipi(unsigned long hartid)
+{
+	writel(0, clint_ipi_base + hartid);
+}
+#else /* CONFIG_RISCV_M_MODE */
+#define clint_init_boot_cpu()	do { } while (0)
+
+/* stubs to for code is only reachable under IS_ENABLED(CONFIG_RISCV_M_MODE): */
+void clint_send_ipi_single(unsigned long hartid);
+void clint_send_ipi_mask(const struct cpumask *hartid_mask);
+void clint_clear_ipi(unsigned long hartid);
+#endif /* CONFIG_RISCV_M_MODE */
+
+#endif /* _ASM_CLINT_H */
diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index a4774bafe033..407d1024f9eb 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -97,6 +97,8 @@ static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
 #else /* CONFIG_RISCV_SBI */
 /* stubs to for code is only reachable under IS_ENABLED(CONFIG_RISCV_SBI): */
 void sbi_set_timer(uint64_t stime_value);
+void sbi_clear_ipi(void);
+void sbi_send_ipi(const unsigned long *hart_mask);
 void sbi_remote_fence_i(const unsigned long *hart_mask);
 #endif /* CONFIG_RISCV_SBI */
 #endif /* _ASM_RISCV_SBI_H */
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index d8c35fa93cc6..2dca51046899 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -29,6 +29,7 @@ obj-y	+= vdso.o
 obj-y	+= cacheinfo.o
 obj-y	+= vdso/
 
+obj-$(CONFIG_RISCV_M_MODE)	+= clint.o
 obj-$(CONFIG_FPU)		+= fpu.o
 obj-$(CONFIG_SMP)		+= smpboot.o
 obj-$(CONFIG_SMP)		+= smp.o
diff --git a/arch/riscv/kernel/clint.c b/arch/riscv/kernel/clint.c
new file mode 100644
index 000000000000..3647980d14c3
--- /dev/null
+++ b/arch/riscv/kernel/clint.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Christoph Hellwig.
+ */
+
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/types.h>
+#include <asm/clint.h>
+#include <asm/csr.h>
+#include <asm/timex.h>
+#include <asm/smp.h>
+
+/*
+ * This is the layout used by the SiFive clint, which is also shared by the qemu
+ * virt platform, and the Kendryte KD210 at least.
+ */
+#define CLINT_IPI_OFF		0
+#define CLINT_TIME_CMP_OFF	0x4000
+#define CLINT_TIME_VAL_OFF	0xbff8
+
+u32 __iomem *clint_ipi_base;
+
+void clint_init_boot_cpu(void)
+{
+	struct device_node *np;
+	void __iomem *base;
+
+	np = of_find_compatible_node(NULL, NULL, "riscv,clint0");
+	if (!np) {
+		panic("clint not found");
+		return;
+	}
+
+	base = of_iomap(np, 0);
+	if (!base)
+		panic("could not map CLINT");
+
+	clint_ipi_base = base + CLINT_IPI_OFF;
+	riscv_time_cmp = base + CLINT_TIME_CMP_OFF;
+	riscv_time_val = base + CLINT_TIME_VAL_OFF;
+
+	clint_clear_ipi(boot_cpu_hartid);
+}
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index a990a6cb184f..f4ba71b66c73 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -17,6 +17,7 @@
 #include <linux/sched/task.h>
 #include <linux/swiotlb.h>
 
+#include <asm/clint.h>
 #include <asm/setup.h>
 #include <asm/sections.h>
 #include <asm/pgtable.h>
@@ -65,6 +66,7 @@ void __init setup_arch(char **cmdline_p)
 	setup_bootmem();
 	paging_init();
 	unflatten_device_tree();
+	clint_init_boot_cpu();
 
 #ifdef CONFIG_SWIOTLB
 	swiotlb_init(1);
diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c
index b18cd6c8e8fb..c46df9c2e927 100644
--- a/arch/riscv/kernel/smp.c
+++ b/arch/riscv/kernel/smp.c
@@ -14,6 +14,7 @@
 #include <linux/seq_file.h>
 #include <linux/delay.h>
 
+#include <asm/clint.h>
 #include <asm/sbi.h>
 #include <asm/tlbflush.h>
 #include <asm/cacheflush.h>
@@ -90,7 +91,10 @@ static void send_ipi_mask(const struct cpumask *mask, enum ipi_message_type op)
 	smp_mb__after_atomic();
 
 	riscv_cpuid_to_hartid_mask(mask, &hartid_mask);
-	sbi_send_ipi(cpumask_bits(&hartid_mask));
+	if (IS_ENABLED(CONFIG_RISCV_SBI))
+		sbi_send_ipi(cpumask_bits(&hartid_mask));
+	else
+		clint_send_ipi_mask(&hartid_mask);
 }
 
 static void send_ipi_single(int cpu, enum ipi_message_type op)
@@ -101,12 +105,18 @@ static void send_ipi_single(int cpu, enum ipi_message_type op)
 	set_bit(op, &ipi_data[cpu].bits);
 	smp_mb__after_atomic();
 
-	sbi_send_ipi(cpumask_bits(cpumask_of(hartid)));
+	if (IS_ENABLED(CONFIG_RISCV_SBI))
+		sbi_send_ipi(cpumask_bits(cpumask_of(hartid)));
+	else
+		clint_send_ipi_single(hartid);
 }
 
 static inline void clear_ipi(void)
 {
-	csr_clear(CSR_SIP, SIE_SSIE);
+	if (IS_ENABLED(CONFIG_RISCV_SBI))
+		csr_clear(CSR_SIP, SIE_SSIE);
+	else
+		clint_clear_ipi(cpuid_to_hartid_map(smp_processor_id()));
 }
 
 void riscv_software_interrupt(void)
diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
index 18ae6da5115e..6300b09f1d1d 100644
--- a/arch/riscv/kernel/smpboot.c
+++ b/arch/riscv/kernel/smpboot.c
@@ -24,6 +24,7 @@
 #include <linux/of.h>
 #include <linux/sched/task_stack.h>
 #include <linux/sched/mm.h>
+#include <asm/clint.h>
 #include <asm/irq.h>
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
@@ -134,6 +135,9 @@ asmlinkage void __init smp_callin(void)
 {
 	struct mm_struct *mm = &init_mm;
 
+	if (!IS_ENABLED(CONFIG_RISCV_SBI))
+		clint_clear_ipi(cpuid_to_hartid_map(smp_processor_id()));
+
 	/* All kernel threads share the same mm context.  */
 	mmgrab(mm);
 	current->active_mm = mm;
-- 
2.20.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 10/15] riscv: read the hart ID from mhartid on boot
  2019-10-17 17:37 RISC-V nommu support v5 Christoph Hellwig
                   ` (8 preceding siblings ...)
  2019-10-17 17:37 ` [PATCH 09/15] riscv: provide native clint access for M-mode Christoph Hellwig
@ 2019-10-17 17:37 ` Christoph Hellwig
  2019-10-18  3:01   ` Anup Patel
  2019-11-14  7:40   ` Paul Walmsley
  2019-10-17 17:37 ` [PATCH 11/15] riscv: use the correct interrupt levels for M-mode Christoph Hellwig
                   ` (5 subsequent siblings)
  15 siblings, 2 replies; 41+ messages in thread
From: Christoph Hellwig @ 2019-10-17 17:37 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley
  Cc: Atish Patra, Damien Le Moal, linux-riscv, linux-kernel

From: Damien Le Moal <Damien.LeMoal@wdc.com>

When in M-Mode, we can use the mhartid CSR to get the ID of the running
HART. Doing so, direct M-Mode boot without firmware is possible.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
---
 arch/riscv/include/asm/csr.h | 1 +
 arch/riscv/kernel/head.S     | 8 ++++++++
 2 files changed, 9 insertions(+)

diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index 0dae5c361f29..d0b5113e1a54 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -81,6 +81,7 @@
 #define SIE_SEIE		(_AC(0x1, UL) << IRQ_S_EXT)
 
 /* symbolic CSR names: */
+#define CSR_MHARTID		0xf14
 #define CSR_MSTATUS		0x300
 #define CSR_MIE			0x304
 #define CSR_MTVEC		0x305
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 679e63d29edb..583784cb3a32 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -50,6 +50,14 @@ _start_kernel:
 	csrw CSR_XIE, zero
 	csrw CSR_XIP, zero
 
+#ifdef CONFIG_RISCV_M_MODE
+	/*
+	 * The hartid in a0 is expected later on, and we have no firmware
+	 * to hand it to us.
+	 */
+	csrr a0, CSR_MHARTID
+#endif
+
 	/* Load the global pointer */
 .option push
 .option norelax
-- 
2.20.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 11/15] riscv: use the correct interrupt levels for M-mode
  2019-10-17 17:37 RISC-V nommu support v5 Christoph Hellwig
                   ` (9 preceding siblings ...)
  2019-10-17 17:37 ` [PATCH 10/15] riscv: read the hart ID from mhartid on boot Christoph Hellwig
@ 2019-10-17 17:37 ` Christoph Hellwig
  2019-10-18  3:01   ` Anup Patel
  2019-10-17 17:37 ` [PATCH 12/15] riscv: clear the instruction cache and all registers when booting Christoph Hellwig
                   ` (4 subsequent siblings)
  15 siblings, 1 reply; 41+ messages in thread
From: Christoph Hellwig @ 2019-10-17 17:37 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley; +Cc: Damien Le Moal, linux-riscv, linux-kernel

The numerical levels for External/Timer/Software interrupts differ
between S-mode and M-mode.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/riscv/kernel/irq.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/kernel/irq.c b/arch/riscv/kernel/irq.c
index 804ff70bb853..dbd1fd7c22e4 100644
--- a/arch/riscv/kernel/irq.c
+++ b/arch/riscv/kernel/irq.c
@@ -14,9 +14,15 @@
 /*
  * Possible interrupt causes:
  */
-#define INTERRUPT_CAUSE_SOFTWARE	IRQ_S_SOFT
-#define INTERRUPT_CAUSE_TIMER		IRQ_S_TIMER
-#define INTERRUPT_CAUSE_EXTERNAL	IRQ_S_EXT
+#ifdef CONFIG_RISCV_M_MODE
+# define INTERRUPT_CAUSE_SOFTWARE	IRQ_M_SOFT
+# define INTERRUPT_CAUSE_TIMER		IRQ_M_TIMER
+# define INTERRUPT_CAUSE_EXTERNAL	IRQ_M_EXT
+#else
+# define INTERRUPT_CAUSE_SOFTWARE	IRQ_S_SOFT
+# define INTERRUPT_CAUSE_TIMER		IRQ_S_TIMER
+# define INTERRUPT_CAUSE_EXTERNAL	IRQ_S_EXT
+#endif /* CONFIG_RISCV_M_MODE */
 
 int arch_show_interrupts(struct seq_file *p, int prec)
 {
-- 
2.20.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 12/15] riscv: clear the instruction cache and all registers when booting
  2019-10-17 17:37 RISC-V nommu support v5 Christoph Hellwig
                   ` (10 preceding siblings ...)
  2019-10-17 17:37 ` [PATCH 11/15] riscv: use the correct interrupt levels for M-mode Christoph Hellwig
@ 2019-10-17 17:37 ` Christoph Hellwig
  2019-10-18  3:05   ` Anup Patel
  2019-10-17 17:37 ` [PATCH 13/15] riscv: add nommu support Christoph Hellwig
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 41+ messages in thread
From: Christoph Hellwig @ 2019-10-17 17:37 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley; +Cc: Damien Le Moal, linux-riscv, linux-kernel

When we get booted we want a clear slate without any leaks from previous
supervisors or the firmware.  Flush the instruction cache and then clear
all registers to known good values.  This is really important for the
upcoming nommu support that runs on M-mode, but can't really harm when
running in S-mode either.  Vaguely based on the concepts from opensbi.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/riscv/include/asm/csr.h |  1 +
 arch/riscv/kernel/head.S     | 88 +++++++++++++++++++++++++++++++++++-
 2 files changed, 88 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index d0b5113e1a54..ee0101278608 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -83,6 +83,7 @@
 /* symbolic CSR names: */
 #define CSR_MHARTID		0xf14
 #define CSR_MSTATUS		0x300
+#define CSR_MISA		0x301
 #define CSR_MIE			0x304
 #define CSR_MTVEC		0x305
 #define CSR_MSCRATCH		0x340
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 583784cb3a32..25867b99cc95 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -11,6 +11,7 @@
 #include <asm/thread_info.h>
 #include <asm/page.h>
 #include <asm/csr.h>
+#include <asm/hwcap.h>
 #include <asm/image.h>
 
 __INIT
@@ -51,12 +52,18 @@ _start_kernel:
 	csrw CSR_XIP, zero
 
 #ifdef CONFIG_RISCV_M_MODE
+	/* flush the instruction cache */
+	fence.i
+
+	/* Reset all registers except ra, a0, a1 */
+	call reset_regs
+
 	/*
 	 * The hartid in a0 is expected later on, and we have no firmware
 	 * to hand it to us.
 	 */
 	csrr a0, CSR_MHARTID
-#endif
+#endif /* CONFIG_RISCV_M_MODE */
 
 	/* Load the global pointer */
 .option push
@@ -203,6 +210,85 @@ relocate:
 	j .Lsecondary_park
 END(_start)
 
+#ifdef CONFIG_RISCV_M_MODE
+ENTRY(reset_regs)
+	li	sp, 0
+	li	gp, 0
+	li	tp, 0
+	li	t0, 0
+	li	t1, 0
+	li	t2, 0
+	li	s0, 0
+	li	s1, 0
+	li	a2, 0
+	li	a3, 0
+	li	a4, 0
+	li	a5, 0
+	li	a6, 0
+	li	a7, 0
+	li	s2, 0
+	li	s3, 0
+	li	s4, 0
+	li	s5, 0
+	li	s6, 0
+	li	s7, 0
+	li	s8, 0
+	li	s9, 0
+	li	s10, 0
+	li	s11, 0
+	li	t3, 0
+	li	t4, 0
+	li	t5, 0
+	li	t6, 0
+	csrw	sscratch, 0
+
+#ifdef CONFIG_FPU
+	csrr	t0, CSR_MISA
+	andi	t0, t0, (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D)
+	bnez	t0, .Lreset_regs_done
+
+	li	t1, SR_FS
+	csrs	CSR_XSTATUS, t1
+	fmv.s.x	f0, zero
+	fmv.s.x	f1, zero
+	fmv.s.x	f2, zero
+	fmv.s.x	f3, zero
+	fmv.s.x	f4, zero
+	fmv.s.x	f5, zero
+	fmv.s.x	f6, zero
+	fmv.s.x	f7, zero
+	fmv.s.x	f8, zero
+	fmv.s.x	f9, zero
+	fmv.s.x	f10, zero
+	fmv.s.x	f11, zero
+	fmv.s.x	f12, zero
+	fmv.s.x	f13, zero
+	fmv.s.x	f14, zero
+	fmv.s.x	f15, zero
+	fmv.s.x	f16, zero
+	fmv.s.x	f17, zero
+	fmv.s.x	f18, zero
+	fmv.s.x	f19, zero
+	fmv.s.x	f20, zero
+	fmv.s.x	f21, zero
+	fmv.s.x	f22, zero
+	fmv.s.x	f23, zero
+	fmv.s.x	f24, zero
+	fmv.s.x	f25, zero
+	fmv.s.x	f26, zero
+	fmv.s.x	f27, zero
+	fmv.s.x	f28, zero
+	fmv.s.x	f29, zero
+	fmv.s.x	f30, zero
+	fmv.s.x	f31, zero
+	csrw	fcsr, 0
+	/* note that the caller must clear SR_FS */
+#endif /* CONFIG_FPU */
+.Lreset_regs_done:
+	ret
+END(reset_regs)
+#endif /* CONFIG_RISCV_M_MODE */
+
 __PAGE_ALIGNED_BSS
 	/* Empty zero page */
 	.balign PAGE_SIZE
-- 
2.20.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 13/15] riscv: add nommu support
  2019-10-17 17:37 RISC-V nommu support v5 Christoph Hellwig
                   ` (11 preceding siblings ...)
  2019-10-17 17:37 ` [PATCH 12/15] riscv: clear the instruction cache and all registers when booting Christoph Hellwig
@ 2019-10-17 17:37 ` Christoph Hellwig
  2019-10-18  3:04   ` Anup Patel
  2019-10-17 17:37 ` [PATCH 14/15] riscv: provide a flat image loader Christoph Hellwig
                   ` (2 subsequent siblings)
  15 siblings, 1 reply; 41+ messages in thread
From: Christoph Hellwig @ 2019-10-17 17:37 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley; +Cc: Damien Le Moal, linux-riscv, linux-kernel

The kernel runs in M-mode without using page tables, and thus can't run
bare metal without help from additional firmware.

Most of the patch is just stubbing out code not needed without page
tables, but there is an interesting detail in the signals implementation:

 - The normal RISC-V syscall ABI only implements rt_sigreturn as VDSO
   entry point, but the ELF VDSO is not supported for nommu Linux.
   We instead copy the code to call the syscall onto the stack.

In addition to enabling the nommu code a new defconfig for a small
kernel image that can run in nommu mode on qemu is also provided, to run
a kernel in qemu you can use the following command line:

qemu-system-riscv64 -smp 2 -m 64 -machine virt -nographic \
	-kernel arch/riscv/boot/loader \
	-drive file=rootfs.ext2,format=raw,id=hd0 \
	-device virtio-blk-device,drive=hd0

Contains contributions from Damien Le Moal <Damien.LeMoal@wdc.com>.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/riscv/Kconfig                      | 26 ++++++---
 arch/riscv/configs/nommu_virt_defconfig | 78 +++++++++++++++++++++++++
 arch/riscv/include/asm/cache.h          |  8 +++
 arch/riscv/include/asm/elf.h            |  4 +-
 arch/riscv/include/asm/fixmap.h         |  2 +
 arch/riscv/include/asm/futex.h          |  6 ++
 arch/riscv/include/asm/io.h             |  4 ++
 arch/riscv/include/asm/mmu.h            |  3 +
 arch/riscv/include/asm/page.h           | 10 +++-
 arch/riscv/include/asm/pgalloc.h        |  2 +
 arch/riscv/include/asm/pgtable.h        | 64 +++++++++++---------
 arch/riscv/include/asm/tlbflush.h       | 12 +++-
 arch/riscv/include/asm/uaccess.h        |  4 ++
 arch/riscv/kernel/Makefile              |  3 +-
 arch/riscv/kernel/entry.S               | 11 ++++
 arch/riscv/kernel/head.S                |  6 ++
 arch/riscv/kernel/signal.c              | 17 +++++-
 arch/riscv/lib/Makefile                 | 11 ++--
 arch/riscv/mm/Makefile                  |  3 +-
 arch/riscv/mm/cacheflush.c              |  2 +
 arch/riscv/mm/context.c                 |  2 +
 arch/riscv/mm/init.c                    | 13 ++++-
 22 files changed, 236 insertions(+), 55 deletions(-)
 create mode 100644 arch/riscv/configs/nommu_virt_defconfig

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index b85492c42ccb..babc8a0d3d2e 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -26,14 +26,14 @@ config RISCV
 	select GENERIC_IRQ_SHOW
 	select GENERIC_PCI_IOMAP
 	select GENERIC_SCHED_CLOCK
-	select GENERIC_STRNCPY_FROM_USER
-	select GENERIC_STRNLEN_USER
+	select GENERIC_STRNCPY_FROM_USER if MMU
+	select GENERIC_STRNLEN_USER if MMU
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_ATOMIC64 if !64BIT
 	select HAVE_ARCH_AUDITSYSCALL
 	select HAVE_ASM_MODVERSIONS
 	select HAVE_MEMBLOCK_NODE_MAP
-	select HAVE_DMA_CONTIGUOUS
+	select HAVE_DMA_CONTIGUOUS if MMU
 	select HAVE_FUTEX_CMPXCHG if FUTEX
 	select HAVE_PERF_EVENTS
 	select HAVE_PERF_REGS
@@ -50,6 +50,7 @@ config RISCV
 	select PCI_DOMAINS_GENERIC if PCI
 	select PCI_MSI if PCI
 	select RISCV_TIMER
+	select UACCESS_MEMCPY if !MMU
 	select GENERIC_IRQ_MULTI_HANDLER
 	select GENERIC_ARCH_TOPOLOGY if SMP
 	select ARCH_HAS_PTE_SPECIAL
@@ -60,7 +61,7 @@ config RISCV
 	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
+	select HAVE_ARCH_MMAP_RND_BITS if MMU
 
 config ARCH_MMAP_RND_BITS_MIN
 	default 18 if 64BIT
@@ -75,6 +76,7 @@ config ARCH_MMAP_RND_BITS_MAX
 # set if we run in machine mode, cleared if we run in supervisor mode
 config RISCV_M_MODE
 	bool
+	default !MMU
 
 # set if we are running in S-mode and can use SBI calls
 config RISCV_SBI
@@ -83,7 +85,11 @@ config RISCV_SBI
 	default y
 
 config MMU
-	def_bool y
+	bool "MMU-based Paged Memory Management Support"
+	default y
+	help
+	  Select if you want MMU-based virtualised addressing space
+	  support by paged memory management. If unsure, say 'Y'.
 
 config ZONE_DMA32
 	bool
@@ -102,6 +108,7 @@ config PA_BITS
 config PAGE_OFFSET
 	hex
 	default 0xC0000000 if 32BIT && MAXPHYSMEM_2GB
+	default 0x80000000 if 64BIT && !MMU
 	default 0xffffffff80000000 if 64BIT && MAXPHYSMEM_2GB
 	default 0xffffffe000000000 if 64BIT && MAXPHYSMEM_128GB
 
@@ -145,7 +152,7 @@ config GENERIC_HWEIGHT
 	def_bool y
 
 config FIX_EARLYCON_MEM
-	def_bool y
+	def_bool CONFIG_MMU
 
 config PGTABLE_LEVELS
 	int
@@ -170,6 +177,7 @@ config ARCH_RV32I
 	select GENERIC_LIB_ASHRDI3
 	select GENERIC_LIB_LSHRDI3
 	select GENERIC_LIB_UCMPDI2
+	select MMU
 
 config ARCH_RV64I
 	bool "RV64I"
@@ -178,9 +186,9 @@ config ARCH_RV64I
 	select HAVE_FUNCTION_TRACER
 	select HAVE_FUNCTION_GRAPH_TRACER
 	select HAVE_FTRACE_MCOUNT_RECORD
-	select HAVE_DYNAMIC_FTRACE
-	select HAVE_DYNAMIC_FTRACE_WITH_REGS
-	select SWIOTLB
+	select HAVE_DYNAMIC_FTRACE if MMU
+	select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE
+	select SWIOTLB if MMU
 
 endchoice
 
diff --git a/arch/riscv/configs/nommu_virt_defconfig b/arch/riscv/configs/nommu_virt_defconfig
new file mode 100644
index 000000000000..cf74e179bf90
--- /dev/null
+++ b/arch/riscv/configs/nommu_virt_defconfig
@@ -0,0 +1,78 @@
+# CONFIG_CPU_ISOLATION is not set
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=12
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EXPERT=y
+# CONFIG_SYSFS_SYSCALL is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_BASE_FULL is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+# CONFIG_IO_URING is not set
+# CONFIG_ADVISE_SYSCALLS is not set
+# CONFIG_MEMBARRIER is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLOB=y
+# CONFIG_SLAB_MERGE_DEFAULT is not set
+# CONFIG_MMU is not set
+CONFIG_MAXPHYSMEM_2GB=y
+CONFIG_SMP=y
+CONFIG_CMDLINE="root=/dev/vda rw earlycon=uart8250,mmio,0x10000000,115200n8 console=ttyS0"
+CONFIG_CMDLINE_FORCE=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_MQ_IOSCHED_DEADLINE is not set
+# CONFIG_MQ_IOSCHED_KYBER is not set
+CONFIG_BINFMT_FLAT=y
+# CONFIG_COREDUMP is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+CONFIG_VIRTIO_BLK=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_LDISC_AUTOLOAD is not set
+# CONFIG_DEVMEM is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_LCD_CLASS_DEVICE is not set
+# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
+CONFIG_SIFIVE_PLIC=y
+# CONFIG_VALIDATE_FS_PARSER is not set
+CONFIG_EXT2_FS=y
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_LSM="[]"
+CONFIG_PRINTK_TIME=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_FTRACE is not set
+# CONFIG_RUNTIME_TESTING_MENU is not set
diff --git a/arch/riscv/include/asm/cache.h b/arch/riscv/include/asm/cache.h
index bfd523e8f0b2..9b58b104559e 100644
--- a/arch/riscv/include/asm/cache.h
+++ b/arch/riscv/include/asm/cache.h
@@ -11,4 +11,12 @@
 
 #define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
 
+/*
+ * RISC-V requires the stack pointer to be 16-byte aligned, so ensure that
+ * the flat loader aligns it accordingly.
+ */
+#ifndef CONFIG_MMU
+#define ARCH_SLAB_MINALIGN	16
+#endif
+
 #endif /* _ASM_RISCV_CACHE_H */
diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index ef04084bf0de..d83a4efd052b 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -56,16 +56,16 @@ extern unsigned long elf_hwcap;
  */
 #define ELF_PLATFORM	(NULL)
 
+#ifdef CONFIG_MMU
 #define ARCH_DLINFO						\
 do {								\
 	NEW_AUX_ENT(AT_SYSINFO_EHDR,				\
 		(elf_addr_t)current->mm->context.vdso);		\
 } while (0)
-
-
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
 struct linux_binprm;
 extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 	int uses_interp);
+#endif /* CONFIG_MMU */
 
 #endif /* _ASM_RISCV_ELF_H */
diff --git a/arch/riscv/include/asm/fixmap.h b/arch/riscv/include/asm/fixmap.h
index 161f28d04a07..42d2c42f3cc9 100644
--- a/arch/riscv/include/asm/fixmap.h
+++ b/arch/riscv/include/asm/fixmap.h
@@ -11,6 +11,7 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
+#ifdef CONFIG_MMU
 /*
  * Here we define all the compile-time 'special' virtual addresses.
  * The point is to have a constant address at compile time, but to
@@ -42,4 +43,5 @@ extern void __set_fixmap(enum fixed_addresses idx,
 
 #include <asm-generic/fixmap.h>
 
+#endif /* CONFIG_MMU */
 #endif /* _ASM_RISCV_FIXMAP_H */
diff --git a/arch/riscv/include/asm/futex.h b/arch/riscv/include/asm/futex.h
index 4ad6409c4647..418564b96dc4 100644
--- a/arch/riscv/include/asm/futex.h
+++ b/arch/riscv/include/asm/futex.h
@@ -12,6 +12,12 @@
 #include <linux/errno.h>
 #include <asm/asm.h>
 
+/* We don't even really need the extable code, but for now keep it simple */
+#ifndef CONFIG_MMU
+#define __enable_user_access()		do { } while (0)
+#define __disable_user_access()		do { } while (0)
+#endif
+
 #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)	\
 {								\
 	uintptr_t tmp;						\
diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
index fc1189ad3777..d39a8f03e85e 100644
--- a/arch/riscv/include/asm/io.h
+++ b/arch/riscv/include/asm/io.h
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <asm/mmiowb.h>
 
+#ifdef CONFIG_MMU
 extern void __iomem *ioremap(phys_addr_t offset, unsigned long size);
 
 /*
@@ -26,6 +27,9 @@ extern void __iomem *ioremap(phys_addr_t offset, unsigned long size);
 #define ioremap_wt(addr, size) ioremap((addr), (size))
 
 extern void iounmap(volatile void __iomem *addr);
+#else
+#define pgprot_noncached(x)	(x)
+#endif /* CONFIG_MMU */
 
 /* Generic IO read/write.  These perform native-endian accesses. */
 #define __raw_writeb __raw_writeb
diff --git a/arch/riscv/include/asm/mmu.h b/arch/riscv/include/asm/mmu.h
index 151476fb58cb..967eacb01ab5 100644
--- a/arch/riscv/include/asm/mmu.h
+++ b/arch/riscv/include/asm/mmu.h
@@ -10,6 +10,9 @@
 #ifndef __ASSEMBLY__
 
 typedef struct {
+#ifndef CONFIG_MMU
+	unsigned long	end_brk;
+#endif
 	void *vdso;
 #ifdef CONFIG_SMP
 	/* A local icache flush is needed before user execution can resume. */
diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h
index 3db261c4810f..ac699246ae7e 100644
--- a/arch/riscv/include/asm/page.h
+++ b/arch/riscv/include/asm/page.h
@@ -88,8 +88,14 @@ typedef struct page *pgtable_t;
 #define PTE_FMT "%08lx"
 #endif
 
+#ifdef CONFIG_MMU
 extern unsigned long va_pa_offset;
 extern unsigned long pfn_base;
+#define ARCH_PFN_OFFSET		(pfn_base)
+#else
+#define va_pa_offset		0
+#define ARCH_PFN_OFFSET		(PAGE_OFFSET >> PAGE_SHIFT)
+#endif /* CONFIG_MMU */
 
 extern unsigned long max_low_pfn;
 extern unsigned long min_low_pfn;
@@ -112,11 +118,9 @@ extern unsigned long min_low_pfn;
 
 #ifdef CONFIG_FLATMEM
 #define pfn_valid(pfn) \
-	(((pfn) >= pfn_base) && (((pfn)-pfn_base) < max_mapnr))
+	(((pfn) >= ARCH_PFN_OFFSET) && (((pfn) - ARCH_PFN_OFFSET) < max_mapnr))
 #endif
 
-#define ARCH_PFN_OFFSET		(pfn_base)
-
 #endif /* __ASSEMBLY__ */
 
 #define virt_addr_valid(vaddr)	(pfn_valid(virt_to_pfn(vaddr)))
diff --git a/arch/riscv/include/asm/pgalloc.h b/arch/riscv/include/asm/pgalloc.h
index d59ea92285ec..3f601ee8233f 100644
--- a/arch/riscv/include/asm/pgalloc.h
+++ b/arch/riscv/include/asm/pgalloc.h
@@ -10,6 +10,7 @@
 #include <linux/mm.h>
 #include <asm/tlb.h>
 
+#ifdef CONFIG_MMU
 #include <asm-generic/pgalloc.h>	/* for pte_{alloc,free}_one */
 
 static inline void pmd_populate_kernel(struct mm_struct *mm,
@@ -81,5 +82,6 @@ do {                                    \
 	pgtable_pte_page_dtor(pte);     \
 	tlb_remove_page((tlb), pte);    \
 } while (0)
+#endif /* CONFIG_MMU */
 
 #endif /* _ASM_RISCV_PGALLOC_H */
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 42292d99cc74..f3636fc22a11 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -24,6 +24,7 @@
 #include <asm/pgtable-32.h>
 #endif /* CONFIG_64BIT */
 
+#ifdef CONFIG_MMU
 /* Number of entries in the page global directory */
 #define PTRS_PER_PGD    (PAGE_SIZE / sizeof(pgd_t))
 /* Number of entries in the page table */
@@ -31,7 +32,6 @@
 
 /* Number of PGD entries that a user-mode program can use */
 #define USER_PTRS_PER_PGD   (TASK_SIZE / PGDIR_SIZE)
-#define FIRST_USER_ADDRESS  0
 
 /* Page protection bits */
 #define _PAGE_BASE	(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER)
@@ -83,10 +83,6 @@ extern pgd_t swapper_pg_dir[];
 #define __S110	PAGE_SHARED_EXEC
 #define __S111	PAGE_SHARED_EXEC
 
-#define VMALLOC_SIZE     (KERN_VIRT_SIZE >> 1)
-#define VMALLOC_END      (PAGE_OFFSET - 1)
-#define VMALLOC_START    (PAGE_OFFSET - VMALLOC_SIZE)
-
 /*
  * Roughly size the vmemmap space to be large enough to fit enough
  * struct pages to map half the virtual address space. Then
@@ -100,21 +96,6 @@ extern pgd_t swapper_pg_dir[];
 
 #define vmemmap		((struct page *)VMEMMAP_START)
 
-#define FIXADDR_TOP      (VMEMMAP_START)
-#ifdef CONFIG_64BIT
-#define FIXADDR_SIZE     PMD_SIZE
-#else
-#define FIXADDR_SIZE     PGDIR_SIZE
-#endif
-#define FIXADDR_START    (FIXADDR_TOP - FIXADDR_SIZE)
-
-/*
- * ZERO_PAGE is a global shared page that is always zero,
- * used for zero-mapped memory areas, etc.
- */
-extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
-#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
-
 static inline int pmd_present(pmd_t pmd)
 {
 	return (pmd_val(pmd) & (_PAGE_PRESENT | _PAGE_PROT_NONE));
@@ -428,13 +409,17 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
 #define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
 #define __swp_entry_to_pte(x)	((pte_t) { (x).val })
 
-#ifdef CONFIG_FLATMEM
-#define kern_addr_valid(addr)   (1) /* FIXME */
-#endif
+#define VMALLOC_SIZE		(KERN_VIRT_SIZE >> 1)
+#define VMALLOC_END		(PAGE_OFFSET - 1)
+#define VMALLOC_START		(PAGE_OFFSET - VMALLOC_SIZE)
 
-extern void *dtb_early_va;
-extern void setup_bootmem(void);
-extern void paging_init(void);
+#define FIXADDR_TOP      VMEMMAP_START
+#ifdef CONFIG_64BIT
+#define FIXADDR_SIZE     PMD_SIZE
+#else
+#define FIXADDR_SIZE     PGDIR_SIZE
+#endif
+#define FIXADDR_START    (FIXADDR_TOP - FIXADDR_SIZE)
 
 /*
  * Task size is 0x4000000000 for RV64 or 0x9fc00000 for RV32.
@@ -446,6 +431,33 @@ extern void paging_init(void);
 #define TASK_SIZE FIXADDR_START
 #endif
 
+#else /* CONFIG_MMU */
+
+#define PAGE_KERNEL		__pgprot(0)
+#define swapper_pg_dir		NULL
+#define VMALLOC_START		0
+
+#define TASK_SIZE 0xffffffffUL
+
+#endif /* !CONFIG_MMU */
+
+#ifdef CONFIG_FLATMEM
+#define kern_addr_valid(addr)   (1) /* FIXME */
+#endif
+
+extern void *dtb_early_va;
+void setup_bootmem(void);
+void paging_init(void);
+
+#define FIRST_USER_ADDRESS  0
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero,
+ * used for zero-mapped memory areas, etc.
+ */
+extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
+#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+
 #include <asm-generic/pgtable.h>
 
 #endif /* !__ASSEMBLY__ */
diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
index f02188a5b0f4..394cfbccdcd9 100644
--- a/arch/riscv/include/asm/tlbflush.h
+++ b/arch/riscv/include/asm/tlbflush.h
@@ -10,6 +10,7 @@
 #include <linux/mm_types.h>
 #include <asm/smp.h>
 
+#ifdef CONFIG_MMU
 static inline void local_flush_tlb_all(void)
 {
 	__asm__ __volatile__ ("sfence.vma" : : : "memory");
@@ -20,14 +21,19 @@ static inline void local_flush_tlb_page(unsigned long addr)
 {
 	__asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory");
 }
+#else /* CONFIG_MMU */
+#define local_flush_tlb_all()			do { } while (0)
+#define local_flush_tlb_page(addr)		do { } while (0)
+#endif /* CONFIG_MMU */
 
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) && defined(CONFIG_MMU)
 void flush_tlb_all(void);
 void flush_tlb_mm(struct mm_struct *mm);
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr);
 void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 		     unsigned long end);
-#else /* CONFIG_SMP */
+#else /* CONFIG_SMP && CONFIG_MMU */
+
 #define flush_tlb_all() local_flush_tlb_all()
 #define flush_tlb_page(vma, addr) local_flush_tlb_page(addr)
 
@@ -38,7 +44,7 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
 }
 
 #define flush_tlb_mm(mm) flush_tlb_all()
-#endif /* CONFIG_SMP */
+#endif /* !CONFIG_SMP || !CONFIG_MMU */
 
 /* Flush a range of kernel pages */
 static inline void flush_tlb_kernel_range(unsigned long start,
diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
index e076437cfafe..f462a183a9c2 100644
--- a/arch/riscv/include/asm/uaccess.h
+++ b/arch/riscv/include/asm/uaccess.h
@@ -11,6 +11,7 @@
 /*
  * User space memory access functions
  */
+#ifdef CONFIG_MMU
 #include <linux/errno.h>
 #include <linux/compiler.h>
 #include <linux/thread_info.h>
@@ -475,4 +476,7 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n)
 	__ret;							\
 })
 
+#else /* CONFIG_MMU */
+#include <asm-generic/uaccess.h>
+#endif /* CONFIG_MMU */
 #endif /* _ASM_RISCV_UACCESS_H */
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 2dca51046899..f40205cb9a22 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -25,9 +25,8 @@ obj-y	+= time.o
 obj-y	+= traps.o
 obj-y	+= riscv_ksyms.o
 obj-y	+= stacktrace.o
-obj-y	+= vdso.o
 obj-y	+= cacheinfo.o
-obj-y	+= vdso/
+obj-$(CONFIG_MMU) += vdso.o vdso/
 
 obj-$(CONFIG_RISCV_M_MODE)	+= clint.o
 obj-$(CONFIG_FPU)		+= fpu.o
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index c0b3732af1ea..4bf6577dde7d 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -392,6 +392,10 @@ ENTRY(__switch_to)
 	ret
 ENDPROC(__switch_to)
 
+#ifndef CONFIG_MMU
+#define do_page_fault do_trap_unknown
+#endif
+
 	.section ".rodata"
 	/* Exception vector table */
 ENTRY(excp_vect_table)
@@ -413,3 +417,10 @@ ENTRY(excp_vect_table)
 	RISCV_PTR do_page_fault   /* store page fault */
 excp_vect_table_end:
 END(excp_vect_table)
+
+#ifndef CONFIG_MMU
+ENTRY(__user_rt_sigreturn)
+	li a7, __NR_rt_sigreturn
+	scall
+END(__user_rt_sigreturn)
+#endif
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 25867b99cc95..71efbba25ed5 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -109,8 +109,10 @@ clear_bss_done:
 	la sp, init_thread_union + THREAD_SIZE
 	mv a0, s1
 	call setup_vm
+#ifdef CONFIG_MMU
 	la a0, early_pg_dir
 	call relocate
+#endif /* CONFIG_MMU */
 
 	/* Restore C environment */
 	la tp, init_task
@@ -121,6 +123,7 @@ clear_bss_done:
 	call parse_dtb
 	tail start_kernel
 
+#ifdef CONFIG_MMU
 relocate:
 	/* Relocate return address */
 	li a1, PAGE_OFFSET
@@ -171,6 +174,7 @@ relocate:
 	sfence.vma
 
 	ret
+#endif /* CONFIG_MMU */
 
 .Lsecondary_start:
 #ifdef CONFIG_SMP
@@ -196,9 +200,11 @@ relocate:
 	beqz tp, .Lwait_for_cpu_up
 	fence
 
+#ifdef CONFIG_MMU
 	/* Enable virtual memory and relocate to virtual address */
 	la a0, swapper_pg_dir
 	call relocate
+#endif
 
 	tail smp_callin
 #endif
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index e1a2cee340f7..eb8ba201feff 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -17,11 +17,16 @@
 #include <asm/switch_to.h>
 #include <asm/csr.h>
 
+extern u32 __user_rt_sigreturn[2];
+
 #define DEBUG_SIG 0
 
 struct rt_sigframe {
 	struct siginfo info;
 	struct ucontext uc;
+#ifndef CONFIG_MMU
+	u32 sigreturn_code[2];
+#endif
 };
 
 #ifdef CONFIG_FPU
@@ -166,7 +171,6 @@ static inline void __user *get_sigframe(struct ksignal *ksig,
 	return (void __user *)sp;
 }
 
-
 static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 	struct pt_regs *regs)
 {
@@ -189,8 +193,19 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 		return -EFAULT;
 
 	/* Set up to return from userspace. */
+#ifdef CONFIG_MMU
 	regs->ra = (unsigned long)VDSO_SYMBOL(
 		current->mm->context.vdso, rt_sigreturn);
+#else
+	/*
+	 * For the nommu case we don't have a VDSO.  Instead we push two
+	 * instructions to call the rt_sigreturn syscall onto the user stack.
+	 */
+	if (copy_to_user(&frame->sigreturn_code, __user_rt_sigreturn,
+			sizeof(frame->sigreturn_code)))
+		return -EFAULT;
+	regs->ra = (unsigned long)&frame->sigreturn_code;;
+#endif /* CONFIG_MMU */
 
 	/*
 	 * Set up registers for signal handler.
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index 267feaa10f6a..47e7a8204460 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -1,7 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
-lib-y	+= delay.o
-lib-y	+= memcpy.o
-lib-y	+= memset.o
-lib-y	+= uaccess.o
-
-lib-$(CONFIG_64BIT) += tishift.o
+lib-y			+= delay.o
+lib-y			+= memcpy.o
+lib-y			+= memset.o
+lib-$(CONFIG_MMU)	+= uaccess.o
+lib-$(CONFIG_64BIT)	+= tishift.o
diff --git a/arch/riscv/mm/Makefile b/arch/riscv/mm/Makefile
index 9d9a17335686..44ab8f28c3fa 100644
--- a/arch/riscv/mm/Makefile
+++ b/arch/riscv/mm/Makefile
@@ -6,9 +6,8 @@ CFLAGS_REMOVE_init.o = -pg
 endif
 
 obj-y += init.o
-obj-y += fault.o
 obj-y += extable.o
-obj-y += ioremap.o
+obj-$(CONFIG_MMU) += fault.o ioremap.o
 obj-y += cacheflush.o
 obj-y += context.o
 obj-y += sifive_l2_cache.o
diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c
index 794c9ab256eb..8f1900686640 100644
--- a/arch/riscv/mm/cacheflush.c
+++ b/arch/riscv/mm/cacheflush.c
@@ -78,6 +78,7 @@ void flush_icache_mm(struct mm_struct *mm, bool local)
 
 #endif /* CONFIG_SMP */
 
+#ifdef CONFIG_MMU
 void flush_icache_pte(pte_t pte)
 {
 	struct page *page = pte_page(pte);
@@ -85,3 +86,4 @@ void flush_icache_pte(pte_t pte)
 	if (!test_and_set_bit(PG_dcache_clean, &page->flags))
 		flush_icache_all();
 }
+#endif /* CONFIG_MMU */
diff --git a/arch/riscv/mm/context.c b/arch/riscv/mm/context.c
index beeb5d7f92ea..073ff12a838a 100644
--- a/arch/riscv/mm/context.c
+++ b/arch/riscv/mm/context.c
@@ -57,8 +57,10 @@ void switch_mm(struct mm_struct *prev, struct mm_struct *next,
 	cpumask_clear_cpu(cpu, mm_cpumask(prev));
 	cpumask_set_cpu(cpu, mm_cpumask(next));
 
+#ifdef CONFIG_MMU
 	csr_write(CSR_SATP, virt_to_pfn(next->pgd) | SATP_MODE);
 	local_flush_tlb_all();
+#endif
 
 	flush_icache_deferred(next);
 }
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 83f7d12042fb..0b063f6acaa1 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -24,6 +24,7 @@ unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]
 EXPORT_SYMBOL(empty_zero_page);
 
 extern char _start[];
+void *dtb_early_va;
 
 static void __init zone_sizes_init(void)
 {
@@ -140,12 +141,12 @@ void __init setup_bootmem(void)
 	}
 }
 
+#ifdef CONFIG_MMU
 unsigned long va_pa_offset;
 EXPORT_SYMBOL(va_pa_offset);
 unsigned long pfn_base;
 EXPORT_SYMBOL(pfn_base);
 
-void *dtb_early_va;
 pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
 pgd_t trampoline_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
 pte_t fixmap_pte[PTRS_PER_PTE] __page_aligned_bss;
@@ -448,6 +449,16 @@ static void __init setup_vm_final(void)
 	csr_write(CSR_SATP, PFN_DOWN(__pa(swapper_pg_dir)) | SATP_MODE);
 	local_flush_tlb_all();
 }
+#else
+asmlinkage void __init setup_vm(uintptr_t dtb_pa)
+{
+	dtb_early_va = (void *)dtb_pa;
+}
+
+static inline void setup_vm_final(void)
+{
+}
+#endif /* CONFIG_MMU */
 
 void __init paging_init(void)
 {
-- 
2.20.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 14/15] riscv: provide a flat image loader
  2019-10-17 17:37 RISC-V nommu support v5 Christoph Hellwig
                   ` (12 preceding siblings ...)
  2019-10-17 17:37 ` [PATCH 13/15] riscv: add nommu support Christoph Hellwig
@ 2019-10-17 17:37 ` Christoph Hellwig
  2019-10-18  3:06   ` Anup Patel
  2019-10-17 17:37 ` [PATCH 15/15] riscv: disable the EFI PECOFF header for M-mode Christoph Hellwig
  2019-10-18  3:08 ` RISC-V nommu support v5 Anup Patel
  15 siblings, 1 reply; 41+ messages in thread
From: Christoph Hellwig @ 2019-10-17 17:37 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley; +Cc: Damien Le Moal, linux-riscv, linux-kernel

This allows just loading the kernel at a pre-set address without
qemu going bonkers trying to map the ELF file.

Contains a controbution from Aurabindo Jayamohanan to reuse the
PAGE_OFFSET definition.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/riscv/Makefile          | 13 +++++++++----
 arch/riscv/boot/Makefile     |  7 ++++++-
 arch/riscv/boot/loader.S     |  8 ++++++++
 arch/riscv/boot/loader.lds.S | 16 ++++++++++++++++
 4 files changed, 39 insertions(+), 5 deletions(-)
 create mode 100644 arch/riscv/boot/loader.S
 create mode 100644 arch/riscv/boot/loader.lds.S

diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index f5e914210245..b9009a2fbaf5 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -83,13 +83,18 @@ PHONY += vdso_install
 vdso_install:
 	$(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@
 
-all: Image.gz
+ifeq ($(CONFIG_RISCV_M_MODE),y)
+KBUILD_IMAGE := $(boot)/loader
+else
+KBUILD_IMAGE := $(boot)/Image.gz
+endif
+BOOT_TARGETS := Image Image.gz loader
 
-Image: vmlinux
-	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+all:	$(notdir $(KBUILD_IMAGE))
 
-Image.%: Image
+$(BOOT_TARGETS): vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+	@$(kecho) '  Kernel: $(boot)/$@ is ready'
 
 zinstall install:
 	$(Q)$(MAKE) $(build)=$(boot) $@
diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile
index 0990a9fdbe5d..8639e0dd2cdf 100644
--- a/arch/riscv/boot/Makefile
+++ b/arch/riscv/boot/Makefile
@@ -16,7 +16,7 @@
 
 OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
 
-targets := Image
+targets := Image loader
 
 $(obj)/Image: vmlinux FORCE
 	$(call if_changed,objcopy)
@@ -24,6 +24,11 @@ $(obj)/Image: vmlinux FORCE
 $(obj)/Image.gz: $(obj)/Image FORCE
 	$(call if_changed,gzip)
 
+loader.o: $(src)/loader.S $(obj)/Image
+
+$(obj)/loader: $(obj)/loader.o $(obj)/Image $(obj)/loader.lds FORCE
+	$(Q)$(LD) -T $(src)/loader.lds -o $@ $(obj)/loader.o
+
 install:
 	$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
 	$(obj)/Image System.map "$(INSTALL_PATH)"
diff --git a/arch/riscv/boot/loader.S b/arch/riscv/boot/loader.S
new file mode 100644
index 000000000000..5586e2610dbb
--- /dev/null
+++ b/arch/riscv/boot/loader.S
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+
+	.align 4
+	.section .payload, "ax", %progbits
+	.globl _start
+_start:
+	.incbin "arch/riscv/boot/Image"
+
diff --git a/arch/riscv/boot/loader.lds.S b/arch/riscv/boot/loader.lds.S
new file mode 100644
index 000000000000..47a5003c2e28
--- /dev/null
+++ b/arch/riscv/boot/loader.lds.S
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <asm/page.h>
+
+OUTPUT_ARCH(riscv)
+ENTRY(_start)
+
+SECTIONS
+{
+	. = PAGE_OFFSET;
+
+	.payload : {
+		*(.payload)
+		. = ALIGN(8);
+	}
+}
-- 
2.20.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 15/15] riscv: disable the EFI PECOFF header for M-mode
  2019-10-17 17:37 RISC-V nommu support v5 Christoph Hellwig
                   ` (13 preceding siblings ...)
  2019-10-17 17:37 ` [PATCH 14/15] riscv: provide a flat image loader Christoph Hellwig
@ 2019-10-17 17:37 ` Christoph Hellwig
  2019-10-18  3:06   ` Anup Patel
  2019-10-18  3:08 ` RISC-V nommu support v5 Anup Patel
  15 siblings, 1 reply; 41+ messages in thread
From: Christoph Hellwig @ 2019-10-17 17:37 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley; +Cc: Damien Le Moal, linux-riscv, linux-kernel

No point in bloating the kernel image with a bootloader header if
we run bare metal.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/riscv/kernel/head.S | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 71efbba25ed5..dc21e409cc49 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -16,6 +16,7 @@
 
 __INIT
 ENTRY(_start)
+#ifndef CONFIG_RISCV_M_MODE
 	/*
 	 * Image header expected by Linux boot-loaders. The image header data
 	 * structure is described in asm/image.h.
@@ -47,6 +48,7 @@ ENTRY(_start)
 
 .global _start_kernel
 _start_kernel:
+#endif /* CONFIG_RISCV_M_MODE */
 	/* Mask all interrupts */
 	csrw CSR_XIE, zero
 	csrw CSR_XIP, zero
-- 
2.20.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH 01/15] riscv: cleanup <asm/bug.h>
  2019-10-17 17:37 ` [PATCH 01/15] riscv: cleanup <asm/bug.h> Christoph Hellwig
@ 2019-10-18  2:50   ` Anup Patel
  2019-10-23 22:04   ` Paul Walmsley
  1 sibling, 0 replies; 41+ messages in thread
From: Anup Patel @ 2019-10-18  2:50 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel@vger.kernel.org List, Damien Le Moal,
	Palmer Dabbelt, linux-riscv, Paul Walmsley

On Thu, Oct 17, 2019 at 11:07 PM Christoph Hellwig <hch@lst.de> wrote:
>
> Remove various not required ifdefs and externs.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  arch/riscv/include/asm/bug.h | 16 +++-------------
>  1 file changed, 3 insertions(+), 13 deletions(-)
>
> diff --git a/arch/riscv/include/asm/bug.h b/arch/riscv/include/asm/bug.h
> index 07ceee8b1747..75604fec1b1b 100644
> --- a/arch/riscv/include/asm/bug.h
> +++ b/arch/riscv/include/asm/bug.h
> @@ -12,7 +12,6 @@
>
>  #include <asm/asm.h>
>
> -#ifdef CONFIG_GENERIC_BUG
>  #define __INSN_LENGTH_MASK  _UL(0x3)
>  #define __INSN_LENGTH_32    _UL(0x3)
>  #define __COMPRESSED_INSN_MASK _UL(0xffff)
> @@ -20,7 +19,6 @@
>  #define __BUG_INSN_32  _UL(0x00100073) /* ebreak */
>  #define __BUG_INSN_16  _UL(0x9002) /* c.ebreak */
>
> -#ifndef __ASSEMBLY__
>  typedef u32 bug_insn_t;
>
>  #ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
> @@ -43,6 +41,7 @@ typedef u32 bug_insn_t;
>         RISCV_SHORT " %2"
>  #endif
>
> +#ifdef CONFIG_GENERIC_BUG
>  #define __BUG_FLAGS(flags)                                     \
>  do {                                                           \
>         __asm__ __volatile__ (                                  \
> @@ -58,14 +57,10 @@ do {                                                                \
>                   "i" (flags),                                  \
>                   "i" (sizeof(struct bug_entry)));              \
>  } while (0)
> -
> -#endif /* !__ASSEMBLY__ */
>  #else /* CONFIG_GENERIC_BUG */
> -#ifndef __ASSEMBLY__
>  #define __BUG_FLAGS(flags) do {                                        \
>         __asm__ __volatile__ ("ebreak\n");                      \
>  } while (0)
> -#endif /* !__ASSEMBLY__ */
>  #endif /* CONFIG_GENERIC_BUG */
>
>  #define BUG() do {                                             \
> @@ -79,15 +74,10 @@ do {                                                                \
>
>  #include <asm-generic/bug.h>
>
> -#ifndef __ASSEMBLY__
> -
>  struct pt_regs;
>  struct task_struct;
>
> -extern void die(struct pt_regs *regs, const char *str);
> -extern void do_trap(struct pt_regs *regs, int signo, int code,
> -       unsigned long addr);
> -
> -#endif /* !__ASSEMBLY__ */
> +void die(struct pt_regs *regs, const char *str);
> +void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr);
>
>  #endif /* _ASM_RISCV_BUG_H */
> --
> 2.20.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Regards,
Anup

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 02/15] riscv: cleanup do_trap_break
  2019-10-17 17:37 ` [PATCH 02/15] riscv: cleanup do_trap_break Christoph Hellwig
@ 2019-10-18  2:51   ` Anup Patel
  2019-10-23 22:05   ` Paul Walmsley
  1 sibling, 0 replies; 41+ messages in thread
From: Anup Patel @ 2019-10-18  2:51 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel@vger.kernel.org List, Damien Le Moal,
	Palmer Dabbelt, linux-riscv, Paul Walmsley

On Thu, Oct 17, 2019 at 11:07 PM Christoph Hellwig <hch@lst.de> wrote:
>
> If we always compile the get_break_insn_length inline function we can
> remove the ifdefs and let dead code elimination take care of the warn
> branch that is now unreadable because the report_bug stub always
> returns BUG_TRAP_TYPE_BUG.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  arch/riscv/kernel/traps.c | 26 ++++++--------------------
>  1 file changed, 6 insertions(+), 20 deletions(-)
>
> diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
> index 1ac75f7d0bff..10a17e545f43 100644
> --- a/arch/riscv/kernel/traps.c
> +++ b/arch/riscv/kernel/traps.c
> @@ -111,7 +111,6 @@ DO_ERROR_INFO(do_trap_ecall_s,
>  DO_ERROR_INFO(do_trap_ecall_m,
>         SIGILL, ILL_ILLTRP, "environment call from M-mode");
>
> -#ifdef CONFIG_GENERIC_BUG
>  static inline unsigned long get_break_insn_length(unsigned long pc)
>  {
>         bug_insn_t insn;
> @@ -120,28 +119,15 @@ static inline unsigned long get_break_insn_length(unsigned long pc)
>                 return 0;
>         return (((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) ? 4UL : 2UL);
>  }
> -#endif /* CONFIG_GENERIC_BUG */
>
>  asmlinkage void do_trap_break(struct pt_regs *regs)
>  {
> -       if (user_mode(regs)) {
> -               force_sig_fault(SIGTRAP, TRAP_BRKPT,
> -                               (void __user *)(regs->sepc));
> -               return;
> -       }
> -#ifdef CONFIG_GENERIC_BUG
> -       {
> -               enum bug_trap_type type;
> -
> -               type = report_bug(regs->sepc, regs);
> -               if (type == BUG_TRAP_TYPE_WARN) {
> -                       regs->sepc += get_break_insn_length(regs->sepc);
> -                       return;
> -               }
> -       }
> -#endif /* CONFIG_GENERIC_BUG */
> -
> -       die(regs, "Kernel BUG");
> +       if (user_mode(regs))
> +               force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->sepc);
> +       else if (report_bug(regs->sepc, regs) == BUG_TRAP_TYPE_WARN)
> +               regs->sepc += get_break_insn_length(regs->sepc);
> +       else
> +               die(regs, "Kernel BUG");
>  }
>
>  #ifdef CONFIG_GENERIC_BUG
> --
> 2.20.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Regards,
Anup

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 03/15] riscv: abstract out CSR names for supervisor vs machine mode
  2019-10-17 17:37 ` [PATCH 03/15] riscv: abstract out CSR names for supervisor vs machine mode Christoph Hellwig
@ 2019-10-18  2:51   ` Anup Patel
  2019-10-18 23:55   ` Paul Walmsley
  1 sibling, 0 replies; 41+ messages in thread
From: Anup Patel @ 2019-10-18  2:51 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Damien Le Moal, Palmer Dabbelt,
	linux-kernel@vger.kernel.org List, Atish Patra, Paul Walmsley,
	linux-riscv

On Thu, Oct 17, 2019 at 11:07 PM Christoph Hellwig <hch@lst.de> wrote:
>
> Many of the privileged CSRs exist in a supervisor and machine version
> that are used very similarly.  Provide a new X-naming layer so that
> we don't have to ifdef everywhere for M-mode Linux support.
>
> Contains contributions from Damien Le Moal <Damien.LeMoal@wdc.com>.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Atish Patra <atish.patra@wdc.com>
> ---
>  arch/riscv/Kconfig                 |  4 ++
>  arch/riscv/include/asm/asm.h       |  6 +++
>  arch/riscv/include/asm/csr.h       | 58 +++++++++++++++++++++++--
>  arch/riscv/include/asm/irqflags.h  | 12 +++---
>  arch/riscv/include/asm/processor.h |  2 +-
>  arch/riscv/include/asm/ptrace.h    | 16 +++----
>  arch/riscv/include/asm/switch_to.h | 10 ++---
>  arch/riscv/kernel/asm-offsets.c    |  8 ++--
>  arch/riscv/kernel/entry.S          | 68 ++++++++++++++++--------------
>  arch/riscv/kernel/fpu.S            |  8 ++--
>  arch/riscv/kernel/head.S           | 12 +++---
>  arch/riscv/kernel/irq.c            |  4 +-
>  arch/riscv/kernel/process.c        | 15 ++++---
>  arch/riscv/kernel/signal.c         | 21 +++++----
>  arch/riscv/kernel/traps.c          | 16 +++----
>  arch/riscv/lib/uaccess.S           | 12 +++---
>  arch/riscv/mm/extable.c            |  4 +-
>  arch/riscv/mm/fault.c              |  6 +--
>  drivers/clocksource/timer-riscv.c  |  8 ++--
>  drivers/irqchip/irq-sifive-plic.c  |  4 +-
>  20 files changed, 181 insertions(+), 113 deletions(-)
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 8eebbc8860bb..86b7e8b0471c 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -72,6 +72,10 @@ config ARCH_MMAP_RND_BITS_MAX
>         default 24 if 64BIT # SV39 based
>         default 17
>
> +# set if we run in machine mode, cleared if we run in supervisor mode
> +config RISCV_M_MODE
> +       bool
> +
>  config MMU
>         def_bool y
>
> diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
> index 9c992a88d858..e362fb741c76 100644
> --- a/arch/riscv/include/asm/asm.h
> +++ b/arch/riscv/include/asm/asm.h
> @@ -66,4 +66,10 @@
>  #error "Unexpected __SIZEOF_SHORT__"
>  #endif
>
> +#ifdef CONFIG_RISCV_M_MODE
> +# define Xret          mret
> +#else
> +# define Xret          sret
> +#endif
> +
>  #endif /* _ASM_RISCV_ASM_H */
> diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
> index a18923fa23c8..0dae5c361f29 100644
> --- a/arch/riscv/include/asm/csr.h
> +++ b/arch/riscv/include/asm/csr.h
> @@ -11,8 +11,11 @@
>
>  /* Status register flags */
>  #define SR_SIE         _AC(0x00000002, UL) /* Supervisor Interrupt Enable */
> +#define SR_MIE         _AC(0x00000008, UL) /* Machine Interrupt Enable */
>  #define SR_SPIE                _AC(0x00000020, UL) /* Previous Supervisor IE */
> +#define SR_MPIE                _AC(0x00000080, UL) /* Previous Machine IE */
>  #define SR_SPP         _AC(0x00000100, UL) /* Previously Supervisor */
> +#define SR_MPP         _AC(0x00001800, UL) /* Previously Machine */
>  #define SR_SUM         _AC(0x00040000, UL) /* Supervisor User Memory Access */
>
>  #define SR_FS          _AC(0x00006000, UL) /* Floating-point Status */
> @@ -44,8 +47,8 @@
>  #define SATP_MODE      SATP_MODE_39
>  #endif
>
> -/* SCAUSE */
> -#define SCAUSE_IRQ_FLAG                (_AC(1, UL) << (__riscv_xlen - 1))
> +/* *CAUSE */
> +#define XCAUSE_IRQ_FLAG                (_AC(1, UL) << (__riscv_xlen - 1))
>
>  #define IRQ_U_SOFT             0
>  #define IRQ_S_SOFT             1
> @@ -67,11 +70,26 @@
>  #define EXC_LOAD_PAGE_FAULT    13
>  #define EXC_STORE_PAGE_FAULT   15
>
> -/* SIE (Interrupt Enable) and SIP (Interrupt Pending) flags */
> +/* SIE/SIP (Machine Interrupt Enable/Pending) flags */
> +#define MIE_MSIE               (_AC(0x1, UL) << IRQ_M_SOFT)
> +#define MIE_MTIE               (_AC(0x1, UL) << IRQ_M_TIMER)
> +#define MIE_MEIE               (_AC(0x1, UL) << IRQ_M_EXT)
> +
> +/* SIE/SIP (Supervisor Interrupt Enable/Pending) flags */
>  #define SIE_SSIE               (_AC(0x1, UL) << IRQ_S_SOFT)
>  #define SIE_STIE               (_AC(0x1, UL) << IRQ_S_TIMER)
>  #define SIE_SEIE               (_AC(0x1, UL) << IRQ_S_EXT)
>
> +/* symbolic CSR names: */
> +#define CSR_MSTATUS            0x300
> +#define CSR_MIE                        0x304
> +#define CSR_MTVEC              0x305
> +#define CSR_MSCRATCH           0x340
> +#define CSR_MEPC               0x341
> +#define CSR_MCAUSE             0x342
> +#define CSR_MTVAL              0x343
> +#define CSR_MIP                        0x344
> +
>  #define CSR_CYCLE              0xc00
>  #define CSR_TIME               0xc01
>  #define CSR_INSTRET            0xc02
> @@ -89,6 +107,40 @@
>  #define CSR_TIMEH              0xc81
>  #define CSR_INSTRETH           0xc82
>
> +#ifdef CONFIG_RISCV_M_MODE
> +# define CSR_XSTATUS   CSR_MSTATUS
> +# define CSR_XIE       CSR_MIE
> +# define CSR_XTVEC     CSR_MTVEC
> +# define CSR_XSCRATCH  CSR_MSCRATCH
> +# define CSR_XEPC      CSR_MEPC
> +# define CSR_XCAUSE    CSR_MCAUSE
> +# define CSR_XTVAL     CSR_MTVAL
> +# define CSR_XIP       CSR_MIP
> +
> +# define SR_XIE                SR_MIE
> +# define SR_XPIE       SR_MPIE
> +# define SR_XPP                SR_MPP
> +
> +# define XIE_XTIE      MIE_MTIE
> +# define XIE_XEIE      MIE_MEIE
> +#else /* CONFIG_RISCV_M_MODE */
> +# define CSR_XSTATUS   CSR_SSTATUS
> +# define CSR_XIE       CSR_SIE
> +# define CSR_XTVEC     CSR_STVEC
> +# define CSR_XSCRATCH  CSR_SSCRATCH
> +# define CSR_XEPC      CSR_SEPC
> +# define CSR_XCAUSE    CSR_SCAUSE
> +# define CSR_XTVAL     CSR_STVAL
> +# define CSR_XIP       CSR_SIP
> +
> +# define SR_XIE                SR_SIE
> +# define SR_XPIE       SR_SPIE
> +# define SR_XPP                SR_SPP
> +
> +# define XIE_XTIE      SIE_STIE
> +# define XIE_XEIE      SIE_SEIE
> +#endif /* CONFIG_RISCV_M_MODE */
> +
>  #ifndef __ASSEMBLY__
>
>  #define csr_swap(csr, val)                                     \
> diff --git a/arch/riscv/include/asm/irqflags.h b/arch/riscv/include/asm/irqflags.h
> index e70f647ce3b7..ba2828a37d72 100644
> --- a/arch/riscv/include/asm/irqflags.h
> +++ b/arch/riscv/include/asm/irqflags.h
> @@ -13,31 +13,31 @@
>  /* read interrupt enabled status */
>  static inline unsigned long arch_local_save_flags(void)
>  {
> -       return csr_read(CSR_SSTATUS);
> +       return csr_read(CSR_XSTATUS);
>  }
>
>  /* unconditionally enable interrupts */
>  static inline void arch_local_irq_enable(void)
>  {
> -       csr_set(CSR_SSTATUS, SR_SIE);
> +       csr_set(CSR_XSTATUS, SR_XIE);
>  }
>
>  /* unconditionally disable interrupts */
>  static inline void arch_local_irq_disable(void)
>  {
> -       csr_clear(CSR_SSTATUS, SR_SIE);
> +       csr_clear(CSR_XSTATUS, SR_XIE);
>  }
>
>  /* get status and disable interrupts */
>  static inline unsigned long arch_local_irq_save(void)
>  {
> -       return csr_read_clear(CSR_SSTATUS, SR_SIE);
> +       return csr_read_clear(CSR_XSTATUS, SR_XIE);
>  }
>
>  /* test flags */
>  static inline int arch_irqs_disabled_flags(unsigned long flags)
>  {
> -       return !(flags & SR_SIE);
> +       return !(flags & SR_XIE);
>  }
>
>  /* test hardware interrupt enable bit */
> @@ -49,7 +49,7 @@ static inline int arch_irqs_disabled(void)
>  /* set interrupt enabled status */
>  static inline void arch_local_irq_restore(unsigned long flags)
>  {
> -       csr_set(CSR_SSTATUS, flags & SR_SIE);
> +       csr_set(CSR_XSTATUS, flags & SR_XIE);
>  }
>
>  #endif /* _ASM_RISCV_IRQFLAGS_H */
> diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
> index f539149d04c2..46f825e34575 100644
> --- a/arch/riscv/include/asm/processor.h
> +++ b/arch/riscv/include/asm/processor.h
> @@ -42,7 +42,7 @@ struct thread_struct {
>         ((struct pt_regs *)(task_stack_page(tsk) + THREAD_SIZE          \
>                             - ALIGN(sizeof(struct pt_regs), STACK_ALIGN)))
>
> -#define KSTK_EIP(tsk)          (task_pt_regs(tsk)->sepc)
> +#define KSTK_EIP(tsk)          (task_pt_regs(tsk)->xepc)
>  #define KSTK_ESP(tsk)          (task_pt_regs(tsk)->sp)
>
>
> diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h
> index d48d1e13973c..7684d81d0e84 100644
> --- a/arch/riscv/include/asm/ptrace.h
> +++ b/arch/riscv/include/asm/ptrace.h
> @@ -12,7 +12,7 @@
>  #ifndef __ASSEMBLY__
>
>  struct pt_regs {
> -       unsigned long sepc;
> +       unsigned long xepc;
>         unsigned long ra;
>         unsigned long sp;
>         unsigned long gp;
> @@ -44,10 +44,10 @@ struct pt_regs {
>         unsigned long t4;
>         unsigned long t5;
>         unsigned long t6;
> -       /* Supervisor CSRs */
> -       unsigned long sstatus;
> -       unsigned long sbadaddr;
> -       unsigned long scause;
> +       /* Supervisor/Machine CSRs */
> +       unsigned long xstatus;
> +       unsigned long xbadaddr;
> +       unsigned long xcause;
>         /* a0 value before the syscall */
>         unsigned long orig_a0;
>  };
> @@ -58,18 +58,18 @@ struct pt_regs {
>  #define REG_FMT "%08lx"
>  #endif
>
> -#define user_mode(regs) (((regs)->sstatus & SR_SPP) == 0)
> +#define user_mode(regs) (((regs)->xstatus & SR_XPP) == 0)
>
>
>  /* Helpers for working with the instruction pointer */
>  static inline unsigned long instruction_pointer(struct pt_regs *regs)
>  {
> -       return regs->sepc;
> +       return regs->xepc;
>  }
>  static inline void instruction_pointer_set(struct pt_regs *regs,
>                                            unsigned long val)
>  {
> -       regs->sepc = val;
> +       regs->xepc = val;
>  }
>
>  #define profile_pc(regs) instruction_pointer(regs)
> diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
> index f0227bdce0f0..77593105b367 100644
> --- a/arch/riscv/include/asm/switch_to.h
> +++ b/arch/riscv/include/asm/switch_to.h
> @@ -16,19 +16,19 @@ extern void __fstate_restore(struct task_struct *restore_from);
>
>  static inline void __fstate_clean(struct pt_regs *regs)
>  {
> -       regs->sstatus = (regs->sstatus & ~SR_FS) | SR_FS_CLEAN;
> +       regs->xstatus = (regs->xstatus & ~SR_FS) | SR_FS_CLEAN;
>  }
>
>  static inline void fstate_off(struct task_struct *task,
>                               struct pt_regs *regs)
>  {
> -       regs->sstatus = (regs->sstatus & ~SR_FS) | SR_FS_OFF;
> +       regs->xstatus = (regs->xstatus & ~SR_FS) | SR_FS_OFF;
>  }
>
>  static inline void fstate_save(struct task_struct *task,
>                                struct pt_regs *regs)
>  {
> -       if ((regs->sstatus & SR_FS) == SR_FS_DIRTY) {
> +       if ((regs->xstatus & SR_FS) == SR_FS_DIRTY) {
>                 __fstate_save(task);
>                 __fstate_clean(regs);
>         }
> @@ -37,7 +37,7 @@ static inline void fstate_save(struct task_struct *task,
>  static inline void fstate_restore(struct task_struct *task,
>                                   struct pt_regs *regs)
>  {
> -       if ((regs->sstatus & SR_FS) != SR_FS_OFF) {
> +       if ((regs->xstatus & SR_FS) != SR_FS_OFF) {
>                 __fstate_restore(task);
>                 __fstate_clean(regs);
>         }
> @@ -49,7 +49,7 @@ static inline void __switch_to_aux(struct task_struct *prev,
>         struct pt_regs *regs;
>
>         regs = task_pt_regs(prev);
> -       if (unlikely(regs->sstatus & SR_SD))
> +       if (unlikely(regs->xstatus & SR_SD))
>                 fstate_save(prev, regs);
>         fstate_restore(next, task_pt_regs(next));
>  }
> diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
> index 9f5628c38ac9..d631ad41917b 100644
> --- a/arch/riscv/kernel/asm-offsets.c
> +++ b/arch/riscv/kernel/asm-offsets.c
> @@ -71,7 +71,7 @@ void asm_offsets(void)
>         OFFSET(TASK_THREAD_FCSR, task_struct, thread.fstate.fcsr);
>
>         DEFINE(PT_SIZE, sizeof(struct pt_regs));
> -       OFFSET(PT_SEPC, pt_regs, sepc);
> +       OFFSET(PT_XEPC, pt_regs, xepc);
>         OFFSET(PT_RA, pt_regs, ra);
>         OFFSET(PT_FP, pt_regs, s0);
>         OFFSET(PT_S0, pt_regs, s0);
> @@ -105,9 +105,9 @@ void asm_offsets(void)
>         OFFSET(PT_T6, pt_regs, t6);
>         OFFSET(PT_GP, pt_regs, gp);
>         OFFSET(PT_ORIG_A0, pt_regs, orig_a0);
> -       OFFSET(PT_SSTATUS, pt_regs, sstatus);
> -       OFFSET(PT_SBADADDR, pt_regs, sbadaddr);
> -       OFFSET(PT_SCAUSE, pt_regs, scause);
> +       OFFSET(PT_XSTATUS, pt_regs, xstatus);
> +       OFFSET(PT_XBADADDR, pt_regs, xbadaddr);
> +       OFFSET(PT_XCAUSE, pt_regs, xcause);
>
>         /*
>          * THREAD_{F,X}* might be larger than a S-type offset can handle, but
> diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
> index 8ca479831142..c0b3732af1ea 100644
> --- a/arch/riscv/kernel/entry.S
> +++ b/arch/riscv/kernel/entry.S
> @@ -26,14 +26,14 @@
>
>         /*
>          * If coming from userspace, preserve the user thread pointer and load
> -        * the kernel thread pointer.  If we came from the kernel, sscratch
> -        * will contain 0, and we should continue on the current TP.
> +        * the kernel thread pointer.  If we came from the kernel, the scratch
> +        * register will contain 0, and we should continue on the current TP.
>          */
> -       csrrw tp, CSR_SSCRATCH, tp
> +       csrrw tp, CSR_XSCRATCH, tp
>         bnez tp, _save_context
>
>  _restore_kernel_tpsp:
> -       csrr tp, CSR_SSCRATCH
> +       csrr tp, CSR_XSCRATCH
>         REG_S sp, TASK_TI_KERNEL_SP(tp)
>  _save_context:
>         REG_S sp, TASK_TI_USER_SP(tp)
> @@ -79,16 +79,16 @@ _save_context:
>         li t0, SR_SUM | SR_FS
>
>         REG_L s0, TASK_TI_USER_SP(tp)
> -       csrrc s1, CSR_SSTATUS, t0
> -       csrr s2, CSR_SEPC
> -       csrr s3, CSR_STVAL
> -       csrr s4, CSR_SCAUSE
> -       csrr s5, CSR_SSCRATCH
> +       csrrc s1, CSR_XSTATUS, t0
> +       csrr s2, CSR_XEPC
> +       csrr s3, CSR_XTVAL
> +       csrr s4, CSR_XCAUSE
> +       csrr s5, CSR_XSCRATCH
>         REG_S s0, PT_SP(sp)
> -       REG_S s1, PT_SSTATUS(sp)
> -       REG_S s2, PT_SEPC(sp)
> -       REG_S s3, PT_SBADADDR(sp)
> -       REG_S s4, PT_SCAUSE(sp)
> +       REG_S s1, PT_XSTATUS(sp)
> +       REG_S s2, PT_XEPC(sp)
> +       REG_S s3, PT_XBADADDR(sp)
> +       REG_S s4, PT_XCAUSE(sp)
>         REG_S s5, PT_TP(sp)
>         .endm
>
> @@ -97,7 +97,7 @@ _save_context:
>   * registers from the stack.
>   */
>         .macro RESTORE_ALL
> -       REG_L a0, PT_SSTATUS(sp)
> +       REG_L a0, PT_XSTATUS(sp)
>         /*
>          * The current load reservation is effectively part of the processor's
>          * state, in the sense that load reservations cannot be shared between
> @@ -115,11 +115,11 @@ _save_context:
>          * completes, implementations are allowed to expand reservations to be
>          * arbitrarily large.
>          */
> -       REG_L  a2, PT_SEPC(sp)
> -       REG_SC x0, a2, PT_SEPC(sp)
> +       REG_L  a2, PT_XEPC(sp)
> +       REG_SC x0, a2, PT_XEPC(sp)
>
> -       csrw CSR_SSTATUS, a0
> -       csrw CSR_SEPC, a2
> +       csrw CSR_XSTATUS, a0
> +       csrw CSR_XEPC, a2
>
>         REG_L x1,  PT_RA(sp)
>         REG_L x3,  PT_GP(sp)
> @@ -163,10 +163,10 @@ ENTRY(handle_exception)
>         SAVE_ALL
>
>         /*
> -        * Set sscratch register to 0, so that if a recursive exception
> +        * Set the scratch register to 0, so that if a recursive exception
>          * occurs, the exception vector knows it came from the kernel
>          */
> -       csrw CSR_SSCRATCH, x0
> +       csrw CSR_XSCRATCH, x0
>
>         /* Load the global pointer */
>  .option push
> @@ -186,10 +186,10 @@ ENTRY(handle_exception)
>         tail do_IRQ
>  1:
>         /* Exceptions run with interrupts enabled or disabled
> -          depending on the state of sstatus.SR_SPIE */
> -       andi t0, s1, SR_SPIE
> +          depending on the state of xstatus.SR_XPIE */
> +       andi t0, s1, SR_XPIE
>         beqz t0, 1f
> -       csrs CSR_SSTATUS, SR_SIE
> +       csrs CSR_XSTATUS, SR_XIE
>
>  1:
>         /* Handle syscalls */
> @@ -217,7 +217,7 @@ handle_syscall:
>          * scall instruction on sret
>          */
>         addi s2, s2, 0x4
> -       REG_S s2, PT_SEPC(sp)
> +       REG_S s2, PT_XEPC(sp)
>         /* Trace syscalls, but only if requested by the user. */
>         REG_L t0, TASK_TI_FLAGS(tp)
>         andi t0, t0, _TIF_SYSCALL_WORK
> @@ -244,9 +244,15 @@ ret_from_syscall:
>         bnez t0, handle_syscall_trace_exit
>
>  ret_from_exception:
> -       REG_L s0, PT_SSTATUS(sp)
> -       csrc CSR_SSTATUS, SR_SIE
> +       REG_L s0, PT_XSTATUS(sp)
> +       csrc CSR_XSTATUS, SR_XIE
> +#ifdef CONFIG_RISCV_M_MODE
> +       /* the MPP value is too large to be used as an immediate arg for addi */
> +       li t0, SR_MPP
> +       and s0, s0, t0
> +#else
>         andi s0, s0, SR_SPP
> +#endif
>         bnez s0, resume_kernel
>
>  resume_userspace:
> @@ -260,14 +266,14 @@ resume_userspace:
>         REG_S s0, TASK_TI_KERNEL_SP(tp)
>
>         /*
> -        * Save TP into sscratch, so we can find the kernel data structures
> -        * again.
> +        * Save TP into the scratch register , so we can find the kernel data
> +        * structures again.
>          */
> -       csrw CSR_SSCRATCH, tp
> +       csrw CSR_XSCRATCH, tp
>
>  restore_all:
>         RESTORE_ALL
> -       sret
> +       Xret
>
>  #if IS_ENABLED(CONFIG_PREEMPT)
>  resume_kernel:
> @@ -287,7 +293,7 @@ work_pending:
>         bnez s1, work_resched
>  work_notifysig:
>         /* Handle pending signals and notify-resume requests */
> -       csrs CSR_SSTATUS, SR_SIE /* Enable interrupts for do_notify_resume() */
> +       csrs CSR_XSTATUS, SR_XIE /* Enable interrupts for do_notify_resume() */
>         move a0, sp /* pt_regs */
>         move a1, s0 /* current_thread_info->flags */
>         tail do_notify_resume
> diff --git a/arch/riscv/kernel/fpu.S b/arch/riscv/kernel/fpu.S
> index 631d31540660..1dade31f4564 100644
> --- a/arch/riscv/kernel/fpu.S
> +++ b/arch/riscv/kernel/fpu.S
> @@ -23,7 +23,7 @@ ENTRY(__fstate_save)
>         li  a2,  TASK_THREAD_F0
>         add a0, a0, a2
>         li t1, SR_FS
> -       csrs CSR_SSTATUS, t1
> +       csrs CSR_XSTATUS, t1
>         frcsr t0
>         fsd f0,  TASK_THREAD_F0_F0(a0)
>         fsd f1,  TASK_THREAD_F1_F0(a0)
> @@ -58,7 +58,7 @@ ENTRY(__fstate_save)
>         fsd f30, TASK_THREAD_F30_F0(a0)
>         fsd f31, TASK_THREAD_F31_F0(a0)
>         sw t0, TASK_THREAD_FCSR_F0(a0)
> -       csrc CSR_SSTATUS, t1
> +       csrc CSR_XSTATUS, t1
>         ret
>  ENDPROC(__fstate_save)
>
> @@ -67,7 +67,7 @@ ENTRY(__fstate_restore)
>         add a0, a0, a2
>         li t1, SR_FS
>         lw t0, TASK_THREAD_FCSR_F0(a0)
> -       csrs CSR_SSTATUS, t1
> +       csrs CSR_XSTATUS, t1
>         fld f0,  TASK_THREAD_F0_F0(a0)
>         fld f1,  TASK_THREAD_F1_F0(a0)
>         fld f2,  TASK_THREAD_F2_F0(a0)
> @@ -101,6 +101,6 @@ ENTRY(__fstate_restore)
>         fld f30, TASK_THREAD_F30_F0(a0)
>         fld f31, TASK_THREAD_F31_F0(a0)
>         fscsr t0
> -       csrc CSR_SSTATUS, t1
> +       csrc CSR_XSTATUS, t1
>         ret
>  ENDPROC(__fstate_restore)
> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> index 72f89b7590dd..679e63d29edb 100644
> --- a/arch/riscv/kernel/head.S
> +++ b/arch/riscv/kernel/head.S
> @@ -47,8 +47,8 @@ ENTRY(_start)
>  .global _start_kernel
>  _start_kernel:
>         /* Mask all interrupts */
> -       csrw CSR_SIE, zero
> -       csrw CSR_SIP, zero
> +       csrw CSR_XIE, zero
> +       csrw CSR_XIP, zero
>
>         /* Load the global pointer */
>  .option push
> @@ -61,7 +61,7 @@ _start_kernel:
>          * floating point in kernel space
>          */
>         li t0, SR_FS
> -       csrc CSR_SSTATUS, t0
> +       csrc CSR_XSTATUS, t0
>
>  #ifdef CONFIG_SMP
>         li t0, CONFIG_NR_CPUS
> @@ -116,7 +116,7 @@ relocate:
>         /* Point stvec to virtual address of intruction after satp write */
>         la a2, 1f
>         add a2, a2, a1
> -       csrw CSR_STVEC, a2
> +       csrw CSR_XTVEC, a2
>
>         /* Compute satp for kernel page tables, but don't load it yet */
>         srl a2, a0, PAGE_SHIFT
> @@ -138,7 +138,7 @@ relocate:
>  1:
>         /* Set trap vector to spin forever to help debug */
>         la a0, .Lsecondary_park
> -       csrw CSR_STVEC, a0
> +       csrw CSR_XTVEC, a0
>
>         /* Reload the global pointer */
>  .option push
> @@ -161,7 +161,7 @@ relocate:
>  #ifdef CONFIG_SMP
>         /* Set trap vector to spin forever to help debug */
>         la a3, .Lsecondary_park
> -       csrw CSR_STVEC, a3
> +       csrw CSR_XTVEC, a3
>
>         slli a3, a0, LGREG
>         la a1, __cpu_up_stack_pointer
> diff --git a/arch/riscv/kernel/irq.c b/arch/riscv/kernel/irq.c
> index 6d8659388c49..804ff70bb853 100644
> --- a/arch/riscv/kernel/irq.c
> +++ b/arch/riscv/kernel/irq.c
> @@ -29,7 +29,7 @@ asmlinkage void __irq_entry do_IRQ(struct pt_regs *regs)
>         struct pt_regs *old_regs = set_irq_regs(regs);
>
>         irq_enter();
> -       switch (regs->scause & ~SCAUSE_IRQ_FLAG) {
> +       switch (regs->xcause & ~XCAUSE_IRQ_FLAG) {
>         case INTERRUPT_CAUSE_TIMER:
>                 riscv_timer_interrupt();
>                 break;
> @@ -46,7 +46,7 @@ asmlinkage void __irq_entry do_IRQ(struct pt_regs *regs)
>                 handle_arch_irq(regs);
>                 break;
>         default:
> -               pr_alert("unexpected interrupt cause 0x%lx", regs->scause);
> +               pr_alert("unexpected interrupt cause 0x%lx", regs->xcause);
>                 BUG();
>         }
>         irq_exit();
> diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
> index fb3a082362eb..b318f7ff740b 100644
> --- a/arch/riscv/kernel/process.c
> +++ b/arch/riscv/kernel/process.c
> @@ -34,7 +34,7 @@ void show_regs(struct pt_regs *regs)
>         show_regs_print_info(KERN_DEFAULT);
>
>         pr_cont("sepc: " REG_FMT " ra : " REG_FMT " sp : " REG_FMT "\n",
> -               regs->sepc, regs->ra, regs->sp);
> +               regs->xepc, 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",
> @@ -56,23 +56,23 @@ void show_regs(struct pt_regs *regs)
>         pr_cont(" t5 : " REG_FMT " t6 : " REG_FMT "\n",
>                 regs->t5, regs->t6);
>
> -       pr_cont("sstatus: " REG_FMT " sbadaddr: " REG_FMT " scause: " REG_FMT "\n",
> -               regs->sstatus, regs->sbadaddr, regs->scause);
> +       pr_cont("status: " REG_FMT " badaddr: " REG_FMT " cause: " REG_FMT "\n",
> +               regs->xstatus, regs->xbadaddr, regs->xcause);
>  }
>
>  void start_thread(struct pt_regs *regs, unsigned long pc,
>         unsigned long sp)
>  {
> -       regs->sstatus = SR_SPIE;
> +       regs->xstatus = SR_XPIE;
>         if (has_fpu) {
> -               regs->sstatus |= SR_FS_INITIAL;
> +               regs->xstatus |= SR_FS_INITIAL;
>                 /*
>                  * Restore the initial value to the FP register
>                  * before starting the user program.
>                  */
>                 fstate_restore(current, regs);
>         }
> -       regs->sepc = pc;
> +       regs->xepc = pc;
>         regs->sp = sp;
>         set_fs(USER_DS);
>  }
> @@ -108,7 +108,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
>                 const register unsigned long gp __asm__ ("gp");
>                 memset(childregs, 0, sizeof(struct pt_regs));
>                 childregs->gp = gp;
> -               childregs->sstatus = SR_SPP | SR_SPIE; /* Supervisor, irqs on */
> +               /* Supervisor/Machine, irqs on: */
> +               childregs->xstatus = SR_XPP | SR_XPIE;
>
>                 p->thread.ra = (unsigned long)ret_from_kernel_thread;
>                 p->thread.s[0] = usp; /* fn */
> diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
> index b14d7647d800..e1a2cee340f7 100644
> --- a/arch/riscv/kernel/signal.c
> +++ b/arch/riscv/kernel/signal.c
> @@ -124,7 +124,7 @@ SYSCALL_DEFINE0(rt_sigreturn)
>                 pr_info_ratelimited(
>                         "%s[%d]: bad frame in %s: frame=%p pc=%p sp=%p\n",
>                         task->comm, task_pid_nr(task), __func__,
> -                       frame, (void *)regs->sepc, (void *)regs->sp);
> +                       frame, (void *)regs->xepc, (void *)regs->sp);
>         }
>         force_sig(SIGSEGV);
>         return 0;
> @@ -199,7 +199,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
>          * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
>          * since some things rely on this (e.g. glibc's debug/segfault.c).
>          */
> -       regs->sepc = (unsigned long)ksig->ka.sa.sa_handler;
> +       regs->xepc = (unsigned long)ksig->ka.sa.sa_handler;
>         regs->sp = (unsigned long)frame;
>         regs->a0 = ksig->sig;                     /* a0: signal number */
>         regs->a1 = (unsigned long)(&frame->info); /* a1: siginfo pointer */
> @@ -208,7 +208,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
>  #if DEBUG_SIG
>         pr_info("SIG deliver (%s:%d): sig=%d pc=%p ra=%p sp=%p\n",
>                 current->comm, task_pid_nr(current), ksig->sig,
> -               (void *)regs->sepc, (void *)regs->ra, frame);
> +               (void *)regs->xepc, (void *)regs->ra, frame);
>  #endif
>
>         return 0;
> @@ -220,10 +220,9 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
>         int ret;
>
>         /* Are we from a system call? */
> -       if (regs->scause == EXC_SYSCALL) {
> +       if (regs->xcause == EXC_SYSCALL) {
>                 /* Avoid additional syscall restarting via ret_from_exception */
> -               regs->scause = -1UL;
> -
> +               regs->xcause = -1UL;
>                 /* If so, check system call restarting.. */
>                 switch (regs->a0) {
>                 case -ERESTART_RESTARTBLOCK:
> @@ -239,7 +238,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
>                         /* fallthrough */
>                 case -ERESTARTNOINTR:
>                          regs->a0 = regs->orig_a0;
> -                       regs->sepc -= 0x4;
> +                       regs->xepc -= 0x4;
>                         break;
>                 }
>         }
> @@ -261,9 +260,9 @@ static void do_signal(struct pt_regs *regs)
>         }
>
>         /* Did we come from a system call? */
> -       if (regs->scause == EXC_SYSCALL) {
> +       if (regs->xcause == EXC_SYSCALL) {
>                 /* Avoid additional syscall restarting via ret_from_exception */
> -               regs->scause = -1UL;
> +               regs->xcause = -1UL;
>
>                 /* Restart the system call - no handlers present */
>                 switch (regs->a0) {
> @@ -271,12 +270,12 @@ static void do_signal(struct pt_regs *regs)
>                 case -ERESTARTSYS:
>                 case -ERESTARTNOINTR:
>                          regs->a0 = regs->orig_a0;
> -                       regs->sepc -= 0x4;
> +                       regs->xepc -= 0x4;
>                         break;
>                 case -ERESTART_RESTARTBLOCK:
>                          regs->a0 = regs->orig_a0;
>                         regs->a7 = __NR_restart_syscall;
> -                       regs->sepc -= 0x4;
> +                       regs->xepc -= 0x4;
>                         break;
>                 }
>         }
> diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
> index 10a17e545f43..2cf1f0f3871e 100644
> --- a/arch/riscv/kernel/traps.c
> +++ b/arch/riscv/kernel/traps.c
> @@ -40,7 +40,7 @@ void die(struct pt_regs *regs, const char *str)
>         print_modules();
>         show_regs(regs);
>
> -       ret = notify_die(DIE_OOPS, str, regs, 0, regs->scause, SIGSEGV);
> +       ret = notify_die(DIE_OOPS, str, regs, 0, regs->xcause, SIGSEGV);
>
>         bust_spinlocks(0);
>         add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
> @@ -85,7 +85,7 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code,
>  #define DO_ERROR_INFO(name, signo, code, str)                          \
>  asmlinkage void name(struct pt_regs *regs)                             \
>  {                                                                      \
> -       do_trap_error(regs, signo, code, regs->sepc, "Oops - " str);    \
> +       do_trap_error(regs, signo, code, regs->xepc, "Oops - " str);    \
>  }
>
>  DO_ERROR_INFO(do_trap_unknown,
> @@ -123,9 +123,9 @@ static inline unsigned long get_break_insn_length(unsigned long pc)
>  asmlinkage void do_trap_break(struct pt_regs *regs)
>  {
>         if (user_mode(regs))
> -               force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->sepc);
> -       else if (report_bug(regs->sepc, regs) == BUG_TRAP_TYPE_WARN)
> -               regs->sepc += get_break_insn_length(regs->sepc);
> +               force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->xepc);
> +       else if (report_bug(regs->xepc, regs) == BUG_TRAP_TYPE_WARN)
> +               regs->xepc += get_break_insn_length(regs->xepc);
>         else
>                 die(regs, "Kernel BUG");
>  }
> @@ -152,9 +152,9 @@ void __init trap_init(void)
>          * Set sup0 scratch register to 0, indicating to exception vector
>          * that we are presently executing in the kernel
>          */
> -       csr_write(CSR_SSCRATCH, 0);
> +       csr_write(CSR_XSCRATCH, 0);
>         /* Set the exception vector address */
> -       csr_write(CSR_STVEC, &handle_exception);
> +       csr_write(CSR_XTVEC, &handle_exception);
>         /* Enable all interrupts */
> -       csr_write(CSR_SIE, -1);
> +       csr_write(CSR_XIE, -1);
>  }
> diff --git a/arch/riscv/lib/uaccess.S b/arch/riscv/lib/uaccess.S
> index ed2696c0143d..f47a2ea4dc89 100644
> --- a/arch/riscv/lib/uaccess.S
> +++ b/arch/riscv/lib/uaccess.S
> @@ -18,7 +18,7 @@ ENTRY(__asm_copy_from_user)
>
>         /* Enable access to user memory */
>         li t6, SR_SUM
> -       csrs CSR_SSTATUS, t6
> +       csrs CSR_XSTATUS, t6
>
>         add a3, a1, a2
>         /* Use word-oriented copy only if low-order bits match */
> @@ -47,7 +47,7 @@ ENTRY(__asm_copy_from_user)
>
>  3:
>         /* Disable access to user memory */
> -       csrc CSR_SSTATUS, t6
> +       csrc CSR_XSTATUS, t6
>         li a0, 0
>         ret
>  4: /* Edge case: unalignment */
> @@ -72,7 +72,7 @@ ENTRY(__clear_user)
>
>         /* Enable access to user memory */
>         li t6, SR_SUM
> -       csrs CSR_SSTATUS, t6
> +       csrs CSR_XSTATUS, t6
>
>         add a3, a0, a1
>         addi t0, a0, SZREG-1
> @@ -94,7 +94,7 @@ ENTRY(__clear_user)
>
>  3:
>         /* Disable access to user memory */
> -       csrc CSR_SSTATUS, t6
> +       csrc CSR_XSTATUS, t6
>         li a0, 0
>         ret
>  4: /* Edge case: unalignment */
> @@ -114,11 +114,11 @@ ENDPROC(__clear_user)
>         /* Fixup code for __copy_user(10) and __clear_user(11) */
>  10:
>         /* Disable access to user memory */
> -       csrs CSR_SSTATUS, t6
> +       csrs CSR_XSTATUS, t6
>         mv a0, a2
>         ret
>  11:
> -       csrs CSR_SSTATUS, t6
> +       csrs CSR_XSTATUS, t6
>         mv a0, a1
>         ret
>         .previous
> diff --git a/arch/riscv/mm/extable.c b/arch/riscv/mm/extable.c
> index 7aed9178d365..e0659deeb16b 100644
> --- a/arch/riscv/mm/extable.c
> +++ b/arch/riscv/mm/extable.c
> @@ -15,9 +15,9 @@ int fixup_exception(struct pt_regs *regs)
>  {
>         const struct exception_table_entry *fixup;
>
> -       fixup = search_exception_tables(regs->sepc);
> +       fixup = search_exception_tables(regs->xepc);
>         if (fixup) {
> -               regs->sepc = fixup->fixup;
> +               regs->xepc = fixup->fixup;
>                 return 1;
>         }
>         return 0;
> diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c
> index 96add1427a75..10a8ce38ac7a 100644
> --- a/arch/riscv/mm/fault.c
> +++ b/arch/riscv/mm/fault.c
> @@ -32,8 +32,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs)
>         int code = SEGV_MAPERR;
>         vm_fault_t fault;
>
> -       cause = regs->scause;
> -       addr = regs->sbadaddr;
> +       cause = regs->xcause;
> +       addr = regs->xbadaddr;
>
>         tsk = current;
>         mm = tsk->mm;
> @@ -51,7 +51,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs)
>                 goto vmalloc_fault;
>
>         /* Enable interrupts if they were enabled in the parent context. */
> -       if (likely(regs->sstatus & SR_SPIE))
> +       if (likely(regs->xstatus & SR_XPIE))
>                 local_irq_enable();
>
>         /*
> diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
> index 470c7ef02ea4..5d2fdc3e28a9 100644
> --- a/drivers/clocksource/timer-riscv.c
> +++ b/drivers/clocksource/timer-riscv.c
> @@ -19,7 +19,7 @@
>  static int riscv_clock_next_event(unsigned long delta,
>                 struct clock_event_device *ce)
>  {
> -       csr_set(sie, SIE_STIE);
> +       csr_set(CSR_XIE, XIE_XTIE);
>         sbi_set_timer(get_cycles64() + delta);
>         return 0;
>  }
> @@ -61,13 +61,13 @@ static int riscv_timer_starting_cpu(unsigned int cpu)
>         ce->cpumask = cpumask_of(cpu);
>         clockevents_config_and_register(ce, riscv_timebase, 100, 0x7fffffff);
>
> -       csr_set(sie, SIE_STIE);
> +       csr_set(CSR_XIE, XIE_XTIE);
>         return 0;
>  }
>
>  static int riscv_timer_dying_cpu(unsigned int cpu)
>  {
> -       csr_clear(sie, SIE_STIE);
> +       csr_clear(CSR_XIE, XIE_XTIE);
>         return 0;
>  }
>
> @@ -76,7 +76,7 @@ void riscv_timer_interrupt(void)
>  {
>         struct clock_event_device *evdev = this_cpu_ptr(&riscv_clock_event);
>
> -       csr_clear(sie, SIE_STIE);
> +       csr_clear(CSR_XIE, XIE_XTIE);
>         evdev->event_handler(evdev);
>  }
>
> diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
> index c72c036aea76..4ee96ac90ea4 100644
> --- a/drivers/irqchip/irq-sifive-plic.c
> +++ b/drivers/irqchip/irq-sifive-plic.c
> @@ -179,7 +179,7 @@ static void plic_handle_irq(struct pt_regs *regs)
>
>         WARN_ON_ONCE(!handler->present);
>
> -       csr_clear(sie, SIE_SEIE);
> +       csr_clear(CSR_XIE, XIE_XEIE);
>         while ((hwirq = readl(claim))) {
>                 int irq = irq_find_mapping(plic_irqdomain, hwirq);
>
> @@ -190,7 +190,7 @@ static void plic_handle_irq(struct pt_regs *regs)
>                         generic_handle_irq(irq);
>                 writel(hwirq, claim);
>         }
> -       csr_set(sie, SIE_SEIE);
> +       csr_set(CSR_XIE, XIE_XEIE);
>  }
>
>  /*
> --
> 2.20.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Regards,
Anup

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 04/15] riscv: don't allow selecting SBI based drivers for M-mode
  2019-10-17 17:37 ` [PATCH 04/15] riscv: don't allow selecting SBI based drivers for M-mode Christoph Hellwig
@ 2019-10-18  2:52   ` Anup Patel
  0 siblings, 0 replies; 41+ messages in thread
From: Anup Patel @ 2019-10-18  2:52 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel@vger.kernel.org List, Damien Le Moal,
	Palmer Dabbelt, linux-riscv, Paul Walmsley

On Thu, Oct 17, 2019 at 11:07 PM Christoph Hellwig <hch@lst.de> wrote:
>
> From: Damien Le Moal <damien.lemoal@wdc.com>
>
> When running in M-mode we can't use SBI based drivers.  Add a new
> CONFIG_RISCV_SBI that drivers that do SBI calls can depend on
> instead.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  arch/riscv/Kconfig         | 6 ++++++
>  drivers/tty/hvc/Kconfig    | 2 +-
>  drivers/tty/serial/Kconfig | 2 +-
>  3 files changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 86b7e8b0471c..b85492c42ccb 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -76,6 +76,12 @@ config ARCH_MMAP_RND_BITS_MAX
>  config RISCV_M_MODE
>         bool
>
> +# set if we are running in S-mode and can use SBI calls
> +config RISCV_SBI
> +       bool
> +       depends on !RISCV_M_MODE
> +       default y
> +
>  config MMU
>         def_bool y
>
> diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig
> index 4d22b911111f..4487a6b9acc8 100644
> --- a/drivers/tty/hvc/Kconfig
> +++ b/drivers/tty/hvc/Kconfig
> @@ -89,7 +89,7 @@ config HVC_DCC
>
>  config HVC_RISCV_SBI
>         bool "RISC-V SBI console support"
> -       depends on RISCV
> +       depends on RISCV_SBI
>         select HVC_DRIVER
>         help
>           This enables support for console output via RISC-V SBI calls, which
> diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
> index 67a9eb3f94ce..540142c5b7b3 100644
> --- a/drivers/tty/serial/Kconfig
> +++ b/drivers/tty/serial/Kconfig
> @@ -88,7 +88,7 @@ config SERIAL_EARLYCON_ARM_SEMIHOST
>
>  config SERIAL_EARLYCON_RISCV_SBI
>         bool "Early console using RISC-V SBI"
> -       depends on RISCV
> +       depends on RISCV_SBI
>         select SERIAL_CORE
>         select SERIAL_CORE_CONSOLE
>         select SERIAL_EARLYCON
> --
> 2.20.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Regards,
Anup

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 05/15] riscv: poison SBI calls for M-mode
  2019-10-17 17:37 ` [PATCH 05/15] riscv: poison SBI calls " Christoph Hellwig
@ 2019-10-18  2:53   ` Anup Patel
  0 siblings, 0 replies; 41+ messages in thread
From: Anup Patel @ 2019-10-18  2:53 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel@vger.kernel.org List, Damien Le Moal,
	Palmer Dabbelt, linux-riscv, Paul Walmsley

On Thu, Oct 17, 2019 at 11:08 PM Christoph Hellwig <hch@lst.de> wrote:
>
> There is no SBI when we run in M-mode, so fail the compile for any code
> trying to use SBI calls.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  arch/riscv/include/asm/sbi.h | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
> index 21134b3ef404..b167af3e7470 100644
> --- a/arch/riscv/include/asm/sbi.h
> +++ b/arch/riscv/include/asm/sbi.h
> @@ -8,6 +8,7 @@
>
>  #include <linux/types.h>
>
> +#ifdef CONFIG_RISCV_SBI
>  #define SBI_SET_TIMER 0
>  #define SBI_CONSOLE_PUTCHAR 1
>  #define SBI_CONSOLE_GETCHAR 2
> @@ -93,5 +94,5 @@ static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
>  {
>         SBI_CALL_4(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask, start, size, asid);
>  }
> -
> -#endif
> +#endif /* CONFIG_RISCV_SBI */
> +#endif /* _ASM_RISCV_SBI_H */
> --
> 2.20.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Regards,
Anup

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 06/15] riscv: cleanup the default power off implementation
  2019-10-17 17:37 ` [PATCH 06/15] riscv: cleanup the default power off implementation Christoph Hellwig
@ 2019-10-18  2:53   ` Anup Patel
  0 siblings, 0 replies; 41+ messages in thread
From: Anup Patel @ 2019-10-18  2:53 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Damien Le Moal, Palmer Dabbelt,
	linux-kernel@vger.kernel.org List, Atish Patra, Paul Walmsley,
	linux-riscv

On Thu, Oct 17, 2019 at 11:08 PM Christoph Hellwig <hch@lst.de> wrote:
>
> Move the sbi poweroff to a separate function and file that is only
> compiled if CONFIG_SBI is set.  Provide a new default fallback
> power off that just sits in a wfi loop to save some power.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Atish Patra <atish.patra@wdc.com>
> ---
>  arch/riscv/kernel/Makefile |  1 +
>  arch/riscv/kernel/reset.c  |  5 ++---
>  arch/riscv/kernel/sbi.c    | 17 +++++++++++++++++
>  3 files changed, 20 insertions(+), 3 deletions(-)
>  create mode 100644 arch/riscv/kernel/sbi.c
>
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> index 696020ff72db..d8c35fa93cc6 100644
> --- a/arch/riscv/kernel/Makefile
> +++ b/arch/riscv/kernel/Makefile
> @@ -41,5 +41,6 @@ obj-$(CONFIG_DYNAMIC_FTRACE)  += mcount-dyn.o
>  obj-$(CONFIG_PERF_EVENTS)      += perf_event.o
>  obj-$(CONFIG_PERF_EVENTS)      += perf_callchain.o
>  obj-$(CONFIG_HAVE_PERF_REGS)   += perf_regs.o
> +obj-$(CONFIG_RISCV_SBI)                += sbi.o
>
>  clean:
> diff --git a/arch/riscv/kernel/reset.c b/arch/riscv/kernel/reset.c
> index d0fe623bfb8f..5e4e69859af1 100644
> --- a/arch/riscv/kernel/reset.c
> +++ b/arch/riscv/kernel/reset.c
> @@ -4,12 +4,11 @@
>   */
>
>  #include <linux/reboot.h>
> -#include <asm/sbi.h>
>
>  static void default_power_off(void)
>  {
> -       sbi_shutdown();
> -       while (1);
> +       while (1)
> +               wait_for_interrupt();
>  }
>
>  void (*pm_power_off)(void) = default_power_off;
> diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c
> new file mode 100644
> index 000000000000..f6c7c3e82d28
> --- /dev/null
> +++ b/arch/riscv/kernel/sbi.c
> @@ -0,0 +1,17 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +
> +#include <linux/init.h>
> +#include <linux/pm.h>
> +#include <asm/sbi.h>
> +
> +static void sbi_power_off(void)
> +{
> +       sbi_shutdown();
> +}
> +
> +static int __init sbi_init(void)
> +{
> +       pm_power_off = sbi_power_off;
> +       return 0;
> +}
> +early_initcall(sbi_init);
> --
> 2.20.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Regards,
Anup

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 07/15] riscv: implement remote sfence.i using IPIs
  2019-10-17 17:37 ` [PATCH 07/15] riscv: implement remote sfence.i using IPIs Christoph Hellwig
@ 2019-10-18  2:55   ` Anup Patel
  0 siblings, 0 replies; 41+ messages in thread
From: Anup Patel @ 2019-10-18  2:55 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel@vger.kernel.org List, Damien Le Moal,
	Palmer Dabbelt, linux-riscv, Paul Walmsley

On Thu, Oct 17, 2019 at 11:08 PM Christoph Hellwig <hch@lst.de> wrote:
>
> The RISC-V ISA only supports flushing the instruction cache for the
> local CPU core.  Currently we always offload the remote TLB flushing to
> the SBI, which then issues an IPI under the hoods.  But with M-mode
> we do not have an SBI so we have to do it ourselves.   IPI to the
> other nodes using the existing kernel helpers instead if we have
> native clint support and thus can IPI directly from the kernel.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  arch/riscv/include/asm/sbi.h |  3 +++
>  arch/riscv/mm/cacheflush.c   | 24 ++++++++++++++++++------
>  2 files changed, 21 insertions(+), 6 deletions(-)
>
> diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
> index b167af3e7470..0cb74eccc73f 100644
> --- a/arch/riscv/include/asm/sbi.h
> +++ b/arch/riscv/include/asm/sbi.h
> @@ -94,5 +94,8 @@ static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
>  {
>         SBI_CALL_4(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask, start, size, asid);
>  }
> +#else /* CONFIG_RISCV_SBI */
> +/* stub to for code is only reachable under IS_ENABLED(CONFIG_RISCV_SBI): */
> +void sbi_remote_fence_i(const unsigned long *hart_mask);
>  #endif /* CONFIG_RISCV_SBI */
>  #endif /* _ASM_RISCV_SBI_H */
> diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c
> index 3f15938dec89..794c9ab256eb 100644
> --- a/arch/riscv/mm/cacheflush.c
> +++ b/arch/riscv/mm/cacheflush.c
> @@ -10,9 +10,17 @@
>
>  #include <asm/sbi.h>
>
> +static void ipi_remote_fence_i(void *info)
> +{
> +       return local_flush_icache_all();
> +}
> +
>  void flush_icache_all(void)
>  {
> -       sbi_remote_fence_i(NULL);
> +       if (IS_ENABLED(CONFIG_RISCV_SBI))
> +               sbi_remote_fence_i(NULL);
> +       else
> +               on_each_cpu(ipi_remote_fence_i, NULL, 1);
>  }
>
>  /*
> @@ -28,7 +36,7 @@ void flush_icache_all(void)
>  void flush_icache_mm(struct mm_struct *mm, bool local)
>  {
>         unsigned int cpu;
> -       cpumask_t others, hmask, *mask;
> +       cpumask_t others, *mask;
>
>         preempt_disable();
>
> @@ -46,10 +54,7 @@ void flush_icache_mm(struct mm_struct *mm, bool local)
>          */
>         cpumask_andnot(&others, mm_cpumask(mm), cpumask_of(cpu));
>         local |= cpumask_empty(&others);
> -       if (mm != current->active_mm || !local) {
> -               riscv_cpuid_to_hartid_mask(&others, &hmask);
> -               sbi_remote_fence_i(hmask.bits);
> -       } else {
> +       if (mm == current->active_mm && local) {
>                 /*
>                  * It's assumed that at least one strongly ordered operation is
>                  * performed on this hart between setting a hart's cpumask bit
> @@ -59,6 +64,13 @@ void flush_icache_mm(struct mm_struct *mm, bool local)
>                  * with flush_icache_deferred().
>                  */
>                 smp_mb();
> +       } else if (IS_ENABLED(CONFIG_RISCV_SBI)) {
> +               cpumask_t hartid_mask;
> +
> +               riscv_cpuid_to_hartid_mask(&others, &hartid_mask);
> +               sbi_remote_fence_i(cpumask_bits(&hartid_mask));
> +       } else {
> +               on_each_cpu_mask(&others, ipi_remote_fence_i, NULL, 1);
>         }
>
>         preempt_enable();
> --
> 2.20.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Regards,
Anup

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 08/15] riscv: add support for MMIO access to the timer registers
  2019-10-17 17:37 ` [PATCH 08/15] riscv: add support for MMIO access to the timer registers Christoph Hellwig
@ 2019-10-18  2:57   ` Anup Patel
  0 siblings, 0 replies; 41+ messages in thread
From: Anup Patel @ 2019-10-18  2:57 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel@vger.kernel.org List, Damien Le Moal,
	Palmer Dabbelt, linux-riscv, Paul Walmsley

On Thu, Oct 17, 2019 at 11:08 PM Christoph Hellwig <hch@lst.de> wrote:
>
> When running in M-mode we can't use the SBI to set the timer, and
> don't have access to the time CSR as that usually is emulated by
> M-mode.  Instead provide code that directly accesses the MMIO for
> the timer.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  arch/riscv/include/asm/sbi.h      |  3 ++-
>  arch/riscv/include/asm/timex.h    | 19 +++++++++++++++++--
>  drivers/clocksource/timer-riscv.c | 21 +++++++++++++++++----
>  3 files changed, 36 insertions(+), 7 deletions(-)
>
> diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
> index 0cb74eccc73f..a4774bafe033 100644
> --- a/arch/riscv/include/asm/sbi.h
> +++ b/arch/riscv/include/asm/sbi.h
> @@ -95,7 +95,8 @@ static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
>         SBI_CALL_4(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask, start, size, asid);
>  }
>  #else /* CONFIG_RISCV_SBI */
> -/* stub to for code is only reachable under IS_ENABLED(CONFIG_RISCV_SBI): */
> +/* stubs to for code is only reachable under IS_ENABLED(CONFIG_RISCV_SBI): */
> +void sbi_set_timer(uint64_t stime_value);
>  void sbi_remote_fence_i(const unsigned long *hart_mask);
>  #endif /* CONFIG_RISCV_SBI */
>  #endif /* _ASM_RISCV_SBI_H */
> diff --git a/arch/riscv/include/asm/timex.h b/arch/riscv/include/asm/timex.h
> index c7ef131b9e4c..e17837d61667 100644
> --- a/arch/riscv/include/asm/timex.h
> +++ b/arch/riscv/include/asm/timex.h
> @@ -7,12 +7,25 @@
>  #define _ASM_RISCV_TIMEX_H
>
>  #include <asm/csr.h>
> +#include <asm/io.h>
>
>  typedef unsigned long cycles_t;
>
> +extern u64 __iomem *riscv_time_val;
> +extern u64 __iomem *riscv_time_cmp;
> +
> +#ifdef CONFIG_64BIT
> +#define mmio_get_cycles()      readq_relaxed(riscv_time_val)
> +#else
> +#define mmio_get_cycles()      readl_relaxed(riscv_time_val)
> +#define mmio_get_cycles_hi()   readl_relaxed(((u32 *)riscv_time_val) + 1)
> +#endif
> +
>  static inline cycles_t get_cycles(void)
>  {
> -       return csr_read(CSR_TIME);
> +       if (IS_ENABLED(CONFIG_RISCV_SBI))
> +               return csr_read(CSR_TIME);
> +       return mmio_get_cycles();
>  }
>  #define get_cycles get_cycles
>
> @@ -24,7 +37,9 @@ static inline u64 get_cycles64(void)
>  #else /* CONFIG_64BIT */
>  static inline u32 get_cycles_hi(void)
>  {
> -       return csr_read(CSR_TIMEH);
> +       if (IS_ENABLED(CONFIG_RISCV_SBI))
> +               return csr_read(CSR_TIMEH);
> +       return mmio_get_cycles_hi();
>  }
>
>  static inline u64 get_cycles64(void)
> diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
> index 5d2fdc3e28a9..2b9fbc4ebe49 100644
> --- a/drivers/clocksource/timer-riscv.c
> +++ b/drivers/clocksource/timer-riscv.c
> @@ -3,9 +3,9 @@
>   * Copyright (C) 2012 Regents of the University of California
>   * Copyright (C) 2017 SiFive
>   *
> - * All RISC-V systems have a timer attached to every hart.  These timers can be
> - * read from the "time" and "timeh" CSRs, and can use the SBI to setup
> - * events.
> + * All RISC-V systems have a timer attached to every hart.  These timers can
> + * either be read from the "time" and "timeh" CSRs, and can use the SBI to
> + * setup events, or directly accessed using MMIO registers.
>   */
>  #include <linux/clocksource.h>
>  #include <linux/clockchips.h>
> @@ -13,14 +13,27 @@
>  #include <linux/delay.h>
>  #include <linux/irq.h>
>  #include <linux/sched_clock.h>
> +#include <linux/io-64-nonatomic-lo-hi.h>
>  #include <asm/smp.h>
>  #include <asm/sbi.h>
>
> +u64 __iomem *riscv_time_cmp;
> +u64 __iomem *riscv_time_val;
> +
> +static inline void mmio_set_timer(u64 val)
> +{
> +       writeq_relaxed(val,
> +               riscv_time_cmp + cpuid_to_hartid_map(smp_processor_id()));
> +}
> +
>  static int riscv_clock_next_event(unsigned long delta,
>                 struct clock_event_device *ce)
>  {
>         csr_set(CSR_XIE, XIE_XTIE);
> -       sbi_set_timer(get_cycles64() + delta);
> +       if (IS_ENABLED(CONFIG_RISCV_SBI))
> +               sbi_set_timer(get_cycles64() + delta);
> +       else
> +               mmio_set_timer(get_cycles64() + delta);
>         return 0;
>  }
>
> --
> 2.20.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Regards,
Anup

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 09/15] riscv: provide native clint access for M-mode
  2019-10-17 17:37 ` [PATCH 09/15] riscv: provide native clint access for M-mode Christoph Hellwig
@ 2019-10-18  3:00   ` Anup Patel
  2019-11-14  7:39   ` Paul Walmsley
  1 sibling, 0 replies; 41+ messages in thread
From: Anup Patel @ 2019-10-18  3:00 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel@vger.kernel.org List, Damien Le Moal,
	Palmer Dabbelt, linux-riscv, Paul Walmsley

On Thu, Oct 17, 2019 at 11:08 PM Christoph Hellwig <hch@lst.de> wrote:
>
> RISC-V has the concept of a cpu level interrupt controller.  The
> interface for it is split between a standardized part that is exposed
> as bits in the mstatus/sstatus register and the mie/mip/sie/sip
> CRS.  But the bit to actually trigger IPIs is not standardized and
> just mentioned as implementable using MMIO.
>
> Add support for IPIs using MMIO using the SiFive clint layout (which is
> also shared by Ariane, Kendrye and the Qemu virt platform).  Additional
> the MMIO block also support the time value and timer compare registers,
> so they are also set up using the same OF node.  Support for other
> layouts should also be relatively easy to add in the future.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  arch/riscv/include/asm/clint.h | 39 ++++++++++++++++++++++++++++++
>  arch/riscv/include/asm/sbi.h   |  2 ++
>  arch/riscv/kernel/Makefile     |  1 +
>  arch/riscv/kernel/clint.c      | 44 ++++++++++++++++++++++++++++++++++
>  arch/riscv/kernel/setup.c      |  2 ++
>  arch/riscv/kernel/smp.c        | 16 ++++++++++---
>  arch/riscv/kernel/smpboot.c    |  4 ++++
>  7 files changed, 105 insertions(+), 3 deletions(-)
>  create mode 100644 arch/riscv/include/asm/clint.h
>  create mode 100644 arch/riscv/kernel/clint.c
>
> diff --git a/arch/riscv/include/asm/clint.h b/arch/riscv/include/asm/clint.h
> new file mode 100644
> index 000000000000..02a26b68f21d
> --- /dev/null
> +++ b/arch/riscv/include/asm/clint.h
> @@ -0,0 +1,39 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#ifndef _ASM_CLINT_H
> +#define _ASM_CLINT_H 1
> +
> +#include <linux/io.h>
> +#include <linux/smp.h>
> +
> +#ifdef CONFIG_RISCV_M_MODE
> +extern u32 __iomem *clint_ipi_base;
> +
> +void clint_init_boot_cpu(void);
> +
> +static inline void clint_send_ipi_single(unsigned long hartid)
> +{
> +       writel(1, clint_ipi_base + hartid);
> +}
> +
> +static inline void clint_send_ipi_mask(const struct cpumask *hartid_mask)
> +{
> +       int hartid;
> +
> +       for_each_cpu(hartid, hartid_mask)
> +               clint_send_ipi_single(hartid);
> +}
> +
> +static inline void clint_clear_ipi(unsigned long hartid)
> +{
> +       writel(0, clint_ipi_base + hartid);
> +}
> +#else /* CONFIG_RISCV_M_MODE */
> +#define clint_init_boot_cpu()  do { } while (0)
> +
> +/* stubs to for code is only reachable under IS_ENABLED(CONFIG_RISCV_M_MODE): */
> +void clint_send_ipi_single(unsigned long hartid);
> +void clint_send_ipi_mask(const struct cpumask *hartid_mask);
> +void clint_clear_ipi(unsigned long hartid);
> +#endif /* CONFIG_RISCV_M_MODE */
> +
> +#endif /* _ASM_CLINT_H */
> diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
> index a4774bafe033..407d1024f9eb 100644
> --- a/arch/riscv/include/asm/sbi.h
> +++ b/arch/riscv/include/asm/sbi.h
> @@ -97,6 +97,8 @@ static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
>  #else /* CONFIG_RISCV_SBI */
>  /* stubs to for code is only reachable under IS_ENABLED(CONFIG_RISCV_SBI): */
>  void sbi_set_timer(uint64_t stime_value);
> +void sbi_clear_ipi(void);
> +void sbi_send_ipi(const unsigned long *hart_mask);
>  void sbi_remote_fence_i(const unsigned long *hart_mask);
>  #endif /* CONFIG_RISCV_SBI */
>  #endif /* _ASM_RISCV_SBI_H */
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> index d8c35fa93cc6..2dca51046899 100644
> --- a/arch/riscv/kernel/Makefile
> +++ b/arch/riscv/kernel/Makefile
> @@ -29,6 +29,7 @@ obj-y += vdso.o
>  obj-y  += cacheinfo.o
>  obj-y  += vdso/
>
> +obj-$(CONFIG_RISCV_M_MODE)     += clint.o
>  obj-$(CONFIG_FPU)              += fpu.o
>  obj-$(CONFIG_SMP)              += smpboot.o
>  obj-$(CONFIG_SMP)              += smp.o
> diff --git a/arch/riscv/kernel/clint.c b/arch/riscv/kernel/clint.c
> new file mode 100644
> index 000000000000..3647980d14c3
> --- /dev/null
> +++ b/arch/riscv/kernel/clint.c
> @@ -0,0 +1,44 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019 Christoph Hellwig.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/of_address.h>
> +#include <linux/types.h>
> +#include <asm/clint.h>
> +#include <asm/csr.h>
> +#include <asm/timex.h>
> +#include <asm/smp.h>
> +
> +/*
> + * This is the layout used by the SiFive clint, which is also shared by the qemu
> + * virt platform, and the Kendryte KD210 at least.
> + */
> +#define CLINT_IPI_OFF          0
> +#define CLINT_TIME_CMP_OFF     0x4000
> +#define CLINT_TIME_VAL_OFF     0xbff8
> +
> +u32 __iomem *clint_ipi_base;
> +
> +void clint_init_boot_cpu(void)
> +{
> +       struct device_node *np;
> +       void __iomem *base;
> +
> +       np = of_find_compatible_node(NULL, NULL, "riscv,clint0");
> +       if (!np) {
> +               panic("clint not found");
> +               return;
> +       }
> +
> +       base = of_iomap(np, 0);
> +       if (!base)
> +               panic("could not map CLINT");
> +
> +       clint_ipi_base = base + CLINT_IPI_OFF;
> +       riscv_time_cmp = base + CLINT_TIME_CMP_OFF;
> +       riscv_time_val = base + CLINT_TIME_VAL_OFF;
> +
> +       clint_clear_ipi(boot_cpu_hartid);
> +}
> diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> index a990a6cb184f..f4ba71b66c73 100644
> --- a/arch/riscv/kernel/setup.c
> +++ b/arch/riscv/kernel/setup.c
> @@ -17,6 +17,7 @@
>  #include <linux/sched/task.h>
>  #include <linux/swiotlb.h>
>
> +#include <asm/clint.h>
>  #include <asm/setup.h>
>  #include <asm/sections.h>
>  #include <asm/pgtable.h>
> @@ -65,6 +66,7 @@ void __init setup_arch(char **cmdline_p)
>         setup_bootmem();
>         paging_init();
>         unflatten_device_tree();
> +       clint_init_boot_cpu();
>
>  #ifdef CONFIG_SWIOTLB
>         swiotlb_init(1);
> diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c
> index b18cd6c8e8fb..c46df9c2e927 100644
> --- a/arch/riscv/kernel/smp.c
> +++ b/arch/riscv/kernel/smp.c
> @@ -14,6 +14,7 @@
>  #include <linux/seq_file.h>
>  #include <linux/delay.h>
>
> +#include <asm/clint.h>
>  #include <asm/sbi.h>
>  #include <asm/tlbflush.h>
>  #include <asm/cacheflush.h>
> @@ -90,7 +91,10 @@ static void send_ipi_mask(const struct cpumask *mask, enum ipi_message_type op)
>         smp_mb__after_atomic();
>
>         riscv_cpuid_to_hartid_mask(mask, &hartid_mask);
> -       sbi_send_ipi(cpumask_bits(&hartid_mask));
> +       if (IS_ENABLED(CONFIG_RISCV_SBI))
> +               sbi_send_ipi(cpumask_bits(&hartid_mask));
> +       else
> +               clint_send_ipi_mask(&hartid_mask);
>  }
>
>  static void send_ipi_single(int cpu, enum ipi_message_type op)
> @@ -101,12 +105,18 @@ static void send_ipi_single(int cpu, enum ipi_message_type op)
>         set_bit(op, &ipi_data[cpu].bits);
>         smp_mb__after_atomic();
>
> -       sbi_send_ipi(cpumask_bits(cpumask_of(hartid)));
> +       if (IS_ENABLED(CONFIG_RISCV_SBI))
> +               sbi_send_ipi(cpumask_bits(cpumask_of(hartid)));
> +       else
> +               clint_send_ipi_single(hartid);
>  }
>
>  static inline void clear_ipi(void)
>  {
> -       csr_clear(CSR_SIP, SIE_SSIE);
> +       if (IS_ENABLED(CONFIG_RISCV_SBI))
> +               csr_clear(CSR_SIP, SIE_SSIE);
> +       else
> +               clint_clear_ipi(cpuid_to_hartid_map(smp_processor_id()));
>  }
>
>  void riscv_software_interrupt(void)
> diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
> index 18ae6da5115e..6300b09f1d1d 100644
> --- a/arch/riscv/kernel/smpboot.c
> +++ b/arch/riscv/kernel/smpboot.c
> @@ -24,6 +24,7 @@
>  #include <linux/of.h>
>  #include <linux/sched/task_stack.h>
>  #include <linux/sched/mm.h>
> +#include <asm/clint.h>
>  #include <asm/irq.h>
>  #include <asm/mmu_context.h>
>  #include <asm/tlbflush.h>
> @@ -134,6 +135,9 @@ asmlinkage void __init smp_callin(void)
>  {
>         struct mm_struct *mm = &init_mm;
>
> +       if (!IS_ENABLED(CONFIG_RISCV_SBI))
> +               clint_clear_ipi(cpuid_to_hartid_map(smp_processor_id()));
> +
>         /* All kernel threads share the same mm context.  */
>         mmgrab(mm);
>         current->active_mm = mm;
> --
> 2.20.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Regards,
Anup

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 10/15] riscv: read the hart ID from mhartid on boot
  2019-10-17 17:37 ` [PATCH 10/15] riscv: read the hart ID from mhartid on boot Christoph Hellwig
@ 2019-10-18  3:01   ` Anup Patel
  2019-11-14  7:40   ` Paul Walmsley
  1 sibling, 0 replies; 41+ messages in thread
From: Anup Patel @ 2019-10-18  3:01 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Damien Le Moal, Palmer Dabbelt,
	linux-kernel@vger.kernel.org List, Atish Patra, Paul Walmsley,
	linux-riscv

On Thu, Oct 17, 2019 at 11:08 PM Christoph Hellwig <hch@lst.de> wrote:
>
> From: Damien Le Moal <Damien.LeMoal@wdc.com>
>
> When in M-Mode, we can use the mhartid CSR to get the ID of the running
> HART. Doing so, direct M-Mode boot without firmware is possible.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Atish Patra <atish.patra@wdc.com>
> ---
>  arch/riscv/include/asm/csr.h | 1 +
>  arch/riscv/kernel/head.S     | 8 ++++++++
>  2 files changed, 9 insertions(+)
>
> diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
> index 0dae5c361f29..d0b5113e1a54 100644
> --- a/arch/riscv/include/asm/csr.h
> +++ b/arch/riscv/include/asm/csr.h
> @@ -81,6 +81,7 @@
>  #define SIE_SEIE               (_AC(0x1, UL) << IRQ_S_EXT)
>
>  /* symbolic CSR names: */
> +#define CSR_MHARTID            0xf14
>  #define CSR_MSTATUS            0x300
>  #define CSR_MIE                        0x304
>  #define CSR_MTVEC              0x305
> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> index 679e63d29edb..583784cb3a32 100644
> --- a/arch/riscv/kernel/head.S
> +++ b/arch/riscv/kernel/head.S
> @@ -50,6 +50,14 @@ _start_kernel:
>         csrw CSR_XIE, zero
>         csrw CSR_XIP, zero
>
> +#ifdef CONFIG_RISCV_M_MODE
> +       /*
> +        * The hartid in a0 is expected later on, and we have no firmware
> +        * to hand it to us.
> +        */
> +       csrr a0, CSR_MHARTID
> +#endif
> +
>         /* Load the global pointer */
>  .option push
>  .option norelax
> --
> 2.20.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Regards,
Anup

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 11/15] riscv: use the correct interrupt levels for M-mode
  2019-10-17 17:37 ` [PATCH 11/15] riscv: use the correct interrupt levels for M-mode Christoph Hellwig
@ 2019-10-18  3:01   ` Anup Patel
  0 siblings, 0 replies; 41+ messages in thread
From: Anup Patel @ 2019-10-18  3:01 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel@vger.kernel.org List, Damien Le Moal,
	Palmer Dabbelt, linux-riscv, Paul Walmsley

On Thu, Oct 17, 2019 at 11:08 PM Christoph Hellwig <hch@lst.de> wrote:
>
> The numerical levels for External/Timer/Software interrupts differ
> between S-mode and M-mode.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  arch/riscv/kernel/irq.c | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/arch/riscv/kernel/irq.c b/arch/riscv/kernel/irq.c
> index 804ff70bb853..dbd1fd7c22e4 100644
> --- a/arch/riscv/kernel/irq.c
> +++ b/arch/riscv/kernel/irq.c
> @@ -14,9 +14,15 @@
>  /*
>   * Possible interrupt causes:
>   */
> -#define INTERRUPT_CAUSE_SOFTWARE       IRQ_S_SOFT
> -#define INTERRUPT_CAUSE_TIMER          IRQ_S_TIMER
> -#define INTERRUPT_CAUSE_EXTERNAL       IRQ_S_EXT
> +#ifdef CONFIG_RISCV_M_MODE
> +# define INTERRUPT_CAUSE_SOFTWARE      IRQ_M_SOFT
> +# define INTERRUPT_CAUSE_TIMER         IRQ_M_TIMER
> +# define INTERRUPT_CAUSE_EXTERNAL      IRQ_M_EXT
> +#else
> +# define INTERRUPT_CAUSE_SOFTWARE      IRQ_S_SOFT
> +# define INTERRUPT_CAUSE_TIMER         IRQ_S_TIMER
> +# define INTERRUPT_CAUSE_EXTERNAL      IRQ_S_EXT
> +#endif /* CONFIG_RISCV_M_MODE */
>
>  int arch_show_interrupts(struct seq_file *p, int prec)
>  {
> --
> 2.20.1
>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Regards,
Anup

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 13/15] riscv: add nommu support
  2019-10-17 17:37 ` [PATCH 13/15] riscv: add nommu support Christoph Hellwig
@ 2019-10-18  3:04   ` Anup Patel
  0 siblings, 0 replies; 41+ messages in thread
From: Anup Patel @ 2019-10-18  3:04 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel@vger.kernel.org List, Damien Le Moal,
	Palmer Dabbelt, linux-riscv, Paul Walmsley

On Thu, Oct 17, 2019 at 11:08 PM Christoph Hellwig <hch@lst.de> wrote:
>
> The kernel runs in M-mode without using page tables, and thus can't run
> bare metal without help from additional firmware.
>
> Most of the patch is just stubbing out code not needed without page
> tables, but there is an interesting detail in the signals implementation:
>
>  - The normal RISC-V syscall ABI only implements rt_sigreturn as VDSO
>    entry point, but the ELF VDSO is not supported for nommu Linux.
>    We instead copy the code to call the syscall onto the stack.
>
> In addition to enabling the nommu code a new defconfig for a small
> kernel image that can run in nommu mode on qemu is also provided, to run
> a kernel in qemu you can use the following command line:
>
> qemu-system-riscv64 -smp 2 -m 64 -machine virt -nographic \
>         -kernel arch/riscv/boot/loader \
>         -drive file=rootfs.ext2,format=raw,id=hd0 \
>         -device virtio-blk-device,drive=hd0
>
> Contains contributions from Damien Le Moal <Damien.LeMoal@wdc.com>.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  arch/riscv/Kconfig                      | 26 ++++++---
>  arch/riscv/configs/nommu_virt_defconfig | 78 +++++++++++++++++++++++++
>  arch/riscv/include/asm/cache.h          |  8 +++
>  arch/riscv/include/asm/elf.h            |  4 +-
>  arch/riscv/include/asm/fixmap.h         |  2 +
>  arch/riscv/include/asm/futex.h          |  6 ++
>  arch/riscv/include/asm/io.h             |  4 ++
>  arch/riscv/include/asm/mmu.h            |  3 +
>  arch/riscv/include/asm/page.h           | 10 +++-
>  arch/riscv/include/asm/pgalloc.h        |  2 +
>  arch/riscv/include/asm/pgtable.h        | 64 +++++++++++---------
>  arch/riscv/include/asm/tlbflush.h       | 12 +++-
>  arch/riscv/include/asm/uaccess.h        |  4 ++
>  arch/riscv/kernel/Makefile              |  3 +-
>  arch/riscv/kernel/entry.S               | 11 ++++
>  arch/riscv/kernel/head.S                |  6 ++
>  arch/riscv/kernel/signal.c              | 17 +++++-
>  arch/riscv/lib/Makefile                 | 11 ++--
>  arch/riscv/mm/Makefile                  |  3 +-
>  arch/riscv/mm/cacheflush.c              |  2 +
>  arch/riscv/mm/context.c                 |  2 +
>  arch/riscv/mm/init.c                    | 13 ++++-
>  22 files changed, 236 insertions(+), 55 deletions(-)
>  create mode 100644 arch/riscv/configs/nommu_virt_defconfig
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index b85492c42ccb..babc8a0d3d2e 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -26,14 +26,14 @@ config RISCV
>         select GENERIC_IRQ_SHOW
>         select GENERIC_PCI_IOMAP
>         select GENERIC_SCHED_CLOCK
> -       select GENERIC_STRNCPY_FROM_USER
> -       select GENERIC_STRNLEN_USER
> +       select GENERIC_STRNCPY_FROM_USER if MMU
> +       select GENERIC_STRNLEN_USER if MMU
>         select GENERIC_SMP_IDLE_THREAD
>         select GENERIC_ATOMIC64 if !64BIT
>         select HAVE_ARCH_AUDITSYSCALL
>         select HAVE_ASM_MODVERSIONS
>         select HAVE_MEMBLOCK_NODE_MAP
> -       select HAVE_DMA_CONTIGUOUS
> +       select HAVE_DMA_CONTIGUOUS if MMU
>         select HAVE_FUTEX_CMPXCHG if FUTEX
>         select HAVE_PERF_EVENTS
>         select HAVE_PERF_REGS
> @@ -50,6 +50,7 @@ config RISCV
>         select PCI_DOMAINS_GENERIC if PCI
>         select PCI_MSI if PCI
>         select RISCV_TIMER
> +       select UACCESS_MEMCPY if !MMU
>         select GENERIC_IRQ_MULTI_HANDLER
>         select GENERIC_ARCH_TOPOLOGY if SMP
>         select ARCH_HAS_PTE_SPECIAL
> @@ -60,7 +61,7 @@ config RISCV
>         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
> +       select HAVE_ARCH_MMAP_RND_BITS if MMU
>
>  config ARCH_MMAP_RND_BITS_MIN
>         default 18 if 64BIT
> @@ -75,6 +76,7 @@ config ARCH_MMAP_RND_BITS_MAX
>  # set if we run in machine mode, cleared if we run in supervisor mode
>  config RISCV_M_MODE
>         bool
> +       default !MMU
>
>  # set if we are running in S-mode and can use SBI calls
>  config RISCV_SBI
> @@ -83,7 +85,11 @@ config RISCV_SBI
>         default y
>
>  config MMU
> -       def_bool y
> +       bool "MMU-based Paged Memory Management Support"
> +       default y
> +       help
> +         Select if you want MMU-based virtualised addressing space
> +         support by paged memory management. If unsure, say 'Y'.
>
>  config ZONE_DMA32
>         bool
> @@ -102,6 +108,7 @@ config PA_BITS
>  config PAGE_OFFSET
>         hex
>         default 0xC0000000 if 32BIT && MAXPHYSMEM_2GB
> +       default 0x80000000 if 64BIT && !MMU
>         default 0xffffffff80000000 if 64BIT && MAXPHYSMEM_2GB
>         default 0xffffffe000000000 if 64BIT && MAXPHYSMEM_128GB
>
> @@ -145,7 +152,7 @@ config GENERIC_HWEIGHT
>         def_bool y
>
>  config FIX_EARLYCON_MEM
> -       def_bool y
> +       def_bool CONFIG_MMU
>
>  config PGTABLE_LEVELS
>         int
> @@ -170,6 +177,7 @@ config ARCH_RV32I
>         select GENERIC_LIB_ASHRDI3
>         select GENERIC_LIB_LSHRDI3
>         select GENERIC_LIB_UCMPDI2
> +       select MMU
>
>  config ARCH_RV64I
>         bool "RV64I"
> @@ -178,9 +186,9 @@ config ARCH_RV64I
>         select HAVE_FUNCTION_TRACER
>         select HAVE_FUNCTION_GRAPH_TRACER
>         select HAVE_FTRACE_MCOUNT_RECORD
> -       select HAVE_DYNAMIC_FTRACE
> -       select HAVE_DYNAMIC_FTRACE_WITH_REGS
> -       select SWIOTLB
> +       select HAVE_DYNAMIC_FTRACE if MMU
> +       select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE
> +       select SWIOTLB if MMU
>
>  endchoice
>
> diff --git a/arch/riscv/configs/nommu_virt_defconfig b/arch/riscv/configs/nommu_virt_defconfig
> new file mode 100644
> index 000000000000..cf74e179bf90
> --- /dev/null
> +++ b/arch/riscv/configs/nommu_virt_defconfig
> @@ -0,0 +1,78 @@
> +# CONFIG_CPU_ISOLATION is not set
> +CONFIG_LOG_BUF_SHIFT=16
> +CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=12
> +CONFIG_BLK_DEV_INITRD=y
> +# CONFIG_RD_BZIP2 is not set
> +# CONFIG_RD_LZMA is not set
> +# CONFIG_RD_XZ is not set
> +# CONFIG_RD_LZO is not set
> +# CONFIG_RD_LZ4 is not set
> +CONFIG_CC_OPTIMIZE_FOR_SIZE=y
> +CONFIG_EXPERT=y
> +# CONFIG_SYSFS_SYSCALL is not set
> +# CONFIG_FHANDLE is not set
> +# CONFIG_BASE_FULL is not set
> +# CONFIG_EPOLL is not set
> +# CONFIG_SIGNALFD is not set
> +# CONFIG_TIMERFD is not set
> +# CONFIG_EVENTFD is not set
> +# CONFIG_AIO is not set
> +# CONFIG_IO_URING is not set
> +# CONFIG_ADVISE_SYSCALLS is not set
> +# CONFIG_MEMBARRIER is not set
> +# CONFIG_KALLSYMS is not set
> +# CONFIG_VM_EVENT_COUNTERS is not set
> +# CONFIG_COMPAT_BRK is not set
> +CONFIG_SLOB=y
> +# CONFIG_SLAB_MERGE_DEFAULT is not set
> +# CONFIG_MMU is not set
> +CONFIG_MAXPHYSMEM_2GB=y
> +CONFIG_SMP=y
> +CONFIG_CMDLINE="root=/dev/vda rw earlycon=uart8250,mmio,0x10000000,115200n8 console=ttyS0"
> +CONFIG_CMDLINE_FORCE=y
> +# CONFIG_BLK_DEV_BSG is not set
> +CONFIG_PARTITION_ADVANCED=y
> +# CONFIG_MSDOS_PARTITION is not set
> +# CONFIG_EFI_PARTITION is not set
> +# CONFIG_MQ_IOSCHED_DEADLINE is not set
> +# CONFIG_MQ_IOSCHED_KYBER is not set
> +CONFIG_BINFMT_FLAT=y
> +# CONFIG_COREDUMP is not set
> +CONFIG_DEVTMPFS=y
> +CONFIG_DEVTMPFS_MOUNT=y
> +# CONFIG_FW_LOADER is not set
> +# CONFIG_ALLOW_DEV_COREDUMP is not set
> +CONFIG_VIRTIO_BLK=y
> +# CONFIG_INPUT_KEYBOARD is not set
> +# CONFIG_INPUT_MOUSE is not set
> +# CONFIG_SERIO is not set
> +# CONFIG_LEGACY_PTYS is not set
> +# CONFIG_LDISC_AUTOLOAD is not set
> +# CONFIG_DEVMEM is not set
> +CONFIG_SERIAL_8250=y
> +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
> +CONFIG_SERIAL_8250_CONSOLE=y
> +CONFIG_SERIAL_8250_NR_UARTS=1
> +CONFIG_SERIAL_8250_RUNTIME_UARTS=1
> +CONFIG_SERIAL_OF_PLATFORM=y
> +# CONFIG_HW_RANDOM is not set
> +# CONFIG_HWMON is not set
> +# CONFIG_LCD_CLASS_DEVICE is not set
> +# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
> +# CONFIG_VGA_CONSOLE is not set
> +# CONFIG_HID is not set
> +# CONFIG_USB_SUPPORT is not set
> +CONFIG_VIRTIO_MMIO=y
> +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
> +CONFIG_SIFIVE_PLIC=y
> +# CONFIG_VALIDATE_FS_PARSER is not set
> +CONFIG_EXT2_FS=y
> +# CONFIG_DNOTIFY is not set
> +# CONFIG_INOTIFY_USER is not set
> +# CONFIG_MISC_FILESYSTEMS is not set
> +CONFIG_LSM="[]"
> +CONFIG_PRINTK_TIME=y
> +# CONFIG_SCHED_DEBUG is not set
> +# CONFIG_RCU_TRACE is not set
> +# CONFIG_FTRACE is not set
> +# CONFIG_RUNTIME_TESTING_MENU is not set
> diff --git a/arch/riscv/include/asm/cache.h b/arch/riscv/include/asm/cache.h
> index bfd523e8f0b2..9b58b104559e 100644
> --- a/arch/riscv/include/asm/cache.h
> +++ b/arch/riscv/include/asm/cache.h
> @@ -11,4 +11,12 @@
>
>  #define L1_CACHE_BYTES         (1 << L1_CACHE_SHIFT)
>
> +/*
> + * RISC-V requires the stack pointer to be 16-byte aligned, so ensure that
> + * the flat loader aligns it accordingly.
> + */
> +#ifndef CONFIG_MMU
> +#define ARCH_SLAB_MINALIGN     16
> +#endif
> +
>  #endif /* _ASM_RISCV_CACHE_H */
> diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
> index ef04084bf0de..d83a4efd052b 100644
> --- a/arch/riscv/include/asm/elf.h
> +++ b/arch/riscv/include/asm/elf.h
> @@ -56,16 +56,16 @@ extern unsigned long elf_hwcap;
>   */
>  #define ELF_PLATFORM   (NULL)
>
> +#ifdef CONFIG_MMU
>  #define ARCH_DLINFO                                            \
>  do {                                                           \
>         NEW_AUX_ENT(AT_SYSINFO_EHDR,                            \
>                 (elf_addr_t)current->mm->context.vdso);         \
>  } while (0)
> -
> -
>  #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
>  struct linux_binprm;
>  extern int arch_setup_additional_pages(struct linux_binprm *bprm,
>         int uses_interp);
> +#endif /* CONFIG_MMU */
>
>  #endif /* _ASM_RISCV_ELF_H */
> diff --git a/arch/riscv/include/asm/fixmap.h b/arch/riscv/include/asm/fixmap.h
> index 161f28d04a07..42d2c42f3cc9 100644
> --- a/arch/riscv/include/asm/fixmap.h
> +++ b/arch/riscv/include/asm/fixmap.h
> @@ -11,6 +11,7 @@
>  #include <asm/page.h>
>  #include <asm/pgtable.h>
>
> +#ifdef CONFIG_MMU
>  /*
>   * Here we define all the compile-time 'special' virtual addresses.
>   * The point is to have a constant address at compile time, but to
> @@ -42,4 +43,5 @@ extern void __set_fixmap(enum fixed_addresses idx,
>
>  #include <asm-generic/fixmap.h>
>
> +#endif /* CONFIG_MMU */
>  #endif /* _ASM_RISCV_FIXMAP_H */
> diff --git a/arch/riscv/include/asm/futex.h b/arch/riscv/include/asm/futex.h
> index 4ad6409c4647..418564b96dc4 100644
> --- a/arch/riscv/include/asm/futex.h
> +++ b/arch/riscv/include/asm/futex.h
> @@ -12,6 +12,12 @@
>  #include <linux/errno.h>
>  #include <asm/asm.h>
>
> +/* We don't even really need the extable code, but for now keep it simple */
> +#ifndef CONFIG_MMU
> +#define __enable_user_access()         do { } while (0)
> +#define __disable_user_access()                do { } while (0)
> +#endif
> +
>  #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)     \
>  {                                                              \
>         uintptr_t tmp;                                          \
> diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
> index fc1189ad3777..d39a8f03e85e 100644
> --- a/arch/riscv/include/asm/io.h
> +++ b/arch/riscv/include/asm/io.h
> @@ -14,6 +14,7 @@
>  #include <linux/types.h>
>  #include <asm/mmiowb.h>
>
> +#ifdef CONFIG_MMU
>  extern void __iomem *ioremap(phys_addr_t offset, unsigned long size);
>
>  /*
> @@ -26,6 +27,9 @@ extern void __iomem *ioremap(phys_addr_t offset, unsigned long size);
>  #define ioremap_wt(addr, size) ioremap((addr), (size))
>
>  extern void iounmap(volatile void __iomem *addr);
> +#else
> +#define pgprot_noncached(x)    (x)
> +#endif /* CONFIG_MMU */
>
>  /* Generic IO read/write.  These perform native-endian accesses. */
>  #define __raw_writeb __raw_writeb
> diff --git a/arch/riscv/include/asm/mmu.h b/arch/riscv/include/asm/mmu.h
> index 151476fb58cb..967eacb01ab5 100644
> --- a/arch/riscv/include/asm/mmu.h
> +++ b/arch/riscv/include/asm/mmu.h
> @@ -10,6 +10,9 @@
>  #ifndef __ASSEMBLY__
>
>  typedef struct {
> +#ifndef CONFIG_MMU
> +       unsigned long   end_brk;
> +#endif
>         void *vdso;
>  #ifdef CONFIG_SMP
>         /* A local icache flush is needed before user execution can resume. */
> diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h
> index 3db261c4810f..ac699246ae7e 100644
> --- a/arch/riscv/include/asm/page.h
> +++ b/arch/riscv/include/asm/page.h
> @@ -88,8 +88,14 @@ typedef struct page *pgtable_t;
>  #define PTE_FMT "%08lx"
>  #endif
>
> +#ifdef CONFIG_MMU
>  extern unsigned long va_pa_offset;
>  extern unsigned long pfn_base;
> +#define ARCH_PFN_OFFSET                (pfn_base)
> +#else
> +#define va_pa_offset           0
> +#define ARCH_PFN_OFFSET                (PAGE_OFFSET >> PAGE_SHIFT)
> +#endif /* CONFIG_MMU */
>
>  extern unsigned long max_low_pfn;
>  extern unsigned long min_low_pfn;
> @@ -112,11 +118,9 @@ extern unsigned long min_low_pfn;
>
>  #ifdef CONFIG_FLATMEM
>  #define pfn_valid(pfn) \
> -       (((pfn) >= pfn_base) && (((pfn)-pfn_base) < max_mapnr))
> +       (((pfn) >= ARCH_PFN_OFFSET) && (((pfn) - ARCH_PFN_OFFSET) < max_mapnr))
>  #endif
>
> -#define ARCH_PFN_OFFSET                (pfn_base)
> -
>  #endif /* __ASSEMBLY__ */
>
>  #define virt_addr_valid(vaddr) (pfn_valid(virt_to_pfn(vaddr)))
> diff --git a/arch/riscv/include/asm/pgalloc.h b/arch/riscv/include/asm/pgalloc.h
> index d59ea92285ec..3f601ee8233f 100644
> --- a/arch/riscv/include/asm/pgalloc.h
> +++ b/arch/riscv/include/asm/pgalloc.h
> @@ -10,6 +10,7 @@
>  #include <linux/mm.h>
>  #include <asm/tlb.h>
>
> +#ifdef CONFIG_MMU
>  #include <asm-generic/pgalloc.h>       /* for pte_{alloc,free}_one */
>
>  static inline void pmd_populate_kernel(struct mm_struct *mm,
> @@ -81,5 +82,6 @@ do {                                    \
>         pgtable_pte_page_dtor(pte);     \
>         tlb_remove_page((tlb), pte);    \
>  } while (0)
> +#endif /* CONFIG_MMU */
>
>  #endif /* _ASM_RISCV_PGALLOC_H */
> diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
> index 42292d99cc74..f3636fc22a11 100644
> --- a/arch/riscv/include/asm/pgtable.h
> +++ b/arch/riscv/include/asm/pgtable.h
> @@ -24,6 +24,7 @@
>  #include <asm/pgtable-32.h>
>  #endif /* CONFIG_64BIT */
>
> +#ifdef CONFIG_MMU
>  /* Number of entries in the page global directory */
>  #define PTRS_PER_PGD    (PAGE_SIZE / sizeof(pgd_t))
>  /* Number of entries in the page table */
> @@ -31,7 +32,6 @@
>
>  /* Number of PGD entries that a user-mode program can use */
>  #define USER_PTRS_PER_PGD   (TASK_SIZE / PGDIR_SIZE)
> -#define FIRST_USER_ADDRESS  0
>
>  /* Page protection bits */
>  #define _PAGE_BASE     (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER)
> @@ -83,10 +83,6 @@ extern pgd_t swapper_pg_dir[];
>  #define __S110 PAGE_SHARED_EXEC
>  #define __S111 PAGE_SHARED_EXEC
>
> -#define VMALLOC_SIZE     (KERN_VIRT_SIZE >> 1)
> -#define VMALLOC_END      (PAGE_OFFSET - 1)
> -#define VMALLOC_START    (PAGE_OFFSET - VMALLOC_SIZE)
> -
>  /*
>   * Roughly size the vmemmap space to be large enough to fit enough
>   * struct pages to map half the virtual address space. Then
> @@ -100,21 +96,6 @@ extern pgd_t swapper_pg_dir[];
>
>  #define vmemmap                ((struct page *)VMEMMAP_START)
>
> -#define FIXADDR_TOP      (VMEMMAP_START)
> -#ifdef CONFIG_64BIT
> -#define FIXADDR_SIZE     PMD_SIZE
> -#else
> -#define FIXADDR_SIZE     PGDIR_SIZE
> -#endif
> -#define FIXADDR_START    (FIXADDR_TOP - FIXADDR_SIZE)
> -
> -/*
> - * ZERO_PAGE is a global shared page that is always zero,
> - * used for zero-mapped memory areas, etc.
> - */
> -extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
> -#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
> -
>  static inline int pmd_present(pmd_t pmd)
>  {
>         return (pmd_val(pmd) & (_PAGE_PRESENT | _PAGE_PROT_NONE));
> @@ -428,13 +409,17 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
>  #define __pte_to_swp_entry(pte)        ((swp_entry_t) { pte_val(pte) })
>  #define __swp_entry_to_pte(x)  ((pte_t) { (x).val })
>
> -#ifdef CONFIG_FLATMEM
> -#define kern_addr_valid(addr)   (1) /* FIXME */
> -#endif
> +#define VMALLOC_SIZE           (KERN_VIRT_SIZE >> 1)
> +#define VMALLOC_END            (PAGE_OFFSET - 1)
> +#define VMALLOC_START          (PAGE_OFFSET - VMALLOC_SIZE)
>
> -extern void *dtb_early_va;
> -extern void setup_bootmem(void);
> -extern void paging_init(void);
> +#define FIXADDR_TOP      VMEMMAP_START
> +#ifdef CONFIG_64BIT
> +#define FIXADDR_SIZE     PMD_SIZE
> +#else
> +#define FIXADDR_SIZE     PGDIR_SIZE
> +#endif
> +#define FIXADDR_START    (FIXADDR_TOP - FIXADDR_SIZE)
>
>  /*
>   * Task size is 0x4000000000 for RV64 or 0x9fc00000 for RV32.
> @@ -446,6 +431,33 @@ extern void paging_init(void);
>  #define TASK_SIZE FIXADDR_START
>  #endif
>
> +#else /* CONFIG_MMU */
> +
> +#define PAGE_KERNEL            __pgprot(0)
> +#define swapper_pg_dir         NULL
> +#define VMALLOC_START          0
> +
> +#define TASK_SIZE 0xffffffffUL
> +
> +#endif /* !CONFIG_MMU */
> +
> +#ifdef CONFIG_FLATMEM
> +#define kern_addr_valid(addr)   (1) /* FIXME */
> +#endif
> +
> +extern void *dtb_early_va;
> +void setup_bootmem(void);
> +void paging_init(void);
> +
> +#define FIRST_USER_ADDRESS  0
> +
> +/*
> + * ZERO_PAGE is a global shared page that is always zero,
> + * used for zero-mapped memory areas, etc.
> + */
> +extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
> +#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
> +
>  #include <asm-generic/pgtable.h>
>
>  #endif /* !__ASSEMBLY__ */
> diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
> index f02188a5b0f4..394cfbccdcd9 100644
> --- a/arch/riscv/include/asm/tlbflush.h
> +++ b/arch/riscv/include/asm/tlbflush.h
> @@ -10,6 +10,7 @@
>  #include <linux/mm_types.h>
>  #include <asm/smp.h>
>
> +#ifdef CONFIG_MMU
>  static inline void local_flush_tlb_all(void)
>  {
>         __asm__ __volatile__ ("sfence.vma" : : : "memory");
> @@ -20,14 +21,19 @@ static inline void local_flush_tlb_page(unsigned long addr)
>  {
>         __asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory");
>  }
> +#else /* CONFIG_MMU */
> +#define local_flush_tlb_all()                  do { } while (0)
> +#define local_flush_tlb_page(addr)             do { } while (0)
> +#endif /* CONFIG_MMU */
>
> -#ifdef CONFIG_SMP
> +#if defined(CONFIG_SMP) && defined(CONFIG_MMU)
>  void flush_tlb_all(void);
>  void flush_tlb_mm(struct mm_struct *mm);
>  void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr);
>  void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
>                      unsigned long end);
> -#else /* CONFIG_SMP */
> +#else /* CONFIG_SMP && CONFIG_MMU */
> +
>  #define flush_tlb_all() local_flush_tlb_all()
>  #define flush_tlb_page(vma, addr) local_flush_tlb_page(addr)
>
> @@ -38,7 +44,7 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
>  }
>
>  #define flush_tlb_mm(mm) flush_tlb_all()
> -#endif /* CONFIG_SMP */
> +#endif /* !CONFIG_SMP || !CONFIG_MMU */
>
>  /* Flush a range of kernel pages */
>  static inline void flush_tlb_kernel_range(unsigned long start,
> diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
> index e076437cfafe..f462a183a9c2 100644
> --- a/arch/riscv/include/asm/uaccess.h
> +++ b/arch/riscv/include/asm/uaccess.h
> @@ -11,6 +11,7 @@
>  /*
>   * User space memory access functions
>   */
> +#ifdef CONFIG_MMU
>  #include <linux/errno.h>
>  #include <linux/compiler.h>
>  #include <linux/thread_info.h>
> @@ -475,4 +476,7 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n)
>         __ret;                                                  \
>  })
>
> +#else /* CONFIG_MMU */
> +#include <asm-generic/uaccess.h>
> +#endif /* CONFIG_MMU */
>  #endif /* _ASM_RISCV_UACCESS_H */
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> index 2dca51046899..f40205cb9a22 100644
> --- a/arch/riscv/kernel/Makefile
> +++ b/arch/riscv/kernel/Makefile
> @@ -25,9 +25,8 @@ obj-y += time.o
>  obj-y  += traps.o
>  obj-y  += riscv_ksyms.o
>  obj-y  += stacktrace.o
> -obj-y  += vdso.o
>  obj-y  += cacheinfo.o
> -obj-y  += vdso/
> +obj-$(CONFIG_MMU) += vdso.o vdso/
>
>  obj-$(CONFIG_RISCV_M_MODE)     += clint.o
>  obj-$(CONFIG_FPU)              += fpu.o
> diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
> index c0b3732af1ea..4bf6577dde7d 100644
> --- a/arch/riscv/kernel/entry.S
> +++ b/arch/riscv/kernel/entry.S
> @@ -392,6 +392,10 @@ ENTRY(__switch_to)
>         ret
>  ENDPROC(__switch_to)
>
> +#ifndef CONFIG_MMU
> +#define do_page_fault do_trap_unknown
> +#endif
> +
>         .section ".rodata"
>         /* Exception vector table */
>  ENTRY(excp_vect_table)
> @@ -413,3 +417,10 @@ ENTRY(excp_vect_table)
>         RISCV_PTR do_page_fault   /* store page fault */
>  excp_vect_table_end:
>  END(excp_vect_table)
> +
> +#ifndef CONFIG_MMU
> +ENTRY(__user_rt_sigreturn)
> +       li a7, __NR_rt_sigreturn
> +       scall
> +END(__user_rt_sigreturn)
> +#endif
> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> index 25867b99cc95..71efbba25ed5 100644
> --- a/arch/riscv/kernel/head.S
> +++ b/arch/riscv/kernel/head.S
> @@ -109,8 +109,10 @@ clear_bss_done:
>         la sp, init_thread_union + THREAD_SIZE
>         mv a0, s1
>         call setup_vm
> +#ifdef CONFIG_MMU
>         la a0, early_pg_dir
>         call relocate
> +#endif /* CONFIG_MMU */
>
>         /* Restore C environment */
>         la tp, init_task
> @@ -121,6 +123,7 @@ clear_bss_done:
>         call parse_dtb
>         tail start_kernel
>
> +#ifdef CONFIG_MMU
>  relocate:
>         /* Relocate return address */
>         li a1, PAGE_OFFSET
> @@ -171,6 +174,7 @@ relocate:
>         sfence.vma
>
>         ret
> +#endif /* CONFIG_MMU */
>
>  .Lsecondary_start:
>  #ifdef CONFIG_SMP
> @@ -196,9 +200,11 @@ relocate:
>         beqz tp, .Lwait_for_cpu_up
>         fence
>
> +#ifdef CONFIG_MMU
>         /* Enable virtual memory and relocate to virtual address */
>         la a0, swapper_pg_dir
>         call relocate
> +#endif
>
>         tail smp_callin
>  #endif
> diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
> index e1a2cee340f7..eb8ba201feff 100644
> --- a/arch/riscv/kernel/signal.c
> +++ b/arch/riscv/kernel/signal.c
> @@ -17,11 +17,16 @@
>  #include <asm/switch_to.h>
>  #include <asm/csr.h>
>
> +extern u32 __user_rt_sigreturn[2];
> +
>  #define DEBUG_SIG 0
>
>  struct rt_sigframe {
>         struct siginfo info;
>         struct ucontext uc;
> +#ifndef CONFIG_MMU
> +       u32 sigreturn_code[2];
> +#endif
>  };
>
>  #ifdef CONFIG_FPU
> @@ -166,7 +171,6 @@ static inline void __user *get_sigframe(struct ksignal *ksig,
>         return (void __user *)sp;
>  }
>
> -
>  static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
>         struct pt_regs *regs)
>  {
> @@ -189,8 +193,19 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
>                 return -EFAULT;
>
>         /* Set up to return from userspace. */
> +#ifdef CONFIG_MMU
>         regs->ra = (unsigned long)VDSO_SYMBOL(
>                 current->mm->context.vdso, rt_sigreturn);
> +#else
> +       /*
> +        * For the nommu case we don't have a VDSO.  Instead we push two
> +        * instructions to call the rt_sigreturn syscall onto the user stack.
> +        */
> +       if (copy_to_user(&frame->sigreturn_code, __user_rt_sigreturn,
> +                       sizeof(frame->sigreturn_code)))
> +               return -EFAULT;
> +       regs->ra = (unsigned long)&frame->sigreturn_code;;
> +#endif /* CONFIG_MMU */
>
>         /*
>          * Set up registers for signal handler.
> diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
> index 267feaa10f6a..47e7a8204460 100644
> --- a/arch/riscv/lib/Makefile
> +++ b/arch/riscv/lib/Makefile
> @@ -1,7 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0-only
> -lib-y  += delay.o
> -lib-y  += memcpy.o
> -lib-y  += memset.o
> -lib-y  += uaccess.o
> -
> -lib-$(CONFIG_64BIT) += tishift.o
> +lib-y                  += delay.o
> +lib-y                  += memcpy.o
> +lib-y                  += memset.o
> +lib-$(CONFIG_MMU)      += uaccess.o
> +lib-$(CONFIG_64BIT)    += tishift.o
> diff --git a/arch/riscv/mm/Makefile b/arch/riscv/mm/Makefile
> index 9d9a17335686..44ab8f28c3fa 100644
> --- a/arch/riscv/mm/Makefile
> +++ b/arch/riscv/mm/Makefile
> @@ -6,9 +6,8 @@ CFLAGS_REMOVE_init.o = -pg
>  endif
>
>  obj-y += init.o
> -obj-y += fault.o
>  obj-y += extable.o
> -obj-y += ioremap.o
> +obj-$(CONFIG_MMU) += fault.o ioremap.o
>  obj-y += cacheflush.o
>  obj-y += context.o
>  obj-y += sifive_l2_cache.o
> diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c
> index 794c9ab256eb..8f1900686640 100644
> --- a/arch/riscv/mm/cacheflush.c
> +++ b/arch/riscv/mm/cacheflush.c
> @@ -78,6 +78,7 @@ void flush_icache_mm(struct mm_struct *mm, bool local)
>
>  #endif /* CONFIG_SMP */
>
> +#ifdef CONFIG_MMU
>  void flush_icache_pte(pte_t pte)
>  {
>         struct page *page = pte_page(pte);
> @@ -85,3 +86,4 @@ void flush_icache_pte(pte_t pte)
>         if (!test_and_set_bit(PG_dcache_clean, &page->flags))
>                 flush_icache_all();
>  }
> +#endif /* CONFIG_MMU */
> diff --git a/arch/riscv/mm/context.c b/arch/riscv/mm/context.c
> index beeb5d7f92ea..073ff12a838a 100644
> --- a/arch/riscv/mm/context.c
> +++ b/arch/riscv/mm/context.c
> @@ -57,8 +57,10 @@ void switch_mm(struct mm_struct *prev, struct mm_struct *next,
>         cpumask_clear_cpu(cpu, mm_cpumask(prev));
>         cpumask_set_cpu(cpu, mm_cpumask(next));
>
> +#ifdef CONFIG_MMU
>         csr_write(CSR_SATP, virt_to_pfn(next->pgd) | SATP_MODE);
>         local_flush_tlb_all();
> +#endif
>
>         flush_icache_deferred(next);
>  }
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index 83f7d12042fb..0b063f6acaa1 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -24,6 +24,7 @@ unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]
>  EXPORT_SYMBOL(empty_zero_page);
>
>  extern char _start[];
> +void *dtb_early_va;
>
>  static void __init zone_sizes_init(void)
>  {
> @@ -140,12 +141,12 @@ void __init setup_bootmem(void)
>         }
>  }
>
> +#ifdef CONFIG_MMU
>  unsigned long va_pa_offset;
>  EXPORT_SYMBOL(va_pa_offset);
>  unsigned long pfn_base;
>  EXPORT_SYMBOL(pfn_base);
>
> -void *dtb_early_va;
>  pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
>  pgd_t trampoline_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
>  pte_t fixmap_pte[PTRS_PER_PTE] __page_aligned_bss;
> @@ -448,6 +449,16 @@ static void __init setup_vm_final(void)
>         csr_write(CSR_SATP, PFN_DOWN(__pa(swapper_pg_dir)) | SATP_MODE);
>         local_flush_tlb_all();
>  }
> +#else
> +asmlinkage void __init setup_vm(uintptr_t dtb_pa)
> +{
> +       dtb_early_va = (void *)dtb_pa;
> +}
> +
> +static inline void setup_vm_final(void)
> +{
> +}
> +#endif /* CONFIG_MMU */
>
>  void __init paging_init(void)
>  {
> --
> 2.20.1
>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Regards,
Anup

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 12/15] riscv: clear the instruction cache and all registers when booting
  2019-10-17 17:37 ` [PATCH 12/15] riscv: clear the instruction cache and all registers when booting Christoph Hellwig
@ 2019-10-18  3:05   ` Anup Patel
  0 siblings, 0 replies; 41+ messages in thread
From: Anup Patel @ 2019-10-18  3:05 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel@vger.kernel.org List, Damien Le Moal,
	Palmer Dabbelt, linux-riscv, Paul Walmsley

On Thu, Oct 17, 2019 at 11:08 PM Christoph Hellwig <hch@lst.de> wrote:
>
> When we get booted we want a clear slate without any leaks from previous
> supervisors or the firmware.  Flush the instruction cache and then clear
> all registers to known good values.  This is really important for the
> upcoming nommu support that runs on M-mode, but can't really harm when
> running in S-mode either.  Vaguely based on the concepts from opensbi.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  arch/riscv/include/asm/csr.h |  1 +
>  arch/riscv/kernel/head.S     | 88 +++++++++++++++++++++++++++++++++++-
>  2 files changed, 88 insertions(+), 1 deletion(-)
>
> diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
> index d0b5113e1a54..ee0101278608 100644
> --- a/arch/riscv/include/asm/csr.h
> +++ b/arch/riscv/include/asm/csr.h
> @@ -83,6 +83,7 @@
>  /* symbolic CSR names: */
>  #define CSR_MHARTID            0xf14
>  #define CSR_MSTATUS            0x300
> +#define CSR_MISA               0x301
>  #define CSR_MIE                        0x304
>  #define CSR_MTVEC              0x305
>  #define CSR_MSCRATCH           0x340
> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> index 583784cb3a32..25867b99cc95 100644
> --- a/arch/riscv/kernel/head.S
> +++ b/arch/riscv/kernel/head.S
> @@ -11,6 +11,7 @@
>  #include <asm/thread_info.h>
>  #include <asm/page.h>
>  #include <asm/csr.h>
> +#include <asm/hwcap.h>
>  #include <asm/image.h>
>
>  __INIT
> @@ -51,12 +52,18 @@ _start_kernel:
>         csrw CSR_XIP, zero
>
>  #ifdef CONFIG_RISCV_M_MODE
> +       /* flush the instruction cache */
> +       fence.i
> +
> +       /* Reset all registers except ra, a0, a1 */
> +       call reset_regs
> +
>         /*
>          * The hartid in a0 is expected later on, and we have no firmware
>          * to hand it to us.
>          */
>         csrr a0, CSR_MHARTID
> -#endif
> +#endif /* CONFIG_RISCV_M_MODE */
>
>         /* Load the global pointer */
>  .option push
> @@ -203,6 +210,85 @@ relocate:
>         j .Lsecondary_park
>  END(_start)
>
> +#ifdef CONFIG_RISCV_M_MODE
> +ENTRY(reset_regs)
> +       li      sp, 0
> +       li      gp, 0
> +       li      tp, 0
> +       li      t0, 0
> +       li      t1, 0
> +       li      t2, 0
> +       li      s0, 0
> +       li      s1, 0
> +       li      a2, 0
> +       li      a3, 0
> +       li      a4, 0
> +       li      a5, 0
> +       li      a6, 0
> +       li      a7, 0
> +       li      s2, 0
> +       li      s3, 0
> +       li      s4, 0
> +       li      s5, 0
> +       li      s6, 0
> +       li      s7, 0
> +       li      s8, 0
> +       li      s9, 0
> +       li      s10, 0
> +       li      s11, 0
> +       li      t3, 0
> +       li      t4, 0
> +       li      t5, 0
> +       li      t6, 0
> +       csrw    sscratch, 0
> +
> +#ifdef CONFIG_FPU
> +       csrr    t0, CSR_MISA
> +       andi    t0, t0, (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D)
> +       bnez    t0, .Lreset_regs_done
> +
> +       li      t1, SR_FS
> +       csrs    CSR_XSTATUS, t1
> +       fmv.s.x f0, zero
> +       fmv.s.x f1, zero
> +       fmv.s.x f2, zero
> +       fmv.s.x f3, zero
> +       fmv.s.x f4, zero
> +       fmv.s.x f5, zero
> +       fmv.s.x f6, zero
> +       fmv.s.x f7, zero
> +       fmv.s.x f8, zero
> +       fmv.s.x f9, zero
> +       fmv.s.x f10, zero
> +       fmv.s.x f11, zero
> +       fmv.s.x f12, zero
> +       fmv.s.x f13, zero
> +       fmv.s.x f14, zero
> +       fmv.s.x f15, zero
> +       fmv.s.x f16, zero
> +       fmv.s.x f17, zero
> +       fmv.s.x f18, zero
> +       fmv.s.x f19, zero
> +       fmv.s.x f20, zero
> +       fmv.s.x f21, zero
> +       fmv.s.x f22, zero
> +       fmv.s.x f23, zero
> +       fmv.s.x f24, zero
> +       fmv.s.x f25, zero
> +       fmv.s.x f26, zero
> +       fmv.s.x f27, zero
> +       fmv.s.x f28, zero
> +       fmv.s.x f29, zero
> +       fmv.s.x f30, zero
> +       fmv.s.x f31, zero
> +       csrw    fcsr, 0
> +       /* note that the caller must clear SR_FS */
> +#endif /* CONFIG_FPU */
> +.Lreset_regs_done:
> +       ret
> +END(reset_regs)
> +#endif /* CONFIG_RISCV_M_MODE */
> +
>  __PAGE_ALIGNED_BSS
>         /* Empty zero page */
>         .balign PAGE_SIZE
> --
> 2.20.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Regards,
Anup

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 14/15] riscv: provide a flat image loader
  2019-10-17 17:37 ` [PATCH 14/15] riscv: provide a flat image loader Christoph Hellwig
@ 2019-10-18  3:06   ` Anup Patel
  0 siblings, 0 replies; 41+ messages in thread
From: Anup Patel @ 2019-10-18  3:06 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel@vger.kernel.org List, Damien Le Moal,
	Palmer Dabbelt, linux-riscv, Paul Walmsley

On Thu, Oct 17, 2019 at 11:08 PM Christoph Hellwig <hch@lst.de> wrote:
>
> This allows just loading the kernel at a pre-set address without
> qemu going bonkers trying to map the ELF file.
>
> Contains a controbution from Aurabindo Jayamohanan to reuse the
> PAGE_OFFSET definition.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  arch/riscv/Makefile          | 13 +++++++++----
>  arch/riscv/boot/Makefile     |  7 ++++++-
>  arch/riscv/boot/loader.S     |  8 ++++++++
>  arch/riscv/boot/loader.lds.S | 16 ++++++++++++++++
>  4 files changed, 39 insertions(+), 5 deletions(-)
>  create mode 100644 arch/riscv/boot/loader.S
>  create mode 100644 arch/riscv/boot/loader.lds.S
>
> diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
> index f5e914210245..b9009a2fbaf5 100644
> --- a/arch/riscv/Makefile
> +++ b/arch/riscv/Makefile
> @@ -83,13 +83,18 @@ PHONY += vdso_install
>  vdso_install:
>         $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@
>
> -all: Image.gz
> +ifeq ($(CONFIG_RISCV_M_MODE),y)
> +KBUILD_IMAGE := $(boot)/loader
> +else
> +KBUILD_IMAGE := $(boot)/Image.gz
> +endif
> +BOOT_TARGETS := Image Image.gz loader
>
> -Image: vmlinux
> -       $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
> +all:   $(notdir $(KBUILD_IMAGE))
>
> -Image.%: Image
> +$(BOOT_TARGETS): vmlinux
>         $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
> +       @$(kecho) '  Kernel: $(boot)/$@ is ready'
>
>  zinstall install:
>         $(Q)$(MAKE) $(build)=$(boot) $@
> diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile
> index 0990a9fdbe5d..8639e0dd2cdf 100644
> --- a/arch/riscv/boot/Makefile
> +++ b/arch/riscv/boot/Makefile
> @@ -16,7 +16,7 @@
>
>  OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
>
> -targets := Image
> +targets := Image loader
>
>  $(obj)/Image: vmlinux FORCE
>         $(call if_changed,objcopy)
> @@ -24,6 +24,11 @@ $(obj)/Image: vmlinux FORCE
>  $(obj)/Image.gz: $(obj)/Image FORCE
>         $(call if_changed,gzip)
>
> +loader.o: $(src)/loader.S $(obj)/Image
> +
> +$(obj)/loader: $(obj)/loader.o $(obj)/Image $(obj)/loader.lds FORCE
> +       $(Q)$(LD) -T $(src)/loader.lds -o $@ $(obj)/loader.o
> +
>  install:
>         $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
>         $(obj)/Image System.map "$(INSTALL_PATH)"
> diff --git a/arch/riscv/boot/loader.S b/arch/riscv/boot/loader.S
> new file mode 100644
> index 000000000000..5586e2610dbb
> --- /dev/null
> +++ b/arch/riscv/boot/loader.S
> @@ -0,0 +1,8 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +       .align 4
> +       .section .payload, "ax", %progbits
> +       .globl _start
> +_start:
> +       .incbin "arch/riscv/boot/Image"
> +
> diff --git a/arch/riscv/boot/loader.lds.S b/arch/riscv/boot/loader.lds.S
> new file mode 100644
> index 000000000000..47a5003c2e28
> --- /dev/null
> +++ b/arch/riscv/boot/loader.lds.S
> @@ -0,0 +1,16 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#include <asm/page.h>
> +
> +OUTPUT_ARCH(riscv)
> +ENTRY(_start)
> +
> +SECTIONS
> +{
> +       . = PAGE_OFFSET;
> +
> +       .payload : {
> +               *(.payload)
> +               . = ALIGN(8);
> +       }
> +}
> --
> 2.20.1
>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Regards,
Anup

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 15/15] riscv: disable the EFI PECOFF header for M-mode
  2019-10-17 17:37 ` [PATCH 15/15] riscv: disable the EFI PECOFF header for M-mode Christoph Hellwig
@ 2019-10-18  3:06   ` Anup Patel
  0 siblings, 0 replies; 41+ messages in thread
From: Anup Patel @ 2019-10-18  3:06 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel@vger.kernel.org List, Damien Le Moal,
	Palmer Dabbelt, linux-riscv, Paul Walmsley

On Thu, Oct 17, 2019 at 11:08 PM Christoph Hellwig <hch@lst.de> wrote:
>
> No point in bloating the kernel image with a bootloader header if
> we run bare metal.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  arch/riscv/kernel/head.S | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> index 71efbba25ed5..dc21e409cc49 100644
> --- a/arch/riscv/kernel/head.S
> +++ b/arch/riscv/kernel/head.S
> @@ -16,6 +16,7 @@
>
>  __INIT
>  ENTRY(_start)
> +#ifndef CONFIG_RISCV_M_MODE
>         /*
>          * Image header expected by Linux boot-loaders. The image header data
>          * structure is described in asm/image.h.
> @@ -47,6 +48,7 @@ ENTRY(_start)
>
>  .global _start_kernel
>  _start_kernel:
> +#endif /* CONFIG_RISCV_M_MODE */
>         /* Mask all interrupts */
>         csrw CSR_XIE, zero
>         csrw CSR_XIP, zero
> --
> 2.20.1
>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Regards,
Anup

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: RISC-V nommu support v5
  2019-10-17 17:37 RISC-V nommu support v5 Christoph Hellwig
                   ` (14 preceding siblings ...)
  2019-10-17 17:37 ` [PATCH 15/15] riscv: disable the EFI PECOFF header for M-mode Christoph Hellwig
@ 2019-10-18  3:08 ` Anup Patel
  2019-10-18  3:29   ` Paul Walmsley
  15 siblings, 1 reply; 41+ messages in thread
From: Anup Patel @ 2019-10-18  3:08 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley
  Cc: Damien Le Moal, Christoph Hellwig, linux-riscv,
	linux-kernel@vger.kernel.org List

Hi Paul/Palmer,

On Thu, Oct 17, 2019 at 11:07 PM Christoph Hellwig <hch@lst.de> wrote:
>
> Hi all,
>
> below is a series to support nommu mode on RISC-V.  For now this series
> just works under qemu with the qemu-virt platform, but Damien has also
> been able to get kernel based on this tree with additional driver hacks
> to work on the Kendryte KD210, but that will take a while to cleanup
> an upstream.
>
> A git tree is available here:
>
>     git://git.infradead.org/users/hch/riscv.git riscv-nommu.5
>
> Gitweb:
>
>     http://git.infradead.org/users/hch/riscv.git/shortlog/refs/heads/riscv-nommu.5
>
> I've also pushed out a builtroot branch that can build a RISC-V nommu
> root filesystem here:
>
>    git://git.infradead.org/users/hch/buildroot.git riscv-nommu.2
>
> Gitweb:
>
>    http://git.infradead.org/users/hch/buildroot.git/shortlog/refs/heads/riscv-nommu.2

It will be really cool to have this series for Linux-5.4-rcX.

Best Regards,
Anup

>
>
> Changes since v4:
>  - rebased to 5.4-rc + latest riscv fixes
>  - clean up do_trap_break
>  - fix an SR_XPIE issue (Paul Walmsley)
>  - use the symbolic PAGE_OFFSET value in the flat loader
>    (Aurabindo Jayamohanan)
>
> Changes since v3:
>  - improve a few commit message
>  - cleanup riscv_cpuid_to_hartid_mask
>  - cleanup the timer handling
>  - cleanup the IPI handling a little more
>  - renamed CONFIG_M_MODE to CONFIG_RISCV_M_MODE
>  - split out CONFIG_RISCV_SBI to make some of the ifdefs more obbious
>  - use IS_ENABLED wherever possible instead of if ifdefs to make the
>    code more readable
>
> Changes since v2:
>  - rebased to 5.3-rc
>  - remove the EFI image header for nommu builds
>  - set ARCH_SLAB_MINALIGN to ensure stack alignment in the flat binary
>    loader
>  - minor comment improvement
>  - use #defines for more CSRs
>
> Changes since v1:
>  - fixes so that a kernel with this series still work on builds with an
>    IOMMU
>  - small clint cleanups
>  - the binfmt_flat base and buildroot now don't put arguments on the stack
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: RISC-V nommu support v5
  2019-10-18  3:08 ` RISC-V nommu support v5 Anup Patel
@ 2019-10-18  3:29   ` Paul Walmsley
  2019-10-18 15:25     ` Christoph Hellwig
  0 siblings, 1 reply; 41+ messages in thread
From: Paul Walmsley @ 2019-10-18  3:29 UTC (permalink / raw)
  To: Anup Patel
  Cc: Damien Le Moal, Palmer Dabbelt, Christoph Hellwig, linux-riscv,
	linux-kernel@vger.kernel.org List

On Fri, 18 Oct 2019, Anup Patel wrote:

> It will be really cool to have this series for Linux-5.4-rcX.

It's way too big to go in via the -rc series.  I'm hoping to have it ready 
to go for v5.5-rc1.


- Paul

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: RISC-V nommu support v5
  2019-10-18  3:29   ` Paul Walmsley
@ 2019-10-18 15:25     ` Christoph Hellwig
  2019-10-18 23:46       ` Paul Walmsley
  0 siblings, 1 reply; 41+ messages in thread
From: Christoph Hellwig @ 2019-10-18 15:25 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: Damien Le Moal, Anup Patel, Palmer Dabbelt,
	linux-kernel@vger.kernel.org List, linux-riscv,
	Christoph Hellwig

On Thu, Oct 17, 2019 at 08:29:59PM -0700, Paul Walmsley wrote:
> On Fri, 18 Oct 2019, Anup Patel wrote:
> 
> > It will be really cool to have this series for Linux-5.4-rcX.
> 
> It's way too big to go in via the -rc series.  I'm hoping to have it ready 
> to go for v5.5-rc1.

Yes, this is 5.5 material.  Btw, the buildbot found two issues that
require one liner fixes, so I'll resend again this weekend.

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: RISC-V nommu support v5
  2019-10-18 15:25     ` Christoph Hellwig
@ 2019-10-18 23:46       ` Paul Walmsley
  0 siblings, 0 replies; 41+ messages in thread
From: Paul Walmsley @ 2019-10-18 23:46 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Anup Patel, Damien Le Moal, Palmer Dabbelt, linux-riscv,
	linux-kernel@vger.kernel.org List

On Fri, 18 Oct 2019, Christoph Hellwig wrote:

> On Thu, Oct 17, 2019 at 08:29:59PM -0700, Paul Walmsley wrote:
> > On Fri, 18 Oct 2019, Anup Patel wrote:
> > 
> > > It will be really cool to have this series for Linux-5.4-rcX.
> > 
> > It's way too big to go in via the -rc series.  I'm hoping to have it ready 
> > to go for v5.5-rc1.
> 
> Yes, this is 5.5 material.  Btw, the buildbot found two issues that
> require one liner fixes, so I'll resend again this weekend.

OK, will wait for the next version.

I do have one significant request for the patch "riscv: abstract out CSR 
names for supervisor vs machine mode" for that next release.  Will follow 
up with a comment on that patch.


- Paul

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 03/15] riscv: abstract out CSR names for supervisor vs machine mode
  2019-10-17 17:37 ` [PATCH 03/15] riscv: abstract out CSR names for supervisor vs machine mode Christoph Hellwig
  2019-10-18  2:51   ` Anup Patel
@ 2019-10-18 23:55   ` Paul Walmsley
  2019-10-28  8:12     ` Christoph Hellwig
  1 sibling, 1 reply; 41+ messages in thread
From: Paul Walmsley @ 2019-10-18 23:55 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Atish Patra, Damien Le Moal, Palmer Dabbelt, linux-riscv, linux-kernel

On Thu, 17 Oct 2019, Christoph Hellwig wrote:

> Many of the privileged CSRs exist in a supervisor and machine version
> that are used very similarly.  Provide a new X-naming layer so that
> we don't have to ifdef everywhere for M-mode Linux support.
> 
> Contains contributions from Damien Le Moal <Damien.LeMoal@wdc.com>.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Atish Patra <atish.patra@wdc.com>

The basic idea looks good to me, but some of the X-prefixing can make the 
code difficult to read.  The Xret macro looks fine to me, as do the 
XIE_XTIE macros.  But I think it would be better if the X-prefixes on the 
rest of the macros and structure members could be dropped.  This also 
aligns with the way that these registers often are discussed at the 
architectural level; e.g., we'd talk about the "epc" registers, not the 
"xepc" registers.

Just for reference, your v4 patch with that change implemented is below. 
I've been testing with here.


- Paul

From: Christoph Hellwig <hch@lst.de>
Date: Mon, 19 Aug 2019 12:30:23 +0200
Subject: [PATCH] riscv: abstract out CSR names for supervisor vs machine mode

Many of the privileged CSRs exist in a supervisor and machine version
that are used very similarly.  Provide a new X-naming layer so that
we don't have to ifdef everywhere for M-mode Linux support.

Contains contributions from Damien Le Moal <Damien.LeMoal@wdc.com>.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
[paul.walmsley@sifive.com: removed X in most macros/variables; fixed
 bug in start_thread; updated to apply]
---
 arch/riscv/Kconfig                 |  4 ++
 arch/riscv/include/asm/asm.h       |  6 +++
 arch/riscv/include/asm/csr.h       | 58 ++++++++++++++++++++++++--
 arch/riscv/include/asm/irqflags.h  | 12 +++---
 arch/riscv/include/asm/processor.h |  2 +-
 arch/riscv/include/asm/ptrace.h    | 16 ++++----
 arch/riscv/include/asm/switch_to.h | 10 ++---
 arch/riscv/kernel/asm-offsets.c    |  8 ++--
 arch/riscv/kernel/entry.S          | 66 ++++++++++++++++--------------
 arch/riscv/kernel/fpu.S            |  8 ++--
 arch/riscv/kernel/head.S           | 12 +++---
 arch/riscv/kernel/irq.c            |  4 +-
 arch/riscv/kernel/process.c        | 15 +++----
 arch/riscv/kernel/signal.c         | 21 +++++-----
 arch/riscv/kernel/traps.c          | 18 ++++----
 arch/riscv/lib/uaccess.S           | 12 +++---
 arch/riscv/mm/extable.c            |  4 +-
 arch/riscv/mm/fault.c              |  6 +--
 drivers/clocksource/timer-riscv.c  |  8 ++--
 drivers/irqchip/irq-sifive-plic.c  |  4 +-
 20 files changed, 181 insertions(+), 113 deletions(-)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 8eebbc8860bb..86b7e8b0471c 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -72,6 +72,10 @@ config ARCH_MMAP_RND_BITS_MAX
 	default 24 if 64BIT # SV39 based
 	default 17
 
+# set if we run in machine mode, cleared if we run in supervisor mode
+config RISCV_M_MODE
+	bool
+
 config MMU
 	def_bool y
 
diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
index 9c992a88d858..e362fb741c76 100644
--- a/arch/riscv/include/asm/asm.h
+++ b/arch/riscv/include/asm/asm.h
@@ -66,4 +66,10 @@
 #error "Unexpected __SIZEOF_SHORT__"
 #endif
 
+#ifdef CONFIG_RISCV_M_MODE
+# define Xret		mret
+#else
+# define Xret		sret
+#endif
+
 #endif /* _ASM_RISCV_ASM_H */
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index a18923fa23c8..583be1861ff1 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -11,8 +11,11 @@
 
 /* Status register flags */
 #define SR_SIE		_AC(0x00000002, UL) /* Supervisor Interrupt Enable */
+#define SR_MIE		_AC(0x00000008, UL) /* Machine Interrupt Enable */
 #define SR_SPIE		_AC(0x00000020, UL) /* Previous Supervisor IE */
+#define SR_MPIE		_AC(0x00000080, UL) /* Previous Machine IE */
 #define SR_SPP		_AC(0x00000100, UL) /* Previously Supervisor */
+#define SR_MPP		_AC(0x00001800, UL) /* Previously Machine */
 #define SR_SUM		_AC(0x00040000, UL) /* Supervisor User Memory Access */
 
 #define SR_FS		_AC(0x00006000, UL) /* Floating-point Status */
@@ -44,8 +47,8 @@
 #define SATP_MODE	SATP_MODE_39
 #endif
 
-/* SCAUSE */
-#define SCAUSE_IRQ_FLAG		(_AC(1, UL) << (__riscv_xlen - 1))
+/* *CAUSE */
+#define CAUSE_IRQ_FLAG		(_AC(1, UL) << (__riscv_xlen - 1))
 
 #define IRQ_U_SOFT		0
 #define IRQ_S_SOFT		1
@@ -67,11 +70,26 @@
 #define EXC_LOAD_PAGE_FAULT	13
 #define EXC_STORE_PAGE_FAULT	15
 
-/* SIE (Interrupt Enable) and SIP (Interrupt Pending) flags */
+/* SIE/SIP (Machine Interrupt Enable/Pending) flags */
+#define MIE_MSIE		(_AC(0x1, UL) << IRQ_M_SOFT)
+#define MIE_MTIE		(_AC(0x1, UL) << IRQ_M_TIMER)
+#define MIE_MEIE		(_AC(0x1, UL) << IRQ_M_EXT)
+
+/* SIE/SIP (Supervisor Interrupt Enable/Pending) flags */
 #define SIE_SSIE		(_AC(0x1, UL) << IRQ_S_SOFT)
 #define SIE_STIE		(_AC(0x1, UL) << IRQ_S_TIMER)
 #define SIE_SEIE		(_AC(0x1, UL) << IRQ_S_EXT)
 
+/* symbolic CSR names: */
+#define CSR_MSTATUS		0x300
+#define CSR_MIE			0x304
+#define CSR_MTVEC		0x305
+#define CSR_MSCRATCH		0x340
+#define CSR_MEPC		0x341
+#define CSR_MCAUSE		0x342
+#define CSR_MTVAL		0x343
+#define CSR_MIP			0x344
+
 #define CSR_CYCLE		0xc00
 #define CSR_TIME		0xc01
 #define CSR_INSTRET		0xc02
@@ -89,6 +107,40 @@
 #define CSR_TIMEH		0xc81
 #define CSR_INSTRETH		0xc82
 
+#ifdef CONFIG_RISCV_M_MODE
+# define CSR_STATUS	CSR_MSTATUS
+# define CSR_IE	CSR_MIE
+# define CSR_TVEC	CSR_MTVEC
+# define CSR_SCRATCH	CSR_MSCRATCH
+# define CSR_EPC	CSR_MEPC
+# define CSR_CAUSE	CSR_MCAUSE
+# define CSR_TVAL	CSR_MTVAL
+# define CSR_IP	CSR_MIP
+
+# define SR_IE		SR_MIE
+# define SR_PIE	SR_MPIE
+# define SR_PP		SR_MPP
+
+# define XIE_XTIE	MIE_MTIE
+# define XIE_XEIE	MIE_MEIE
+#else /* CONFIG_RISCV_M_MODE */
+# define CSR_STATUS	CSR_SSTATUS
+# define CSR_IE	CSR_SIE
+# define CSR_TVEC	CSR_STVEC
+# define CSR_SCRATCH	CSR_SSCRATCH
+# define CSR_EPC	CSR_SEPC
+# define CSR_CAUSE	CSR_SCAUSE
+# define CSR_TVAL	CSR_STVAL
+# define CSR_IP	CSR_SIP
+
+# define SR_IE		SR_SIE
+# define SR_PIE	SR_SPIE
+# define SR_PP		SR_SPP
+
+# define XIE_XTIE	SIE_STIE
+# define XIE_XEIE	SIE_SEIE
+#endif /* CONFIG_RISCV_M_MODE */
+
 #ifndef __ASSEMBLY__
 
 #define csr_swap(csr, val)					\
diff --git a/arch/riscv/include/asm/irqflags.h b/arch/riscv/include/asm/irqflags.h
index e70f647ce3b7..08d4d6a5b7e9 100644
--- a/arch/riscv/include/asm/irqflags.h
+++ b/arch/riscv/include/asm/irqflags.h
@@ -13,31 +13,31 @@
 /* read interrupt enabled status */
 static inline unsigned long arch_local_save_flags(void)
 {
-	return csr_read(CSR_SSTATUS);
+	return csr_read(CSR_STATUS);
 }
 
 /* unconditionally enable interrupts */
 static inline void arch_local_irq_enable(void)
 {
-	csr_set(CSR_SSTATUS, SR_SIE);
+	csr_set(CSR_STATUS, SR_IE);
 }
 
 /* unconditionally disable interrupts */
 static inline void arch_local_irq_disable(void)
 {
-	csr_clear(CSR_SSTATUS, SR_SIE);
+	csr_clear(CSR_STATUS, SR_IE);
 }
 
 /* get status and disable interrupts */
 static inline unsigned long arch_local_irq_save(void)
 {
-	return csr_read_clear(CSR_SSTATUS, SR_SIE);
+	return csr_read_clear(CSR_STATUS, SR_IE);
 }
 
 /* test flags */
 static inline int arch_irqs_disabled_flags(unsigned long flags)
 {
-	return !(flags & SR_SIE);
+	return !(flags & SR_IE);
 }
 
 /* test hardware interrupt enable bit */
@@ -49,7 +49,7 @@ static inline int arch_irqs_disabled(void)
 /* set interrupt enabled status */
 static inline void arch_local_irq_restore(unsigned long flags)
 {
-	csr_set(CSR_SSTATUS, flags & SR_SIE);
+	csr_set(CSR_STATUS, flags & SR_IE);
 }
 
 #endif /* _ASM_RISCV_IRQFLAGS_H */
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index f539149d04c2..3ddb798264f1 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -42,7 +42,7 @@ struct thread_struct {
 	((struct pt_regs *)(task_stack_page(tsk) + THREAD_SIZE		\
 			    - ALIGN(sizeof(struct pt_regs), STACK_ALIGN)))
 
-#define KSTK_EIP(tsk)		(task_pt_regs(tsk)->sepc)
+#define KSTK_EIP(tsk)		(task_pt_regs(tsk)->epc)
 #define KSTK_ESP(tsk)		(task_pt_regs(tsk)->sp)
 
 
diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h
index d48d1e13973c..ee49f80c9533 100644
--- a/arch/riscv/include/asm/ptrace.h
+++ b/arch/riscv/include/asm/ptrace.h
@@ -12,7 +12,7 @@
 #ifndef __ASSEMBLY__
 
 struct pt_regs {
-	unsigned long sepc;
+	unsigned long epc;
 	unsigned long ra;
 	unsigned long sp;
 	unsigned long gp;
@@ -44,10 +44,10 @@ struct pt_regs {
 	unsigned long t4;
 	unsigned long t5;
 	unsigned long t6;
-	/* Supervisor CSRs */
-	unsigned long sstatus;
-	unsigned long sbadaddr;
-	unsigned long scause;
+	/* Supervisor/Machine CSRs */
+	unsigned long status;
+	unsigned long badaddr;
+	unsigned long cause;
 	/* a0 value before the syscall */
 	unsigned long orig_a0;
 };
@@ -58,18 +58,18 @@ struct pt_regs {
 #define REG_FMT "%08lx"
 #endif
 
-#define user_mode(regs) (((regs)->sstatus & SR_SPP) == 0)
+#define user_mode(regs) (((regs)->status & SR_PP) == 0)
 
 
 /* Helpers for working with the instruction pointer */
 static inline unsigned long instruction_pointer(struct pt_regs *regs)
 {
-	return regs->sepc;
+	return regs->epc;
 }
 static inline void instruction_pointer_set(struct pt_regs *regs,
 					   unsigned long val)
 {
-	regs->sepc = val;
+	regs->epc = val;
 }
 
 #define profile_pc(regs) instruction_pointer(regs)
diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
index f0227bdce0f0..8b5c5c8c36fa 100644
--- a/arch/riscv/include/asm/switch_to.h
+++ b/arch/riscv/include/asm/switch_to.h
@@ -16,19 +16,19 @@ extern void __fstate_restore(struct task_struct *restore_from);
 
 static inline void __fstate_clean(struct pt_regs *regs)
 {
-	regs->sstatus = (regs->sstatus & ~SR_FS) | SR_FS_CLEAN;
+	regs->status = (regs->status & ~SR_FS) | SR_FS_CLEAN;
 }
 
 static inline void fstate_off(struct task_struct *task,
 			      struct pt_regs *regs)
 {
-	regs->sstatus = (regs->sstatus & ~SR_FS) | SR_FS_OFF;
+	regs->status = (regs->status & ~SR_FS) | SR_FS_OFF;
 }
 
 static inline void fstate_save(struct task_struct *task,
 			       struct pt_regs *regs)
 {
-	if ((regs->sstatus & SR_FS) == SR_FS_DIRTY) {
+	if ((regs->status & SR_FS) == SR_FS_DIRTY) {
 		__fstate_save(task);
 		__fstate_clean(regs);
 	}
@@ -37,7 +37,7 @@ static inline void fstate_save(struct task_struct *task,
 static inline void fstate_restore(struct task_struct *task,
 				  struct pt_regs *regs)
 {
-	if ((regs->sstatus & SR_FS) != SR_FS_OFF) {
+	if ((regs->status & SR_FS) != SR_FS_OFF) {
 		__fstate_restore(task);
 		__fstate_clean(regs);
 	}
@@ -49,7 +49,7 @@ static inline void __switch_to_aux(struct task_struct *prev,
 	struct pt_regs *regs;
 
 	regs = task_pt_regs(prev);
-	if (unlikely(regs->sstatus & SR_SD))
+	if (unlikely(regs->status & SR_SD))
 		fstate_save(prev, regs);
 	fstate_restore(next, task_pt_regs(next));
 }
diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
index 9f5628c38ac9..07cb9c10de4e 100644
--- a/arch/riscv/kernel/asm-offsets.c
+++ b/arch/riscv/kernel/asm-offsets.c
@@ -71,7 +71,7 @@ void asm_offsets(void)
 	OFFSET(TASK_THREAD_FCSR, task_struct, thread.fstate.fcsr);
 
 	DEFINE(PT_SIZE, sizeof(struct pt_regs));
-	OFFSET(PT_SEPC, pt_regs, sepc);
+	OFFSET(PT_EPC, pt_regs, epc);
 	OFFSET(PT_RA, pt_regs, ra);
 	OFFSET(PT_FP, pt_regs, s0);
 	OFFSET(PT_S0, pt_regs, s0);
@@ -105,9 +105,9 @@ void asm_offsets(void)
 	OFFSET(PT_T6, pt_regs, t6);
 	OFFSET(PT_GP, pt_regs, gp);
 	OFFSET(PT_ORIG_A0, pt_regs, orig_a0);
-	OFFSET(PT_SSTATUS, pt_regs, sstatus);
-	OFFSET(PT_SBADADDR, pt_regs, sbadaddr);
-	OFFSET(PT_SCAUSE, pt_regs, scause);
+	OFFSET(PT_STATUS, pt_regs, status);
+	OFFSET(PT_BADADDR, pt_regs, badaddr);
+	OFFSET(PT_CAUSE, pt_regs, cause);
 
 	/*
 	 * THREAD_{F,X}* might be larger than a S-type offset can handle, but
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 8ca479831142..6a5bd4ba5ed8 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -26,14 +26,14 @@
 
 	/*
 	 * If coming from userspace, preserve the user thread pointer and load
-	 * the kernel thread pointer.  If we came from the kernel, sscratch
-	 * will contain 0, and we should continue on the current TP.
+	 * the kernel thread pointer.  If we came from the kernel, the scratch
+	 * register will contain 0, and we should continue on the current TP.
 	 */
-	csrrw tp, CSR_SSCRATCH, tp
+	csrrw tp, CSR_SCRATCH, tp
 	bnez tp, _save_context
 
 _restore_kernel_tpsp:
-	csrr tp, CSR_SSCRATCH
+	csrr tp, CSR_SCRATCH
 	REG_S sp, TASK_TI_KERNEL_SP(tp)
 _save_context:
 	REG_S sp, TASK_TI_USER_SP(tp)
@@ -79,16 +79,16 @@ _save_context:
 	li t0, SR_SUM | SR_FS
 
 	REG_L s0, TASK_TI_USER_SP(tp)
-	csrrc s1, CSR_SSTATUS, t0
-	csrr s2, CSR_SEPC
-	csrr s3, CSR_STVAL
-	csrr s4, CSR_SCAUSE
-	csrr s5, CSR_SSCRATCH
+	csrrc s1, CSR_STATUS, t0
+	csrr s2, CSR_EPC
+	csrr s3, CSR_TVAL
+	csrr s4, CSR_CAUSE
+	csrr s5, CSR_SCRATCH
 	REG_S s0, PT_SP(sp)
-	REG_S s1, PT_SSTATUS(sp)
-	REG_S s2, PT_SEPC(sp)
-	REG_S s3, PT_SBADADDR(sp)
-	REG_S s4, PT_SCAUSE(sp)
+	REG_S s1, PT_STATUS(sp)
+	REG_S s2, PT_EPC(sp)
+	REG_S s3, PT_BADADDR(sp)
+	REG_S s4, PT_CAUSE(sp)
 	REG_S s5, PT_TP(sp)
 	.endm
 
@@ -97,7 +97,7 @@ _save_context:
  * registers from the stack.
  */
 	.macro RESTORE_ALL
-	REG_L a0, PT_SSTATUS(sp)
+	REG_L a0, PT_STATUS(sp)
 	/*
 	 * The current load reservation is effectively part of the processor's
 	 * state, in the sense that load reservations cannot be shared between
@@ -115,11 +115,11 @@ _save_context:
 	 * completes, implementations are allowed to expand reservations to be
 	 * arbitrarily large.
 	 */
-	REG_L  a2, PT_SEPC(sp)
-	REG_SC x0, a2, PT_SEPC(sp)
+	REG_L  a2, PT_EPC(sp)
+	REG_SC x0, a2, PT_EPC(sp)
 
-	csrw CSR_SSTATUS, a0
-	csrw CSR_SEPC, a2
+	csrw CSR_STATUS, a0
+	csrw CSR_EPC, a2
 
 	REG_L x1,  PT_RA(sp)
 	REG_L x3,  PT_GP(sp)
@@ -163,10 +163,10 @@ ENTRY(handle_exception)
 	SAVE_ALL
 
 	/*
-	 * Set sscratch register to 0, so that if a recursive exception
+	 * Set the scratch register to 0, so that if a recursive exception
 	 * occurs, the exception vector knows it came from the kernel
 	 */
-	csrw CSR_SSCRATCH, x0
+	csrw CSR_SCRATCH, x0
 
 	/* Load the global pointer */
 .option push
@@ -187,9 +187,9 @@ ENTRY(handle_exception)
 1:
 	/* Exceptions run with interrupts enabled or disabled
 	   depending on the state of sstatus.SR_SPIE */
-	andi t0, s1, SR_SPIE
+	andi t0, s1, SR_PIE
 	beqz t0, 1f
-	csrs CSR_SSTATUS, SR_SIE
+	csrs CSR_STATUS, SR_IE
 
 1:
 	/* Handle syscalls */
@@ -217,7 +217,7 @@ handle_syscall:
 	 * scall instruction on sret
 	 */
 	addi s2, s2, 0x4
-	REG_S s2, PT_SEPC(sp)
+	REG_S s2, PT_EPC(sp)
 	/* Trace syscalls, but only if requested by the user. */
 	REG_L t0, TASK_TI_FLAGS(tp)
 	andi t0, t0, _TIF_SYSCALL_WORK
@@ -244,9 +244,15 @@ ret_from_syscall:
 	bnez t0, handle_syscall_trace_exit
 
 ret_from_exception:
-	REG_L s0, PT_SSTATUS(sp)
-	csrc CSR_SSTATUS, SR_SIE
+	REG_L s0, PT_STATUS(sp)
+	csrc CSR_STATUS, SR_IE
+#ifdef CONFIG_RISCV_M_MODE
+	/* the MPP value is too large to be used as an immediate arg for addi */
+	li t0, SR_MPP
+	and s0, s0, t0
+#else
 	andi s0, s0, SR_SPP
+#endif
 	bnez s0, resume_kernel
 
 resume_userspace:
@@ -260,14 +266,14 @@ resume_userspace:
 	REG_S s0, TASK_TI_KERNEL_SP(tp)
 
 	/*
-	 * Save TP into sscratch, so we can find the kernel data structures
-	 * again.
+	 * Save TP into the scratch register , so we can find the kernel data
+	 * structures again.
 	 */
-	csrw CSR_SSCRATCH, tp
+	csrw CSR_SCRATCH, tp
 
 restore_all:
 	RESTORE_ALL
-	sret
+	Xret
 
 #if IS_ENABLED(CONFIG_PREEMPT)
 resume_kernel:
@@ -287,7 +293,7 @@ work_pending:
 	bnez s1, work_resched
 work_notifysig:
 	/* Handle pending signals and notify-resume requests */
-	csrs CSR_SSTATUS, SR_SIE /* Enable interrupts for do_notify_resume() */
+	csrs CSR_STATUS, SR_IE /* Enable interrupts for do_notify_resume() */
 	move a0, sp /* pt_regs */
 	move a1, s0 /* current_thread_info->flags */
 	tail do_notify_resume
diff --git a/arch/riscv/kernel/fpu.S b/arch/riscv/kernel/fpu.S
index 631d31540660..dd2205473de7 100644
--- a/arch/riscv/kernel/fpu.S
+++ b/arch/riscv/kernel/fpu.S
@@ -23,7 +23,7 @@ ENTRY(__fstate_save)
 	li  a2,  TASK_THREAD_F0
 	add a0, a0, a2
 	li t1, SR_FS
-	csrs CSR_SSTATUS, t1
+	csrs CSR_STATUS, t1
 	frcsr t0
 	fsd f0,  TASK_THREAD_F0_F0(a0)
 	fsd f1,  TASK_THREAD_F1_F0(a0)
@@ -58,7 +58,7 @@ ENTRY(__fstate_save)
 	fsd f30, TASK_THREAD_F30_F0(a0)
 	fsd f31, TASK_THREAD_F31_F0(a0)
 	sw t0, TASK_THREAD_FCSR_F0(a0)
-	csrc CSR_SSTATUS, t1
+	csrc CSR_STATUS, t1
 	ret
 ENDPROC(__fstate_save)
 
@@ -67,7 +67,7 @@ ENTRY(__fstate_restore)
 	add a0, a0, a2
 	li t1, SR_FS
 	lw t0, TASK_THREAD_FCSR_F0(a0)
-	csrs CSR_SSTATUS, t1
+	csrs CSR_STATUS, t1
 	fld f0,  TASK_THREAD_F0_F0(a0)
 	fld f1,  TASK_THREAD_F1_F0(a0)
 	fld f2,  TASK_THREAD_F2_F0(a0)
@@ -101,6 +101,6 @@ ENTRY(__fstate_restore)
 	fld f30, TASK_THREAD_F30_F0(a0)
 	fld f31, TASK_THREAD_F31_F0(a0)
 	fscsr t0
-	csrc CSR_SSTATUS, t1
+	csrc CSR_STATUS, t1
 	ret
 ENDPROC(__fstate_restore)
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 72f89b7590dd..5cfd2c582945 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -47,8 +47,8 @@ ENTRY(_start)
 .global _start_kernel
 _start_kernel:
 	/* Mask all interrupts */
-	csrw CSR_SIE, zero
-	csrw CSR_SIP, zero
+	csrw CSR_IE, zero
+	csrw CSR_IP, zero
 
 	/* Load the global pointer */
 .option push
@@ -61,7 +61,7 @@ _start_kernel:
 	 * floating point in kernel space
 	 */
 	li t0, SR_FS
-	csrc CSR_SSTATUS, t0
+	csrc CSR_STATUS, t0
 
 #ifdef CONFIG_SMP
 	li t0, CONFIG_NR_CPUS
@@ -116,7 +116,7 @@ relocate:
 	/* Point stvec to virtual address of intruction after satp write */
 	la a2, 1f
 	add a2, a2, a1
-	csrw CSR_STVEC, a2
+	csrw CSR_TVEC, a2
 
 	/* Compute satp for kernel page tables, but don't load it yet */
 	srl a2, a0, PAGE_SHIFT
@@ -138,7 +138,7 @@ relocate:
 1:
 	/* Set trap vector to spin forever to help debug */
 	la a0, .Lsecondary_park
-	csrw CSR_STVEC, a0
+	csrw CSR_TVEC, a0
 
 	/* Reload the global pointer */
 .option push
@@ -161,7 +161,7 @@ relocate:
 #ifdef CONFIG_SMP
 	/* Set trap vector to spin forever to help debug */
 	la a3, .Lsecondary_park
-	csrw CSR_STVEC, a3
+	csrw CSR_TVEC, a3
 
 	slli a3, a0, LGREG
 	la a1, __cpu_up_stack_pointer
diff --git a/arch/riscv/kernel/irq.c b/arch/riscv/kernel/irq.c
index 6d8659388c49..af942e17629c 100644
--- a/arch/riscv/kernel/irq.c
+++ b/arch/riscv/kernel/irq.c
@@ -29,7 +29,7 @@ asmlinkage void __irq_entry do_IRQ(struct pt_regs *regs)
 	struct pt_regs *old_regs = set_irq_regs(regs);
 
 	irq_enter();
-	switch (regs->scause & ~SCAUSE_IRQ_FLAG) {
+	switch (regs->cause & ~CAUSE_IRQ_FLAG) {
 	case INTERRUPT_CAUSE_TIMER:
 		riscv_timer_interrupt();
 		break;
@@ -46,7 +46,7 @@ asmlinkage void __irq_entry do_IRQ(struct pt_regs *regs)
 		handle_arch_irq(regs);
 		break;
 	default:
-		pr_alert("unexpected interrupt cause 0x%lx", regs->scause);
+		pr_alert("unexpected interrupt cause 0x%lx", regs->cause);
 		BUG();
 	}
 	irq_exit();
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index fb3a082362eb..4e78b062470c 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -34,7 +34,7 @@ void show_regs(struct pt_regs *regs)
 	show_regs_print_info(KERN_DEFAULT);
 
 	pr_cont("sepc: " REG_FMT " ra : " REG_FMT " sp : " REG_FMT "\n",
-		regs->sepc, regs->ra, regs->sp);
+		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",
@@ -56,23 +56,23 @@ void show_regs(struct pt_regs *regs)
 	pr_cont(" t5 : " REG_FMT " t6 : " REG_FMT "\n",
 		regs->t5, regs->t6);
 
-	pr_cont("sstatus: " REG_FMT " sbadaddr: " REG_FMT " scause: " REG_FMT "\n",
-		regs->sstatus, regs->sbadaddr, regs->scause);
+	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->sstatus = SR_SPIE;
+	regs->status = SR_PIE;
 	if (has_fpu) {
-		regs->sstatus |= SR_FS_INITIAL;
+		regs->status |= SR_FS_INITIAL;
 		/*
 		 * Restore the initial value to the FP register
 		 * before starting the user program.
 		 */
 		fstate_restore(current, regs);
 	}
-	regs->sepc = pc;
+	regs->epc = pc;
 	regs->sp = sp;
 	set_fs(USER_DS);
 }
@@ -108,7 +108,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
 		const register unsigned long gp __asm__ ("gp");
 		memset(childregs, 0, sizeof(struct pt_regs));
 		childregs->gp = gp;
-		childregs->sstatus = SR_SPP | SR_SPIE; /* Supervisor, irqs on */
+		/* 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 */
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index b14d7647d800..c639d517bc03 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -124,7 +124,7 @@ SYSCALL_DEFINE0(rt_sigreturn)
 		pr_info_ratelimited(
 			"%s[%d]: bad frame in %s: frame=%p pc=%p sp=%p\n",
 			task->comm, task_pid_nr(task), __func__,
-			frame, (void *)regs->sepc, (void *)regs->sp);
+			frame, (void *)regs->epc, (void *)regs->sp);
 	}
 	force_sig(SIGSEGV);
 	return 0;
@@ -199,7 +199,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 	 * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
 	 * since some things rely on this (e.g. glibc's debug/segfault.c).
 	 */
-	regs->sepc = (unsigned long)ksig->ka.sa.sa_handler;
+	regs->epc = (unsigned long)ksig->ka.sa.sa_handler;
 	regs->sp = (unsigned long)frame;
 	regs->a0 = ksig->sig;                     /* a0: signal number */
 	regs->a1 = (unsigned long)(&frame->info); /* a1: siginfo pointer */
@@ -208,7 +208,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 #if DEBUG_SIG
 	pr_info("SIG deliver (%s:%d): sig=%d pc=%p ra=%p sp=%p\n",
 		current->comm, task_pid_nr(current), ksig->sig,
-		(void *)regs->sepc, (void *)regs->ra, frame);
+		(void *)regs->epc, (void *)regs->ra, frame);
 #endif
 
 	return 0;
@@ -220,10 +220,9 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 	int ret;
 
 	/* Are we from a system call? */
-	if (regs->scause == EXC_SYSCALL) {
+	if (regs->cause == EXC_SYSCALL) {
 		/* Avoid additional syscall restarting via ret_from_exception */
-		regs->scause = -1UL;
-
+		regs->cause = -1UL;
 		/* If so, check system call restarting.. */
 		switch (regs->a0) {
 		case -ERESTART_RESTARTBLOCK:
@@ -239,7 +238,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 			/* fallthrough */
 		case -ERESTARTNOINTR:
                         regs->a0 = regs->orig_a0;
-			regs->sepc -= 0x4;
+			regs->epc -= 0x4;
 			break;
 		}
 	}
@@ -261,9 +260,9 @@ static void do_signal(struct pt_regs *regs)
 	}
 
 	/* Did we come from a system call? */
-	if (regs->scause == EXC_SYSCALL) {
+	if (regs->cause == EXC_SYSCALL) {
 		/* Avoid additional syscall restarting via ret_from_exception */
-		regs->scause = -1UL;
+		regs->cause = -1UL;
 
 		/* Restart the system call - no handlers present */
 		switch (regs->a0) {
@@ -271,12 +270,12 @@ static void do_signal(struct pt_regs *regs)
 		case -ERESTARTSYS:
 		case -ERESTARTNOINTR:
                         regs->a0 = regs->orig_a0;
-			regs->sepc -= 0x4;
+			regs->epc -= 0x4;
 			break;
 		case -ERESTART_RESTARTBLOCK:
                         regs->a0 = regs->orig_a0;
 			regs->a7 = __NR_restart_syscall;
-			regs->sepc -= 0x4;
+			regs->epc -= 0x4;
 			break;
 		}
 	}
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 93742df9067f..b2405c11bf5f 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -40,7 +40,7 @@ void die(struct pt_regs *regs, const char *str)
 	print_modules();
 	show_regs(regs);
 
-	ret = notify_die(DIE_OOPS, str, regs, 0, regs->scause, SIGSEGV);
+	ret = notify_die(DIE_OOPS, str, regs, 0, regs->cause, SIGSEGV);
 
 	bust_spinlocks(0);
 	add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
@@ -85,7 +85,7 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code,
 #define DO_ERROR_INFO(name, signo, code, str)				\
 asmlinkage void name(struct pt_regs *regs)				\
 {									\
-	do_trap_error(regs, signo, code, regs->sepc, "Oops - " str);	\
+	do_trap_error(regs, signo, code, regs->epc, "Oops - " str);	\
 }
 
 DO_ERROR_INFO(do_trap_unknown,
@@ -127,12 +127,12 @@ asmlinkage void do_trap_break(struct pt_regs *regs)
 	if (!user_mode(regs)) {
 		enum bug_trap_type type;
 
-		type = report_bug(regs->sepc, regs);
+		type = report_bug(regs->epc, regs);
 		switch (type) {
 #ifdef CONFIG_GENERIC_BUG
 		case BUG_TRAP_TYPE_WARN:
-			regs->sepc += get_break_insn_length(regs->sepc);
-			return;
+			regs->epc += get_break_insn_length(regs->epc);
+			break;
 		case BUG_TRAP_TYPE_BUG:
 #endif /* CONFIG_GENERIC_BUG */
 		default:
@@ -140,7 +140,7 @@ asmlinkage void do_trap_break(struct pt_regs *regs)
 		}
 	} else {
 		force_sig_fault(SIGTRAP, TRAP_BRKPT,
-				(void __user *)(regs->sepc));
+				(void __user *)(regs->epc));
 	}
 }
 
@@ -166,9 +166,9 @@ void __init trap_init(void)
 	 * Set sup0 scratch register to 0, indicating to exception vector
 	 * that we are presently executing in the kernel
 	 */
-	csr_write(CSR_SSCRATCH, 0);
+	csr_write(CSR_SCRATCH, 0);
 	/* Set the exception vector address */
-	csr_write(CSR_STVEC, &handle_exception);
+	csr_write(CSR_TVEC, &handle_exception);
 	/* Enable all interrupts */
-	csr_write(CSR_SIE, -1);
+	csr_write(CSR_IE, -1);
 }
diff --git a/arch/riscv/lib/uaccess.S b/arch/riscv/lib/uaccess.S
index ed2696c0143d..fecd65657a6f 100644
--- a/arch/riscv/lib/uaccess.S
+++ b/arch/riscv/lib/uaccess.S
@@ -18,7 +18,7 @@ ENTRY(__asm_copy_from_user)
 
 	/* Enable access to user memory */
 	li t6, SR_SUM
-	csrs CSR_SSTATUS, t6
+	csrs CSR_STATUS, t6
 
 	add a3, a1, a2
 	/* Use word-oriented copy only if low-order bits match */
@@ -47,7 +47,7 @@ ENTRY(__asm_copy_from_user)
 
 3:
 	/* Disable access to user memory */
-	csrc CSR_SSTATUS, t6
+	csrc CSR_STATUS, t6
 	li a0, 0
 	ret
 4: /* Edge case: unalignment */
@@ -72,7 +72,7 @@ ENTRY(__clear_user)
 
 	/* Enable access to user memory */
 	li t6, SR_SUM
-	csrs CSR_SSTATUS, t6
+	csrs CSR_STATUS, t6
 
 	add a3, a0, a1
 	addi t0, a0, SZREG-1
@@ -94,7 +94,7 @@ ENTRY(__clear_user)
 
 3:
 	/* Disable access to user memory */
-	csrc CSR_SSTATUS, t6
+	csrc CSR_STATUS, t6
 	li a0, 0
 	ret
 4: /* Edge case: unalignment */
@@ -114,11 +114,11 @@ ENDPROC(__clear_user)
 	/* Fixup code for __copy_user(10) and __clear_user(11) */
 10:
 	/* Disable access to user memory */
-	csrs CSR_SSTATUS, t6
+	csrs CSR_STATUS, t6
 	mv a0, a2
 	ret
 11:
-	csrs CSR_SSTATUS, t6
+	csrs CSR_STATUS, t6
 	mv a0, a1
 	ret
 	.previous
diff --git a/arch/riscv/mm/extable.c b/arch/riscv/mm/extable.c
index 7aed9178d365..2fc729422151 100644
--- a/arch/riscv/mm/extable.c
+++ b/arch/riscv/mm/extable.c
@@ -15,9 +15,9 @@ int fixup_exception(struct pt_regs *regs)
 {
 	const struct exception_table_entry *fixup;
 
-	fixup = search_exception_tables(regs->sepc);
+	fixup = search_exception_tables(regs->epc);
 	if (fixup) {
-		regs->sepc = fixup->fixup;
+		regs->epc = fixup->fixup;
 		return 1;
 	}
 	return 0;
diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c
index 96add1427a75..081fab3fbda9 100644
--- a/arch/riscv/mm/fault.c
+++ b/arch/riscv/mm/fault.c
@@ -32,8 +32,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs)
 	int code = SEGV_MAPERR;
 	vm_fault_t fault;
 
-	cause = regs->scause;
-	addr = regs->sbadaddr;
+	cause = regs->cause;
+	addr = regs->badaddr;
 
 	tsk = current;
 	mm = tsk->mm;
@@ -51,7 +51,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs)
 		goto vmalloc_fault;
 
 	/* Enable interrupts if they were enabled in the parent context. */
-	if (likely(regs->sstatus & SR_SPIE))
+	if (likely(regs->status & SR_PIE))
 		local_irq_enable();
 
 	/*
diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
index 470c7ef02ea4..d4852af315c2 100644
--- a/drivers/clocksource/timer-riscv.c
+++ b/drivers/clocksource/timer-riscv.c
@@ -19,7 +19,7 @@
 static int riscv_clock_next_event(unsigned long delta,
 		struct clock_event_device *ce)
 {
-	csr_set(sie, SIE_STIE);
+	csr_set(CSR_IE, XIE_XTIE);
 	sbi_set_timer(get_cycles64() + delta);
 	return 0;
 }
@@ -61,13 +61,13 @@ static int riscv_timer_starting_cpu(unsigned int cpu)
 	ce->cpumask = cpumask_of(cpu);
 	clockevents_config_and_register(ce, riscv_timebase, 100, 0x7fffffff);
 
-	csr_set(sie, SIE_STIE);
+	csr_set(CSR_IE, XIE_XTIE);
 	return 0;
 }
 
 static int riscv_timer_dying_cpu(unsigned int cpu)
 {
-	csr_clear(sie, SIE_STIE);
+	csr_clear(CSR_IE, XIE_XTIE);
 	return 0;
 }
 
@@ -76,7 +76,7 @@ void riscv_timer_interrupt(void)
 {
 	struct clock_event_device *evdev = this_cpu_ptr(&riscv_clock_event);
 
-	csr_clear(sie, SIE_STIE);
+	csr_clear(CSR_IE, XIE_XTIE);
 	evdev->event_handler(evdev);
 }
 
diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index c72c036aea76..067c6cf38620 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -179,7 +179,7 @@ static void plic_handle_irq(struct pt_regs *regs)
 
 	WARN_ON_ONCE(!handler->present);
 
-	csr_clear(sie, SIE_SEIE);
+	csr_clear(CSR_IE, XIE_XEIE);
 	while ((hwirq = readl(claim))) {
 		int irq = irq_find_mapping(plic_irqdomain, hwirq);
 
@@ -190,7 +190,7 @@ static void plic_handle_irq(struct pt_regs *regs)
 			generic_handle_irq(irq);
 		writel(hwirq, claim);
 	}
-	csr_set(sie, SIE_SEIE);
+	csr_set(CSR_IE, XIE_XEIE);
 }
 
 /*
-- 
2.23.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH 01/15] riscv: cleanup <asm/bug.h>
  2019-10-17 17:37 ` [PATCH 01/15] riscv: cleanup <asm/bug.h> Christoph Hellwig
  2019-10-18  2:50   ` Anup Patel
@ 2019-10-23 22:04   ` Paul Walmsley
  1 sibling, 0 replies; 41+ messages in thread
From: Paul Walmsley @ 2019-10-23 22:04 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Damien Le Moal, Palmer Dabbelt, linux-riscv, linux-kernel

On Thu, 17 Oct 2019, Christoph Hellwig wrote:

> Remove various not required ifdefs and externs.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Thanks, queued for v5.4-rc.


- Paul

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 02/15] riscv: cleanup do_trap_break
  2019-10-17 17:37 ` [PATCH 02/15] riscv: cleanup do_trap_break Christoph Hellwig
  2019-10-18  2:51   ` Anup Patel
@ 2019-10-23 22:05   ` Paul Walmsley
  1 sibling, 0 replies; 41+ messages in thread
From: Paul Walmsley @ 2019-10-23 22:05 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Damien Le Moal, Palmer Dabbelt, linux-riscv, linux-kernel

On Thu, 17 Oct 2019, Christoph Hellwig wrote:

> If we always compile the get_break_insn_length inline function we can
> remove the ifdefs and let dead code elimination take care of the warn
> branch that is now unreadable because the report_bug stub always
> returns BUG_TRAP_TYPE_BUG.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Thanks, queued for v5.4-rc.


- Paul

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 03/15] riscv: abstract out CSR names for supervisor vs machine mode
  2019-10-18 23:55   ` Paul Walmsley
@ 2019-10-28  8:12     ` Christoph Hellwig
  0 siblings, 0 replies; 41+ messages in thread
From: Christoph Hellwig @ 2019-10-28  8:12 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: Damien Le Moal, Palmer Dabbelt, linux-kernel, Atish Patra,
	linux-riscv, Christoph Hellwig

On Fri, Oct 18, 2019 at 04:55:02PM -0700, Paul Walmsley wrote:
> The basic idea looks good to me, but some of the X-prefixing can make the 
> code difficult to read.  The Xret macro looks fine to me, as do the 
> XIE_XTIE macros.  But I think it would be better if the X-prefixes on the 
> rest of the macros and structure members could be dropped.  This also 
> aligns with the way that these registers often are discussed at the 
> architectural level; e.g., we'd talk about the "epc" registers, not the 
> "xepc" registers.

If we get of the x we should get rid of all of them.  I'll make sure it
is all gone for the next version.

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 09/15] riscv: provide native clint access for M-mode
  2019-10-17 17:37 ` [PATCH 09/15] riscv: provide native clint access for M-mode Christoph Hellwig
  2019-10-18  3:00   ` Anup Patel
@ 2019-11-14  7:39   ` Paul Walmsley
  1 sibling, 0 replies; 41+ messages in thread
From: Paul Walmsley @ 2019-11-14  7:39 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Damien Le Moal, Palmer Dabbelt, linux-riscv, linux-kernel

On Thu, 17 Oct 2019, Christoph Hellwig wrote:

> RISC-V has the concept of a cpu level interrupt controller.  The
> interface for it is split between a standardized part that is exposed
> as bits in the mstatus/sstatus register and the mie/mip/sie/sip
> CRS.  But the bit to actually trigger IPIs is not standardized and
> just mentioned as implementable using MMIO.
> 
> Add support for IPIs using MMIO using the SiFive clint layout (which is
> also shared by Ariane, Kendrye and the Qemu virt platform).  Additional
> the MMIO block also support the time value and timer compare registers,
> so they are also set up using the same OF node.  Support for other
> layouts should also be relatively easy to add in the future.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Thanks, queued the following for v5.5-rc1.


- Paul

From: Christoph Hellwig <hch@lst.de>
Date: Mon, 28 Oct 2019 13:10:38 +0100
Subject: [PATCH] riscv: provide native clint access for M-mode

RISC-V has the concept of a cpu level interrupt controller.  The
interface for it is split between a standardized part that is exposed
as bits in the mstatus/sstatus register and the mie/mip/sie/sip
CRS.  But the bit to actually trigger IPIs is not standardized and
just mentioned as implementable using MMIO.

Add support for IPIs using MMIO using the SiFive clint layout (which
is also shared by Ariane, Kendryte and the Qemu virt platform).
Additionally the MMIO block also supports the time value and timer
compare registers, so they are also set up using the same OF node.
Support for other layouts should also be relatively easy to add in the
future.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Anup Patel <anup@brainfault.org>
[paul.walmsley@sifive.com: update include guard format; fix checkpatch
 issues; minor commit message cleanups]
Signed-off-by: Paul Walmsley <paul.walmsley@sifive.com>
---
 arch/riscv/include/asm/clint.h | 39 ++++++++++++++++++++++++++++++
 arch/riscv/include/asm/sbi.h   |  2 ++
 arch/riscv/kernel/Makefile     |  1 +
 arch/riscv/kernel/clint.c      | 44 ++++++++++++++++++++++++++++++++++
 arch/riscv/kernel/setup.c      |  2 ++
 arch/riscv/kernel/smp.c        | 16 ++++++++++---
 arch/riscv/kernel/smpboot.c    |  4 ++++
 7 files changed, 105 insertions(+), 3 deletions(-)
 create mode 100644 arch/riscv/include/asm/clint.h
 create mode 100644 arch/riscv/kernel/clint.c

diff --git a/arch/riscv/include/asm/clint.h b/arch/riscv/include/asm/clint.h
new file mode 100644
index 000000000000..6eaa2eedd694
--- /dev/null
+++ b/arch/riscv/include/asm/clint.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_RISCV_CLINT_H
+#define _ASM_RISCV_CLINT_H 1
+
+#include <linux/io.h>
+#include <linux/smp.h>
+
+#ifdef CONFIG_RISCV_M_MODE
+extern u32 __iomem *clint_ipi_base;
+
+void clint_init_boot_cpu(void);
+
+static inline void clint_send_ipi_single(unsigned long hartid)
+{
+	writel(1, clint_ipi_base + hartid);
+}
+
+static inline void clint_send_ipi_mask(const struct cpumask *hartid_mask)
+{
+	int hartid;
+
+	for_each_cpu(hartid, hartid_mask)
+		clint_send_ipi_single(hartid);
+}
+
+static inline void clint_clear_ipi(unsigned long hartid)
+{
+	writel(0, clint_ipi_base + hartid);
+}
+#else /* CONFIG_RISCV_M_MODE */
+#define clint_init_boot_cpu()	do { } while (0)
+
+/* stubs to for code is only reachable under IS_ENABLED(CONFIG_RISCV_M_MODE): */
+void clint_send_ipi_single(unsigned long hartid);
+void clint_send_ipi_mask(const struct cpumask *hartid_mask);
+void clint_clear_ipi(unsigned long hartid);
+#endif /* CONFIG_RISCV_M_MODE */
+
+#endif /* _ASM_RISCV_CLINT_H */
diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index 8e14d4819d0f..2570c1e683d3 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -97,6 +97,8 @@ static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
 #else /* CONFIG_RISCV_SBI */
 /* stubs for code that is only reachable under IS_ENABLED(CONFIG_RISCV_SBI): */
 void sbi_set_timer(uint64_t stime_value);
+void sbi_clear_ipi(void);
+void sbi_send_ipi(const unsigned long *hart_mask);
 void sbi_remote_fence_i(const unsigned long *hart_mask);
 #endif /* CONFIG_RISCV_SBI */
 #endif /* _ASM_RISCV_SBI_H */
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index d8c35fa93cc6..2dca51046899 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -29,6 +29,7 @@ obj-y	+= vdso.o
 obj-y	+= cacheinfo.o
 obj-y	+= vdso/
 
+obj-$(CONFIG_RISCV_M_MODE)	+= clint.o
 obj-$(CONFIG_FPU)		+= fpu.o
 obj-$(CONFIG_SMP)		+= smpboot.o
 obj-$(CONFIG_SMP)		+= smp.o
diff --git a/arch/riscv/kernel/clint.c b/arch/riscv/kernel/clint.c
new file mode 100644
index 000000000000..3647980d14c3
--- /dev/null
+++ b/arch/riscv/kernel/clint.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Christoph Hellwig.
+ */
+
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/types.h>
+#include <asm/clint.h>
+#include <asm/csr.h>
+#include <asm/timex.h>
+#include <asm/smp.h>
+
+/*
+ * This is the layout used by the SiFive clint, which is also shared by the qemu
+ * virt platform, and the Kendryte KD210 at least.
+ */
+#define CLINT_IPI_OFF		0
+#define CLINT_TIME_CMP_OFF	0x4000
+#define CLINT_TIME_VAL_OFF	0xbff8
+
+u32 __iomem *clint_ipi_base;
+
+void clint_init_boot_cpu(void)
+{
+	struct device_node *np;
+	void __iomem *base;
+
+	np = of_find_compatible_node(NULL, NULL, "riscv,clint0");
+	if (!np) {
+		panic("clint not found");
+		return;
+	}
+
+	base = of_iomap(np, 0);
+	if (!base)
+		panic("could not map CLINT");
+
+	clint_ipi_base = base + CLINT_IPI_OFF;
+	riscv_time_cmp = base + CLINT_TIME_CMP_OFF;
+	riscv_time_val = base + CLINT_TIME_VAL_OFF;
+
+	clint_clear_ipi(boot_cpu_hartid);
+}
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index 845ae0e12115..365ff8420bfe 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -17,6 +17,7 @@
 #include <linux/sched/task.h>
 #include <linux/swiotlb.h>
 
+#include <asm/clint.h>
 #include <asm/setup.h>
 #include <asm/sections.h>
 #include <asm/pgtable.h>
@@ -67,6 +68,7 @@ void __init setup_arch(char **cmdline_p)
 	setup_bootmem();
 	paging_init();
 	unflatten_device_tree();
+	clint_init_boot_cpu();
 
 #ifdef CONFIG_SWIOTLB
 	swiotlb_init(1);
diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c
index c0fbc04e6810..eb878abcaaf8 100644
--- a/arch/riscv/kernel/smp.c
+++ b/arch/riscv/kernel/smp.c
@@ -16,6 +16,7 @@
 #include <linux/seq_file.h>
 #include <linux/delay.h>
 
+#include <asm/clint.h>
 #include <asm/sbi.h>
 #include <asm/tlbflush.h>
 #include <asm/cacheflush.h>
@@ -92,7 +93,10 @@ static void send_ipi_mask(const struct cpumask *mask, enum ipi_message_type op)
 	smp_mb__after_atomic();
 
 	riscv_cpuid_to_hartid_mask(mask, &hartid_mask);
-	sbi_send_ipi(cpumask_bits(&hartid_mask));
+	if (IS_ENABLED(CONFIG_RISCV_SBI))
+		sbi_send_ipi(cpumask_bits(&hartid_mask));
+	else
+		clint_send_ipi_mask(&hartid_mask);
 }
 
 static void send_ipi_single(int cpu, enum ipi_message_type op)
@@ -103,12 +107,18 @@ static void send_ipi_single(int cpu, enum ipi_message_type op)
 	set_bit(op, &ipi_data[cpu].bits);
 	smp_mb__after_atomic();
 
-	sbi_send_ipi(cpumask_bits(cpumask_of(hartid)));
+	if (IS_ENABLED(CONFIG_RISCV_SBI))
+		sbi_send_ipi(cpumask_bits(cpumask_of(hartid)));
+	else
+		clint_send_ipi_single(hartid);
 }
 
 static inline void clear_ipi(void)
 {
-	csr_clear(CSR_IP, IE_SIE);
+	if (IS_ENABLED(CONFIG_RISCV_SBI))
+		csr_clear(CSR_IP, IE_SIE);
+	else
+		clint_clear_ipi(cpuid_to_hartid_map(smp_processor_id()));
 }
 
 void riscv_software_interrupt(void)
diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
index 261f4087cc39..8bc01f0ca73b 100644
--- a/arch/riscv/kernel/smpboot.c
+++ b/arch/riscv/kernel/smpboot.c
@@ -24,6 +24,7 @@
 #include <linux/of.h>
 #include <linux/sched/task_stack.h>
 #include <linux/sched/mm.h>
+#include <asm/clint.h>
 #include <asm/irq.h>
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
@@ -137,6 +138,9 @@ asmlinkage __visible void __init smp_callin(void)
 {
 	struct mm_struct *mm = &init_mm;
 
+	if (!IS_ENABLED(CONFIG_RISCV_SBI))
+		clint_clear_ipi(cpuid_to_hartid_map(smp_processor_id()));
+
 	/* All kernel threads share the same mm context.  */
 	mmgrab(mm);
 	current->active_mm = mm;
-- 
2.24.0.rc0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH 10/15] riscv: read the hart ID from mhartid on boot
  2019-10-17 17:37 ` [PATCH 10/15] riscv: read the hart ID from mhartid on boot Christoph Hellwig
  2019-10-18  3:01   ` Anup Patel
@ 2019-11-14  7:40   ` Paul Walmsley
  1 sibling, 0 replies; 41+ messages in thread
From: Paul Walmsley @ 2019-11-14  7:40 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Atish Patra, Damien Le Moal, Palmer Dabbelt, linux-riscv, linux-kernel

On Thu, 17 Oct 2019, Christoph Hellwig wrote:

> From: Damien Le Moal <Damien.LeMoal@wdc.com>
> 
> When in M-Mode, we can use the mhartid CSR to get the ID of the running
> HART. Doing so, direct M-Mode boot without firmware is possible.
> 
> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Atish Patra <atish.patra@wdc.com>

Thanks, queued for v5.5-rc1.


- Paul

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2019-11-14  7:40 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-17 17:37 RISC-V nommu support v5 Christoph Hellwig
2019-10-17 17:37 ` [PATCH 01/15] riscv: cleanup <asm/bug.h> Christoph Hellwig
2019-10-18  2:50   ` Anup Patel
2019-10-23 22:04   ` Paul Walmsley
2019-10-17 17:37 ` [PATCH 02/15] riscv: cleanup do_trap_break Christoph Hellwig
2019-10-18  2:51   ` Anup Patel
2019-10-23 22:05   ` Paul Walmsley
2019-10-17 17:37 ` [PATCH 03/15] riscv: abstract out CSR names for supervisor vs machine mode Christoph Hellwig
2019-10-18  2:51   ` Anup Patel
2019-10-18 23:55   ` Paul Walmsley
2019-10-28  8:12     ` Christoph Hellwig
2019-10-17 17:37 ` [PATCH 04/15] riscv: don't allow selecting SBI based drivers for M-mode Christoph Hellwig
2019-10-18  2:52   ` Anup Patel
2019-10-17 17:37 ` [PATCH 05/15] riscv: poison SBI calls " Christoph Hellwig
2019-10-18  2:53   ` Anup Patel
2019-10-17 17:37 ` [PATCH 06/15] riscv: cleanup the default power off implementation Christoph Hellwig
2019-10-18  2:53   ` Anup Patel
2019-10-17 17:37 ` [PATCH 07/15] riscv: implement remote sfence.i using IPIs Christoph Hellwig
2019-10-18  2:55   ` Anup Patel
2019-10-17 17:37 ` [PATCH 08/15] riscv: add support for MMIO access to the timer registers Christoph Hellwig
2019-10-18  2:57   ` Anup Patel
2019-10-17 17:37 ` [PATCH 09/15] riscv: provide native clint access for M-mode Christoph Hellwig
2019-10-18  3:00   ` Anup Patel
2019-11-14  7:39   ` Paul Walmsley
2019-10-17 17:37 ` [PATCH 10/15] riscv: read the hart ID from mhartid on boot Christoph Hellwig
2019-10-18  3:01   ` Anup Patel
2019-11-14  7:40   ` Paul Walmsley
2019-10-17 17:37 ` [PATCH 11/15] riscv: use the correct interrupt levels for M-mode Christoph Hellwig
2019-10-18  3:01   ` Anup Patel
2019-10-17 17:37 ` [PATCH 12/15] riscv: clear the instruction cache and all registers when booting Christoph Hellwig
2019-10-18  3:05   ` Anup Patel
2019-10-17 17:37 ` [PATCH 13/15] riscv: add nommu support Christoph Hellwig
2019-10-18  3:04   ` Anup Patel
2019-10-17 17:37 ` [PATCH 14/15] riscv: provide a flat image loader Christoph Hellwig
2019-10-18  3:06   ` Anup Patel
2019-10-17 17:37 ` [PATCH 15/15] riscv: disable the EFI PECOFF header for M-mode Christoph Hellwig
2019-10-18  3:06   ` Anup Patel
2019-10-18  3:08 ` RISC-V nommu support v5 Anup Patel
2019-10-18  3:29   ` Paul Walmsley
2019-10-18 15:25     ` Christoph Hellwig
2019-10-18 23:46       ` Paul Walmsley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).