rust-embedded/rust-raspberrypi-OS-tutorials · critical
Should not be here. Use of SP_EL0 in EL1 is not supported.
Error message
Should not be here. Use of SP_EL0 in EL1 is not supported.
What it means
current_el0_synchronous is the vector-table entry for synchronous exceptions taken at the current exception level when using SP_EL0, which this kernel does not support (it runs at EL1 with its own stack). The handler unconditionally panics. It exists only so that every vector slot is defined; reaching it means user-mode (EL0) execution or SP_EL0 use happened although the kernel never intends to support it.
Source
Thrown at 20_timer_callbacks/kernel/src/_arch/aarch64/exception.rs:76
// Private Code
//--------------------------------------------------------------------------------------------------
/// Prints verbose information about the exception and then panics.
fn default_exception_handler(exc: &ExceptionContext) {
panic!(
"CPU Exception!\n\n\
{}",
exc
);
}
//------------------------------------------------------------------------------
// Current, EL0
//------------------------------------------------------------------------------
#[no_mangle]
extern "C" fn current_el0_synchronous(_e: &mut ExceptionContext) {
panic!("Should not be here. Use of SP_EL0 in EL1 is not supported.")
}
#[no_mangle]
extern "C" fn current_el0_irq(_e: &mut ExceptionContext) {
panic!("Should not be here. Use of SP_EL0 in EL1 is not supported.")
}
#[no_mangle]
extern "C" fn current_el0_serror(_e: &mut ExceptionContext) {
panic!("Should not be here. Use of SP_EL0 in EL1 is not supported.")
}
//------------------------------------------------------------------------------
// Current, ELx
//------------------------------------------------------------------------------
#[no_mangle]
extern "C" fn current_elx_synchronous(e: &mut ExceptionContext) {View on GitHub (pinned to 644474cc09)
Solutions
- Do not run code at EL0 or switch to SP_EL0; audit boot and context-switch code for `msr spsel, #0` and remove it.
- If user-mode support is intended, replace this stub with a real EL0 synchronous handler (syscall dispatch, abort handling) as a prerequisite.
- Check the ESR in a temporary debug handler to find what invoked the vector if the origin is unclear.
Example fix
// before
unsafe { core::arch::asm!("msr SPSel, #0"); } // switches to SP_EL0 -> unsupported
// after
// keep SPSel = 1: kernel always uses SP_ELx at EL1
unsafe { core::arch::asm!("msr SPSel, #1"); } Defensive patterns
Strategy: validation
Validate before calling
// Assert the kernel never switches to SP_EL0:
fn ensure_kernel_sp() {
let spsel: u64;
unsafe { core::arch::asm!("mrs {}, SPSel", out(reg) spsel) };
assert!(spsel == 1, "SPSel must be 1 at EL1");
} Prevention
- Never run code at EL0 or switch SPSel to 0 in this kernel.
- Mask exceptions (DAIF) around any stack-pointer manipulation.
- Do not issue SVC/syscall instructions unless EL0 support is implemented.
- Verify VBAR_EL1 routing so exceptions land on supported entries.
When it happens
Trigger: Taking a synchronous exception (e.g. SVC, instruction abort, data abort) at the current EL while SP_EL0 is the active stack pointer — i.e. code running in EL0 state or an explicit SP switch to SP_EL0 in EL1.
Common situations: Attempting to implement user-space processes before the kernel supports EL0, accidentally setting SPSel to 0 in early boot or context-switch code, or porting code that issues `svc` calls expecting syscall support that this tutorial kernel does not provide.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- CPU Exception! {}
- No handler registered for IRQ {}
- Error handling IRQ
- No handler registered for IRQ {}
- Error handling IRQ
AI-assisted analysis of rust-embedded/rust-raspberrypi-OS-tutorials@644474cc09 (2026-09-06).
Data as JSON: /api/errors/71a7c12561f22bbe.
Report an issue: GitHub.