Skip to content

guestmem: add supports_locking to gate zero-copy IO#3924

Open
jstarks wants to merge 3 commits into
microsoft:mainfrom
jstarks:bounce
Open

guestmem: add supports_locking to gate zero-copy IO#3924
jstarks wants to merge 3 commits into
microsoft:mainfrom
jstarks:bounce

Conversation

@jstarks

@jstarks jstarks commented Jul 11, 2026

Copy link
Copy Markdown
Member

Memory behind an emulated IOMMU translates each guest access on demand and has no stable host mapping, so its pages cannot be locked for zero-copy IO. Devices that lock guest buffers as a fast path would fail or produce incorrect results against such backings.

Add a supports_locking query to GuestMemory (and the underlying GuestMemoryAccess trait) that reports whether locking is possible. The result is computed once at construction and cached, since it never changes for a given backing and is checked on hot IO paths; multi-region memory reports support only when every region supports it.

Update the block device and virtio-vsock zero-copy paths to consult this query and fall back to bounce buffering / read_at/write_at when locking is unavailable.

Memory behind an emulated IOMMU translates each guest access on demand and
has no stable host mapping, so its pages cannot be locked for zero-copy IO.
Devices that lock guest buffers as a fast path would fail or produce
incorrect results against such backings.

Add a supports_locking query to GuestMemory (and the underlying
GuestMemoryAccess trait) that reports whether locking is possible. The
result is computed once at construction and cached, since it never changes
for a given backing and is checked on hot IO paths; multi-region memory
reports support only when every region supports it.

Update the block device and virtio-vsock zero-copy paths to consult this
query and fall back to bounce buffering / read_at/write_at when locking is
unavailable.
@jstarks jstarks requested a review from a team as a code owner July 11, 2026 14:07
Copilot AI review requested due to automatic review settings July 11, 2026 14:07
@jstarks jstarks requested a review from a team as a code owner July 11, 2026 14:07
@github-actions

Copy link
Copy Markdown

⚠️ Unsafe Code Detected

This PR modifies files containing unsafe Rust code. Extra scrutiny is required during review.

For more on why we check whole files, instead of just diffs, check out the Rustonomicon

@github-actions github-actions Bot added the unsafe Related to unsafe code label Jul 11, 2026

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.

Pull request overview

This PR adds an explicit supports_locking() capability query to GuestMemory/GuestMemoryAccess so zero-copy IO paths can reliably detect when page-locking is impossible (e.g., guest memory accessed via on-demand translation behind an emulated IOMMU) and fall back to copying/bounce-buffer paths.

Changes:

  • Introduces GuestMemoryAccess::supports_locking() (defaulting to mapping().is_some()) and exposes GuestMemory::supports_locking() with a cached per-backing result.
  • Computes conservative locking support for multi-region guest memory (only true when all present backing regions support locking).
  • Gates zero-copy fast paths in virtio_vsock and disk_blockdevice on supports_locking(), falling back to copying paths when needed.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
vm/vmcore/guestmem/src/lib.rs Adds supports_locking() query and caches the value in GuestMemoryInner, including multi-region aggregation.
vm/devices/virtio/virtio_vsock/src/lib.rs Avoids attempting payload locking when guest memory doesn’t support locking, triggering the bounce-buffer path.
vm/devices/storage/disk_blockdevice/src/lib.rs Forces bounce buffering (no zero-copy lock) when guest memory reports locking is unsupported.

Comment thread vm/vmcore/guestmem/src/lib.rs Outdated
Comment on lines +1195 to +1197
/// Cached result of [`DynGuestMemoryAccess::supports_locking`], since it is
/// queried on hot zero-copy paths and never changes for a given backing.
supports_locking: bool,
@github-actions

Copy link
Copy Markdown

Copilot AI review requested due to automatic review settings July 12, 2026 07:22

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.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment on lines +1468 to +1472
// Locking is only supported if every backing region supports it.
let supports_locking = imps
.iter()
.flatten()
.all(GuestMemoryAccess::supports_locking);
Comment on lines +1634 to +1642
/// Returns whether this memory supports locking pages via
/// [`lock_gpns`](Self::lock_gpns) and [`lock_range`](Self::lock_range).
///
/// Memory behind an emulated IOMMU has no stable host mapping and cannot
/// be locked; zero-copy callers should check this and fall back to a
/// copying path when it returns `false`.
pub fn supports_locking(&self) -> bool {
self.inner.supports_locking
}
@github-actions

Copy link
Copy Markdown

Copilot AI review requested due to automatic review settings July 13, 2026 12:35

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.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

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

Labels

unsafe Related to unsafe code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants