Repository navigation
Conversation
This commit introduces support for the UFFD_FEATURE_WP_UNPOPULATED feature flag, which was added in Linux 6.4. This feature allows write-protection on unpopulated anonymous memory pages. Changes: - Add linux6_4 module in userfaultfd-sys - Update UFFD_API_FEATURES to include WP_UNPOPULATED - Add linux6_4 Cargo feature with appropriate dependencies - Expose WP_UNPOPULATED flag in high-level FeatureFlags API Signed-off-by: Babis Chalios <babis.chalios@e2b.dev>
This commit introduces support for the UFFD_FEATURE_WP_ASYNC feature flag, which was added in Linux 6.7. This feature enables asynchronous write-protection resolution - when a write happens to a write-protected page, the kernel automatically resolves the protection without generating pagefault events. Changes: - Add linux6_7 module in userfaultfd-sys - Update UFFD_API_FEATURES to include WP_ASYNC - Add linux6_7 Cargo feature with dependency on linux6_4 - Expose WP_ASYNC flag in high-level FeatureFlags API Signed-off-by: Babis Chalios <babis.chalios@e2b.dev>
The userfaultfd-sys crate chains its feature levels, but the top-level crate does not, so enabling only `linux5_13` leaves `cfg(feature = "linux5_7")` items such as `RegisterMode::WRITE_PROTECT` compiled out. Chain the new `linux6_4` and `linux6_7` levels so a single feature selects everything up to that kernel version. The existing levels are left alone: making them imply lower levels would add a field to `Event::Pagefault` and variants to `FaultKind` for current users, which can break exhaustive patterns. Enabling 5.7 and 5.13 together also exposes a non-exhaustive match in the write-protect test, which never compiled with both on before; add the missing `FaultKind::Minor` arm. Signed-off-by: Babis Chalios <babis.chalios@e2b.dev>
Expose the full UFFDIO_COPY mode word instead of only the wake flag, so callers can request UFFDIO_COPY_MODE_WP and have the copied pages mapped write-protected (Linux 5.7+). The existing `copy` keeps its signature and delegates to the new method, mirroring the `register`/`register_with_mode` pair. Signed-off-by: Babis Chalios <babis.chalios@e2b.dev>
Signed-off-by: Babis Chalios <babis.chalios@e2b.dev>
Signed-off-by: Babis Chalios <babis.chalios@e2b.dev>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This adds the two userfaultfd write-protect features introduced in Linux 6.4 and 6.7, and a way to request
UFFDIO_COPY_MODE_WPwhen resolving a missing fault.linux6_4feature:UFFD_FEATURE_WP_UNPOPULATED, exposed asFeatureFlags::WP_UNPOPULATED. LetsUFFDIO_WRITEPROTECTapply to pages that have never been populated.linux6_7feature:UFFD_FEATURE_WP_ASYNC, exposed asFeatureFlags::WP_ASYNC. The kernel resolves write-protect faults itself without queueing an event.Uffd::copy_with_modeandCopyMode: exposes the fullUFFDIO_COPYmode word.CopyMode::WRITE_PROTECT(behindlinux5_7) maps the copied pages write-protected so the retried write raises a write-protect fault.Uffd::copykeeps its signature and delegates to the new method, mirroring the existingregister/register_with_modepair.Feature levels
The
userfaultfd-syscrate already chains its feature levels, but the top-level crate does not, so enabling onlylinux5_13leavescfg(feature = "linux5_7")items such asRegisterMode::WRITE_PROTECTcompiled out. The newlinux6_4andlinux6_7features enable every lower level so a single feature selects everything up to that kernel.I deliberately left existing features
linux4_14,linux5_7, andlinux5_13as they are. Chaining them would add thethread_idfield toEvent::Pagefaultand theWriteProtectedvariant toFaultKindfor current users, which could break exhaustive patterns.If we want to ever fix that, we should do it in a release that bumps major to declare the breaking change.
However, since enabling
linux6_4/linux6_7enables 5.7 and 5.13 together, they expose a non-exhaustive match intest_write_protect, which wasn't there before. So, I've extended it with aFaultKind::Minorarm.Scope
linux6_7just brings in write-protect. There are other features that we can add such asUFFDIO_POISON(6.6) orUFFDIO_MOVE(6.8), but I'd do these as separate PR.As with the existing levels, the new feature bits come from bindgen, so building with
linux6_4orlinux6_7needs kernel headers of at least that version.Tests
Four new tests, gated on the corresponding feature:
copy_with_modewithDONTWAKE: the page holds the source bytes before the faulting thread is woken.copy_with_modewithWRITE_PROTECT: the retried write raises a write-protect fault with the copied data intact.WP_UNPOPULATED: write-protecting a never-touched page makes the first write fault instead of silently populating.WP_ASYNC: a write to a protected page succeeds from the same thread and no event is queued, for both an unpopulated and a repopulated page.I ran those locally on a 7.1 kernel via both
/dev/userfaultfdand the syscall fallback, at every feature level.I added a new
linux6_7step in the CI using theubuntu-latestrunner.Compatibility
Changes are backwards compatible.
Uffd::copyproduces the same ioctl mode bits as before.CopyMode,copy_with_mode, and the two feature levels are purely additive, so we don't need a major version bump.