Skip to content

Inter-VM Communication

TL;DR

VMs on a cockpit SoC are deliberately isolated: separate memory, separate kernels, separate device views. Yet QNX must push vehicle speed to VHAL, route audio, and share camera frames with AAOS. Inter-VM communication uses layered mechanisms: VirtIO (standardized virtual devices over shared queues), vsock (socket-like VM-to-VM addressing), gRPC over vsock (structured RPC for VHAL and services), and shared memory / RTISM (zero-copy bulk data). Pick the wrong mechanism and you get latency spikes, security holes, or fragile integrations.

Vehicle speed in your Android app didn’t magically cross from CAN. It traveled QNX gateway → IPC → VHAL → CarService → your app, mostly across VM boundaries. This page maps that pipe.

Guest VMs have separate stage-2 address spaces. AAOS cannot dereference a QNX pointer. The hypervisor would trap and kill the access. All cross-VM data exchange must go through hypervisor-approved channels:

  1. Explicit shared memory regions (carved at boot)
  2. Virtual devices (VirtIO) with queue-based I/O
  3. Socket abstraction (vsock) over hypervisor-mediated transport

VMs are air-gapped computers. Communication goes through diplomatic channels, not shared walls.

Mental Model

Two embassy buildings (VMs) in the same city (SoC). Staff cannot walk through walls. They exchange:

  • Formal letters (gRPC messages over vsock) for structured requests
  • Parcel drops (VirtIO queues) for standard device I/O
  • Shared courier lockers (RTISM shared memory) for bulky packages (audio buffers, camera frames)

The hypervisor is the diplomatic corps — inspects every channel, no unauthorized tunnels.

VirtIO is an open standard for paravirtualized devices. Guests use a common driver model instead of emulating legacy hardware register-by-register.

Component Role
Virtqueue Ring buffer in shared memory: host/guest post requests and completions
VirtIO device Block, network, console, socket, custom vendor devices
Transport MMIO or modern virtio-vsock, virtio-gpu variants

On automotive QNX + AAOS stacks, VirtIO often backs:

  • Console / logging taps between host and guest
  • Block device access to shared storage regions
  • Network-style pipes where full TCP stack is overkill

VirtIO is virtual I/O with a common standard: write once, run on any hypervisor that supports it.

Common Gotcha

VirtIO is not “free IPC.” Each virtqueue operation has notify/trap overhead. High-frequency, small messages (1000 Hz vehicle signals) may need shared memory rings or batching, not per-signal VirtIO block requests.

vsock (Virtual Socket) provides socket semantics between VMs and between guest and host, without real network hardware.

Property Detail
Addressing CID (Context ID) per VM + port number, not IP addresses
Typical CIDs Host (QNX) = CID 2, first guest (AAOS) = CID 3 (platform-specific)
API BSD sockets-like: socket(AF_VSOCK, ...), connect, bind, listen
Isolation Hypervisor routes; VMs cannot spoof arbitrary CIDs without config

vsock is VM-to-VM socket addressing over the hypervisor, not over real network hardware.

Example mental model (not literal API):

AAOS (CID 3, port 5000) ──vsock──▶ QNX (CID 2, port 5000)
"connect to host VHAL proxy"

vsock is the transport. What you send over it defines the protocol, often gRPC.

gRPC (HTTP/2 + Protobuf) gives typed, versioned RPC, ideal for Vehicle HAL (VHAL) property get/set/subscribe across VM boundaries.

Typical flow for vehicle speed:

sequenceDiagram
participant CAN as CAN Bus / Gateway
participant QNX as QNX Host (VM0)
participant VSOCK as vsock Channel
participant VHAL as VHAL Proxy (AAOS)
participant CS as CarService
participant APP as Android App
CAN->>QNX: Vehicle speed frame
QNX->>QNX: Parse signal · update property cache
VHAL->>VSOCK: gRPC Get / Subscribe (PERF_VEHICLE_SPEED)
VSOCK->>QNX: Forward request
QNX->>VSOCK: gRPC response (speed = 72.4 km/h)
VSOCK->>VHAL: Return property value
VHAL->>CS: AIDL property update
CS->>APP: OnChangeListener callback
Layer Technology Purpose
Physical signal CAN / Ethernet Raw vehicle data
QNX side Gateway service, property store Parse, validate, rate-limit
Transport vsock VM-safe byte stream
RPC gRPC + Protobuf Typed VHAL property access
AAOS side VHAL implementation → AIDL → CarService Android-facing API
Where You'll See This

When VHAL returns WRONG_VALUE or TIMEOUT:

  1. Check QNX gateway: is the CAN signal arriving? (slog2info, gateway logs)
  2. Check vsock connectivity: is AAOS CID reaching QNX CID? (port conflicts, firewall rules in VM config)
  3. Check gRPC service: is VehicleHal proxy running on QNX side post-boot?
  4. Don’t assume Android bug first. Most VHAL issues are host-side signal or IPC, not app code.

adb shell dumpsys android.automotive.evs and vendor VHAL test tools help, but QNX serial often tells the truth first.

For high bandwidth, low latency data (audio PCM rings, camera frame buffers, large sensor blobs), shared memory (SHM) beats socket copy loops.

Mechanism Typical Use
RTISM (Real-Time IPC Shared Memory) QNX ↔ guest bulk IPC regions configured at hypervisor boot
ION / dma-buf (Android side) Graphics and media buffer sharing, often mediated by host
Hypervisor-carved SHM Fixed physical pages mapped into multiple VM address spaces

Properties:

  • Zero-copy (after setup): producer writes, consumer reads same physical frames
  • Synchronization required: doorbells, futexes, or QNX pulse events
  • Security-critical: only explicitly shared regions are mapped; size and VM access are fixed at integration

RTISM (Real-Time IPC Shared Memory) is the high-throughput path when setup and sync are done right.

Common Gotcha

Shared memory without a sync protocol = data races. Audio glitches and torn camera frames often trace to missing doorbell interrupts or cache coherency assumptions, not buffer size alone.

Need Mechanism Why
VHAL property get/set/subscribe gRPC over vsock Typed, versioned, moderate frequency
Audio PCM streaming Shared memory (RTISM) + doorbell Zero-copy, low latency, high bandwidth
Camera / display buffer handoff Shared memory + ION/dma-buf mediation Large frames, GPU alignment requirements
Console / debug tap VirtIO console Standard, simple
Bulk logging to host VirtIO console or vsock stream Fire-and-forget tolerance
Modem ↔ AP communication SMD / GLink / QRTR (not inter-VM) Cross-processor, not QHEE guest IPC
QNX ↔ AAOS generic service RPC gRPC over vsock Extensible beyond VHAL
High-rate sensor fan-in (100+ Hz) Shared memory ring or batched gRPC Avoid per-sample syscall overhead
OTA status / low-rate events gRPC over vsock or vsock datagram Small payloads, reliability matters
flowchart LR
subgraph VM0["QNX Host VM (CID 2)"]
GW["CAN / Ethernet Gateway"]
PROP["VHAL Property Service"]
AUD["Audio Manager"]
CAM["Camera / ISP Bridge"]
end
subgraph IPC["Hypervisor-Mediated IPC"]
VSOCK["vsock<br/>(CID + port routing)"]
VIRTIO["VirtIO Queues"]
SHM["Shared Memory<br/>(RTISM regions)"]
end
subgraph VM1["AAOS Guest VM (CID 3)"]
VHAL["VHAL Implementation"]
CS["CarService"]
AF["AudioFlinger"]
HAL["Camera HAL"]
end
subgraph MP["Modem (Separate Processor)"]
AMSS["AMSS / Telephony"]
end
GW --> PROP
PROP <-->|"gRPC"| VSOCK
VSOCK <-->|"gRPC"| VHAL
VHAL --> CS
AUD <-->|"PCM buffers"| SHM
SHM <-->|"PCM buffers"| AF
CAM <-->|"Frame buffers"| SHM
SHM <-->|"Frame buffers"| HAL
VIRTIO <-->|"Console / misc I/O"| VM0
VIRTIO <-->|"Console / misc I/O"| VM1
GW <-->|"SMD / QRTR<br/>(not vsock)"| AMSS
Security and Attack Surface

Every IPC channel is a trust boundary. vsock ports must be allowlisted in VM config. A compromised AAOS guest shouldn’t reach arbitrary QNX services. gRPC services should authenticate callers where OEM policy requires. Shared memory regions must be read-only on one side when possible (e.g., AAOS reads speed ring, QNX writes). Threat modeling treats guest → host as hostile direction by default.

Connect the Dots

Page 5.4 showed QNX and AAOS as separate VMs. This page explains the wires between them, the path Module 6’s VHAL rides on. Module 3’s service-oriented thinking (RPC, typed contracts) reappears here as gRPC over vsock. Module 7’s AMSS path uses SMD/QRTR, not VirtIO: different processor, different rules.

  1. VMs cannot share pointers. Use VirtIO, vsock, gRPC, or shared memory.
  2. VHAL typically uses gRPC over vsock for typed property access QNX → AAOS.
  3. Audio and camera use shared memory (RTISM) for zero-copy throughput.
  4. AMSS uses SMD/GLink/QRTR: cross-processor IPC, not inter-VM vsock.

Check Your Understanding

1. Which IPC stack is the standard path for AAOS VHAL to request vehicle speed from the QNX host?

2. Why is shared memory (RTISM) preferred over gRPC for audio PCM streaming between QNX and AAOS?

3. How does AMSS on the modem processor communicate with the applications processor?