rust-vmm / vfio-user Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
See the title. It would be really helpful, if this crate were just available on crates.io.
Background: We have internal tooling for Rust crates from crates.io that makes it easier for us to import and use them via Bazel.
Hi and thanks a lot for providing that crate.
When testing it against the pending QEMU patches at https://github.com/oracle/qemu/commits/vfio-user-patch1-noreq [1], it seems to be failing going further than the version/caps negotiation. I'm running the above qemu code base with -device vfio-user-pci,socket=/tmp/vfu-gpio.sock. --trace "vfio_*"
after starting the gpio
example at /tmp/vfu-gpio.sock
as well.
QEMU segfaults with that trace:
vfio_user_version major 0 minor 0 caps: {"capabilities": {"pgsizes": 4096, "max_msg_fds": 16, "max_dma_maps": 65535, "max_data_xfer_size": 1048576, "migration": {"max_bitmap_size": 268435456, "pgsize": 4096}, "write_multiple": true}}
vfio_user_send_write id 0x0 wrote 0xd6
vfio_user_recv_hdr (unix:/tmp/vfu-rot.sock) id 0x0 cmd 0x1 size 0xd6 flags 0x1
vfio_user_recv_read id 0x0 read 0x4f
Thread 1 "qemu-system-ris" received signal SIGSEGV, Segmentation fault.
0x0000555555ae5806 in vfio_user_send_wait (proxy=proxy@entry=0x555556bdbc80, hdr=hdr@entry=0x555556bdc7a0, fds=fds@entry=0x0, rsize=rsize@entry=0, nobql=nobql@entry=false) at ../hw/vfio/user.c:749
749 QTAILQ_REMOVE(list, msg, next);
(gdb) bt
#0 0x0000555555ae5806 in vfio_user_send_wait (proxy=proxy@entry=0x555556bdbc80, hdr=hdr@entry=0x555556bdc7a0, fds=fds@entry=0x0, rsize=rsize@entry=0, nobql=nobql@entry=false) at ../hw/vfio/user.c:749
#1 0x0000555555ae824b in vfio_user_send_wait (nobql=false, rsize=0, fds=0x0, hdr=0x555556bdc7a0, proxy=0x555556bdbc80) at ../hw/vfio/user.c:718
#2 vfio_user_validate_version (proxy=proxy@entry=0x555556bdbc80, errp=errp@entry=0x7fffffffd598) at ../hw/vfio/user.c:1285
#3 0x0000555555ae405f in vfio_user_pci_realize (pdev=0x555556bd4980, errp=0x7fffffffd670) at ../hw/vfio/pci.c:3736
#4 0x000055555590f074 in pci_qdev_realize (qdev=<optimized out>, errp=<optimized out>) at ../hw/pci/pci.c:2218
#5 0x0000555555bac8ab in device_set_realized (obj=<optimized out>, value=<optimized out>, errp=0x7fffffffd8a0) at ../hw/core/qdev.c:553
#6 0x0000555555bb0b48 in property_set_bool (obj=0x555556bd4980, v=<optimized out>, name=<optimized out>, opaque=0x55555630a9e0, errp=0x7fffffffd8a0) at ../qom/object.c:2273
#7 0x0000555555bb3a93 in object_property_set (obj=obj@entry=0x555556bd4980, name=name@entry=0x555555e045da "realized", v=v@entry=0x555556307580, errp=errp@entry=0x7fffffffd8a0) at ../qom/object.c:1408
#8 0x0000555555bb6d8f in object_property_set_qobject (obj=obj@entry=0x555556bd4980, name=name@entry=0x555555e045da "realized", value=value@entry=0x555556b0d340, errp=errp@entry=0x7fffffffd8a0) at ../qom/qom-qobject.c:28
#9 0x0000555555bb4094 in object_property_set_bool (obj=0x555556bd4980, name=name@entry=0x555555e045da "realized", value=value@entry=true, errp=errp@entry=0x7fffffffd8a0) at ../qom/object.c:1477
#10 0x0000555555bad44c in qdev_realize (dev=<optimized out>, bus=bus@entry=0x555556817140, errp=errp@entry=0x7fffffffd8a0) at ../hw/core/qdev.c:333
#11 0x000055555599d1ff in qdev_device_add_from_qdict (opts=opts@entry=0x5555569d5080, from_json=from_json@entry=false, errp=0x7fffffffd8a0, errp@entry=0x55555628d0f0 <error_fatal>) at ../softmmu/qdev-monitor.c:714
#12 0x000055555599d621 in qdev_device_add (opts=0x555556307950, errp=errp@entry=0x55555628d0f0 <error_fatal>) at ../softmmu/qdev-monitor.c:733
#13 0x000055555599f42f in device_init_func (opaque=<optimized out>, opts=<optimized out>, errp=0x55555628d0f0 <error_fatal>) at ../softmmu/vl.c:1142
#14 0x0000555555d113b1 in qemu_opts_foreach (list=<optimized out>, func=func@entry=0x55555599f420 <device_init_func>, opaque=opaque@entry=0x0, errp=errp@entry=0x55555628d0f0 <error_fatal>) at ../util/qemu-option.c:1135
#15 0x00005555559a1cfa in qemu_create_cli_devices () at ../softmmu/vl.c:2516
#16 qmp_x_exit_preconfig (errp=<optimized out>) at ../softmmu/vl.c:2584
#17 0x00005555559a5498 in qmp_x_exit_preconfig (errp=<optimized out>) at ../softmmu/vl.c:2578
#18 qemu_init (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at ../softmmu/vl.c:3591
#19 0x0000555555ba9d06 in qemu_main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at ../softmmu/main.c:37
#20 0x00007ffff772f510 in __libc_start_call_main (main=main@entry=0x555555818580 <main>, argc=argc@entry=28, argv=argv@entry=0x7fffffffdcf8) at ../sysdeps/nptl/libc_start_call_main.h:58
#21 0x00007ffff772f5c9 in __libc_start_main_impl (main=0x555555818580 <main>, argc=28, argv=0x7fffffffdcf8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdce8) at ../csu/libc-start.c:381
#22 0x0000555555819c15 in _start ()
(gdb) q
and this is the gpio
example output:
[2023-03-15T13:36:34Z INFO vfio_user] Received client version: major = 0 minor = 0 capabilities = Capabilities { max_msg_fds: 1, max_data_xfer_size: 1048576, migration: MigrationCapabilities { pgsize: 4096 } }
[2023-03-15T13:36:34Z INFO vfio_user] Sent server version: major = 0 minor = 1 capabilities = Capabilities { max_msg_fds: 1, max_data_xfer_size: 1048576, migration: MigrationCapabilities { pgsize: 4096 } }
While debugging I realized QEMU is not getting all the bytes from the server version reply, and with the following hack:
diff --git a/src/lib.rs b/src/lib.rs
index 5093902..cd88662 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -905,11 +905,12 @@ impl Server {
message_id: client_version.header.message_id,
command: Command::Version,
flags: HeaderFlags::Reply as u32,
- message_size: (size_of::<Version>() + version_data.len() + 1) as u32,
+ // message_size: (size_of::<Version>() + version_data.len() + 1) as u32,
+ message_size: (size_of::<Version>()) as u32,
..Default::default()
},
major: 0,
- minor: 1,
+ minor: 0,
};
let server_capabilities = Capabilities::default();
@@ -939,13 +940,15 @@ impl Server {
.read_exact(&mut cmd.as_mut_slice()[size_of::<Header>()..])
.map_err(Error::StreamRead)?;
+ let f = if fds.is_empty() { None } else { Some(&fds[0]) };
+
backend
.dma_map(
DmaMapFlags::from_bits_truncate(cmd.flags),
cmd.offset,
cmd.address,
cmd.size,
- Some(&fds[0]),
+ f,
)
.map_err(Error::Backend)?;
I get a little further:
vfio_user_version major 0 minor 0 caps: {"capabilities": {"pgsizes": 4096, "max_msg_fds": 16, "max_dma_maps": 65535, "max_data_xfer_size": 1048576, "migration": {"max_bitmap_size": 268435456, "pgsize": 4096}, "write_multiple": true}}
vfio_user_send_write id 0x0 wrote 0xd6
vfio_user_recv_hdr (unix:/tmp/vfu-rot.sock) id 0x0 cmd 0x1 size 0x14 flags 0x1
vfio_user_recv_read id 0x0 read 0x4
qemu-system-riscv64: -device vfio-user-pci,socket=/tmp/vfu-rot.sock: vfio_user_recv: unknown message type
vfio_user_version major 0 minor 0 caps: {"capabilities": {"pgsizes": 4096, "max_msg_fds": 16, "max_dma_maps": 65535, "max_data_xfer_size": 1048576, "migration": {"max_bitmap_size": 268435456, "pgsize": 4096}, "write_multiple": true}}
vfio_listener_region_add_ram region_add [ram] 0x1000 - 0xffff [0x7ffff4800000]
vfio_user_dma_map iova 0x1000 size 0xf000 off 0x0 flags 0x1 will_commit 1
vfio_user_send_write id 0x1 wrote 0x30
vfio_listener_region_add_skip SKIPPING region_add 0x100000 - 0x100fff
vfio_listener_region_add_skip SKIPPING region_add 0x101000 - 0x101023
vfio_listener_region_add_skip SKIPPING region_add 0x2000000 - 0x2003fff
vfio_listener_region_add_skip SKIPPING region_add 0x2004000 - 0x200bfff
vfio_listener_region_add_skip SKIPPING region_add 0x3000000 - 0x300ffff
vfio_listener_region_add_skip SKIPPING region_add 0xc000000 - 0xc5fffff
vfio_listener_region_add_skip SKIPPING region_add 0x10000000 - 0x10000007
vfio_listener_region_add_skip SKIPPING region_add 0x10001000 - 0x100011ff
vfio_listener_region_add_skip SKIPPING region_add 0x10002000 - 0x100021ff
vfio_listener_region_add_skip SKIPPING region_add 0x10003000 - 0x100031ff
vfio_listener_region_add_skip SKIPPING region_add 0x10004000 - 0x100041ff
vfio_listener_region_add_skip SKIPPING region_add 0x10005000 - 0x100051ff
vfio_listener_region_add_skip SKIPPING region_add 0x10006000 - 0x100061ff
vfio_listener_region_add_skip SKIPPING region_add 0x10007000 - 0x100071ff
vfio_listener_region_add_skip SKIPPING region_add 0x10008000 - 0x100081ff
vfio_listener_region_add_skip SKIPPING region_add 0x20000000 - 0x21ffffff
vfio_listener_region_add_skip SKIPPING region_add 0x22000000 - 0x23ffffff
vfio_listener_region_add_skip SKIPPING region_add 0x30000000 - 0x3fffffff
vfio_listener_region_add_skip SKIPPING region_add 0x40000000 - 0x7fffffff
vfio_listener_region_add_ram region_add [ram] 0x80000000 - 0x17fffffff [0x7ffeafe00000]
vfio_user_dma_map iova 0x80000000 size 0x100000000 off 0x0 flags 0x3 will_commit 1
vfio_user_send_write id 0x2 wrote 0x30
vfio_listener_region_add_skip SKIPPING region_add 0x400000000 - 0x7ffffffff
vfio_wait_reqs - timed out
and the corresponding vfio-user debug log:
[2023-03-15T13:41:33Z INFO vfio_user] Received client version: major = 0 minor = 0 capabilities = Capabilities { max_msg_fds: 1, max_data_xfer_size: 1048576, migration: MigrationCapabilities { pgsize: 4096 } }
[2023-03-15T13:41:33Z INFO vfio_user] Sent server version: major = 0 minor = 0 capabilities = Capabilities { max_msg_fds: 1, max_data_xfer_size: 1048576, migration: MigrationCapabilities { pgsize: 4096 } }
[2023-03-15T13:41:33Z INFO gpio] dma_map flags = READ_ONLY offset = 0 address = 4096 size = 61440 fd = None
[2023-03-15T13:41:33Z ERROR vfio_user] Error handling command: DmaMap: Error writing to stream: Broken pipe (os error 32)
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: StreamWrite(Os { code: 32, kind: BrokenPipe, message: "Broken pipe" })', examples/gpio/main.rs:219:30
stack backtrace:
0: rust_begin_unwind
at /rustc/39f2657d1101b50f9b71ae460b762d330cc8426b/library/std/src/panicking.rs:579:5
1: core::panicking::panic_fmt
at /rustc/39f2657d1101b50f9b71ae460b762d330cc8426b/library/core/src/panicking.rs:64:14
2: core::result::unwrap_failed
at /rustc/39f2657d1101b50f9b71ae460b762d330cc8426b/library/core/src/result.rs:1750:5
3: core::result::Result<T,E>::unwrap
at /rustc/39f2657d1101b50f9b71ae460b762d330cc8426b/library/core/src/result.rs:1090:23
4: gpio::main
at ./examples/gpio/main.rs:219:5
5: core::ops::function::FnOnce::call_once
at /rustc/39f2657d1101b50f9b71ae460b762d330cc8426b/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
I'll continue debugging this on a best-effort basis and will let you know of any progress.
[1] https://www.mail-archive.com/[email protected]/msg920798.html
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.