mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
vfio-user: implement message send infrastructure
Add plumbing for sending vfio-user messages on the control socket. Add initial version negotation on connection. Originally-by: John Johnson <john.g.johnson@oracle.com> Signed-off-by: Jagannathan Raman <jag.raman@oracle.com> Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com> Signed-off-by: John Levon <john.levon@nutanix.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20250625193012.2316242-5-john.levon@nutanix.com Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
committed by
Cédric Le Goater
parent
0b3d881a06
commit
36227628d8
+18
-2
@@ -20,6 +20,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(VFIOUserPCIDevice, VFIO_USER_PCI)
|
||||
struct VFIOUserPCIDevice {
|
||||
VFIOPCIDevice device;
|
||||
SocketAddress *socket;
|
||||
bool send_queued; /* all sends are queued */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -92,6 +93,16 @@ static void vfio_user_pci_realize(PCIDevice *pdev, Error **errp)
|
||||
vbasedev->proxy = proxy;
|
||||
vfio_user_set_handler(vbasedev, vfio_user_pci_process_req, vdev);
|
||||
|
||||
vbasedev->name = g_strdup_printf("vfio-user:%s", sock_name);
|
||||
|
||||
if (udev->send_queued) {
|
||||
proxy->flags |= VFIO_PROXY_FORCE_QUEUED;
|
||||
}
|
||||
|
||||
if (!vfio_user_validate_version(proxy, errp)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* vfio-user devices are effectively mdevs (don't use a host iommu).
|
||||
*/
|
||||
@@ -101,9 +112,13 @@ static void vfio_user_pci_realize(PCIDevice *pdev, Error **errp)
|
||||
if (!vfio_device_attach_by_iommu_type(TYPE_VFIO_IOMMU_USER,
|
||||
vbasedev->name, vbasedev,
|
||||
as, errp)) {
|
||||
error_prepend(errp, VFIO_MSG_PREFIX, vbasedev->name);
|
||||
return;
|
||||
goto error;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
error_prepend(errp, VFIO_MSG_PREFIX, vdev->vbasedev.name);
|
||||
}
|
||||
|
||||
static void vfio_user_instance_init(Object *obj)
|
||||
@@ -153,6 +168,7 @@ static const Property vfio_user_pci_dev_properties[] = {
|
||||
sub_vendor_id, PCI_ANY_ID),
|
||||
DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice,
|
||||
sub_device_id, PCI_ANY_ID),
|
||||
DEFINE_PROP_BOOL("x-send-queued", VFIOUserPCIDevice, send_queued, false),
|
||||
};
|
||||
|
||||
static void vfio_user_pci_set_socket(Object *obj, Visitor *v, const char *name,
|
||||
|
||||
@@ -50,4 +50,66 @@ enum vfio_user_command {
|
||||
#define VFIO_USER_NO_REPLY 0x10
|
||||
#define VFIO_USER_ERROR 0x20
|
||||
|
||||
|
||||
/*
|
||||
* VFIO_USER_VERSION
|
||||
*/
|
||||
typedef struct {
|
||||
VFIOUserHdr hdr;
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
char capabilities[];
|
||||
} VFIOUserVersion;
|
||||
|
||||
#define VFIO_USER_MAJOR_VER 0
|
||||
#define VFIO_USER_MINOR_VER 0
|
||||
|
||||
#define VFIO_USER_CAP "capabilities"
|
||||
|
||||
/* "capabilities" members */
|
||||
#define VFIO_USER_CAP_MAX_FDS "max_msg_fds"
|
||||
#define VFIO_USER_CAP_MAX_XFER "max_data_xfer_size"
|
||||
#define VFIO_USER_CAP_PGSIZES "pgsizes"
|
||||
#define VFIO_USER_CAP_MAP_MAX "max_dma_maps"
|
||||
#define VFIO_USER_CAP_MIGR "migration"
|
||||
|
||||
/* "migration" members */
|
||||
#define VFIO_USER_CAP_PGSIZE "pgsize"
|
||||
#define VFIO_USER_CAP_MAX_BITMAP "max_bitmap_size"
|
||||
|
||||
/*
|
||||
* Max FDs mainly comes into play when a device supports multiple interrupts
|
||||
* where each ones uses an eventfd to inject it into the guest.
|
||||
* It is clamped by the the number of FDs the qio channel supports in a
|
||||
* single message.
|
||||
*/
|
||||
#define VFIO_USER_DEF_MAX_FDS 8
|
||||
#define VFIO_USER_MAX_MAX_FDS 16
|
||||
|
||||
/*
|
||||
* Max transfer limits the amount of data in region and DMA messages.
|
||||
* Region R/W will be very small (limited by how much a single instruction
|
||||
* can process) so just use a reasonable limit here.
|
||||
*/
|
||||
#define VFIO_USER_DEF_MAX_XFER (1024 * 1024)
|
||||
#define VFIO_USER_MAX_MAX_XFER (64 * 1024 * 1024)
|
||||
|
||||
/*
|
||||
* Default pagesizes supported is 4k.
|
||||
*/
|
||||
#define VFIO_USER_DEF_PGSIZE 4096
|
||||
|
||||
/*
|
||||
* Default max number of DMA mappings is stolen from the
|
||||
* linux kernel "dma_entry_limit"
|
||||
*/
|
||||
#define VFIO_USER_DEF_MAP_MAX 65535
|
||||
|
||||
/*
|
||||
* Default max bitmap size is also take from the linux kernel,
|
||||
* where usage of signed ints limits the VA range to 2^31 bytes.
|
||||
* Dividing that by the number of bits per byte yields 256MB
|
||||
*/
|
||||
#define VFIO_USER_DEF_MAX_BITMAP (256 * 1024 * 1024)
|
||||
|
||||
#endif /* VFIO_USER_PROTOCOL_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,7 @@ typedef struct VFIOUserMsg {
|
||||
uint32_t id;
|
||||
QemuCond cv;
|
||||
bool complete;
|
||||
bool pending;
|
||||
enum msg_type type;
|
||||
} VFIOUserMsg;
|
||||
|
||||
@@ -56,6 +57,12 @@ typedef struct VFIOUserProxy {
|
||||
struct QIOChannel *ioc;
|
||||
void (*request)(void *opaque, VFIOUserMsg *msg);
|
||||
void *req_arg;
|
||||
uint64_t max_xfer_size;
|
||||
uint64_t max_send_fds;
|
||||
uint64_t max_dma;
|
||||
uint64_t dma_pgsizes;
|
||||
uint64_t max_bitmap;
|
||||
uint64_t migr_pgsize;
|
||||
int flags;
|
||||
QemuCond close_cv;
|
||||
AioContext *ctx;
|
||||
@@ -78,6 +85,7 @@ typedef struct VFIOUserProxy {
|
||||
|
||||
/* VFIOProxy flags */
|
||||
#define VFIO_PROXY_CLIENT 0x1
|
||||
#define VFIO_PROXY_FORCE_QUEUED 0x4
|
||||
|
||||
typedef struct VFIODevice VFIODevice;
|
||||
|
||||
@@ -86,5 +94,6 @@ void vfio_user_disconnect(VFIOUserProxy *proxy);
|
||||
void vfio_user_set_handler(VFIODevice *vbasedev,
|
||||
void (*handler)(void *opaque, VFIOUserMsg *msg),
|
||||
void *reqarg);
|
||||
bool vfio_user_validate_version(VFIOUserProxy *proxy, Error **errp);
|
||||
|
||||
#endif /* VFIO_USER_PROXY_H */
|
||||
|
||||
@@ -6,3 +6,5 @@
|
||||
vfio_user_recv_hdr(const char *name, uint16_t id, uint16_t cmd, uint32_t size, uint32_t flags) " (%s) id 0x%x cmd 0x%x size 0x%x flags 0x%x"
|
||||
vfio_user_recv_read(uint16_t id, int read) " id 0x%x read 0x%x"
|
||||
vfio_user_recv_request(uint16_t cmd) " command 0x%x"
|
||||
vfio_user_send_write(uint16_t id, int wrote) " id 0x%x wrote 0x%x"
|
||||
vfio_user_version(uint16_t major, uint16_t minor, const char *caps) " major %d minor %d caps: %s"
|
||||
|
||||
Reference in New Issue
Block a user