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 <git.ts@trainwit.ch>
This commit is contained in:
julia
2025-08-20 17:52:35 +10:00
committed by Indan Zupancic
parent f5e45a2453
commit 09e6c3f5e2
3 changed files with 11 additions and 3 deletions

View File

@@ -41,6 +41,10 @@ static inline void c_exit_hook(void)
} }
#endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */ #endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
#ifdef TRACK_KERNEL_ENTRIES
ksKernelEntry.path = Entry_Unknown;
#endif
arch_c_exit_hook(); arch_c_exit_hook();
} }

View File

@@ -12,15 +12,19 @@
#if (defined CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES || defined CONFIG_DEBUG_BUILD) #if (defined CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES || defined CONFIG_DEBUG_BUILD)
/* the following code can be used at any point in the kernel /* 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 { typedef enum {
/* The kernel doesn't know why */
Entry_Unknown,
Entry_Interrupt, Entry_Interrupt,
Entry_UnknownSyscall, Entry_UnknownSyscall,
Entry_UserLevelFault, Entry_UserLevelFault,
Entry_DebugFault, Entry_DebugFault,
Entry_VMFault, Entry_VMFault,
Entry_Syscall, Entry_Syscall,
Entry_UnimplementedDevice,
#ifdef CONFIG_ARCH_ARM #ifdef CONFIG_ARCH_ARM
Entry_VCPUFault, Entry_VCPUFault,
#endif #endif

View File

@@ -587,7 +587,7 @@ exception_t handleUserLevelDebugException(int int_vector)
getAndResetActiveBreakpoint_t active_bp; getAndResetActiveBreakpoint_t active_bp;
testAndResetSingleStepException_t single_step_info; 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.path = Entry_UserLevelFault;
ksKernelEntry.word = int_vector; ksKernelEntry.word = int_vector;
#endif /* DEBUG */ #endif /* DEBUG */