# SEV SNP Runner in LiteBox: Architecture, Boot Sequence, and Runtime Services

> Explore the SEV SNP runner in LiteBox. Learn how this minimal no_std binary bootstraps the LiteBox sandbox inside AMD SEV-SNP VMs using the GHCB protocol.

- Repository: [Microsoft/litebox](https://github.com/microsoft/litebox)
- Tags: architecture
- Published: 2026-02-16

---

**The SEV SNP runner is a minimal `no_std` binary that executes inside an AMD SEV-SNP virtual machine to bootstrap the LiteBox sandbox, bridging guest-side code to the host VMM through the GHCB protocol.**

The SEV SNP runner serves as the secure foundation for Microsoft's LiteBox project, enabling confidential computing by running Linux user-mode programs within AMD SEV-SNP protected virtual machines. This `no_std` Rust binary functions as both a bootloader and runtime environment, managing everything from initial VM setup to graceful termination through SEV-SNP hypercalls.

## What Is the SEV SNP Runner?

The **SEV SNP runner** (`litebox_runner_snp`) is a specialized, `no_std` executable designed specifically for AMD SEV-SNP (Secure Encrypted Virtualization-Secure Nested Paging) environments. Unlike traditional hypervisor-based runners, this component operates entirely within the encrypted guest VM, providing the minimal runtime necessary to bootstrap the LiteBox sandbox.

The runner fulfills three critical roles:

- **Bootstrapper**: Initializes the GHCB (Guest-Host Communication Block) and establishes the encrypted memory environment using the SEV encryption bit (`PRIVATE_PTE_MASK = 1 << 51`).
- **Bridge**: Translates between guest-side Linux ABI expectations and host VMM services through SEV-SNP hypercalls.
- **Runtime**: Manages page faults, system calls, thread scheduling, network I/O, and clean VM termination via the SEV-SNP termination protocol.

## Architectural Components

The SEV SNP runner consists of tightly integrated assembly and Rust components that handle the transition from bare-metal VM startup to high-level sandbox execution.

| Component | Role | Source Location |
|-----------|------|-----------------|
| **`entry.S`** | Assembly entry points including `_start`, `sandbox_kernel_start`, `sandbox_process_start`, and `entry_SYSCALL_64`. Handles stack alignment and ISR vector setup. | `litebox_runner_snp/src/entry.S` |
| **[`main.rs`](https://github.com/microsoft/litebox/blob/main/main.rs)** | Core Rust logic implementing `page_fault_handler`, `sandbox_process_init`, and `sandbox_tun_read_write`. Constructs the `LinuxShim` and manages program loading. | [`litebox_runner_snp/src/main.rs`](https://github.com/microsoft/litebox/blob/main/litebox_runner_snp/src/main.rs) |
| **[`globals.rs`](https://github.com/microsoft/litebox/blob/main/globals.rs)** | Defines SEV-SNP termination constants (`SM_TERM_EXCEPTION`, `SM_TERM_INVALID_PARAM`, etc.) used for hypercall-based shutdown. | [`litebox_runner_snp/src/globals.rs`](https://github.com/microsoft/litebox/blob/main/litebox_runner_snp/src/globals.rs) |
| **[`snp_impl.rs`](https://github.com/microsoft/litebox/blob/main/snp_impl.rs)** | Implements `HostSnpInterface` providing GHCB-based communication, memory allocation callbacks, and the `terminate` hypercall. | [`litebox_platform_linux_kernel/src/host/snp/snp_impl.rs`](https://github.com/microsoft/litebox/blob/main/litebox_platform_linux_kernel/src/host/snp/snp_impl.rs) |
| **[`platform_multiplex.rs`](https://github.com/microsoft/litebox/blob/main/platform_multiplex.rs)** | Compile-time platform selection that routes to `SnpLinuxKernel` when the `platform_linux_snp` feature is enabled. | [`litebox_platform_multiplex/src/lib.rs`](https://github.com/microsoft/litebox/blob/main/litebox_platform_multiplex/src/lib.rs) |

## Boot Sequence: From CPU Reset to Guest Execution

The SEV SNP runner follows a strict three-phase boot process that transitions from assembly initialization to Rust-based runtime management.

### Phase 1: Assembly Entry Point

When the SEV-SNP VM boots, execution begins at `_start` in `litebox_runner_snp/src/entry.S`. This assembly routine performs critical early setup:

1. Aligns the stack pointer to satisfy System V AMD64 ABI requirements.
2. Disables interrupts to prevent early exception handling before the IDT is ready.
3. Jumps to `sandbox_kernel_init` to enter the Rust runtime.

### Phase 2: Kernel Initialization

The `sandbox_kernel_init` function in [`main.rs`](https://github.com/microsoft/litebox/blob/main/main.rs) receives the `vmpl2_boot_params` structure from the host VMM, which contains the GHCB page address and CPU frequency. This phase:

- Validates and maps the GHCB page via `GhcbProtocol::setup_ghcb_page`, establishing the encrypted communication channel.
- Stores the GHCB reference in `HostSnpInterface` for future hypercalls.
- Invokes `HostSnpInterface::return_to_host` to trigger a VM-exit, allowing the host to complete kernel setup.

### Phase 3: Process Initialization

After the host resumes the VM, execution continues at `sandbox_process_start` → `sandbox_process_init`. This final boot phase:

- Reads the current CR3 register to obtain the guest page-directory base.
- Constructs the `SnpLinuxKernel` platform implementation (`litebox_platform_linux_kernel::host::snp::snp_impl::SnpLinuxKernel`).
- Builds a `LinuxShim` using `LinuxShimBuilder` to wire LiteBox core services to the host.
- Parses `argv` and environment variables from `boot_params`.
- Loads the guest ELF binary via `shim.load_program`.
- Transfers control to `run_thread` in [`snp_impl.rs`](https://github.com/microsoft/litebox/blob/main/snp_impl.rs), entering the guest program's entry point.

## Runtime Services and System Integration

Once booted, the SEV SNP runner provides comprehensive runtime services that allow unmodified Linux binaries to execute securely within the encrypted VM.

### Page Fault Handling

The `page_fault_handler` in [`litebox_runner_snp/src/main.rs`](https://github.com/microsoft/litebox/blob/main/litebox_runner_snp/src/main.rs) manages memory access violations. When a fault occurs:

1. The handler queries the `page_manager` from the `LinuxShim` to resolve the fault.
2. For kernel-space faults, it searches the exception table (`exception_table::search_exception_tables`) to determine if the fault is recoverable.
3. Unrecoverable faults trigger `HostSnpInterface::terminate` with `SM_SEV_TERM_SET` (0x3) and `SM_TERM_EXCEPTION`, causing the VMM to shut down the VM.

### System Call Dispatch

System calls from the guest binary flow through a dedicated assembly stub:

1. The `entry_SYSCALL_64` vector in `entry.S` saves guest registers to the stack.
2. Control transfers to `do_syscall_64`, which forwards to `snp_impl::handle_syscall`.
3. The Rust handler interprets the syscall using `litebox::syscalls` and routes requests to the host via GHCB when necessary.

### Thread Lifecycle Management

The runner manages guest threads through structures defined in [`snp_impl.rs`](https://github.com/microsoft/litebox/blob/main/snp_impl.rs):

- **`run_thread`**: Installs the shim in thread-local storage and invokes the shim's `init` method.
- **`ACTIVE_THREAD_COUNT`**: Tracks running threads; incremented on thread creation and decremented on exit.
- **Reinvocation**: The shim returns `ResumeGuest` to continue execution or `ExitThread` to terminate the thread.
- **Shutdown**: When `all_threads_exited()` returns true, the main loop in `sandbox_tun_read_write` terminates and returns control to the host.

### Network I/O Bridge

Network operations bridge the guest and host through `sandbox_tun_read_write` in [`main.rs`](https://github.com/microsoft/litebox/blob/main/main.rs):

1. The shim's `perform_network_interaction` method determines if the operation can complete immediately or requires waiting.
2. Return values `CallAgainImmediately` or `WaitOnDeviceOrSocketInteraction` drive the polling loop.
3. The loop continues until all threads exit, ensuring asynchronous network I/O does not block VM termination.

### Graceful Termination

The SEV SNP runner implements clean shutdown through the AMD SEV-SNP termination protocol:

- **Error Handling**: Fatal errors (invalid boot parameters, missing GHCB, unhandled exceptions) invoke `HostSnpInterface::terminate`.
- **Termination Sets**: The runner uses `SM_SEV_TERM_SET` (0x3) with specific reason codes from [`globals.rs`](https://github.com/microsoft/litebox/blob/main/globals.rs) such as `SM_TERM_EXCEPTION`, `SM_TERM_INVALID_PARAM`, or `SM_TERM_NO_GHCB`.
- **VM Exit**: The termination hypercall triggers a SEV-SNP "VM exit with termination request," allowing the host VMM to cleanly shut down the VM and log the termination reason.

## SEV-SNP Specific Implementation Details

The runner leverages AMD-specific confidential computing features to maintain isolation between the guest and hypervisor while enabling necessary communication.

### GHCB Communication Protocol

The **Guest-Host Communication Block (GHCB)** serves as the sole communication channel between the encrypted guest and the host VMM:

- **Setup**: During initialization, `GhcbProtocol::setup_ghcb_page` validates the GHCB page address provided in `vmpl2_boot_params` and maps it for use.
- **Debug Output**: The `ghcb_prints` function writes to the GHCB console buffer, making debug messages visible to the host without breaking encryption boundaries.
- **Hypercalls**: All host requests—including memory allocation, I/O, and termination—flow through GHCB-based protocols defined in `HostSnpInterface`.

### Memory Encryption

The runner ensures all guest memory remains encrypted using the VM-derived key:

- **Encryption Bit**: The `SnpLinuxKernel` memory provider sets `PRIVATE_PTE_MASK = 1 << 51`, the AMD-defined encryption bit for SEV-SNP.
- **Secure Allocation**: Guest physical pages are allocated through `HostSnpInterface::alloc`, which routes requests to the VMM via GHCB to ensure proper encryption metadata.
- **Isolation**: The `free` callback similarly routes through the GHCB, ensuring the hypervisor cannot observe decrypted memory contents during deallocation.

### Termination Constants

The [`globals.rs`](https://github.com/microsoft/litebox/blob/main/globals.rs) file defines constants that map directly to the AMD SEV-SNP specification:

- **`SM_SEV_TERM_SET = 0x3`**: Identifies the termination set for SEV-SNP specific reasons.
- **Reason Codes**: `SM_TERM_EXCEPTION`, `SM_TERM_INVALID_PARAM`, `SM_TERM_NO_GHCB`, and others provide granular error reporting to the host VMM.
- **Protocol Compliance**: By using these constants with `HostSnpInterface::terminate`, the runner ensures the VMM can interpret shutdown reasons according to the AMD SEV-SNP standard.

## Building and Running the SEV SNP Runner

To deploy the SEV SNP runner inside an encrypted VM, you must build it as a `no_std` binary using the custom target configuration provided in the repository.

### Building the Runner

The build process requires nightly Rust to support the custom target and `no_std` environment:

```bash

# Build the runner (no_std, custom target)

cargo +nightly build --manifest-path litebox_runner_snp/Cargo.toml \
    --target litebox_runner_snp/target.json -Zbuild-std=core,alloc

```

The resulting ELF (e.g., `target/litebox_runner_snp/release/litebox_runner_snp`) must be copied into the guest VM image. The host VMM boots the VM and passes the `vmpl2_boot_params` structure containing the GHCB page address and boot arguments.

### Runtime Initialization Flow

The following simplified excerpt from [`litebox_runner_snp/src/main.rs`](https://github.com/microsoft/litebox/blob/main/litebox_runner_snp/src/main.rs) demonstrates how the runner initializes the platform and transfers control to the guest program:

```rust
#[unsafe(no_mangle)]
pub extern "C" fn sandbox_process_init(
    _pt_regs: &mut litebox_common_linux::PtRegs,
    boot_params: &'static litebox_platform_linux_kernel::host::snp::snp_impl::vmpl2_boot_params,
) -> ! {
    // 1️⃣ Initialise the platform (GHCB, CPU frequency, etc.)
    ghcb_prints("sandbox_kernel_init called\n");
    
    // 2️⃣ Build the LiteBox shim
    let mut shim_builder = litebox_shim_linux::LinuxShimBuilder::new();
    let litebox = shim_builder.litebox();
    let in_mem_fs = litebox::fs::in_mem::FileSystem::new(litebox);
    shim_builder.set_fs(shim_builder.default_fs(in_mem_fs, /* ... */));

    // 3️⃣ Parse argv / env from the boot params
    let (program, argv, envp) = parse_args(boot_params).expect("invalid args");

    // 4️⃣ Load the guest ELF and store the shim globally
    let shim = shim_builder.build();
    unsafe { SHIM = Some(shim) };

    // 5️⃣ Load the program and start the first thread
    let program = SHIM.as_ref().unwrap()
        .load_program(platform.init_task(boot_params), &program, argv, envp)
        .expect("load failed");

    // 6️⃣ Transfer control to the guest thread (never returns)
    unsafe {
        litebox_platform_linux_kernel::host::snp::snp_impl::run_thread(
            alloc::boxed::Box::new(program.entrypoints),
            _pt_regs,
        )
    }
}

```

This initialization sequence demonstrates how the SEV SNP runner transitions from bare-metal VM state to executing a sandboxed Linux binary, with all host communication routed through the GHCB protocol established during the kernel initialization phase.

## Summary

The SEV SNP runner is the critical `no_std` binary that enables LiteBox to operate within AMD SEV-SNP confidential computing environments. Key takeaways include:

- **Minimal Footprint**: The runner is a `no_std` Rust binary compiled with a custom target, eliminating standard library dependencies that could compromise the trusted computing base.
- **GHCB-Based Communication**: All host interactions—including memory allocation, debug output, and VM termination—flow through the Guest-Host Communication Block protocol defined in [`snp_impl.rs`](https://github.com/microsoft/litebox/blob/main/snp_impl.rs).
- **Three-Phase Boot**: The runner progresses from assembly entry (`_start`) to kernel initialization (`sandbox_kernel_init`) to process initialization (`sandbox_process_init`) before transferring control to the guest program via `run_thread`.
- **Encrypted Memory**: The runner ensures all guest pages are marked with the SEV encryption bit (`PRIVATE_PTE_MASK = 1 << 51`), maintaining confidentiality even from the hypervisor.
- **Standardized Termination**: Error handling uses AMD SEV-SNP termination constants (`SM_SEV_TERM_SET = 0x3`) to communicate shutdown reasons to the VMM via the `terminate` hypercall.

## Frequently Asked Questions

### What is the primary purpose of the SEV SNP runner in LiteBox?

The SEV SNP runner serves as the secure bootstrapper and runtime environment for LiteBox inside AMD SEV-SNP virtual machines. It is a `no_std` binary that initializes the GHCB communication channel, sets up encrypted memory pages using the SEV encryption bit, and bridges Linux user-mode system calls to the host VMM while maintaining strict confidentiality guarantees against a potentially malicious hypervisor.

### How does the SEV SNP runner communicate with the host VMM?

All communication flows through the **Guest-Host Communication Block (GHCB)** protocol implemented in [`snp_impl.rs`](https://github.com/microsoft/litebox/blob/main/snp_impl.rs). During initialization, `GhcbProtocol::setup_ghcb_page` validates the GHCB page address provided in `vmpl2_boot_params` and maps it for use. The runner then uses this channel for debug output via `ghcb_prints`, memory allocation requests through `HostSnpInterface::alloc`, and VM termination via the `terminate` hypercall. This protocol ensures that all host interactions follow AMD SEV-SNP security specifications.

### What happens when the SEV SNP runner encounters a fatal error?

Fatal errors trigger the SEV-SNP termination protocol defined in [`globals.rs`](https://github.com/microsoft/litebox/blob/main/globals.rs). The runner invokes `HostSnpInterface::terminate` with `SM_SEV_TERM_SET` (0x3) and a specific reason code such as `SM_TERM_EXCEPTION` for unhandled page faults or `SM_TERM_INVALID_PARAM` for boot parameter errors. This generates a SEV-SNP "VM exit with termination request" that forces the VMM to shut down the VM cleanly while preserving the error code for host-side logging and debugging.

### How is the SEV SNP runner different from standard LiteBox runners?

Unlike standard runners that may execute within a traditional Linux environment or rely on the Rust standard library, the SEV SNP runner is built with `no_std` and targets a custom JSON target specification ([`litebox_runner_snp/target.json`](https://github.com/microsoft/litebox/blob/main/litebox_runner_snp/target.json)). It operates exclusively within the SEV-SNP trust boundary, managing memory encryption explicitly via `PRIVATE_PTE_MASK` and using GHCB-based hypercalls rather than standard system calls. This design eliminates dependencies on the host operating system, reducing the attack surface for confidential computing workloads.