All of lore.kernel.org
 help / color / mirror / Atom feed
From: Philippe Gerum <rpm@xenomai.org>
To: Tobias Schaffner <tobias.schaffner@siemens.com>
Cc: xenomai@lists.linux.dev
Subject: Re: [PATCH dovetail v4 11/12] riscv: add out-of-band aware trap handling
Date: Thu, 22 Jan 2026 20:57:09 +0100	[thread overview]
Message-ID: <874iodifoq.fsf@xenomai.org> (raw)
In-Reply-To: <20260122102304.421957-12-tobias.schaffner@siemens.com> (Tobias Schaffner's message of "Thu, 22 Jan 2026 11:23:03 +0100")


"riscv: dovetail: add core support" as well.

Tobias Schaffner <tobias.schaffner@siemens.com> writes:

> 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 | 110 ++++++++++++++++++++++++++++++++------
>  arch/riscv/mm/fault.c     |  21 +++++---
>  2 files changed, 108 insertions(+), 23 deletions(-)
>
> diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
> index d0400086a075..51e1407ee066 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>
> @@ -115,6 +117,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
> @@ -126,21 +130,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()) {
> @@ -153,6 +176,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);
>  }
> @@ -163,7 +194,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
> @@ -181,9 +212,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);				\
>  		local_irq_enable();						\
> @@ -195,19 +229,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);
>  
> @@ -237,10 +276,11 @@ 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);
>  
>  enum misaligned_access_type {
>  	MISALIGNED_STORE,
> @@ -264,6 +304,9 @@ static void do_trap_misaligned(struct pt_regs *regs, enum misaligned_access_type
>  {
>  	irqentry_state_t state;
>  
> +	if(!mark_trap_entry(EXC_LOAD_MISALIGNED, regs))
> +		return;
> +
>  	if (user_mode(regs)) {
>  		irqentry_enter_from_user_mode(regs);
>  		local_irq_enable();
> @@ -281,6 +324,8 @@ static void do_trap_misaligned(struct pt_regs *regs, enum misaligned_access_type
>  	} else {
>  		irqentry_nmi_exit(regs, state);
>  	}
> +
> +	mark_trap_exit(EXC_LOAD_MISALIGNED, regs);
>  }
>  
>  asmlinkage __visible __trap_section void do_trap_load_misaligned(struct pt_regs *regs)
> @@ -290,15 +335,36 @@ asmlinkage __visible __trap_section void do_trap_load_misaligned(struct pt_regs
>  
>  asmlinkage __visible __trap_section void do_trap_store_misaligned(struct pt_regs *regs)
>  {
> -	do_trap_misaligned(regs, MISALIGNED_STORE);
> +	if(!mark_trap_entry(EXC_STORE_MISALIGNED, regs))
> +		return;
> +
> +	if (user_mode(regs)) {
> +		irqentry_enter_from_user_mode(regs);
> +
> +		if (handle_misaligned_store(regs))
> +			do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
> +				"Oops - store (or AMO) address misaligned");
> +
> +		irqentry_exit_to_user_mode(regs);
> +	} else {
> +		irqentry_state_t state = irqentry_nmi_enter(regs);
> +
> +		if (handle_misaligned_store(regs))
> +			do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
> +				"Oops - store (or AMO) address misaligned");
> +
> +		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)
>  {
> @@ -350,6 +416,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);
>  		local_irq_enable();
> @@ -365,6 +434,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
> @@ -381,6 +452,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)
> @@ -398,6 +478,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);
> @@ -407,7 +488,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 d64d01874a79..42450c47ee12 100644
> --- a/arch/riscv/mm/fault.c
> +++ b/arch/riscv/mm/fault.c
> @@ -385,6 +385,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)
> @@ -403,7 +407,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);
> @@ -421,7 +425,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:
>  
> @@ -430,7 +434,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;
>  	}
>  
>  	/*
> @@ -442,7 +446,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;
>  	}
>  
>  	/*
> @@ -460,12 +464,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;
> @@ -484,7 +488,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);
>  }

-- 
Philippe.

  reply	other threads:[~2026-01-22 19:57 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-22 10:22 [PATCH dovetail v4 00/12] riscv: Add dovetail support Tobias Schaffner
2026-01-22 10:22 ` [PATCH dovetail v4 01/12] riscv: irq_pipeline: add IRQ pipelining core Tobias Schaffner
2026-01-22 19:35   ` Philippe Gerum
2026-01-22 10:22 ` [PATCH dovetail v4 02/12] riscv: irq_pipeline: fix irq stack handling Tobias Schaffner
2026-01-22 19:55   ` Philippe Gerum
2026-01-22 10:22 ` [PATCH dovetail v4 03/12] riscv: irq_pipeline: synchronize IRQs on exit to user mode Tobias Schaffner
2026-01-22 10:22 ` [PATCH dovetail v4 04/12] irqchip/riscv-aplic-direct: enable pipelined interrupt control Tobias Schaffner
2026-01-22 10:22 ` [PATCH dovetail v4 05/12] irqchip/irq-riscv-aplic-msi: " Tobias Schaffner
2026-01-22 10:22 ` [PATCH dovetail v4 06/12] irqchip/irq-riscv-imsic-platform: " Tobias Schaffner
2026-01-22 10:22 ` [PATCH dovetail v4 07/12] irqchip/irq-riscv-intc: " Tobias Schaffner
2026-01-22 10:23 ` [PATCH dovetail v4 08/12] irqchip/irq-sifive-plic: " Tobias Schaffner
2026-01-22 10:23 ` [PATCH dovetail v4 09/12] clocksource/timer-riscv: irq_pipeline: enable pipelined clock events Tobias Schaffner
2026-01-22 10:23 ` [PATCH dovetail v4 10/12] riscv: add initial dovetail co-kernel skeleton Tobias Schaffner
2026-01-22 19:56   ` Philippe Gerum
2026-01-22 10:23 ` [PATCH dovetail v4 11/12] riscv: add out-of-band aware trap handling Tobias Schaffner
2026-01-22 19:57   ` Philippe Gerum [this message]
2026-01-22 10:23 ` [PATCH dovetail v4 12/12] riscv: add dovetail-aware memory management Tobias Schaffner
2026-01-22 11:05 ` [PATCH dovetail v4 00/12] riscv: Add dovetail support Florian Bezdeka
2026-01-22 11:48   ` Tobias Schaffner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=874iodifoq.fsf@xenomai.org \
    --to=rpm@xenomai.org \
    --cc=tobias.schaffner@siemens.com \
    --cc=xenomai@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.