CV-Bowen opened a new pull request, #18265:
URL: https://github.com/apache/nuttx/pull/18265
## Summary
This PR adds a new API `virtio_read_config_bytes()` and updates VirtIO
drivers to use size-matched operations when reading the VirtIO configuration
space, following the VirtIO specification requirements.
### Why is this change needed?
According to the VirtIO specification:
> For the device-specific configuration space, the driver MUST use 8-bit
wide accesses for 8-bit wide fields, 16-bit wide and aligned accesses for
16-bit wide fields and 32-bit wide and aligned accesses for 32 and 64-bit wide
fields.
The current implementation uses `virtio_read_config()` to read strings (like
CPU names, MAC addresses, and tags) as a whole block, which violates the
specification. For string fields in the VirtIO config space, we should use
byte-by-byte read operations.
### What does this PR do?
1. **Add `virtio_read_config_bytes()` API**
(`include/nuttx/virtio/virtio-config.h`)
- New inline function that reads config space byte-by-byte
- Suitable for reading string-type fields that require 8-bit accesses
2. **Update `rpmsg_virtio` driver** (`drivers/rpmsg/rpmsg_virtio.c`)
- Use `virtio_read_config_bytes()` to read `host_cpuname` and
`remote_cpuname` strings
3. **Update `virtio-net` driver** (`drivers/virtio/virtio-net.c`)
- Use `virtio_read_config_bytes()` to read MAC address (6 bytes)
4. **Update `virtio-snd` driver** (`drivers/virtio/virtio-snd.c`)
- Use `virtio_read_config_member()` to read individual config members
(`jacks`, `streams`, `chmaps`)
- Each member is read with proper size-matched access
5. **Update `virtio_9p` driver** (`fs/v9fs/virtio_9p.c`)
- Use `virtio_read_config_bytes()` to read the tag string
## Impact
- **Stability**: Improves compatibility with VirtIO backends that strictly
enforce the specification
- **Compatibility**: No breaking changes; existing functionality preserved
- **Code Quality**: Better adherence to VirtIO specification
## Testing
### Build Verification
```bash
cmake -B cmake_out/v8a_netnsh -DBOARD_CONFIG=qemu-armv8a:netnsh -GNinja
cmake --build cmake_out/v8a_netnsh
cmake -B cmake_out/v8a_server -DBOARD_CONFIG=qemu-armv8a:rpserver -GNinja
cmake --build cmake_out/v8a_server
cmake -B cmake_out/v8a_proxy -DBOARD_CONFIG=qemu-armv8a:rpproxy -GNinja
cmake --build cmake_out/v8a_proxy
```
### Test Environment
- **Host OS**: Ubuntu 22.04
- **QEMU Version**: 9.2.3
- **Target**: qemu-armv8a
### Test Results
#### VirtIO Network/9p Test
```c
❯ /data/software/qemu/qemu-9.2.3/build/qemu-system-aarch64 -cpu cortex-a53
-nographic \
-machine virt,virtualization=on,gic-version=3 \
-chardev stdio,id=con,mux=on -serial chardev:con \
-global virtio-mmio.force-legacy=false \
-device virtio-serial-device,bus=virtio-mmio-bus.0 \
-chardev
socket,telnet=on,host=127.0.0.1,port=3450,server=on,wait=off,id=foo \
-device virtconsole,chardev=foo \
-device virtio-rng-device,bus=virtio-mmio-bus.1 \
-netdev
user,id=u1,hostfwd=tcp:127.0.0.1:10023-10.0.2.15:23,hostfwd=tcp:127.0.0.1:15001-10.0.2.15:5001
\
-device virtio-net-device,netdev=u1,bus=virtio-mmio-bus.2 \
-drive file=./mydisk-1gb.img,if=none,format=raw,id=hd \
-device virtio-blk-device,bus=virtio-mmio-bus.3,drive=hd \
-fsdev
local,security_model=none,id=fsdev0,path=/data/project/code/apache/nuttx \
-device virtio-9p-device,id=fs0,fsdev=fsdev0,mount_tag=host \
-mon chardev=con,mode=readline -kernel
./nuttx/cmake_out/v8a_netnsh/nuttx \
-gdb tcp::7777
[ 0.350000] pci_scan_bus: pci_scan_bus for bus 0
[ 0.350000] pci_scan_bus: class = 00000600, hdr_type = 00000000
[ 0.350000] pci_scan_bus: 00:00 [1b36:0008]
[ 0.350000] pci_setup_device: pbar0 set bad mask
[ 0.350000] pci_setup_device: pbar1 set bad mask
[ 0.350000] pci_setup_device: pbar2 set bad mask
[ 0.350000] pci_setup_device: pbar3 set bad mask
[ 0.360000] pci_setup_device: pbar4 set bad mask
[ 0.360000] pci_setup_device: pbar5 set bad mask
telnetd [4:100]
NuttShell (NSH) NuttX-12.10.0
nsh>
nsh>
nsh>
nsh> ls
/:
dev/
proc/
nsh> mount -t v9fs -o trans=virtio,tag=host /9p
nsh> ls
/:
9p/
dev/
proc/
nsh> ls 9p
/9p:
pass1/
.codespellrc
README.md
.gitignore
net/
build/
AUTHORS
sched/
Makefile
CONTRIBUTING.md
openamp/
ReleaseNotes
mm/
.editorconfig
.codespell-ignore-lines
LICENSE
.version
.yamllint
crypto/
drivers/
CMakeLists.txt
INVIOLABLES.md
arch/
syscall/
video/
.asf.yaml
boards/
audio/
Kconfig
include/
.git/
.gitmessage
binfmt/
NOTICE
tools/
cmake_out/
dummy/
libs/
fs/
.pre-commit-config.yaml
.github/
cmake/
Documentation/
graphics/
wireless/
nsh> ifconfig
eth0 Link encap:Ethernet HWaddr 00:e0:de:ad:be:ef at RUNNING mtu 1500
inet addr:10.0.2.15 DRaddr:10.0.2.2 Mask:255.255.255.0
IPv4 TCP UDP ICMP
Received 0000 0000 0000 0000
Dropped 0000 0000 0000 0000
IPv4 VHL: 0000 Frg: 0000
Checksum 0000 0000 0000 ----
TCP ACK: 0000 SYN: 0000
RST: 0000 0000
Type 0000 ---- ---- 0000
Sent 0000 0000 0000 0000
Rexmit ---- 0000 ---- ----
nsh>
nsh> iperf -s -i 1
IP: 10.0.2.15
mode=tcp-server sip=10.0.2.15:5001,dip=0.0.0.0:5001, interval=1, time=0
accept: 10.0.2.2:60720
Interval Transfer Bandwidth
0.00- 1.01 sec 9222196 Bytes 73.05 Mbits/sec
1.01- 2.02 sec 9433012 Bytes 74.72 Mbits/sec
2.02- 3.03 sec 9463248 Bytes 74.96 Mbits/sec
3.03- 4.04 sec 9453436 Bytes 74.88 Mbits/sec
4.04- 5.05 sec 9419736 Bytes 74.61 Mbits/sec
5.05- 6.06 sec 9451292 Bytes 74.86 Mbits/sec
6.06- 7.07 sec 9501272 Bytes 75.26 Mbits/sec
7.07- 8.08 sec 9452464 Bytes 74.87 Mbits/sec
8.08- 9.09 sec 9434036 Bytes 74.73 Mbits/sec
9.09- 10.10 sec 9404416 Bytes 74.49 Mbits/sec
closed by the peer: 10.0.2.2:60720
iperf exit
nsh>
nsh> uname -a
NuttX 12.10.0 ff74c26cdd9 Jan 30 2026 10:56:04 arm64 qemu-armv8a
nsh>
```
#### RPMSG VirtIO Test (Dual-Core QEMU)
```c
❯ qemu-system-aarch64 -cpu cortex-a53 -nographic \
-machine virt,virtualization=on,gic-version=3 \
-chardev stdio,id=con,mux=on -serial chardev:con \
-object
memory-backend-file,discard-data=on,id=shmmem-shmem0,mem-path=/dev/shm/my_shmem0,size=4194304,share=yes
\
-device ivshmem-plain,id=shmem0,memdev=shmmem-shmem0,addr=0xb \
-device virtio-serial-device,bus=virtio-mmio-bus.0 \
-chardev socket,path=/tmp/rpmsg_port_uart_socket,server=on,wait=off,id=foo \
-device virtconsole,chardev=foo \
-mon chardev=con,mode=readline -kernel ./nuttx/cmake_out/v8a_server/nuttx \
-gdb tcp::7775
[ 0.000000] [ 0] [ INFO] [server] pci_register_rptun_ivshmem_driver:
Register ivshmem driver, id=0, cpuname=proxy, master=1
[ 0.000000] [ 3] [ INFO] [server] pci_scan_bus: pci_scan_bus for bus 0
[ 0.000000] [ 3] [ INFO] [server] pci_scan_bus: class = 00000600,
hdr_type = 00000000
[ 0.000000] [ 3] [ INFO] [server] pci_scan_bus: 00:00 [1b36:0008]
[ 0.000000] [ 3] [ INFO] [server] pci_setup_device: pbar0 set bad mask
[ 0.000000] [ 3] [ INFO] [server] pci_setup_device: pbar1 set bad mask
[ 0.000000] [ 3] [ INFO] [server] pci_setup_device: pbar2 set bad mask
[ 0.000000] [ 3] [ INFO] [server] pci_setup_device: pbar3 set bad mask
[ 0.000000] [ 3] [ INFO] [server] pci_setup_device: pbar4 set bad mask
[ 0.000000] [ 3] [ INFO] [server] pci_setup_device: pbar5 set bad mask
[ 0.000000] [ 3] [ INFO] [server] pci_scan_bus: class = 00000200,
hdr_type = 00000000
[ 0.000000] [ 3] [ INFO] [server] pci_scan_bus: 00:08 [1af4:1000]
[ 0.000000] [ 3] [ INFO] [server] pci_setup_device: pbar0:
mask64=fffffffe 32bytes
[ 0.000000] [ 3] [ INFO] [server] pci_setup_device: pbar1:
mask64=fffffff0 4096bytes
[ 0.000000] [ 3] [ INFO] [server] pci_setup_device: pbar2 set bad mask
[ 0.000000] [ 3] [ INFO] [server] pci_setup_device: pbar3 set bad mask
[ 0.000000] [ 3] [ INFO] [server] pci_setup_device: pbar4:
mask64=fffffffffffffff0 16384bytes
[ 0.000000] [ 3] [ INFO] [server] pci_scan_bus: class = 00000500,
hdr_type = 00000000
[ 0.000000] [ 3] [ INFO] [server] pci_scan_bus: 00:58 [1af4:1110]
[ 0.000000] [ 3] [ INFO] [server] pci_setup_device: pbar0:
mask64=fffffff0 256bytes
[ 0.000000] [ 3] [ INFO] [server] pci_setup_device: pbar1 set bad mask
[ 0.000000] [ 3] [ INFO] [server] pci_setup_device: pbar2:
mask64=fffffffffffffff0 4194304bytes
[ 0.000000] [ 3] [ INFO] [server] pci_setup_device: pbar4 set bad mask
[ 0.000000] [ 3] [ INFO] [server] pci_setup_device: pbar5 set bad mask
[ 0.000000] [ 3] [ INFO] [server] ivshmem_probe: shmem addr=0x8000400000
size=4194304 reg=0x10001000
[ 0.000000] [ 3] [ INFO] [server] rptun_ivshmem_probe: shmem
addr=0x8000400000 size=4194304
NuttShell (NSH) NuttX-12.10.0
server> [ 0.000000] [ 0] [ INFO] [proxy]
pci_register_rptun_ivshmem_driver: Register ivshmem driver, id=0,
cpuname=server, master=0
[ 0.000000] [ 3] [ INFO] [proxy] pci_scan_bus: pci_scan_bus for bus 0
[ 0.000000] [ 3] [ INFO] [proxy] pci_scan_bus: class = 00000600,
hdr_type = 00000000
[ 0.000000] [ 3] [ INFO] [proxy] pci_scan_bus: 00:00 [1b36:0008]
[ 0.000000] [ 3] [ INFO] [proxy] pci_setup_device: pbar0 set bad mask
[ 0.000000] [ 3] [ INFO] [proxy] pci_setup_device: pbar1 set bad mask
[ 0.000000] [ 3] [ INFO] [proxy] pci_setup_device: pbar2 set bad mask
[ 0.000000] [ 3] [ INFO] [proxy] pci_setup_device: pbar3 set bad mask
[ 0.000000] [ 3] [ INFO] [proxy] pci_setup_device: pbar4 set bad mask
[ 0.000000] [ 3] [ INFO] [proxy] pci_setup_device: pbar5 set bad mask
[ 0.000000] [ 3] [ INFO] [proxy] pci_scan_bus: class = 00000200,
hdr_type = 00000000
[ 0.000000] [ 3] [ INFO] [proxy] pci_scan_bus: 00:08 [1af4:1000]
[ 0.000000] [ 3] [ INFO] [proxy] pci_setup_device: pbar0:
mask64=fffffffe 32bytes
[ 0.000000] [ 3] [ INFO] [proxy] pci_setup_device: pbar1:
mask64=fffffff0 4096bytes
[ 0.000000] [ 3] [ INFO] [proxy] pci_setup_device: pbar2 set bad mask
[ 0.000000] [ 3] [ INFO] [proxy] pci_setup_device: pbar3 set bad mask
[ 0.000000] [ 3] [ INFO] [proxy] pci_setup_device: pbar4:
mask64=fffffffffffffff0 16384bytes
[ 0.000000] [ 3] [ INFO] [proxy] pci_scan_bus: class = 00000500,
hdr_type = 00000000
[ 0.000000] [ 3] [ INFO] [proxy] pci_scan_bus: 00:58 [1af4:1110]
[ 0.000000] [ 3] [ INFO] [proxy] pci_setup_device: pbar0:
mask64=fffffff0 256bytes
[ 0.000000] [ 3] [ INFO] [proxy] pci_setup_device: pbar1 set bad mask
[ 0.000000] [ 3] [ INFO] [proxy] pci_setup_device: pbar2:
mask64=fffffffffffffff0 4194304bytes
[ 0.000000] [ 3] [ INFO] [proxy] pci_setup_device: pbar4 set bad mask
[ 0.000000] [ 3] [ INFO] [proxy] pci_setup_device: pbar5 set bad mask
[ 0.000000] [ 3] [ INFO] [proxy] ivshmem_probe: shmem addr=0x8000400000
size=4194304 reg=0x10001000
[ 0.000000] [ 3] [ INFO] [proxy] rptun_ivshmem_probe: shmem
addr=0x8000400000 size=4194304
[ 0.000000] [ 3] [ INFO] [proxy] rptun_ivshmem_probe: Start the wdog
server>
server>
server> ps
TID PID PPID PRI POLICY TYPE NPX STATE EVENT SIGMASK
STACK USED FILLED COMMAND
0 0 0 0 FIFO Kthread - Ready
0000000000000000 0008144 0001792 22.0% Idle_Task
1 0 0 192 FIFO Kthread - Waiting Semaphore
0000000000000000 0008080 0001328 16.4% hpwork 0x4047bc60 0x4047bce0
2 0 0 100 FIFO Kthread - Waiting Semaphore
0000000000000000 0008080 0001328 16.4% lpwork 0x4047bd10 0x4047bd90
5 0 0 224 FIFO Kthread - Waiting Semaphore
0000000000000000 0008080 0002224 27.5% rpmsg-uart-rx proxy2 0x404b1048
6 0 0 224 FIFO Kthread - Waiting Event
0000000000000000 0008080 0001968 24.3% rpmsg-uart-tx proxy2 0x404b1048
7 7 0 100 FIFO Task - Running
0000000000000000 0008112 0004176 51.4% nsh_main
8 0 0 224 FIFO Kthread - Waiting Semaphore
0000000000000000 0008080 0002208 27.3% rpmsg-virtio proxy 0x40495b38
server>
server>
server> rpmsg ping all 1 1 1 1
[ 0.000000] [ 7] [ EMERG] [server] ping times: 1
[ 0.000000] [ 7] [ EMERG] [server] buffer_len: 1520, send_len: 17
[ 0.000000] [ 7] [ EMERG] [server] avg: 0 s, 19125584 ns
[ 0.000000] [ 7] [ EMERG] [server] min: 0 s, 19125584 ns
[ 0.000000] [ 7] [ EMERG] [server] max: 0 s, 19125584 ns
[ 0.000000] [ 7] [ EMERG] [server] rate: 0.007110 Mbits/sec
[ 0.000000] [ 7] [ EMERG] [server] ping times: 1
[ 0.000000] [ 7] [ EMERG] [server] buffer_len: 2024, send_len: 17
[ 0.000000] [ 7] [ EMERG] [server] avg: 0 s, 18162928 ns
[ 0.000000] [ 7] [ EMERG] [server] min: 0 s, 18162928 ns
[ 0.000000] [ 7] [ EMERG] [server] max: 0 s, 18162928 ns
[ 0.000000] [ 7] [ EMERG] [server] rate: 0.007487 Mbits/sec
server> rpmsg dump all
[ 0.000000] [ 7] [ EMERG] [server] Local: server Remote: proxy Headrx 8
[ 0.000000] [ 7] [ EMERG] [server] Dump rpmsg info between cpu (master:
yes)server <==> proxy:
[ 0.000000] [ 7] [ EMERG] [server] rpmsg vq RX:
[ 0.000000] [ 7] [ EMERG] [server] rpmsg vq TX:
[ 0.000000] [ 7] [ EMERG] [server] rpmsg ept list:
[ 0.000000] [ 7] [ EMERG] [server] ept NS
[ 0.000000] [ 7] [ EMERG] [server] ept rpmsg-sensor
[ 0.000000] [ 7] [ EMERG] [server] ept rpmsg-ping
[ 0.000000] [ 7] [ EMERG] [server] ept rpmsg-syslog
[ 0.000000] [ 7] [ EMERG] [server] rpmsg buffer list:
[ 0.000000] [ 7] [ EMERG] [server] RX buffer, total 8, pending 0
[ 0.000000] [ 7] [ EMERG] [server] TX buffer, total 8, pending 0
[ 0.000000] [ 7] [ EMERG] [server] Remote: proxy2 state: 1
[ 0.000000] [ 7] [ EMERG] [server] ept NS
[ 0.000000] [ 7] [ EMERG] [server] ept rpmsg-sensor
[ 0.000000] [ 7] [ EMERG] [server] ept rpmsg-ping
[ 0.000000] [ 7] [ EMERG] [server] rpmsg_port queue RX: {used: 0, avail:
8}
[ 0.000000] [ 7] [ EMERG] [server] rpmsg buffer list:
[ 0.000000] [ 7] [ EMERG] [server] rpmsg_port queue TX: {used: 0, avail:
8}
[ 0.000000] [ 7] [ EMERG] [server] rpmsg buffer list:
[ 0.000000] [ 7] [ ALERT] [server] sched_dumpstack: backtrace| 5:
0x00000000402a8554 0x00000000402aa218 0x000000004029bfc8 0x000000004028ca54
0x00000000402e3b48 0x00000000402e3bf8 0x00000000402bca60 0x00000000402bcee8
[ 0.000000] [ 7] [ ALERT] [server] sched_dumpstack: backtrace| 5:
0x00000000402aced8
[ 0.000000] [ 7] [ ALERT] [server] sched_dumpstack: backtrace| 6:
0x00000000402a8974 0x00000000402f5c1c 0x00000000402bbe34 0x00000000402bcfd0
0x00000000402aced8
server>
server> uname -a
NuttX server 12.10.0 ff74c26cdd9-dirty Jan 30 2026 10:56:23 arm64 qemu-armv8a
server>
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]