Skip to content

Inside DULI ​

DULI is a processor extension, not a scheduler trick. It changes the moment an interrupt is acknowledged: instead of entering the kernel, the hardware activates the target handler together with the protection domains it is allowed to run in.

The isolation–determinism trade-off ​

A microkernel isolates each component as an unprivileged process, which is what makes modern secure embedded software possible. The interrupt handler of that component, however, is on the wrong side of the boundary:

  • In the kernel, the handler runs at kernel speed but the component's untrusted code has to be moved into the most privileged code base — the opposite of isolation.
  • In the process, the handler is confined but every activation needs a kernel round trip. Forwarding costs hundreds of cycles, an order of magnitude above a kernel interrupt.

Existing user-level interrupt mechanisms only help when the target process is already running. Intel's UINTR and the RISC-V N extension take a short path while the target is scheduled; when it is dormant, the kernel must switch to it, and the latency doubles into a slow path. The result is a bimodal distribution that improves average throughput but not the worst case. SBI solves determinism for exactly one trusted process per core.

ApproachSpatial isolationTemporal isolationMulti-processInterrupt latencyDeterminism
TockOS (kernel handlers)yesyesyeshighmedium
Hopter———mediummedium
CV32RT———lowhigh
RTOSUnit———lowhigh
UINTR / RISC-V-Nyes—yeslow (fast path)low
SBI (TrustZone-M)yesyesone processlowhigh
DULIyesyesyeslowhigh

One interrupt, two domains ​

Every user-level interrupt is described by an entry in the Interrupt Identification Data (IID). The entry answers three questions at interrupt time:

  1. is this source user-level or kernel-level?
  2. which spatial domain does its handler run in — a pointer to an entry in the PMP table, holding the complete PMP configuration for that domain;
  3. which temporal domain does it run in — a pointer to a 32-bit execution budget, loaded into a hardware countdown timer.

Several interrupts may share a spatial domain, a budget, or both. The IID is the only place where the mapping lives; the kernel can update it without touching the interrupt vector table.

The delivery path ​

IdentificationThe interrupt controller queries the IID unit. A CAM lookup (V5) or a RAM table read (V1/V2) decides whether this source is user-level and which domains it targets.
critical path
Domain activationThe PMP configuration is loaded from the PMP table; the budget is loaded from the budget table into the countdown timer. Both are ordinary memory reads, so they can run in parallel.
parallel
Context isolationThe interrupted register set — 160 bytes including mepc, mcause, mtval and the internal interrupt state — is saved to a register bank or spilled to a TCM, then zeroized before the handler sees it.
banked in V5
Handler executionThe user-level vector starts in unprivileged mode. The handler runs to completion, ending with a custom uiret instruction.
latency ends here
ReturnThe remaining budget is written back to the budget table, the context and the interrupted PMP configuration are restored, and the preempted execution continues.
no kernel code

In the V5 variant the IID lookup is folded into the acknowledge cycle and the context is banked, so the modeled entry latency is 11 cycles — 15 cycles measured end-to-end on FPGA at 50 MHz.

Confinement is enforced, not promised ​

The handler is untrusted by assumption. Two hardware conditions terminate it:

  • Spatial violation — the PMP rejects an access outside the domain. The handler is forced to return immediately, without involving the kernel.
  • Temporal violation — the budget counter reaches zero. The handler is forced to return, and the remaining budget is zero.

The same rule covers synchronous exceptions: a faulting instruction does not trap into the kernel synchronously (which would create unsafe kernel reentrancy). The cause is recorded in an optional CSR, the handler returns, and the kernel may inspect the record later, after all nested user-level interrupts have unwound.

Because a user-level interrupt can preempt the kernel itself, the kernel-managed PMP set is shadow-banked and the kernel's own timer is paused while the handler executes. The kernel resumes exactly where it left off.

Nesting without an unbounded budget ​

User-level handlers can preempt one another. The hardware keeps additional register banks for the nested contexts; when they are exhausted, it deterministically spills to a tightly-coupled memory. V5 therefore has a bounded fast path and a graceful fallback: an exhausted bank degrades to the V2 latency instead of failing.

Preemption priority is configured when the handler is registered. The extension is deliberately not a scheduler — handlers are run-to-completion, and the kernel replenishes budgets using a deferrable-server policy.

The software view ​

The kernel exposes a small API; everything else is hardware:

C
/* Register a user-level interrupt: vector, handler, scheduling policy */
int_reg(INT_UART0, uart_handler, POLICY_DEFERRABLE);

/* Set its hardware preemption priority and enable it */
int_prio(INT_UART0, 2);
int_ena(INT_UART0);
C
void uart_handler(void)
{
    /* Runs unprivileged inside the registered PMP domain */
    UART0->DATA = UART0->DATA;
    uiret();            /* return to the preempted context */
}

The kernel's process manager allocates the IID entry and the PMP domain; its budget manager programs the budget entry and replenishes it every server period. No interrupt-path code is added to the kernel.

Compatibility ​

DULI adds a handful of CSRs — duictl (global enable and IID base), duistk (spill stack), duiepc (interrupted PC) and the iid* CAM/table registers. Bit 0 of duictl disables the whole extension; the core then behaves as a standard RISC-V processor. Legacy interrupts keep the original vector table and the original entry path, so existing firmware and RTOSes do not need to change.

The prototype targets a single RISC-V core. Multi-core routing and arbitration are explicitly future work.

A research hardware extension for deterministic user-level interrupts.

DULI·Deterministic user-level interrupts·Artifact