Skip to content

Migrate virtio-net from semu#748

Open
Charlie-Tsai1123 wants to merge 1 commit into
sysprog21:masterfrom
Charlie-Tsai1123:research/virtio-net
Open

Migrate virtio-net from semu#748
Charlie-Tsai1123 wants to merge 1 commit into
sysprog21:masterfrom
Charlie-Tsai1123:research/virtio-net

Conversation

@Charlie-Tsai1123

@Charlie-Tsai1123 Charlie-Tsai1123 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR migrates virtio-net support from semu and follows the existing virtio-blk and virtio-rng integration in rv32emu.

The implementation adds a TAP-backed virtio-net device model for system emulation mode, including MMIO register handling, queue setup, feature negotiation, RX/TX virtqueue handling, virtio-net header processing, interrupt delivery through the PLIC, dynamic DTB node creation, and a runtime option for enabling the device.

Implementation notes

  • Add a TAP backend helper for host network I/O.
  • Add a virtio-net device model with RX and TX virtqueue handling.
  • Handle the virtio-net header on both guest TX and RX paths.
  • Route virtio-net MMIO accesses through the system MMIO path.
  • Update virtio-net interrupts through the PLIC.
  • Dynamically create a virtio,mmio DTB node for virtio-net.
  • Ensure virtio-net can coexist with existing virtio-blk and virtio-rng devices without reusing MMIO bases or IRQs.
  • Add a runtime option for enabling virtio-net with a TAP backend.
  • Note that opening a TAP device usually requires elevated privileges, so rv32emu should be executed with sudo or equivalent permissions when using the TAP backend.

Test

Build:

make system_defconfig
make ENABLE_SYSTEM=1

sudo build/rv32emu \
  -k build/linux-image/Image \
  -i build/linux-image/rootfs.cpio \
  -x vblk:build/disks/disk.img \
  -x vrng \
  -x vnet:tap

After run rv32emu with -x vnet:tap rv32emu would build TAP, so host linux doesn't need to build TAP again.
Host TAP setup:

ip link | grep tap
sudo ip addr add 192.168.100.1/24 dev tap0
sudo ip link set  tap0 up
sudo tcpdump -i tap0 -n -vv

Guest device verification:

readlink /sys/bus/virtio/devices/virtio0/driver
ip link set eth0 up
ip addr add 192.168.100.2/24 dev eth0
ip addr show eth0
ping -c 3 192.168.100.1

Expected Result:

# readlink /sys/bus/virtio/devices/virtio0/driver
../../../../../bus/virtio/drivers/virtio_net
# ip link set eth0 up
# ip addr add 192.168.100.2/24 dev eth0
# ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether aa:e0:56:5b:58:bc brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.2/24 scope global eth0
       valid_lft forever preferred_lft forever
# ping -c 3 192.168.100.1
PING 192.168.100.1 (192.168.100.1): 56 data bytes
64 bytes from 192.168.100.1: seq=0 ttl=64 time=1.200 ms

64 bytes from 192.168.100.1: seq=1 ttl=64 time=1001.085 ms
64 bytes from 192.168.100.1: seq=2 ttl=64 time=1.334 ms

--- 192.168.100.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.200/334.539/1001.085 ms
# 

Summary by cubic

Adds a TAP-backed virtio-net device for system emulation. It’s wired through VirtIO-MMIO and the PLIC, auto-added to the DTB, and enabled via -x vnet:tap for guest networking.

  • New Features

    • Virtio-net: feature negotiation, RX/TX queues, virtio-net header (TX skip, RX prepend), QueueNotify/used ring, and reset.
    • Linux TAP backend with non-blocking I/O; interface auto-created (tapN); polled in the main loop; MMIO and PLIC interrupt wiring.
    • DTB node for virtio,mmio with unique MMIO base/IRQ; coexists with virtio-blk/virtio-rng.
  • Migration

    • Run with -x vnet:tap; Linux hosts only. Use elevated privileges to create TAP. Bring the host TAP up and assign an IP if needed.

Written for commit 56a5c0b. Summary will update on new commits.

Review in cubic

@jserv jserv left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmarks

Details
Benchmark suite Current: 56a5c0b Previous: b775142 Ratio
Dhrystone 1576.667 DMIPS 1585.333 DMIPS 1.01
CoreMark 1115.023 iterations/sec 1120.589 iterations/sec 1.00

This comment was automatically generated by workflow using github-action-benchmark.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 9 files

Re-trigger cubic

@Charlie-Tsai1123 Charlie-Tsai1123 force-pushed the research/virtio-net branch 2 times, most recently from 7658d0a to b775142 Compare July 1, 2026 15:18
@shengwen-tw

Copy link
Copy Markdown
Contributor

Hi @Charlie-Tsai1123,

I’m not the original author of the virtio-net device. Please check the commit history via git log --follow -- virtio-net.c; I believe the original author is @jserv.

@Charlie-Tsai1123

Copy link
Copy Markdown
Contributor Author

Thanks for the clarification, and sorry for the incorrect attribution.
I checked the semu history with git log --follow -- virtio-net.c. The original virtio-net implementation appears to have been introduced by jserv. I will update the commit message accordingly.

This commit migrates virtio-net support from semu with the
following modifications:

1. Implement virtio-net device model
The virtio-net implementation follows the VirtIO-MMIO flow used by
virtio-blk, including feature negotiation, queue setup, QueueNotify
handling, used ring update, interrupt status, and device status reset.

The device currently supports a TAP-backend network interface and
handles basic RX/TX virtqueue processing for guest network packets.

2. Add TAP backend helper
Introduce netdev.c and netdev.h to provide host-side TAP device access.
Future work may support other host-side backend.

3. Handle virtio-net header processing
For guest TX, the device skips the virtio-net header before writing the
Ethernet frame to the TAP backend.
For guest RX, the device prepends a virtio-net header before copying
the received Ethernet frame into the guest-provided RX buffer.

4. Implement MMIO_VIRTIONET
Add MMIO routing for virtio-net and connect the device interrupt status
to the PLIC, following the existing virtio-blk and virtio-rng interrupt
update model.

5. Introduce new argument '-x vnet:<tap>'
When virtio-net is enabled, rv32emu dynamically creates a virtio-mmio
node in the generated device tree and assigns an MMIO base address and
IRQ for the device.

6. Support coexistence with virtio-blk and virtio-rng
Update the dynamic virtio-mmio device tree allocation path so
virtio-net can coexist with existing virtio-blk and virtio-rng devices
without reusing MMIO base addresses or IRQs.

7. Use virtio-net state
Unlike semu's device integration model, rv32emu stores the virtio-net
state in vm_attr_t so MMIO routing, interrupt routing, and device
cleanup can access the same device instance.

The emulator should be run with sudo when using the virtio-net TAP
backend.

This implementation is based on semu's virtio-net device, originally
introduced by Jserv.

Co-authored-by: Jim Huang <jserv@biilabs.io>
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.

3 participants