QNX Hypervisor
About 1228 wordsAbout 4 min
2026-03-25
Overview
The QNX Hypervisor is a Type-1 bare-metal hypervisor that runs directly on hardware. It enables multiple independent guest operating systems (VMs) to share a single SoC while maintaining strict isolation between them.
Key use cases:
- Automotive: Run AUTOSAR Adaptive (Linux-based) alongside a QNX safety partition on the same SoC
- Industrial: Isolate real-time control from Linux-based SCADA
- Medical: Separate certified software from connectivity software
- Defense: Geographically separate red/black networks on one platform
Architecture Overview
┌─────────────────────────────────────────────────────────────────┐
│ QNX Hypervisor (Type-1) │
│ Runs in EL2 (AArch64) / VMX Root (x86_64) │
│ Tiny footprint, deterministic scheduling │
├──────────────────────┬──────────────────────┬───────────────────┤
│ VM 0 (Host VM) │ VM 1 (Guest QNX) │ VM 2 (Guest Linux│
│ QNX Neutrino │ QNX Neutrino / OS │ AUTOSAR, ADAS) │
│ ASIL D (safety) │ for Safety │ QM │
│ │ │ │
│ EL1/EL0 │ EL1/EL0 │ EL1/EL0 │
└──────────────────────┴──────────────────────┴───────────────────┘
│ │ │
└──────────────────────┼──────────────────────┘
│
┌──────────────────────▼──────────────────────┐
│ Physical Hardware (AArch64) │
│ CPUs DRAM Peripherals Interrupts │
└─────────────────────────────────────────────┘The hypervisor itself is extremely small (runs entirely in privileged EL2 mode), and delegates workloads to the Host VM (always QNX Neutrino) which manages physical devices and hosts virtual device (vdev) backends.
VM Types
| Type | Description |
|---|---|
| Host VM | First VM to start. Runs QNX Neutrino. Has direct access to physical hardware. Hosts vdev backends. One per system. |
| Guest VM | Can run QNX Neutrino, Linux, or other OSes. Sees only virtual hardware. Multiple can coexist. |
ARM Virtualization Extensions
The QNX Hypervisor leverages ARM's hardware virtualization support:
| Feature | Role |
|---|---|
| EL2 (Exception Level 2) | Hypervisor mode — traps privileged guest operations |
| Stage-2 MMU | Translates Guest Physical Address (GPA) → Host Physical Address (HPA), enforcing VM memory isolation |
| VHE (Virtualization Host Extensions) | Allows EL2 to run OS-like code more efficiently (used by Host VM) |
| Generic Timer | Per-VM virtual timer, injected as virtual interrupt |
| GICv3/GICv4 | Hardware interrupt controller with virtual interrupt injection |
| SMMU | I/O MMU — restricts DMA-capable devices to their assigned VM's memory |
VM Configuration File
Each VM is configured with a .qvmconf file:
# /etc/vms/guest-qnx.qvmconf
{
"name": "safety-vm",
"image": "/boot/safety-qnx.ifs",
"cpus": 2,
"cpulist": "2,3",
"ram": [
{ "base": "0x80000000", "size": "256M" }
],
"vdev": [
{
"type": "qvm-vdev-qcar-uart",
"config": "base=0x9000000,irq=33,baud=115200"
},
{
"type": "qvm-vdev-virtio-net",
"config": "peer=vswitch0,mac=52:54:00:12:34:56"
},
{
"type": "qvm-vdev-virtio-blk",
"config": "file=/dev/sd0t79"
}
]
}# /etc/vms/guest-linux.qvmconf
{
"name": "linux-adas",
"image": "/boot/linux-adas-kernel.bin",
"dtb": "/boot/linux-adas.dtb",
"cpus": 4,
"cpulist": "4,5,6,7",
"ram": [
{ "base": "0x100000000", "size": "1G" }
],
"vdev": [
{
"type": "qvm-vdev-virtio-net",
"config": "peer=vswitch0"
},
{
"type": "qvm-vdev-virtio-blk",
"config": "file=/dev/sd0t83"
},
{
"type": "qvm-vdev-shmem",
"config": "name=shm-safety-adas,size=4M,role=client"
}
]
}Starting and Managing VMs
# Start the hypervisor (done via IFS script in Host VM)
# The hypervisor is started by the Host VM's startup code
# In the Host VM IFS .script section:
# Start virtual device server
qvm-vdev-server &
waitfor /dev/qvm 5
# Start guest VMs
qvm start /etc/vms/guest-qnx.qvmconf
qvm start /etc/vms/guest-linux.qvmconf
# List running VMs
qvm list
# Pause a VM
qvm pause safety-vm
# Resume a VM
qvm resume safety-vm
# Stop a VM gracefully
qvm stop safety-vm
# Force destroy a VM
qvm destroy safety-vm
# Show VM statistics
qvm stat safety-vmVirtual Devices (vdevs)
Virtual devices are user-space processes in the Host VM that emulate hardware for guest VMs. They communicate with the hypervisor via ioctl() on /dev/qvm.
Available vdev Types
| vdev | Description |
|---|---|
qvm-vdev-ramfb | Frame buffer (shared memory display) |
qvm-vdev-qcar-uart | Virtual UART (mapped to host UART or PTY) |
qvm-vdev-virtio-net | VirtIO network interface |
qvm-vdev-virtio-blk | VirtIO block device |
qvm-vdev-virtio-console | VirtIO console (character device) |
qvm-vdev-shmem | Shared memory region between VMs |
qvm-vdev-gic | ARM Generic Interrupt Controller emulation |
qvm-vdev-timer | Virtual timer |
qvm-vdev-pl011 | ARM PL011 UART emulation |
qvm-vdev-ioapic | x86 I/O APIC emulation |
qvm-vdev-pic | x86 PIC emulation |
qvm-vdev-ps2 | PS/2 keyboard/mouse |
VirtIO: The Guest-to-Host Communication Protocol
Guest VMs use VirtIO to communicate efficiently with the Host VM for I/O:
Guest VM Host VM (via vdev)
┌─────────────────────┐ ┌────────────────────────────┐
│ virtio-net driver │ │ qvm-vdev-virtio-net │
│ (in Linux/QNX) │ │ (in Host VM user space) │
│ │ │ │
│ virtqueue (TX) ───┼──────┼──► process packet │
│ virtqueue (RX) ◄──┼──────┼─── inject packet + IRQ │
└─────────────────────┘ └────────────────────────────┘
│ shared memory (mapped into both VMs by hypervisor)
│ virtqueue metadata in shared DMA memoryInter-VM Communication: Shared Memory
VMs can share memory regions for high-performance data exchange:
Host VM Configuration
{
"vdev": [
{
"type": "qvm-vdev-shmem",
"config": "name=shm-safety-hmi,size=8M,role=server,paddr=0x70000000"
}
]
}Guest VM Configuration
{
"vdev": [
{
"type": "qvm-vdev-shmem",
"config": "name=shm-safety-hmi,size=8M,role=client"
}
]
}Accessing Shared Memory from a QNX Guest
#include <sys/mman.h>
#include <fcntl.h>
/* Open the shared memory region (appears as typed memory in QNX guest) */
int fd = posix_typed_mem_open("shm-safety-hmi",
O_RDWR,
POSIX_TYPED_MEM_ALLOCATE);
void *shared = mmap(NULL, 8 * 1024 * 1024,
PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
/* Use a lock-free ring buffer or spinlock for synchronization */
struct shared_data *data = (struct shared_data *)shared;HVC: Hypervisor Call Interface
Guests can make HVC (Hypervisor Call) calls to request services from the hypervisor. These are similar to system calls but cross the EL1→EL2 boundary:
/* QNX-specific: vdev API for making HVC calls is wrapped
* by the qvm device driver inside the guest VM.
* Applications do not call HVC directly.
* The microkernel in each guest issues HVC for:
* - Physical interrupt routing
* - Stage-2 memory mappings
* - VM lifecycle management
*/CPU Affinity and Scheduling
# Assign CPUs 0-1 to Host VM (safety), CPUs 2-5 to Linux guest
{
"host": {
"cpulist": "0,1",
"priority": 240
},
"vms": [
{
"name": "linux-guest",
"cpulist": "2,3,4,5",
"priority": 10
}
]
}The hypervisor scheduler ensures:
- Host VM vCPUs get pinned to their assigned physical CPUs
- Guest VM vCPUs are scheduled by the QNX hypervisor scheduler on their assigned physical CPUs
- Priority-based scheduling: higher-priority VMs preempt lower-priority VMs on shared CPUs
Device Assignment (Pass-Through)
Physical devices can be assigned directly to a Guest VM, bypassing the Host VM:
{
"name": "safety-vm",
"cpulist": "0,1",
"ram": [ { "base": "0x80000000", "size": "256M" } ],
"vdev": [
{
"type": "qvm-vdev-passthrough",
"config": "paddr=0xFF000000,size=0x1000,irq=32"
}
]
}With an SMMU (ARM IOMMU), DMA from the passed-through device is restricted to the guest's physical memory range, preventing the device from accessing other VMs' memory.
QNX Hypervisor with AUTOSAR Adaptive
A common automotive deployment runs AUTOSAR Adaptive Platform on Linux in a Guest VM, alongside a QNX safety partition in the Host VM:
┌──────────────────────────────────────────────────────────────────────┐
│ QNX Hypervisor │
├──────────────────────────────────┬───────────────────────────────────┤
│ Host VM: QNX Neutrino (ASIL D) │ Guest VM: Linux + AUTOSAR AP │
│ │ │
│ • Wheel speed sensor driver │ • ARA::COM (DDS/SOME-IP) │
│ • Brake controller (ISO 26262) │ • Execution Management │
│ • APS: 40% CPU │ • Service registry │
│ │ • Navigation, ADAS apps │
│ Shares data via shmem vdev │ • Reads safety data via shmem │
└──────────────────────────────────┴───────────────────────────────────┘Nested Virtualization
QNX Hypervisor supports nested virtualization on platforms with ARM VHE:
Bare metal
└── QNX Hypervisor (EL2)
└── Host VM: QNX Neutrino
└── Guest VM 1: Another QNX hypervisor instance (for testing)This is primarily used for development and CI/CD testing of hypervisor configurations.
Diagnostic and Monitoring
# List VMs and their status
qvm list
# Show VM CPU/memory statistics
qvm stat --all
# Show interrupt statistics per VM
qvm irqstat safety-vm
# Show vdev status
qvm vdevstat safety-vm
# Debug: dump VM memory (host VM only, requires privilege)
qvm memdump safety-vm 0x80000000 4096
# Trace hypervisor events
tracelogger -f /tmp/hv_trace.kev &
pidin sched
# then:
tracelogger -X
traceevent -v /tmp/hv_trace.kev | grep qvm