Syscall ABI

This page documents the system call interface between userspace and the kernel.

Calling Convention

x86_64

Syscall instruction: syscall.

Register Direction Content

rax

in

Syscall number (0-30).

rdi

in

Argument 1 (capability address or operand).

rsi

in

Argument 2 (message info or operand).

rdx

in/out

Argument 3 / return value 2.

r10

in

Argument 4 (replaces rcx, which is clobbered by syscall).

r8

in

Argument 5.

r9

in

Argument 6.

rax

out

Error code (0 = success).

rdx

out

Return value (badge, bits, result).

Entry point: syscall.S swaps to the kernel GS base and saves the caller’s user RSP on the per-thread kernel stack. The per-CPU %gs:16 slot is shared state overwritten by other threads' syscalls and is not used for RSP preservation. After executing the fastpath attempt or dispatching to syscall_handle_rust(), the stub restores the user RSP from the per-thread kernel stack before sysretq. The assembly stub checks the syscall number and dispatches Call (2) and ReplyRecv (3) to the IPC fastpath before falling through to syscall_handle_rust().

aarch64

Syscall instruction: svc #0.

Register Direction Content

x8

in

Syscall number.

x0-x5

in

Arguments 1-6.

x0

out

Error code.

x1

out

Return value.

Syscall Table

# Name Description

0

Send

Blocking send to endpoint.

1

Recv

Blocking receive from endpoint.

2

Call

Send + receive (client RPC). Has fastpath.

3

ReplyRecv

Reply to caller + wait for next. Has fastpath.

4

NBSend

DEPRECATED. Slot retired; kernel returns InvalidArgument. Do not use.

5

Signal

Signal notification (atomic OR).

6

Wait

Wait on notification (blocks if no bits pending).

7

Poll

Non-blocking poll notification.

8

Yield

Yield CPU to next ready thread.

9

Invoke

Capability invocation (CNode/Untyped/TCB/VSpace/IRQ/IoPort/MO operations).

10

DebugPutChar

Write character to serial.

11

DebugDumpState

Dump CPU/scheduler state to serial.

12

ClockGetTime

Read monotonic clock (nanoseconds).

13

NanoSleep

Sleep for duration (nanoseconds).

14

DebugPutStr

Write string to serial.

15

DebugPutBuf

Write buffer to serial.

16

DebugConsoleControl

Enable/disable kernel console.

17

SetInvokeDepths

Set CNode resolution depths for invoke.

18

Futex

Userspace futex (wait/wake/requeue).

19

GetRandom

Get random bytes (RDRAND on x86_64).

20

Shutdown

ACPI system shutdown.

21

SendTimed

Blocking send with timeout.

22

RecvTimed

Blocking receive with timeout.

23

RecvAny

Receive from any registered endpoint.

24

ReplyRecvAny

Reply + receive from any endpoint.

25

RecvAnyTimed

RecvAny with timeout.

26

ReplyRecvAnyTimed

ReplyRecvAny with timeout.

27

NotifReturn

Return from notification dispatcher.

28

ThreadExit

Terminate the calling thread and release its kernel-owned state.

29

SysInfo

Read kernel-wide static info (uptime, online CPU count, tick frequency, version).

30

SysMemInfo

Sample global memory accounting (total / free / used frame counts and allocator watermarks).

Message Info Encoding

The msg_info word (passed in rsi on x86_64, x1 on aarch64) packs three fields:

Bits  6:0  — length     (0-127 message registers)
Bits 11:7  — extra_caps (0-4 capabilities to transfer)
Bits 51:12 — label      (40-bit operation identifier)

MR0-MR3 are passed in registers. MR4-MR19 overflow into the IPC buffer.

Dispatch Flow

Diagram

Error Codes

SyscallError variants returned in rax (x86_64) or x0 (aarch64):

Value Name Meaning

0

None

Success.

1

InvalidCapability

Capability address does not resolve to a valid capability.

2

InvalidOperation

Operation not supported for this object type, or the object is in an incompatible state.

3

InsufficientRights

Capability lacks the required right for the operation.

4

InvalidArgument

Argument value out of range or semantically invalid.

5

OutOfMemory

Untyped memory exhausted, no free frames, or kernel pool saturated.

6

NotFound

Named resource or slot is empty / absent.

7

Busy

Object is in use by another operation and the caller did not request blocking.

8

AlreadyExists

Target identity already assigned (bound notification, mapping, etc.).

9

WouldBlock

Non-blocking variant could not proceed without blocking.

10

BadAddress

User pointer is unmapped, non-canonical, or lacks the required permissions.

11

OutOfRange

Requested index, count, or derivation depth exceeds a kernel limit.

12

Cancelled

Operation aborted because the caller or target was torn down.

13

Restart

Kernel asks userspace to retry (e.g. interrupted notification dispatcher).

14

Deadlock

Requested lock or donation chain would violate the global ordering.

15

Interrupted

Operation interrupted by a signal or notification.

0x10

TRONA_IN_PROGRESS

Operation in progress.

0x11

TRONA_TOO_LARGE

Object or buffer too large.

0x12

TRONA_NOT_SUPPORTED

Operation not supported.

0x13

TRONA_READONLY

Target is read-only.

0x14

TRONA_NOT_DIRECTORY

Not a directory.

0x15

TRONA_IS_DIRECTORY

Is a directory.

0x16

TRONA_LOOP

Symbolic link loop detected.

0x17

TRONA_IO_ERROR

I/O error.

0x18

SlotOccupied

Destination CNode slot is not empty.

0x19

AlreadyMapped

VSpace range already has a mapping installed.

0x1A

AlreadyBound

TCB is already bound to a notification / scheduling context.

Invoke Dispatch

Syscall 9 (Invoke) resolves a capability and dispatches based on the message label. See Capability Invocations for the complete label table.

The invoke path:

  1. Resolve the capability address through the caller’s CSpace.

  2. Check that the capability has the required rights for the operation.

  3. Dispatch to the object-type-specific handler based on msg_info.label.

  4. Return the result to userspace.