Skip to content

fs/v9fs: Split virtio buffers where their physical pages are not adjacent. - #20548

Merged
acassis merged 1 commit into
apache:masterfrom
casaroli:v9fs-virtio-split-pages
Oct 12, 2026
Merged

acassis merged 1 commit into
apache:masterfrom
casaroli:v9fs-virtio-split-pages

Conversation

@casaroli

@casaroli casaroli commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Summary

virtio_9p_request() gave each buffer to the device as one descriptor, and libmetal translates only its start address with up_addrenv_va_to_pa(). In a kernel build, a buffer in a user address environment is contiguous only in virtual memory. A read that crossed a page boundary was written into whatever physical page followed the first one: the data was wrong and other memory was overwritten. When that range left guest memory, QEMU stopped the device with "virtio: bogus descriptor or out of resources".

With CONFIG_ARCH_ADDRENV, this PR splits each buffer at the pages that are not physically adjacent, so each descriptor covers one physical range.

Impact

Builds with CONFIG_ARCH_ADDRENV and the virtio 9P transport. Other builds are unchanged.

Testing

qemu-armv8a:knsh with CONFIG_DRIVERS_VIRTIO, CONFIG_DRIVERS_VIRTIO_MMIO, CONFIG_FS_V9FS and CONFIG_V9FS_VIRTIO_9P, QEMU 11 (-m 512M, a virtio-9p-device share). The test programs were built outside the tree against the export package.

A program reads a 1 MB file from the 9P share in one read() into a heap buffer and checks every byte. Two other programs run first, so that the heap pages of the test program are not physically contiguous: hold 512 3 & (exits after 3 s) and hold 64 120 &.

Before:

nsh> readbig /mnt/data.bin
readbig: read 1048576 bytes, first wrong byte at 462840

After:

nsh> readbig /mnt/data.bin
readbig: read 1048576 bytes, all correct

@github-actions github-actions Bot added Area: File System File System issues Size: M The size of the change in this PR is medium labels Oct 9, 2026
@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

MemBrowse Memory Report

qemu-armv8a

  • Code: .text.init_builtin_run +60 B (+0.0%, 347,480 B)

qemu-intel64

Comment thread fs/v9fs/virtio_9p.c Outdated
…cent.

virtio_9p_request() gave each buffer to the device as one descriptor,
and libmetal translates only its start address.  In a kernel build a
buffer in a user address environment is contiguous only in virtual
memory, so a read that crossed a page wrote into whatever physical page
followed the first one.  QEMU stops the device with "virtio: bogus
descriptor or out of resources" when that range leaves guest memory.

With CONFIG_ARCH_ADDRENV, split each buffer at the pages that are not
physically adjacent.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
@casaroli
casaroli force-pushed the v9fs-virtio-split-pages branch from 79a93e6 to d75940b Compare October 11, 2026 06:36
@casaroli casaroli closed this Oct 11, 2026
@casaroli casaroli reopened this Oct 11, 2026
@acassis
acassis merged commit 21593b8 into apache:master Oct 12, 2026
87 of 106 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: File System File System issues Size: M The size of the change in this PR is medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants