Project 4: A Real rust-vmm Upstream Contribution

This is the one project whose primary deliverable does not land in the Firecracker repository at all. It lands in a rust-vmm crate — one of the shared, community-maintained building blocks that Firecracker is built on — and then flows into Firecracker through a dependency bump you coordinate. A small, well-scoped fix or improvement to kvm-ioctls, vm-memory, linux-loader, virtio-queue, vm-superio, event-manager, or vmm-sys-util is the cleanest path in this entire portfolio to a real merged PR in a tier-1 systems project, with the least Firecracker-specific surface area to learn — and it teaches you the relationship that defines Firecracker's place in the ecosystem.

It is also the project where you contribute under a different process. rust-vmm is not AWS-owned; it is jointly maintained by AWS, Intel, Red Hat, and others, and shared between Firecracker and Cloud Hypervisor (and more). Each crate has its own CONTRIBUTING.md, its own CI, its own maintainers, and its own review norms — not Firecracker's DCO-plus-two-AWS-approvals model. Project 4 is as much about learning that process as about the code.

Note: Read the rust-vmm section in full — what is rust-vmm and the per-crate chapters for kvm-ioctls/kvm-bindings, vm-memory, linux-loader, virtio-queue, vm-superio, event-manager, and vmm-sys-util — and do Lab R4: contribute to rust-vmm. This brief assumes you can already build a chosen crate, run its tests, and read its public API with cargo doc. The lab is the on-ramp; this brief is the real thing.


Problem & motivation

Firecracker deliberately does not reinvent the low-level wheels. It consumes rust-vmm crates for the layers that every VMM needs identically: the KVM ioctl wrappers (kvm-ioctls/kvm-bindings), guest-memory abstractions (vm-memory: GuestMemoryMmap/GuestAddress), kernel loading (linux-loader), the virtqueue ring logic (virtio-queue), legacy devices (vm-superio: serial/i8042/rtc), the epoll wrapper (event-manager), and the utility belt (vmm-sys-util: EventFd, ioctl macros). Firecracker even donated several crates upstream (seccompiler, event-manager, vm-superio).

This creates a uniquely good contribution surface for someone who has studied Firecracker's internals:

  • You already understand how Firecracker uses these crates — which means you can spot a missing safe wrapper, an awkward API, a missing ioctl binding, a documentation gap, or a real bug that Firecracker has had to work around in-tree.
  • The crates are smaller, more focused, and have a lower review barrier per line than core Firecracker, because they are pure libraries with sharp boundaries.
  • The blast radius is large: a fix in vm-memory is exercised by Firecracker, Cloud Hypervisor, and every other rust-vmm consumer — the highest leverage-per-line in the portfolio.

The motivation is the cleanest credential in the curriculum: a merged PR in a community systems crate, plus the demonstrated ability to coordinate a dependency bump back into Firecracker — which is exactly the cross-repo skill a maintainer needs.


What you'll build

Two coordinated artifacts:

  1. A merged (or review-ready) PR in a rust-vmm crate — a scoped fix, a missing safe wrapper, a missing binding/ioctl, a documentation/API ergonomics improvement, or a small correctness/perf fix.
  2. A coordinated Firecracker change that consumes it: bump the crate version in Firecracker's Cargo.toml/Cargo.lock, remove the in-tree workaround your upstream change makes unnecessary (if any), and show Firecracker still builds and tests pass.

The second half is what makes this a Firecracker portfolio project and not just "a rust-vmm PR." Coordinating an upstream change with a downstream bump is the real skill.


Prerequisites


Phased plan

Phase 0 — Find which crate Firecracker pins, and where it strains (1–2 days)

Start from Firecracker, not from rust-vmm. Find the exact versions Firecracker consumes, then look for where Firecracker works around a crate limitation — that is where the upstreamable fix lives.

# Which rust-vmm crates and versions does Firecracker pin? (verify on your branch)
rg -n "kvm-ioctls|kvm-bindings|vm-memory|linux-loader|virtio-queue|vm-superio|event-manager|vmm-sys-util|vm-fdt" Cargo.toml Cargo.lock
# Where does Firecracker re-implement or wrap around a crate? These are candidates:
rg -n "TODO|FIXME|workaround|upstream|once .* lands|HACK" src/vmm/src/ | rg -i "kvm|memory|loader|virtio|superio|event"
# What does the crate's public API look like? (clone the crate, then:)
cargo doc -p kvm-ioctls --no-deps --open    # or whichever crate

Anti-staleness: the pinned versions move on every Firecracker release and the rust-vmm crates publish independently. Always confirm the current version Firecracker uses and the current main of the crate. Check the crate's open issues: gh issue list --repo rust-vmm/<crate> and its recent merged PRs to see what kind of change lands.

Produce capstone-work/crate-map.md: which crate you chose, the version Firecracker pins, the public API surface relevant to your change, and the specific gap — with code references on both the Firecracker side and the crate side.

Phase 1 — Pick and reproduce a scoped target

Choose one target type. Mergeability depends on scoping this small.

Target typeExampleWhy it's reachable
A missing safe wrapper / bindingA kvm-ioctls wrapper for an ioctl Firecracker calls raw, or a kvm-bindings struct/constant not yet exposedBounded, clearly useful, mirrors existing wrappers
A correctness bugAn edge case in a vm-memory bounds check, a virtio-queue descriptor-chain corner, a linux-loader ELF-parse edgeTestable against the spec/reference
An API ergonomics / docs fixA confusing signature, a missing #[derive], a doc example that doesn't compile, a missing error variantLow risk, real value, easy review
A small perf / allocation fixA reduced allocation on a hot path with a benchmarkHigh value if measured cleanly

Then reproduce it inside the crate's own test framework. rust-vmm reviewers, like all good systems-library maintainers, want a failing test before they look at a fix.

# In your clone of the crate:
cargo test                                   # see the suite pass first
# write a test that fails without your change:
cargo test your_new_test                     # confirm it FAILS on main

Phase 2 — The fix (minimum diff), the crate's way

Fix it where it lives, nothing more. Each rust-vmm crate has its own CONTRIBUTING.md, its own CI matrix (often multiple architectures, MSRV, clippy -D warnings, coverage gates, unsafe review), and its own code style. Read it and follow it exactly.

cat CONTRIBUTING.md          # the crate's rules — read fully, they differ per crate
cargo clippy --all-targets --all-features -- -D warnings
cargo fmt --check
cargo test --all-features
# many crates test multiple arches; check the CI config:
ls .github/workflows/ && cat .github/workflows/*.yml | rg -i "arch|matrix|coverage|kani"

If your change adds unsafe, expect intense scrutiny — these crates are the safe boundary over raw kernel interfaces, and an unjustified unsafe will block the PR. Document the safety invariant in a // SAFETY: comment.

Phase 3 — Open the rust-vmm PR

Open a PR against the crate's main following its template and conventions. Note the differences from Firecracker:

Firecrackerrust-vmm crate (varies)
Sign-offDCO Signed-off-by requiredOften DCO too — check each crate's CONTRIBUTING
Approvals≥2 AWS maintainersThe crate's maintainer set (cross-vendor)
ChangelogCHANGELOG.md ## [Unreleased]Usually a CHANGELOG.md per crate — confirm the format
CItools/devtool gatesPer-crate GitHub Actions matrix
ReleaseAWS release cadenceIndependent crates.io publish by crate maintainers
git commit -s   # DCO is common in rust-vmm too, but VERIFY per crate

Respond to review by changing code or explaining with a test — not by arguing. Expect questions about cross-arch behavior, unsafe, and MSRV.

Phase 4 — Coordinate the Firecracker bump

This is the half that makes it a Firecracker project. Once your change is merged (or a pre-release is available), bump Firecracker to consume it and prove the integration.

# Bump the crate in Firecracker (point at the new version, or a git rev for a pre-release):
rg -n "kvm-ioctls|vm-memory|<your-crate>" Cargo.toml
cargo update -p <your-crate>
# Remove the in-tree workaround your upstream change replaces, if any:
rg -n "workaround|TODO.*upstream|HACK" src/vmm/src/
# Prove Firecracker still builds and tests pass:
tools/devtool build --release
tools/devtool checkbuild --all
tools/devtool test -- -k <relevant_area>

If the bump deletes a Firecracker workaround, that deletion is a small, clean, very satisfying Firecracker PR with a CHANGELOG.md note crediting the upstream change.

Tip: Firecracker can depend on a crate via a git revision or a path override temporarily to test the integration before the crate publishes a release. Use that to validate the bump early — but the final Firecracker PR should point at a published version, not a git rev.


Key code areas

AreaFind it with
Firecracker's pinned versionsrg -n "<crate>" Cargo.toml Cargo.lock
Where Firecracker wraps/works around a crate`rg -n "TODO
The crate's public APIcargo doc -p <crate> --no-deps
The crate's contribution rulescat CONTRIBUTING.md in the crate clone
The crate's CI matrixls .github/workflows/ in the crate clone
rust-vmm open issuesgh issue list --repo rust-vmm/<crate>

Good first targets by crate: kvm-ioctls (a missing ioctl wrapper or a doc fix), vm-memory (a bounds-check edge or a doc example), vm-superio (a UART/i8042/rtc register-behavior fix — Firecracker donated this), vmm-sys-util (an EventFd/ioctl macro ergonomics fix), linux-loader (an ELF/bzImage parse edge), virtio-queue (a descriptor-chain validation corner).


Design considerations & trade-offs

  • Cross-vendor, not AWS-owned. The maintainers represent multiple companies and multiple downstream VMMs. A change that helps Firecracker but hurts Cloud Hypervisor's use of the crate will not land. Argue from the crate's general utility, not from Firecracker's needs.
  • The crate boundary is sacred. These crates are the safe layer over raw kernel interfaces. The bar for unsafe, for public API changes, and for new dependencies is very high. Stay inside an existing pattern.
  • Versioning and semver. A public API change is a semver event for everyone. Prefer additive, non-breaking changes; a breaking change needs a strong case and a major bump the maintainers must agree to.
  • MSRV and multi-arch. rust-vmm crates support a minimum Rust version and multiple architectures (x86_64, aarch64). Your change must hold on all of them. Test accordingly.
  • Don't fork the workaround. The temptation is to fix it only in Firecracker's in-tree code. Resist — the upstream fix is the higher-leverage, more durable change, and removing the downstream workaround is the proof it worked.

How to test & validate

  • In the crate: a test that is red on main and green with your change, run across the crate's full CI gate (clippy -D warnings, fmt, all features, every supported arch you can run, coverage if gated).
  • In Firecracker: after the bump, tools/devtool build --release, checkbuild --all, and the relevant pytest area must pass. If you removed a workaround, add/adjust a test proving the behavior is now correct end to end.
  • The integration claim: demonstrate Firecracker actually exercises the new code path — a boot, a snapshot, a device op, depending on the crate.

Stretch goals

  • After a fix lands, propose a small follow-up in the same crate (a related ergonomics or perf improvement) — building a track record with that crate's maintainers.
  • Close the loop in writing: in your write-up, trace your merged rust-vmm change from the crate PR, through the crates.io release, into the Firecracker bump, into a running microVM. This is the clearest demonstration in the curriculum of how the layers connect.
  • If you donated/found a missing wrapper, add the Firecracker PR that switches the in-tree raw call to the new safe wrapper — a clean, mergeable Firecracker change.

What a strong deliverable looks like

A strong deliverable is a merged (or review-ready) rust-vmm PR — minimum diff, crate conventions followed, a test red on main and green with the fix, unsafe justified — plus a coordinated Firecracker bump that consumes it, builds, passes tests, and ideally deletes an in-tree workaround.

The upstreaming path here is the project:

  1. This is the real contribution. Unlike the device or limiter projects, the upstream PR is the primary deliverable, not an optional stretch. Scope Phase 1 to land.
  2. Reproduce in the crate's tests first. A failing test is the entry ticket; no reproducer, no review.
  3. Learn the crate's process deliberately. Each rust-vmm crate has its own CONTRIBUTING.md, CI matrix, sign-off rule, and maintainer set. Read it; do not assume Firecracker's rules apply.
  4. Coordinate the bump. The Firecracker-side change — point at the new version, remove the workaround, prove it builds and tests — is what turns "a rust-vmm PR" into "a Firecracker contributor's cross-repo change."

A merged rust-vmm PR with a coordinated Firecracker bump at 90+ on the rubric is the single most transferable credential in this portfolio: a tier-1 systems-library merge and demonstrated cross-repo coordination, the exact skill set a Firecracker maintainer needs.


Next: Project 5 — a CPU template for a new host generation, which builds directly on the KVM and snapshot understanding this project deepens, or back to the portfolio overview.