Skip to content

feat: implement virtio based host-guest communication - #1717

Open
andreiltd wants to merge 34 commits into
hyperlight-dev:mainfrom
andreiltd:virtq-takeover
Open

feat: implement virtio based host-guest communication#1717
andreiltd wants to merge 34 commits into
hyperlight-dev:mainfrom
andreiltd:virtq-takeover

Conversation

@andreiltd

Copy link
Copy Markdown
Member

See rendered design doc. For broader context see HIP PR: #1112

This patch replaces stack based communication with function calls transported over virtual queues. The documentation covers two current limitations: snapshots do not support retained buffers, and the host owns the transport arena. Addressing both is deferred to future work.

Add distinct VecBytes and ByteChunks function value types while
preserving embedded stack encoding. Introduce the external-byte marker
for future virtq codecs and simplify the virtq message header.

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Add external-aware function call and result encoding and decoding. This
changes are transitional only and next commits will unify embedded and
external (de)coding paths.

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Read received payloads directly into caller owned storage and require
paired completion of readable/writable chains.

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Make pool restoration transactional.

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Split and rename the pool implementations, add explicit lower/upper
SlotPool regions.

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Define deterministic producer and consumer reset behavior. Validate
canonical events, descriptor chains, IDs, buffer policy, and unused
descriptors.

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Represent scratch bookkeeping with one repr(C) layout. Derive offsets
and assert the host/guest ABI at compile time.

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Use the first GPA of the reserved pages as an exclusive limit. Accept
allocations ending at the limit and reject address overflow.

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Define directional queue depths, buffer sizes, and pool page counts.
Account for guest allocated rings and pools in minimum scratch
calculations. Publish the transport contract through scratch-top
metadata.

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
This patch adds guest owned G2H and H2G rings and pools during guest
initialization, and prefill H2G receive capacity. The guest then
publishes their gpas through scratch metadata.

The patch is also validates allocation order, scratch ownership, and
canonical ring images before installing either host consumer.

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Persist validated G2H and H2G ring images in running snapshots. Restore fixed transport allocations and install fresh host consumers before sandbox execution.

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Initialize queues before first guest entry. Carry host calls, logs,
external values, and bounded responses over G2H chains.

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Route guest calls, host calls, results, and logs through bidirectional
packed virtqueues. Stream dense messages across exact chain batches and
reserve H2G capacity for retained external values.

Keep external byte returns typed through guest dispatch and support
owner-backed byte chunks in Rust and C guests.

Store canonical rings in a versioned OCI transport layer and validate
them during snapshot load and restore.

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Enter the guest once before capture to canonicalize both queues.

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Report retained pool slots through the checkpoint mailbox. Keep rejected
sandboxes usable for release and retry.

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Use queue_size instead of queue_depth

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Copilot AI lite review requested due to automatic review settings August 11, 2026 17:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

@andreiltd andreiltd added the kind/enhancement For PRs adding features, improving functionality, docs, tests, etc. label Aug 11, 2026
Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
@andreiltd andreiltd added regen-goldens Regenerate snapshot golden fixtures ready-for-review PR is ready for (re-)review labels Aug 11, 2026
@jsturtevant

Copy link
Copy Markdown
Contributor

The documentation covers two current limitations: snapshots do not support retained buffers, and the host owns the transport arena. Addressing both is deferred to future work.

What are the implications? Is there any behavior changes for existing hyperlight consumers?

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
@andreiltd

andreiltd commented Aug 12, 2026

Copy link
Copy Markdown
Member Author

The documentation covers two current limitations: snapshots do not support retained buffers, and the host owns the transport arena. Addressing both is deferred to future work.

What are the implications? Is there any behavior changes for existing hyperlight consumers?

There is no behavior changes for existing consumers, there is a new parameter type that is zero-copy: ByteChunks. VecBytes  still copies into guest heap memory, so retained values survive snapshots. The limitation applies only to this new type.

Adding snapshot support for retained  ByteChunks  is relatively straightforward. Buffer allocation state lives entirely in the guest, so the guest must publish a manifest listing the addresses the host should capture. The current implementation only detects outstanding  ByteChunks  borrows and returns an error if any exist. That said, the PR is already enormous so I decided to not implement it for this mvp.

The only real change for existing customers is minimum scratch and guest heap size increase as they need to account for virtual queues bookkeeping.

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
Allocate logical regions atomically

Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
This still will cause OOM as the test requires but will increase initial
heap size so that virtqueus finish initialization.
Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>

@ludfjig ludfjig left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't looked very detailed through the code yet:

You mentioned offline that separating ByteChunks into a separate PR without the virtio stuff is hard because ByteChunks dependo on virtio. Would it be possible instead to have the first pr be virtio stuff, and second be the bytechunks (just to make it easier to review)?

It's also my understanding that the new parameter type vec<Bytes> (rather than just Bytes without vec) is necessary for the guest to receive data zerocopy as it's not contiguous memory, but this type is also mirrored in the host api. I guess my question is do we expect it to be a useful for a host to provide multiple Bytes rather than just 1 contiguous one?

It looks like hlbytechunks and hlsizeprefixedbytechunks are not used anymore after recent commits, should they be removed?

Comment on lines 334 to 364
pub(crate) fn is_compatible_with(&self, other: &Self) -> bool {
// Exhaustive destructure so adding a field to
// `SandboxMemoryLayout` fails to compile here, forcing the
// author to decide whether it participates in compatibility.
let Self {
input_data_size,
output_data_size,
heap_size,
code_size,
init_data_size,
init_data_permissions,
scratch_size,
g2h_queue_size,
h2g_queue_size,
g2h_buffer_size,
h2g_buffer_size,
g2h_pool_pages,
h2g_pool_pages,
snapshot_size: _,
pt_size: _,
} = self;
*input_data_size == other.input_data_size
&& *output_data_size == other.output_data_size
&& *heap_size == other.heap_size
*heap_size == other.heap_size
&& *code_size == other.code_size
&& *init_data_size == other.init_data_size
&& *init_data_permissions == other.init_data_permissions
&& *scratch_size == other.scratch_size
&& *g2h_queue_size == other.g2h_queue_size
&& *h2g_queue_size == other.h2g_queue_size
&& *g2h_buffer_size == other.g2h_buffer_size
&& *h2g_buffer_size == other.h2g_buffer_size
&& *g2h_pool_pages == other.g2h_pool_pages
&& *h2g_pool_pages == other.h2g_pool_pages
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just fyi I have a draft PR #1728 that will relax this requiement, and use the target snapshot as authority, requiring nothing from the sandbox's layout

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/enhancement For PRs adding features, improving functionality, docs, tests, etc. ready-for-review PR is ready for (re-)review regen-goldens Regenerate snapshot golden fixtures

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants