Skip to content

Conversation

@trasz
Copy link
Contributor

@trasz trasz commented Dec 24, 2025

This adds pacmanfs plus necessary linuxkpi bits.

bukinr and others added 19 commits December 24, 2025 11:34
When using the slirp backend with the e1000 frontend, I otherwise get
hangs in readv(), caused by the e1000 emulation not checking whether
bytes are available before trying to read them.  In particular, that
device model expects the recv callback to return 0 if no bytes are
available, and with slirp it would end up blocking forever.  The virtio
device model uses the peek_recvlen to check first, so I didn't notice
the problem when implementing the slirp backend.

Make the slirp backend more flexible to accommodate e1000.

MFC after:	1 month
Differential Revision:	https://reviews.freebsd.org/D48164

(cherry picked from commit d3bdfa5)
libslirp can invoke a callback when received data is removed from a
socket buffer, generally because the guest ACKed some data.  Previously
it didn't do anything, but it needs to wake up the poll thread to get
reasonable throughput.

Suppose one is using scp to copy data into a guest filesystem via the
slirp backend.  Data is received on libslirp's socket, which we poll for
data in slirp_pollfd_td_loop().  That data gets buffered in priv->pipe,
and eventually is placed in the device model's RX rings by the backend's
mevent handler.  When implementing TCP, libslirp holds on to a copy of
data until it's ACKed by the guest via slirp_send(), at which point it
drops that data and invokes the notify callback.

The initial implementation of this backend didn't take into account the
fact that slirp_pollfds_fill() will not add libslirp's socket to the
pollfd set if more than a threshold amount of data is already buffered.
Then poll() needs to time out before the backend sends more data to the
guest.  With a default timeout of 500ms, this kills throughput.

Use a pipe to implement a simple in-band signal to the poll thread so
that it reacts quickly when more buffer space becomes available.

MFC after:	1 month
Differential Revision:	https://reviews.freebsd.org/D48192

(cherry picked from commit 20a51e6)
The previous implementation implemented hostfwd rules which would allow
the host to connect to the guest via a NATed TCP connection.  libslirp
also permits NAT in the other direction, but this was prevented by
bhyve's capsicum sandbox.

To make the slirp backend more useful, split the backend out into a
separate process which does not enter capability mode if outbound
connections are permitted (enabled by setting the new "open" keyword).
The process communicates with the bhyve network frontend (typically a
virtio network interface) using a unix SOCK_SEQPACKET socket pair.  If
the bhyve process exits, the helper will automatically exit.

Aside from this restructuring, there is not much actual change.  Many
slirp parameters are still hard-coded for now, though this may change.
The "restricted" feature is toggled by the new "open" keyword; in
particular, the backend is restricted by default for compatibility with
15.0 and 14.3.

Each packet now has to traverse an extra socket, but this overhead
should be acceptable given that the slirp backend cannot be said to
provide high-performance networking.  With iperf3 I can get 4Gbps from
the guest to the host on a Zen 4 system.

MFC after:	1 month
Sponsored by:	CHERI Research Centre (EPSRC grant UKRI3001)
Differential Revision:	https://reviews.freebsd.org/D53454

(cherry picked from commit 0e62ebd)
Fixes:	0e62ebd ("bhyve: Move the slirp backend out into a separate process")

(cherry picked from commit bac572b)
When in restricted mode, the slirp-helper process enters a capsicum
sandbox, after which we cannot look up the uid for the "nobody" user.
Reverse the order.

Reported by:	kp
Fixes:	0e62ebd ("bhyve: Move the slirp backend out into a separate process")

(cherry picked from commit b0c7eaf)
FreeBSD main has a number of improvements to SEQPACKET sockets which are not yet
backported.  The main reason to use a SEQPACKET socket is so that the slirp
helper is reliably notified when the other end hangs up.

Rather than backporting the upstream improvements, switch to a DGRAM socket and
use an extra control pipe to find out when the parent bhyve process has exited.
No data is written to the pipe, we just use it to poll for POLLHUP.

This commit can be reverted once CheriBSD has been synced up to commit
69f61ce or later.
This is unmodified pacmanfs at 98bd8d180343f20cfa80a50eb2c59628cca760f0
from [email protected]:CTSRD-CHERI/SIFT-PACMAN-linux.git
Much of this will be reverted later.
This is something our <linux/fs.h> does by default,
but both pacmanfs _and_ lkpi need their respective
per-vnode data fields.
This includes an ugly hack to vfs_bio.c, to be reverted later.
@trasz
Copy link
Contributor Author

trasz commented Dec 24, 2025

Forgot to mention - this includes some unrelated commits to bhyve and em(4) from upstream; it's because I've forked my branch slightly later. They should disappear at the next merge.

@bsdjhb
Copy link
Collaborator

bsdjhb commented Dec 26, 2025

Can you locally do git rebase --onto sift_ace2 dev to drop the extra commits from the branch?

@trasz
Copy link
Contributor Author

trasz commented Dec 27, 2025

Can you locally do git rebase --onto sift_ace2 dev to drop the extra commits from the branch?

I tried, and it gave me merge conflicts:

% git rebase --onto sift_ace2 dev                                       
warning: skipped previously applied commit 784a417a34d9                                             
warning: skipped previously applied commit fa884c12fd0e                                             
warning: skipped previously applied commit 1104c42927d0                                             
warning: skipped previously applied commit 2ef781734e1e                                             
warning: skipped previously applied commit 59aa136509c3                                             
warning: skipped previously applied commit 3108be32e075                                             
warning: skipped previously applied commit ad2befe28708                                             
hint: use --reapply-cherry-picks to include skipped commits                                         
hint: Disable this message with "git config set advice.skippedCherryPicks false"
Auto-merging share/man/man4/Makefile                                                                
CONFLICT (content): Merge conflict in share/man/man4/Makefile                                       
Auto-merging share/man/man4/ace2.4                                                                  
CONFLICT (add/add): Merge conflict in share/man/man4/ace2.4                                         
Auto-merging sys/dev/sift/ace2/ace2.c                                                               
CONFLICT (add/add): Merge conflict in sys/dev/sift/ace2/ace2.c                                      
Auto-merging sys/modules/sift/Makefile                                                              
CONFLICT (add/add): Merge conflict in sys/modules/sift/Makefile                                     
error: could not apply 14981fa09f8e... ace2: New character device driver for SIFT-PACMAN
hint: Resolve all conflicts manually, mark them as resolved with                                    
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".                            
hint: You can instead skip this commit: run "git rebase --skip".                                                                                                                                        
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".                                                                                                                 
hint: Disable this message with "git config set advice.mergeConflict false"                                                                                                                             
Could not apply 14981fa09f8e... # ace2: New character device driver for SIFT-PACMAN   

@bsdjhb
Copy link
Collaborator

bsdjhb commented Dec 27, 2025

Oh, you had already rebased onto sift_ace2. Maybe try git rebase --abort then either git rebase -i sift_ace2 and just drop the extra commits from dev into the todo list, or you can use git rebase --onto sift_ace2 <hash of last dev commit> which would be ad2befe287081ddc55833b87a822aa28f96a0224 for the branch currently pushed to the PR.

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.

5 participants