From 09e6c3f5e27607cd6f7854bdc5e87d829c48d500 Mon Sep 17 00:00:00 2001 From: julia Date: Wed, 20 Aug 2025 17:52:35 +1000 Subject: [PATCH] debug: invalidate ksKernelEntry on kernel exit There's a few cases in the kernel where the ksKernelEntry tracking is not perfect, such as in SError reporting, and (I believe) a few other places which I haven't tracked down to a cause - but some of e.g. the RISC-V trap code where the first entry faults and the 2nd proceeds can report stale information. In these cases, the kernel says that the entry was via a certain syscall or interrupt (etc), even though that was clearly not the case because we know the kernel exited. Now we will print out this: halting... Kernel entry via Unknown (0) The changes: - When exiting the kernel, via `c_exit_hook()`, reset `ksKernelEntry.path` to "Unknown". An alternative here would have been add a global "valid" boolean to the kernel state, but this requires modifying every site where we set the ksKernelEntry.path to also set valid = true, which is ugly. - Remove Entry_UnimplementedDevice from entry_type_t as it is never used, to leave enough room to add Entry_Unknown. - Switch out the CONFIG_DEBUG_BUILD || BENCHMARK TRACK ENTRIES #if in the x86 breakpoint code with the more concise `TRACK_KERNEL_ENTRIES` define used elsewhere. Signed-off-by: julia --- include/kernel/traps.h | 4 ++++ libsel4/include/sel4/benchmark_track_types.h | 8 ++++++-- src/arch/x86/machine/breakpoint.c | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/include/kernel/traps.h b/include/kernel/traps.h index 3574db8fb..22d53e1db 100644 --- a/include/kernel/traps.h +++ b/include/kernel/traps.h @@ -41,6 +41,10 @@ static inline void c_exit_hook(void) } #endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */ +#ifdef TRACK_KERNEL_ENTRIES + ksKernelEntry.path = Entry_Unknown; +#endif + arch_c_exit_hook(); } diff --git a/libsel4/include/sel4/benchmark_track_types.h b/libsel4/include/sel4/benchmark_track_types.h index 8aa349dde..c51992a5a 100644 --- a/libsel4/include/sel4/benchmark_track_types.h +++ b/libsel4/include/sel4/benchmark_track_types.h @@ -12,15 +12,19 @@ #if (defined CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES || defined CONFIG_DEBUG_BUILD) /* the following code can be used at any point in the kernel - * to determine detail about the kernel entry point */ + * to determine detail about the kernel entry point. + * Note that all these values must fit in 3 bits for the `seL4_Word path: 3` + * bitfield below. + */ typedef enum { + /* The kernel doesn't know why */ + Entry_Unknown, Entry_Interrupt, Entry_UnknownSyscall, Entry_UserLevelFault, Entry_DebugFault, Entry_VMFault, Entry_Syscall, - Entry_UnimplementedDevice, #ifdef CONFIG_ARCH_ARM Entry_VCPUFault, #endif diff --git a/src/arch/x86/machine/breakpoint.c b/src/arch/x86/machine/breakpoint.c index 412eb87aa..9d2a3ec13 100644 --- a/src/arch/x86/machine/breakpoint.c +++ b/src/arch/x86/machine/breakpoint.c @@ -587,7 +587,7 @@ exception_t handleUserLevelDebugException(int int_vector) getAndResetActiveBreakpoint_t active_bp; testAndResetSingleStepException_t single_step_info; -#if defined(CONFIG_DEBUG_BUILD) || defined(CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES) +#ifdef TRACK_KERNEL_ENTRIES ksKernelEntry.path = Entry_UserLevelFault; ksKernelEntry.word = int_vector; #endif /* DEBUG */