Skip to content

Conversation

roypat
Copy link
Contributor

@roypat roypat commented Apr 15, 2025

Changes

Implement userspace bounce buffering for virtio devices if secret freedom is enabled, yet no swiotlb region is configured or even possible (e.g. x86)

Reason

swiotlb had significantly worse performance than expected (up to 80% throughput degradations), so try userspace bounce buffers instead, as these allow us to persist the bounce buffers (instead of swiotlb which re-allocates a new bounce buffer every time)

License Acceptance

By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache 2.0 license. For more information on following Developer
Certificate of Origin and signing off your commits, please check
CONTRIBUTING.md.

PR Checklist

  • I have read and understand CONTRIBUTING.md.
  • I have run tools/devtool checkstyle to verify that the PR passes the
    automated style checks.
  • I have described what is done in these changes, why they are needed, and
    how they are solving the problem in a clear and encompassing way.
  • I have updated any relevant documentation (both in code and in the docs)
    in the PR.
  • I have mentioned all user-facing changes in CHANGELOG.md.
  • If a specific issue led to this PR, this PR closes the issue.
  • When making API changes, I have followed the
    Runbook for Firecracker API changes.
  • I have tested all new and changed functionalities in unit tests and/or
    integration tests.
  • I have linked an issue to every new TODO.

  • This functionality cannot be added in rust-vmm.

@roypat roypat force-pushed the secret-freedom-userspace-bounce branch 4 times, most recently from 6b758d2 to 262639c Compare April 15, 2025 16:39
Copy link

codecov bot commented Apr 15, 2025

Codecov Report

Attention: Patch coverage is 58.10811% with 124 lines in your changes missing coverage. Please review.

Project coverage is 82.51%. Comparing base (9b6327d) to head (61e747d).
Report is 9 commits behind head on feature/secret-hiding.

Files with missing lines Patch % Lines
src/vmm/src/devices/virtio/net/device.rs 39.62% 32 Missing ⚠️
src/vmm/src/resources.rs 8.57% 32 Missing ⚠️
src/vmm/src/builder.rs 75.00% 13 Missing ⚠️
src/vmm/src/devices/virtio/block/device.rs 0.00% 10 Missing ⚠️
src/vmm/src/devices/virtio/block/virtio/device.rs 36.36% 7 Missing ⚠️
.../vmm/src/devices/virtio/block/vhost_user/device.rs 0.00% 6 Missing ⚠️
src/vmm/src/devices/virtio/vsock/unix/muxer.rs 54.54% 5 Missing ⚠️
src/vmm/src/vstate/memory.rs 92.30% 5 Missing ⚠️
src/vmm/src/devices/virtio/balloon/device.rs 50.00% 3 Missing ⚠️
.../vmm/src/devices/virtio/block/virtio/io/sync_io.rs 76.92% 3 Missing ⚠️
... and 4 more
Additional details and impacted files
@@                    Coverage Diff                    @@
##           feature/secret-hiding    #5156      +/-   ##
=========================================================
- Coverage                  82.72%   82.51%   -0.22%     
=========================================================
  Files                        251      251              
  Lines                      27522    27731     +209     
=========================================================
+ Hits                       22768    22881     +113     
- Misses                      4754     4850      +96     
Flag Coverage Δ
5.10-c5n.metal 82.95% <58.10%> (-0.25%) ⬇️
5.10-m5n.metal 82.95% <58.10%> (-0.25%) ⬇️
5.10-m6a.metal 82.12% <58.10%> (-0.26%) ⬇️
5.10-m6g.metal 78.85% <58.02%> (-0.22%) ⬇️
5.10-m6i.metal 82.95% <58.10%> (-0.25%) ⬇️
5.10-m7a.metal-48xl 82.12% <58.10%> (?)
5.10-m7g.metal 78.85% <58.02%> (-0.22%) ⬇️
6.1-c5n.metal 83.00% <58.10%> (-0.25%) ⬇️
6.1-m5n.metal 83.00% <58.10%> (-0.25%) ⬇️
6.1-m6a.metal 82.16% <58.10%> (-0.25%) ⬇️
6.1-m6g.metal 78.85% <58.02%> (-0.21%) ⬇️
6.1-m6i.metal 82.99% <58.10%> (-0.25%) ⬇️
6.1-m7a.metal-48xl 82.17% <58.10%> (?)
6.1-m7g.metal 78.85% <58.02%> (-0.22%) ⬇️
6.14-c5n.metal 82.97% <58.10%> (?)
6.14-m5n.metal 82.96% <58.10%> (?)
6.14-m6a.metal 82.13% <58.10%> (?)
6.14-m6g.metal 78.82% <58.02%> (?)
6.14-m6i.metal 82.95% <58.10%> (?)
6.14-m7a.metal-48xl 82.13% <58.10%> (?)
6.14-m7g.metal 78.81% <58.02%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@roypat roypat force-pushed the secret-freedom-userspace-bounce branch 8 times, most recently from c5ec769 to d6eadd4 Compare April 16, 2025 16:50
kalyazin
kalyazin previously approved these changes Apr 24, 2025
@roypat roypat force-pushed the secret-freedom-userspace-bounce branch from d6eadd4 to da205ce Compare April 24, 2025 10:18
kalyazin
kalyazin previously approved these changes Apr 24, 2025
JackThomson2
JackThomson2 previously approved these changes Apr 24, 2025
roypat added 9 commits April 24, 2025 15:13
It has a boolean inside of it that determines whether we actually
bounce, so rename it to reflect that.

Signed-off-by: Patrick Roy <[email protected]>
This is particularly useful for virtio devices, where on-demand
allocation of bounce buffers leads to sever performance impacts (~80%)
in synthetic throughput tests. Additionally, for virtio devices we can
know approximately what the optimal size of a statically allocated
bounce buffer is.

Allocate bounce buffers on the heap, as trying to even temporarily place
a 65k bounce buffer on the stack can lead to stack overflow errors.

Signed-off-by: Patrick Roy <[email protected]>
We put the bounds as AsFd to work around limitations in vm-memory about
not implementing Read/WriteVolatile for &File and &mut File, but it
ended up just causing even more workarounds being required elsewhere
(vsock unittests, where AsFd cannot meaningfully be implemented for
mocks). So just bite the bullet and clone some files until vm-memory
gets some more impls.

Signed-off-by: Patrick Roy <[email protected]>
kvm-clock is incompatible with direct map removal for now. This is
because kvm-clock tries to access guest memory through the direct map.
Additionally, it does not handle failures during guest-attempted
activations of kvm-clock gracefully (e.g. it cannot/does not communicate
these back to the guest). This means a guest will unconditionally assume
that if it wrote to the kvm-clock MSR to activate kvm-clock, it will
work. But if KVM internally fails to activate kvm-clock, KVM will never
write the information the guest expects into guest memory, resulting in
the guest reading garbage data (generally, zeros), resulting in division
by zero panics in the guest.

Hence, explicitly tells guests that they shouldn't even try to enable
kvm-clock, if they value their lives.

Signed-off-by: Patrick Roy <[email protected]>
Add support to our virtio devices to allow userspace bounce buffering of
virtio buffers. This is an alternative to swiotlb.

Don't implement it for vhost-user-blk and for virtio-block with async
engine, because I have no idea how that would even work.

Signed-off-by: Patrick Roy <[email protected]>
Mark vhost-user and async block engine as incompatible, as for
vhost-user-blk, we would need to communicate the need for bounce buffers
to the backend somehow, and for the async block engine we would need to
somehow keep the bounce buffers around until io_uring finishes requests
(which is not impossible, but complicated and not needed for now).

Signed-off-by: Patrick Roy <[email protected]>
Now that we have userspace bounce buffers, we can run secret freedom
tests (including perf tests!) with then, which additionally allows us to
run them on x86 too.

Remove the swiotlb test cases from the performance tests, as the
performance impact here was shown too significant.

Signed-off-by: Patrick Roy <[email protected]>
Ensure that `ps(1)` does not truncate the command, which might result in
the grep failing (if the jailer_id gets truncated), using the -ww
option. While we're at it, also use -o cmd so that ps only prints the
command names and nothing else (as we're not using anything else from
this output).

This causes false-positives instead of false-negatives funnily enough,
because we're using check_output, meaning if the grep doesnt find
anything we fail the command (in the "everything works" scenario,
firecracker is dead but grep still matches the "ps | grep" process
itself).

Signed-off-by: Patrick Roy <[email protected]>
Currently, creation of UFFDs fails with Failure to create UFFD: System
error

Signed-off-by: Patrick Roy <[email protected]>
@roypat roypat dismissed stale reviews from kalyazin and JackThomson2 via a95c1db April 24, 2025 14:19
@roypat roypat force-pushed the secret-freedom-userspace-bounce branch from 98c83b3 to a95c1db Compare April 24, 2025 14:19
@roypat roypat requested review from JackThomson2 and kalyazin April 24, 2025 16:33
@roypat roypat enabled auto-merge (rebase) April 25, 2025 06:25
@roypat roypat merged commit 82ca3c9 into firecracker-microvm:feature/secret-hiding Apr 25, 2025
5 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants