Hi Edgar,
On 30 Apr 2026, at 15:23, Edgar E. Iglesias edgar.iglesias@amd.com wrote:
On Thu, Apr 23, 2026 at 01:40:40PM +0000, Bertrand Marquis wrote:
Hi Everyone,
I have a first PoC showing virtio-msg working with a loopback system between Linux kernel and Qemu.
The patches, build and run instructions can be found here:
https://github.com/bertrand-marquis/virtio-msg-spec/tree/linux-poc/v0/linux-...
This is very early stage but this shows a fully functional version with rng and block validated. I used ChatGPT help to fix issues and write part of the code (or big parts for Qemu) and this is far from upstreamable so do not share that.
I will share a v1 in the next weeks with FF-A support but i still have some timings and DMA issues to solve.
Any comment on this is more than welcome !!
Cheers Bertrand
Nice work Bertrand!
Thanks
Most of the QEMU parts look good! And I think this code highlights some issues with the current implementation. Thanks.
The new RAMBlock is a good idea. It makes sense to me for these bridge-published DMA windows, since you want them to work through the normal DMA and address space paths in QEMU.
The thing I would watch carefully is lifetime tracking of host pointer use. Once a published range is exposed that way, every path that gets a direct host pointer really needs to give it back again. Otherwise DEL_REQ teardown can end up waiting on references that never drop.
That feels like the main thing worth double checking in this part of the code. Just thought I'd mention it.
Yes I am having some trouble there and I am working on it. Finding when to release a shared area without having to much performance impact is an issue right now and i am working on improving the interface to have a way to signal to qemu to keep some shared areas until linux ask them back to optimize the pool case.
On the new virtio-msg kernel interface, I was hoping we would not need to expose the rings to user-space. I do agree that the kernel probably needs an internal ring, queue or something. I would just like to understand better why we need to expose that part too. I made a few changes to Viresh code at some point to internally use the AMP queues but still maintaining the read/write/select/poll interface towards user-space. A little similar to a UDP socket.
E.g. Driver to Device:
- Driver puts msg-1 on internal queue.
- Driver puts msg-2 on internal queue before device reads msg-1.
- At some point device wakes up, reads msg-1 and msg-2 in a loop before read() would block.
Device to driver:
- write() msg-1
- Before driver reads msg-1, device write() msg-2.
- write() blocks when the internal queue is full.
That was the direction I was hoping to go with Viresh code. With a suitable depth of queue.
Idea of the ring was to reduce qemu to kernel ping pongs by just waiting on the fd and then reading messages inside the ring.
In fact i reworked the interface this week to also put the memory sharing/unsharing inside the ring to keep ordering and prevent the dual ioctl/ring poll inside qemu.
But using a blocking read is an idea i can definitely look at.
I will try to share an updated version with the reworked bridge interface and also linux kernel ffa implementation. I was hopping to do that today but i still have some issues to work on.
Another problem I found in the AMP code when using Viresh's virtio-msg was the problem if multiple contexts are trying to send/receive messages at the same time, e.g interrupt context vs normal thread context. IIRC, I worked around it in the AMP code by having separate rx buffers. The problem was for example that the driver would send a msg-1 and wait for a response to that msg. While it waits, it would process incoming msg's and look for a match to msg-1. During this wait, interrupt context sends msg-2 (in my case notification), and it would override the buffer holding msg-1 causing a hang.
My early PoC was doing something like that and i went into troubles because I ended up with EVENT_AVAIL being processed before the VQUEUE_SET or DMA_SHARE things so i went back to a single queue to enforce ordering and prevent events to be processed before queue configuration or share memory requests.
I don't know what the best way to solve it is, but in the AMP code, multiple buffers solved the problem for us.
Let's discuss that because i have trouble with ordering that i needed to solve. Mostly in the virtio block case which is doing dma_map and queue config and queue kick from interrupt context
It would be good to discuss this a bit more before going too far down a substantial redesign, and first see if the problems we hit there can be solved within Viresh's design.
Ack
A few nitpicks:
I've tried to call virtio-msg-bus implementations virtio-msg-bus-something. In this case, virtio-msg-bus-linux-bridge.c I guess.
Ok
include/hw/virtio/virtio-msg-prot.h has some general code to print messages and convert some parts to strings. It's missing stuff but it looks like you could reuse some of it or extend it for your needs.
The debug print which are added there were a temporary debug i removed since and i now have errors through GUEST_ERRORS and i am using tracing to follow the protocol.
A couple more things I think are worth a look (assisted by codex):
Commit 6899bd4d48 `hw/virtio: add virtio-msg linux bridge transport parent`
High: `virtio_msg_linux_bridge_transport_unrealize()` destroys the bridge before it unrealizes the `VirtIOMSGProxy`. The bridge unrealize path destroys the bridge DMA address space, but child virtio devices under the proxy can still hold and use that address space through the earlier latched transport caps / `vdev->dma_as`. That looks like a use-after-free risk.
Ack, will check that.
Commit 466fbe293e `virtio-msg: latch transport capabilities during pre-plug`
Medium: this introduces a one-time cached transport capability snapshot on the proxy, but there is no invalidation path once `latched_caps_valid` becomes true. If the backend later tears down or recreates its DMA address space, `virtio_msg_get_dma_as()` may keep returning a stale pointer.
Nice, I will check that to.
Thanks a lot for the review that is really helpfull.
Regards Bertrand
Best regards, Edgar
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.