Repository navigation
9p/xen: grant each ring page by its own frame - #72
Merged
Merged
Conversation
The data pages of a ring are granted as the first page's frame plus the page index. That holds for auto-translated guests, whose grant frames are pseudo-physical. A PV guest grants machine frames, and alloc_pages_exact() only promises pseudo-physical contiguity. When the pages are not machine-contiguous the backend maps the frames that follow the first one. Some of those are other pages of the guest, so requests read as garbage, and some cannot be granted at all, so the mapping fails. A freshly built PV guest is usually machine-contiguous within a 2 MiB block, which hid this. A PV guest restored from a snapshot gets its frames one page at a time, so its first request on ring 0 after the restore arrives as a malformed frame and the mount hangs. Look up the frame of each page instead. Signed-off-by: Kavi Daula <kavi@edera.dev>
kdaula
marked this pull request as ready for review
November 3, 2026 00:51
azenla
approved these changes
Nov 3, 2026
3 tasks done
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.
The frontend currently assumes that a ring's data pages are contiguous in machine memory and calculates each frame by adding the page index to the first page's frame. That assumption doesn't hold for PV guests. alloc_pages_exact() only guarantees pseudo-physical contiguity, so the actual machine frames can be scattered. When that happens, the backend ends up mapping the wrong frames. Sometimes it reads unrelated guest pages and the requests come back as garbage. Other times Xen refuses the grant and the mapping fails with EINVAL.
We haven't seen this consistently because freshly created PV zones usually get machine-contiguous pages within a 2 MiB block. But when a PV zone is restored from a snapshot, memory is allocated one page at a time, so that assumption breaks. The first request on ring 0 ends up with an invalid frame mapping and the mount hangs. This explains the intermittent snapshot import failures in edera-dev/protect#4749. The dumped grant entries also show consecutive frames that Xen refuses to map.
The fix is to look up the actual machine frame for each page instead of assuming they're sequential. I haven't built or tested this locally yet.