* [PATCH dovetail v3 0/8] riscv: Add Dovetail support
@ 2025-11-13 12:09 Tobias Schaffner
2025-11-13 12:09 ` [PATCH dovetail v3 1/8] riscv: fix interrupt enable/disable order in native_irq_sync() Tobias Schaffner
` (8 more replies)
0 siblings, 9 replies; 11+ messages in thread
From: Tobias Schaffner @ 2025-11-13 12:09 UTC (permalink / raw)
To: xenomai; +Cc: rpm, Tobias Schaffner
Hi all,
this series introduces initial support for Dovetail on RISC-V and
adds some fixes to the current IQR Pipeline implementation.
It is based on the current tip of the wip/dovetail-riscv branch.
Feedback, suggestions, and especially reviews are very welcome.
Changes since v1:
* Disable independent irq/softirq stack usage when pipelining
* Drop KVM changes as long as they can not be properly tested
Changes since v2:
* Rework trap handling
Best,
Tobias
Tobias Schaffner (6):
riscv: only store interrupt enable flag in native_save_flags()
riscv: restore exact interrupt state in native_irq_restore()
riscv: save program counter in arch_save_timer_regs()
riscv: add initial dovetail co-kernel skeleton
riscv: add out-of-band aware trap handling
riscv: no inpependent irq/softirq stacks when pipelining
shannmu (2):
riscv: fix interrupt enable/disable order in native_irq_sync()
riscv: add dovetail-aware memory management
arch/riscv/Kconfig | 3 +
arch/riscv/include/asm/dovetail.h | 23 +++++++
arch/riscv/include/asm/irq_pipeline.h | 1 +
arch/riscv/include/asm/irqflags.h | 11 ++--
arch/riscv/include/asm/mmu_context.h | 2 +
arch/riscv/include/asm/syscall.h | 6 ++
arch/riscv/include/asm/thread_info.h | 9 +++
arch/riscv/kernel/traps.c | 92 +++++++++++++++++++++++----
arch/riscv/mm/cacheflush.c | 5 +-
arch/riscv/mm/context.c | 18 +++++-
arch/riscv/mm/fault.c | 24 ++++---
arch/riscv/mm/tlbflush.c | 5 +-
12 files changed, 167 insertions(+), 32 deletions(-)
create mode 100644 arch/riscv/include/asm/dovetail.h
--
2.43.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH dovetail v3 1/8] riscv: fix interrupt enable/disable order in native_irq_sync()
2025-11-13 12:09 [PATCH dovetail v3 0/8] riscv: Add Dovetail support Tobias Schaffner
@ 2025-11-13 12:09 ` Tobias Schaffner
2025-11-13 12:09 ` [PATCH dovetail v3 2/8] riscv: only store interrupt enable flag in native_save_flags() Tobias Schaffner
` (7 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Tobias Schaffner @ 2025-11-13 12:09 UTC (permalink / raw)
To: xenomai; +Cc: rpm, shannmu, Tobias Schaffner
From: shannmu <shanmu1901@gmail.com>
Correct the sequence by enabling interrupts first, issuing the memory
barrier, and then disabling them to ensure proper synchronization.
Signed-off-by: Tobias Schaffner <tobias.schaffner@siemens.com>
---
arch/riscv/include/asm/irqflags.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/include/asm/irqflags.h b/arch/riscv/include/asm/irqflags.h
index 839aaadfc036..d488b316735a 100644
--- a/arch/riscv/include/asm/irqflags.h
+++ b/arch/riscv/include/asm/irqflags.h
@@ -55,9 +55,9 @@ static inline void native_irq_restore(unsigned long flags)
static inline void native_irq_sync(void)
{
- native_irq_disable();
- asm volatile("nop" : : : "memory");
native_irq_enable();
+ asm volatile("nop" : : : "memory");
+ native_irq_disable();
}
#endif /* _ASM_RISCV_IRQFLAGS_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH dovetail v3 2/8] riscv: only store interrupt enable flag in native_save_flags()
2025-11-13 12:09 [PATCH dovetail v3 0/8] riscv: Add Dovetail support Tobias Schaffner
2025-11-13 12:09 ` [PATCH dovetail v3 1/8] riscv: fix interrupt enable/disable order in native_irq_sync() Tobias Schaffner
@ 2025-11-13 12:09 ` Tobias Schaffner
2025-11-13 12:09 ` [PATCH dovetail v3 3/8] riscv: restore exact interrupt state in native_irq_restore() Tobias Schaffner
` (6 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Tobias Schaffner @ 2025-11-13 12:09 UTC (permalink / raw)
To: xenomai; +Cc: rpm, Tobias Schaffner
Limit the saved flags to the interrupt enable bit (SR_IE), since this
is the only status flag that matters for interrupt handling.
Signed-off-by: Tobias Schaffner <tobias.schaffner@siemens.com>
---
arch/riscv/include/asm/irqflags.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/riscv/include/asm/irqflags.h b/arch/riscv/include/asm/irqflags.h
index d488b316735a..c7602250e981 100644
--- a/arch/riscv/include/asm/irqflags.h
+++ b/arch/riscv/include/asm/irqflags.h
@@ -12,7 +12,7 @@
/* read interrupt enabled status */
static inline unsigned long native_save_flags(void)
{
- return csr_read(CSR_STATUS);
+ return csr_read(CSR_STATUS) & SR_IE;
}
/* unconditionally enable interrupts */
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH dovetail v3 3/8] riscv: restore exact interrupt state in native_irq_restore()
2025-11-13 12:09 [PATCH dovetail v3 0/8] riscv: Add Dovetail support Tobias Schaffner
2025-11-13 12:09 ` [PATCH dovetail v3 1/8] riscv: fix interrupt enable/disable order in native_irq_sync() Tobias Schaffner
2025-11-13 12:09 ` [PATCH dovetail v3 2/8] riscv: only store interrupt enable flag in native_save_flags() Tobias Schaffner
@ 2025-11-13 12:09 ` Tobias Schaffner
2025-11-13 12:09 ` [PATCH dovetail v3 4/8] riscv: save program counter in arch_save_timer_regs() Tobias Schaffner
` (5 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Tobias Schaffner @ 2025-11-13 12:09 UTC (permalink / raw)
To: xenomai; +Cc: rpm, Tobias Schaffner
The previous implementation only set the SR_IE bit if it was set in the
saved flags but never cleared it when it was unset. This could leave
interrupts enabled unintentionally. Update the function to both set and
clear SR_IE as needed to fully restore the saved interrupt state.
Signed-off-by: Tobias Schaffner <tobias.schaffner@siemens.com>
---
arch/riscv/include/asm/irqflags.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/include/asm/irqflags.h b/arch/riscv/include/asm/irqflags.h
index c7602250e981..c3087b74752b 100644
--- a/arch/riscv/include/asm/irqflags.h
+++ b/arch/riscv/include/asm/irqflags.h
@@ -48,7 +48,10 @@ static inline bool native_irqs_disabled(void)
/* set interrupt enabled status */
static inline void native_irq_restore(unsigned long flags)
{
- csr_set(CSR_STATUS, flags & SR_IE);
+ if (flags & SR_IE)
+ csr_set(CSR_STATUS, SR_IE);
+ else
+ csr_clear(CSR_STATUS, SR_IE);
}
#include <asm/irq_pipeline.h>
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH dovetail v3 4/8] riscv: save program counter in arch_save_timer_regs()
2025-11-13 12:09 [PATCH dovetail v3 0/8] riscv: Add Dovetail support Tobias Schaffner
` (2 preceding siblings ...)
2025-11-13 12:09 ` [PATCH dovetail v3 3/8] riscv: restore exact interrupt state in native_irq_restore() Tobias Schaffner
@ 2025-11-13 12:09 ` Tobias Schaffner
2025-11-13 12:10 ` [PATCH dovetail v3 5/8] riscv: add initial dovetail co-kernel skeleton Tobias Schaffner
` (4 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Tobias Schaffner @ 2025-11-13 12:09 UTC (permalink / raw)
To: xenomai; +Cc: rpm, Tobias Schaffner
Extend arch_save_timer_regs() to also save the EPC (program counter)
from the source pt_regs.
Signed-off-by: Tobias Schaffner <tobias.schaffner@siemens.com>
---
arch/riscv/include/asm/irq_pipeline.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/riscv/include/asm/irq_pipeline.h b/arch/riscv/include/asm/irq_pipeline.h
index 030823745787..c479ec44b3a5 100644
--- a/arch/riscv/include/asm/irq_pipeline.h
+++ b/arch/riscv/include/asm/irq_pipeline.h
@@ -88,6 +88,7 @@ static inline
void arch_save_timer_regs(struct pt_regs *dst, struct pt_regs *src)
{
dst->status = src->status;
+ dst->epc = src->epc;
}
#else /* !CONFIG_IRQ_PIPELINE */
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH dovetail v3 5/8] riscv: add initial dovetail co-kernel skeleton
2025-11-13 12:09 [PATCH dovetail v3 0/8] riscv: Add Dovetail support Tobias Schaffner
` (3 preceding siblings ...)
2025-11-13 12:09 ` [PATCH dovetail v3 4/8] riscv: save program counter in arch_save_timer_regs() Tobias Schaffner
@ 2025-11-13 12:10 ` Tobias Schaffner
2025-11-13 12:10 ` [PATCH dovetail v3 6/8] riscv: add out-of-band aware trap handling Tobias Schaffner
` (3 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Tobias Schaffner @ 2025-11-13 12:10 UTC (permalink / raw)
To: xenomai; +Cc: rpm, Tobias Schaffner
Signed-off-by: Tobias Schaffner <tobias.schaffner@siemens.com>
---
arch/riscv/Kconfig | 2 ++
arch/riscv/include/asm/dovetail.h | 23 +++++++++++++++++++++++
arch/riscv/include/asm/mmu_context.h | 4 ++++
arch/riscv/include/asm/syscall.h | 6 ++++++
arch/riscv/include/asm/thread_info.h | 9 +++++++++
5 files changed, 44 insertions(+)
create mode 100644 arch/riscv/include/asm/dovetail.h
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 19c5624b3ffb..5cc3df56a58c 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -136,6 +136,7 @@ config RISCV
select HAVE_ARCH_USERFAULTFD_MINOR if 64BIT && USERFAULTFD
select HAVE_ARCH_VMAP_STACK if MMU && 64BIT
select HAVE_IRQ_PIPELINE
+ select HAVE_DOVETAIL
select HAVE_ASM_MODVERSIONS
select HAVE_CONTEXT_TRACKING_USER
select HAVE_DEBUG_KMEMLEAK
@@ -371,6 +372,7 @@ config AS_HAS_OPTION_ARCH
source "arch/riscv/Kconfig.socs"
source "arch/riscv/Kconfig.errata"
+source "kernel/Kconfig.dovetail"
menu "Platform type"
diff --git a/arch/riscv/include/asm/dovetail.h b/arch/riscv/include/asm/dovetail.h
new file mode 100644
index 000000000000..bb342e9eb18a
--- /dev/null
+++ b/arch/riscv/include/asm/dovetail.h
@@ -0,0 +1,23 @@
+/*
+* SPDX-License-Identifier: GPL-2.0
+*
+* Copyright (C) 2024 Tobias Schaffner
+*/
+#ifndef _ASM_RISCV_DOVETAIL_H
+#define _ASM_RISCV_DOVETAIL_H
+
+#if !defined(__ASSEMBLY__)
+#ifdef CONFIG_DOVETAIL
+
+static inline void arch_dovetail_exec_prepare(void)
+{ }
+
+static inline void arch_dovetail_switch_prepare(bool leave_inband)
+{ }
+
+static inline void arch_dovetail_switch_finish(bool enter_inband)
+{ }
+
+#endif /* CONFIG_DOVETAIL */
+#endif /* !__ASSEMBLY__ */
+#endif /* _ASM_RISCV_DOVETAIL_H */
diff --git a/arch/riscv/include/asm/mmu_context.h b/arch/riscv/include/asm/mmu_context.h
index 7030837adc1a..acf3b8e20e27 100644
--- a/arch/riscv/include/asm/mmu_context.h
+++ b/arch/riscv/include/asm/mmu_context.h
@@ -33,6 +33,10 @@ static inline int init_new_context(struct task_struct *tsk,
return 0;
}
+static inline void
+switch_oob_mm(struct mm_struct *prev, struct mm_struct *next,
+ struct task_struct *tsk) { }
+
DECLARE_STATIC_KEY_FALSE(use_asid_allocator);
#include <asm-generic/mmu_context.h>
diff --git a/arch/riscv/include/asm/syscall.h b/arch/riscv/include/asm/syscall.h
index 121fff429dce..0e02161280e6 100644
--- a/arch/riscv/include/asm/syscall.h
+++ b/arch/riscv/include/asm/syscall.h
@@ -95,6 +95,12 @@ static inline bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs)
return false;
}
+static inline unsigned long syscall_get_arg0(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return regs->orig_a0;
+}
+
asmlinkage long sys_riscv_flush_icache(uintptr_t, uintptr_t, uintptr_t);
asmlinkage long sys_riscv_hwprobe(struct riscv_hwprobe *, size_t, size_t,
diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h
index 1c7a61a4292e..b8e0a5ea2fed 100644
--- a/arch/riscv/include/asm/thread_info.h
+++ b/arch/riscv/include/asm/thread_info.h
@@ -41,6 +41,7 @@
#include <asm/processor.h>
#include <asm/csr.h>
+#include <dovetail/thread_info.h>
/*
* low level task data that entry.S needs immediate access to
@@ -77,6 +78,7 @@ struct thread_info {
*/
unsigned long a0, a1, a2;
#endif
+ struct oob_thread_state oob_state; /* co-kernel thread state */
};
#ifdef CONFIG_SHADOW_CALL_STACK
@@ -120,6 +122,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
#define TIF_UPROBE 10 /* uprobe breakpoint or singlestep */
#define TIF_32BIT 11 /* compat-mode 32bit process */
#define TIF_RISCV_V_DEFER_RESTORE 12 /* restore Vector before returing to user */
+#define TIF_RETUSER 13 /* INBAND_TASK_RETUSER is pending */
+#define TIF_MAYDAY 14 /* emergency trap pending */
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
@@ -127,10 +131,15 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
#define _TIF_UPROBE (1 << TIF_UPROBE)
#define _TIF_RISCV_V_DEFER_RESTORE (1 << TIF_RISCV_V_DEFER_RESTORE)
+#define _TIF_RETUSER (1 << TIF_RETUSER)
+#define _TIF_MAYDAY (1 << TIF_MAYDAY)
/*
* Local (synchronous) thread flags.
*/
#define _TLF_OOB 0x0001
+#define _TLF_DOVETAIL 0x0002
+#define _TLF_OFFSTAGE 0x0004
+#define _TLF_OOBTRAP 0x0008
#endif /* _ASM_RISCV_THREAD_INFO_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH dovetail v3 6/8] riscv: add out-of-band aware trap handling
2025-11-13 12:09 [PATCH dovetail v3 0/8] riscv: Add Dovetail support Tobias Schaffner
` (4 preceding siblings ...)
2025-11-13 12:10 ` [PATCH dovetail v3 5/8] riscv: add initial dovetail co-kernel skeleton Tobias Schaffner
@ 2025-11-13 12:10 ` Tobias Schaffner
2025-11-13 12:10 ` [PATCH dovetail v3 7/8] riscv: add dovetail-aware memory management Tobias Schaffner
` (2 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Tobias Schaffner @ 2025-11-13 12:10 UTC (permalink / raw)
To: xenomai; +Cc: rpm, Tobias Schaffner
Introduce trap handling hooks for the Dovetail co-kernel, integrating
out-of-band (OOB) notification and unwind support.
Signed-off-by: Tobias Schaffner <tobias.schaffner@siemens.com>
---
arch/riscv/kernel/traps.c | 92 +++++++++++++++++++++++++++++++++------
arch/riscv/mm/fault.c | 21 +++++----
2 files changed, 91 insertions(+), 22 deletions(-)
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 83aef3fac26f..e156f83acd2e 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -3,6 +3,8 @@
* Copyright (C) 2012 Regents of the University of California
*/
+#include <asm-generic/signal.h>
+#include <linux/compiler_attributes.h>
#include <linux/cpu.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -114,6 +116,8 @@ void die(struct pt_regs *regs, const char *str)
static __always_inline
bool mark_trap_entry(int signo, struct pt_regs *regs)
{
+ oob_trap_notify(signo, regs);
+
/*
* Dovetail: irqentry_enter*() already synchronized the
* virtual and real interrupt states for us. If running
@@ -125,21 +129,40 @@ bool mark_trap_entry(int signo, struct pt_regs *regs)
return true;
}
+ oob_trap_unwind(signo, regs);
+
return false;
}
static __always_inline
void mark_trap_exit(int signo, struct pt_regs *regs)
{
+ oob_trap_unwind(signo, regs);
hard_cond_local_irq_disable();
}
-void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr)
+static __always_inline
+bool mark_trap_entry_raw(int trapnr, struct pt_regs *regs)
{
- struct task_struct *tsk = current;
+ oob_trap_notify(trapnr, regs);
- if (!mark_trap_entry(signo, regs))
- return;
+ if (running_oob()) {
+ oob_trap_unwind(trapnr, regs);
+ return false;
+ }
+
+ return true;
+}
+
+static __always_inline
+void mark_trap_exit_raw(int trapnr, struct pt_regs *regs)
+{
+ oob_trap_unwind(trapnr, regs);
+}
+
+static void do_trap_raw(struct pt_regs *regs, int signo, int code, unsigned long addr)
+{
+ struct task_struct *tsk = current;
if (show_unhandled_signals && unhandled_signal(tsk, signo)
&& printk_ratelimit()) {
@@ -152,6 +175,14 @@ void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr)
}
force_sig_fault(signo, code, (void __user *)addr);
+}
+
+void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr)
+{
+ if(!mark_trap_entry(signo, regs))
+ return;
+
+ do_trap_raw(regs, signo, code, addr);
mark_trap_exit(signo, regs);
}
@@ -162,7 +193,7 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code,
current->thread.bad_cause = regs->cause;
if (user_mode(regs)) {
- do_trap(regs, signo, code, addr);
+ do_trap_raw(regs, signo, code, addr);
} else {
/*
* Dovetail: If we trapped from kernel space, either
@@ -180,9 +211,12 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code,
#else
#define __trap_section noinstr
#endif
-#define DO_ERROR_INFO(name, signo, code, str) \
+#define DO_ERROR_INFO(name, signo, code, str, trapnr) \
asmlinkage __visible __trap_section void name(struct pt_regs *regs) \
{ \
+ if(!mark_trap_entry(trapnr, regs)) \
+ return; \
+ \
if (user_mode(regs)) { \
irqentry_enter_from_user_mode(regs); \
do_trap_error(regs, signo, code, regs->epc, "Oops - " str); \
@@ -192,19 +226,24 @@ asmlinkage __visible __trap_section void name(struct pt_regs *regs) \
do_trap_error(regs, signo, code, regs->epc, "Oops - " str); \
irqentry_nmi_exit(regs, state); \
} \
+ \
+ mark_trap_exit(trapnr, regs); \
}
DO_ERROR_INFO(do_trap_unknown,
- SIGILL, ILL_ILLTRP, "unknown exception");
+ SIGILL, ILL_ILLTRP, "unknown exception", EXC_INST_ILLEGAL);
DO_ERROR_INFO(do_trap_insn_misaligned,
- SIGBUS, BUS_ADRALN, "instruction address misaligned");
+ SIGBUS, BUS_ADRALN, "instruction address misaligned", EXC_INST_MISALIGNED);
DO_ERROR_INFO(do_trap_insn_fault,
- SIGSEGV, SEGV_ACCERR, "instruction access fault");
+ SIGSEGV, SEGV_ACCERR, "instruction access fault", EXC_INST_ACCESS);
asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *regs)
{
bool handled;
+ if(!mark_trap_entry(EXC_INST_ILLEGAL, regs))
+ return;
+
if (user_mode(regs)) {
irqentry_enter_from_user_mode(regs);
@@ -233,13 +272,17 @@ asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *re
irqentry_nmi_exit(regs, state);
}
+ mark_trap_exit(EXC_INST_ILLEGAL, regs);
}
DO_ERROR_INFO(do_trap_load_fault,
- SIGSEGV, SEGV_ACCERR, "load access fault");
+ SIGSEGV, SEGV_ACCERR, "load access fault", EXC_LOAD_ACCESS);
asmlinkage __visible __trap_section void do_trap_load_misaligned(struct pt_regs *regs)
{
+ if(!mark_trap_entry(EXC_LOAD_MISALIGNED, regs))
+ return;
+
if (user_mode(regs)) {
irqentry_enter_from_user_mode(regs);
@@ -257,10 +300,15 @@ asmlinkage __visible __trap_section void do_trap_load_misaligned(struct pt_regs
irqentry_nmi_exit(regs, state);
}
+
+ mark_trap_exit(EXC_LOAD_MISALIGNED, regs);
}
asmlinkage __visible __trap_section void do_trap_store_misaligned(struct pt_regs *regs)
{
+ if(!mark_trap_entry(EXC_STORE_MISALIGNED, regs))
+ return;
+
if (user_mode(regs)) {
irqentry_enter_from_user_mode(regs);
@@ -278,13 +326,15 @@ asmlinkage __visible __trap_section void do_trap_store_misaligned(struct pt_regs
irqentry_nmi_exit(regs, state);
}
+
+ mark_trap_exit(EXC_STORE_MISALIGNED, regs);
}
DO_ERROR_INFO(do_trap_store_fault,
- SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault");
+ SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault", EXC_STORE_ACCESS);
DO_ERROR_INFO(do_trap_ecall_s,
- SIGILL, ILL_ILLTRP, "environment call from S-mode");
+ SIGILL, ILL_ILLTRP, "environment call from S-mode", EXC_SYSCALL);
DO_ERROR_INFO(do_trap_ecall_m,
- SIGILL, ILL_ILLTRP, "environment call from M-mode");
+ SIGILL, ILL_ILLTRP, "environment call from M-mode", EXC_SUPERVISOR_SYSCALL);
static inline unsigned long get_break_insn_length(unsigned long pc)
{
@@ -336,6 +386,9 @@ void handle_break(struct pt_regs *regs)
asmlinkage __visible __trap_section void do_trap_break(struct pt_regs *regs)
{
+ if(!mark_trap_entry_raw(EXC_BREAKPOINT, regs))
+ return;
+
if (user_mode(regs)) {
irqentry_enter_from_user_mode(regs);
@@ -349,6 +402,8 @@ asmlinkage __visible __trap_section void do_trap_break(struct pt_regs *regs)
irqentry_nmi_exit(regs, state);
}
+
+ mark_trap_exit_raw(EXC_BREAKPOINT, regs);
}
asmlinkage __visible __trap_section __no_stack_protector
@@ -365,6 +420,15 @@ void do_trap_ecall_u(struct pt_regs *regs)
syscall = syscall_enter_from_user_mode(regs, syscall);
+ if(dovetailing()) {
+ if (syscall == EXIT_SYSCALL_OOB) {
+ hard_local_irq_disable();
+ return;
+ }
+ if (syscall == EXIT_SYSCALL_TAIL)
+ goto done_inband;
+ }
+
add_random_kstack_offset();
if (syscall >= 0 && syscall < NR_syscalls)
@@ -382,6 +446,7 @@ void do_trap_ecall_u(struct pt_regs *regs)
*/
choose_random_kstack_offset(get_random_u16());
+done_inband:
syscall_exit_to_user_mode(regs);
} else {
irqentry_state_t state = irqentry_nmi_enter(regs);
@@ -391,7 +456,6 @@ void do_trap_ecall_u(struct pt_regs *regs)
irqentry_nmi_exit(regs, state);
}
-
}
#ifdef CONFIG_MMU
diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c
index f7275f1a39ac..7033119e4e2f 100644
--- a/arch/riscv/mm/fault.c
+++ b/arch/riscv/mm/fault.c
@@ -279,6 +279,10 @@ void handle_page_fault(struct pt_regs *regs)
die_kernel_fault("access to user memory without uaccess routines", addr, regs);
}
+ oob_trap_notify(EXC_INST_PAGE_FAULT, regs);
+ if (!running_inband())
+ goto out;
+
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);
if (cause == EXC_STORE_PAGE_FAULT)
@@ -297,7 +301,7 @@ void handle_page_fault(struct pt_regs *regs)
count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
tsk->thread.bad_cause = cause;
bad_area_nosemaphore(regs, SEGV_ACCERR, addr);
- return;
+ goto out;
}
fault = handle_mm_fault(vma, addr, flags | FAULT_FLAG_VMA_LOCK, regs);
@@ -315,7 +319,7 @@ void handle_page_fault(struct pt_regs *regs)
if (fault_signal_pending(fault, regs)) {
if (!user_mode(regs))
no_context(regs, addr);
- return;
+ goto out;
}
lock_mmap:
@@ -324,7 +328,7 @@ void handle_page_fault(struct pt_regs *regs)
if (unlikely(!vma)) {
tsk->thread.bad_cause = cause;
bad_area_nosemaphore(regs, code, addr);
- return;
+ goto out;
}
/*
@@ -336,7 +340,7 @@ void handle_page_fault(struct pt_regs *regs)
if (unlikely(access_error(cause, vma))) {
tsk->thread.bad_cause = cause;
bad_area(regs, mm, code, addr);
- return;
+ goto out;
}
/*
@@ -354,12 +358,12 @@ void handle_page_fault(struct pt_regs *regs)
if (fault_signal_pending(fault, regs)) {
if (!user_mode(regs))
no_context(regs, addr);
- return;
+ goto out;
}
/* The fault is fully completed (including releasing mmap lock) */
if (fault & VM_FAULT_COMPLETED)
- return;
+ goto out;
if (unlikely(fault & VM_FAULT_RETRY)) {
flags |= FAULT_FLAG_TRIED;
@@ -378,7 +382,8 @@ void handle_page_fault(struct pt_regs *regs)
if (unlikely(fault & VM_FAULT_ERROR)) {
tsk->thread.bad_cause = cause;
mm_fault_error(regs, addr, fault);
- return;
}
- return;
+
+out:
+ oob_trap_unwind(EXC_INST_PAGE_FAULT, regs);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH dovetail v3 7/8] riscv: add dovetail-aware memory management
2025-11-13 12:09 [PATCH dovetail v3 0/8] riscv: Add Dovetail support Tobias Schaffner
` (5 preceding siblings ...)
2025-11-13 12:10 ` [PATCH dovetail v3 6/8] riscv: add out-of-band aware trap handling Tobias Schaffner
@ 2025-11-13 12:10 ` Tobias Schaffner
2025-11-13 12:10 ` [PATCH dovetail v3 8/8] riscv: no inpependent irq/softirq stacks when pipelining Tobias Schaffner
2025-11-13 12:26 ` [PATCH dovetail v3 0/8] riscv: Add Dovetail support Tobias Schaffner
8 siblings, 0 replies; 11+ messages in thread
From: Tobias Schaffner @ 2025-11-13 12:10 UTC (permalink / raw)
To: xenomai; +Cc: rpm, shannmu, Tobias Schaffner
From: shannmu <shanmu1901@gmail.com>
This patch provides the foundation for safely managing memory contexts
for both in-band and out-of-band tasks in the co-kernel.
Signed-off-by: Tobias Schaffner <tobias.schaffner@siemens.com>
---
arch/riscv/include/asm/mmu_context.h | 6 ++----
arch/riscv/mm/cacheflush.c | 5 +++--
arch/riscv/mm/context.c | 18 +++++++++++++++++-
arch/riscv/mm/fault.c | 3 ++-
arch/riscv/mm/tlbflush.c | 5 +++--
5 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/arch/riscv/include/asm/mmu_context.h b/arch/riscv/include/asm/mmu_context.h
index acf3b8e20e27..b62d69dbdd06 100644
--- a/arch/riscv/include/asm/mmu_context.h
+++ b/arch/riscv/include/asm/mmu_context.h
@@ -15,6 +15,8 @@
void switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *task);
+void switch_oob_mm(struct mm_struct *prev, struct mm_struct *next,
+ struct task_struct *task);
#define activate_mm activate_mm
static inline void activate_mm(struct mm_struct *prev,
@@ -33,10 +35,6 @@ static inline int init_new_context(struct task_struct *tsk,
return 0;
}
-static inline void
-switch_oob_mm(struct mm_struct *prev, struct mm_struct *next,
- struct task_struct *tsk) { }
-
DECLARE_STATIC_KEY_FALSE(use_asid_allocator);
#include <asm-generic/mmu_context.h>
diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c
index b81672729887..6dabe4c0a203 100644
--- a/arch/riscv/mm/cacheflush.c
+++ b/arch/riscv/mm/cacheflush.c
@@ -45,8 +45,9 @@ void flush_icache_mm(struct mm_struct *mm, bool local)
{
unsigned int cpu;
cpumask_t others, *mask;
+ unsigned long flags;
- preempt_disable();
+ flags = hard_preempt_disable();
/* Mark every hart's icache as needing a flush for this MM. */
mask = &mm->context.icache_stale_mask;
@@ -78,7 +79,7 @@ void flush_icache_mm(struct mm_struct *mm, bool local)
on_each_cpu_mask(&others, ipi_remote_fence_i, NULL, 1);
}
- preempt_enable();
+ hard_preempt_enable(flags);
}
#endif /* CONFIG_SMP */
diff --git a/arch/riscv/mm/context.c b/arch/riscv/mm/context.c
index 4abe3de23225..81199e192804 100644
--- a/arch/riscv/mm/context.c
+++ b/arch/riscv/mm/context.c
@@ -315,7 +315,7 @@ static inline void flush_icache_deferred(struct mm_struct *mm, unsigned int cpu,
#endif
}
-void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+static void do_switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *task)
{
unsigned int cpu;
@@ -336,3 +336,19 @@ void switch_mm(struct mm_struct *prev, struct mm_struct *next,
flush_icache_deferred(next, cpu, task);
}
+
+void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+ struct task_struct *task)
+{
+ unsigned flags;
+
+ protect_inband_mm(flags);
+ do_switch_mm(prev, next, task);
+ unprotect_inband_mm(flags);
+}
+
+void switch_oob_mm(struct mm_struct *prev, struct mm_struct *next,
+ struct task_struct *task)
+{
+ do_switch_mm(prev, next, task);
+}
\ No newline at end of file
diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c
index 7033119e4e2f..712ba55e7a7c 100644
--- a/arch/riscv/mm/fault.c
+++ b/arch/riscv/mm/fault.c
@@ -7,6 +7,7 @@
*/
+#include <linux/preempt.h>
#include <linux/mm.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
@@ -263,7 +264,7 @@ void handle_page_fault(struct pt_regs *regs)
* If we're in an interrupt, have no user context, or are running
* in an atomic region, then we must not take the fault.
*/
- if (unlikely(faulthandler_disabled() || !mm)) {
+ if (unlikely(running_inband() && (faulthandler_disabled() || !mm))) {
tsk->thread.bad_cause = cause;
no_context(regs, addr);
return;
diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
index 9b6e86ce3867..0009593bd5ec 100644
--- a/arch/riscv/mm/tlbflush.c
+++ b/arch/riscv/mm/tlbflush.c
@@ -83,11 +83,12 @@ static void __flush_tlb_range(const struct cpumask *cmask, unsigned long asid,
unsigned long stride)
{
unsigned int cpu;
+ unsigned long flags;
if (cpumask_empty(cmask))
return;
- cpu = get_cpu();
+ cpu = hard_get_cpu(flags);
/* Check if the TLB flush needs to be sent to other CPUs. */
if (cpumask_any_but(cmask, cpu) >= nr_cpu_ids) {
@@ -104,7 +105,7 @@ static void __flush_tlb_range(const struct cpumask *cmask, unsigned long asid,
on_each_cpu_mask(cmask, __ipi_flush_tlb_range_asid, &ftd, 1);
}
- put_cpu();
+ hard_put_cpu(flags);
}
static inline unsigned long get_mm_asid(struct mm_struct *mm)
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH dovetail v3 8/8] riscv: no inpependent irq/softirq stacks when pipelining
2025-11-13 12:09 [PATCH dovetail v3 0/8] riscv: Add Dovetail support Tobias Schaffner
` (6 preceding siblings ...)
2025-11-13 12:10 ` [PATCH dovetail v3 7/8] riscv: add dovetail-aware memory management Tobias Schaffner
@ 2025-11-13 12:10 ` Tobias Schaffner
2025-11-13 12:26 ` [PATCH dovetail v3 0/8] riscv: Add Dovetail support Tobias Schaffner
8 siblings, 0 replies; 11+ messages in thread
From: Tobias Schaffner @ 2025-11-13 12:10 UTC (permalink / raw)
To: xenomai; +Cc: rpm, Tobias Schaffner
Do not use independent irq stacks when irq-pipelining is configured.
Signed-off-by: Tobias Schaffner <tobias.schaffner@siemens.com>
---
arch/riscv/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 5cc3df56a58c..0e720f52261a 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -770,6 +770,7 @@ config FPU
config IRQ_STACKS
bool "Independent irq & softirq stacks" if EXPERT
+ depends on !IRQ_PIPELINE
default y
select HAVE_IRQ_EXIT_ON_IRQ_STACK
select HAVE_SOFTIRQ_ON_OWN_STACK
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH dovetail v3 0/8] riscv: Add Dovetail support
2025-11-13 12:09 [PATCH dovetail v3 0/8] riscv: Add Dovetail support Tobias Schaffner
` (7 preceding siblings ...)
2025-11-13 12:10 ` [PATCH dovetail v3 8/8] riscv: no inpependent irq/softirq stacks when pipelining Tobias Schaffner
@ 2025-11-13 12:26 ` Tobias Schaffner
2025-11-14 18:22 ` Philippe Gerum
8 siblings, 1 reply; 11+ messages in thread
From: Tobias Schaffner @ 2025-11-13 12:26 UTC (permalink / raw)
To: xenomai, rpm; +Cc: Jan Kiszka
Hi Philippe,
The EVL testsuite is running successfully on QEMU with this set of patches.
I’d like to ask how we should proceed from here.
If possible, I’d like to merge the RISC-V components for xenomai-images
so that we can set up an initial testing pipeline. To do that, we’ll
need a development branch that integrates the Dovetail and EVL
components, which can be referenced.
My private testing branch[1] is currently based on v6.12-evl1-rebase,
but I’m happy to port it to whichever version you’d prefer to continue with.
Best,
Tobias
[1] https://github.com/TobiasSchaffner/linux/tree/tobsch/evl-riscv
On 11/13/25 13:09, Tobias Schaffner wrote:
> Hi all,
>
> this series introduces initial support for Dovetail on RISC-V and
> adds some fixes to the current IQR Pipeline implementation.
>
> It is based on the current tip of the wip/dovetail-riscv branch.
>
> Feedback, suggestions, and especially reviews are very welcome.
>
> Changes since v1:
> * Disable independent irq/softirq stack usage when pipelining
> * Drop KVM changes as long as they can not be properly tested
>
> Changes since v2:
> * Rework trap handling
>
> Best,
> Tobias
>
> Tobias Schaffner (6):
> riscv: only store interrupt enable flag in native_save_flags()
> riscv: restore exact interrupt state in native_irq_restore()
> riscv: save program counter in arch_save_timer_regs()
> riscv: add initial dovetail co-kernel skeleton
> riscv: add out-of-band aware trap handling
> riscv: no inpependent irq/softirq stacks when pipelining
>
> shannmu (2):
> riscv: fix interrupt enable/disable order in native_irq_sync()
> riscv: add dovetail-aware memory management
>
> arch/riscv/Kconfig | 3 +
> arch/riscv/include/asm/dovetail.h | 23 +++++++
> arch/riscv/include/asm/irq_pipeline.h | 1 +
> arch/riscv/include/asm/irqflags.h | 11 ++--
> arch/riscv/include/asm/mmu_context.h | 2 +
> arch/riscv/include/asm/syscall.h | 6 ++
> arch/riscv/include/asm/thread_info.h | 9 +++
> arch/riscv/kernel/traps.c | 92 +++++++++++++++++++++++----
> arch/riscv/mm/cacheflush.c | 5 +-
> arch/riscv/mm/context.c | 18 +++++-
> arch/riscv/mm/fault.c | 24 ++++---
> arch/riscv/mm/tlbflush.c | 5 +-
> 12 files changed, 167 insertions(+), 32 deletions(-)
> create mode 100644 arch/riscv/include/asm/dovetail.h
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH dovetail v3 0/8] riscv: Add Dovetail support
2025-11-13 12:26 ` [PATCH dovetail v3 0/8] riscv: Add Dovetail support Tobias Schaffner
@ 2025-11-14 18:22 ` Philippe Gerum
0 siblings, 0 replies; 11+ messages in thread
From: Philippe Gerum @ 2025-11-14 18:22 UTC (permalink / raw)
To: Tobias Schaffner; +Cc: xenomai, Jan Kiszka
Hi Tobias,
Tobias Schaffner <tobias.schaffner@siemens.com> writes:
> Hi Philippe,
>
> The EVL testsuite is running successfully on QEMU with this set of patches.
>
Nice work.
> I’d like to ask how we should proceed from here.
>
> If possible, I’d like to merge the RISC-V components for
> xenomai-images so that we can set up an initial testing pipeline. To
> do that, we’ll need a development branch that integrates the Dovetail
> and EVL components, which can be referenced.
>
> My private testing branch[1] is currently based on v6.12-evl1-rebase,
> but I’m happy to port it to whichever version you’d prefer to continue
> with.
>
You now have maintainer access to the
linux-dovetail.git/wip/dovetail-riscv and linux-evl.git/wip/evl-riscv
branches. You should be able to maintain the Dovetail and EVL core ports
from those separate trees. Both branches should be considered as
rebasable. Those kernel trees contain the riscv bits I once harvested on
the mailing list some time ago, so by no mean up to date. You can
definitely replace them at will.
You also have maintainer access to the libevl.git/wip/libevl-riscv branch
(rebasable too), which I just forked off the -next branch. I'll pull
from the former branch when deemed ready. Please keep in sync with
-next, not master.
linux-evl/wip/evl-riscv and libevl/wip/libevl-riscv can be the source
trees for xenomai-images at the moment, until merged.
The Dovetail kernel tree should not contain any EVL-specific bit so that
other real-time cores (e.g. x3 Cobalt) can use it seamlessly as well,
the EVL tree should include the Dovetail tree plus the EVL core with
riscv support.
The Dovetail patch set should introduce riscv support piecemeal, in a
way which allows us to bisect code when chasing regressions by enabling
features incrementally, from mere interrupt pipelining to alternate
scheduling of oob threads, along with oob networking, oob device support
(gpio, clocksources, timers). Of course, as development goes on, we end
up with individual fixes stacked on top of this ideal series of
commits. From time to time, these fixes are squashed into the commits
forming the fundamental series I just mentioned.
e.g. looking at rebase/v6.17-dovetail, the fundamental series adding
Dovetail support piecemeal goes from 12e0fbdff1d45 to
c09b64e1767a2. Commits on top of this range are fixes to this series,
which we may squash at some point, when forward porting to some upcoming
kernel release (this normally happens during the upstream -rc cycle).
As you know, the EVL tree for a newer kernel release is obtained from
forking off the matching Dovetail tree, forward porting the EVL bits
from the latest release. Pretty straightforward. Here again, we may have
Dovetail fixes landing on top, and EVL fixes as well. The latter are
never squashed though. Any merge-related change to the EVL bits most
often appears explicitly in an individual commit, because there are very
few places for merge conflicts with upstream changes in the EVL code
base, so we are usually able to merge seamlessly, we have to compile and
run it for finding issues in most cases.
Eventually, the plan is to merge wip/dovetail-riscv and wip/evl-riscv
into the linux-dovetail and linux-evl trees when ready. A working
initial port of EVL to some riscv hardware would indicate that such port
is ready for inclusion.
Basing the initial riscv port on v6.12.y-cip would benefit people who
need an SLTS kernel. However, this would also double the initial
maintenance work on your end, since we are going to need a port to v6.18
which is brewing here. What's your take on this?
--
Philippe.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2025-11-14 18:22 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-13 12:09 [PATCH dovetail v3 0/8] riscv: Add Dovetail support Tobias Schaffner
2025-11-13 12:09 ` [PATCH dovetail v3 1/8] riscv: fix interrupt enable/disable order in native_irq_sync() Tobias Schaffner
2025-11-13 12:09 ` [PATCH dovetail v3 2/8] riscv: only store interrupt enable flag in native_save_flags() Tobias Schaffner
2025-11-13 12:09 ` [PATCH dovetail v3 3/8] riscv: restore exact interrupt state in native_irq_restore() Tobias Schaffner
2025-11-13 12:09 ` [PATCH dovetail v3 4/8] riscv: save program counter in arch_save_timer_regs() Tobias Schaffner
2025-11-13 12:10 ` [PATCH dovetail v3 5/8] riscv: add initial dovetail co-kernel skeleton Tobias Schaffner
2025-11-13 12:10 ` [PATCH dovetail v3 6/8] riscv: add out-of-band aware trap handling Tobias Schaffner
2025-11-13 12:10 ` [PATCH dovetail v3 7/8] riscv: add dovetail-aware memory management Tobias Schaffner
2025-11-13 12:10 ` [PATCH dovetail v3 8/8] riscv: no inpependent irq/softirq stacks when pipelining Tobias Schaffner
2025-11-13 12:26 ` [PATCH dovetail v3 0/8] riscv: Add Dovetail support Tobias Schaffner
2025-11-14 18:22 ` Philippe Gerum
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox