[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 10/23] vfio-user: get device info
From: |
John Johnson |
Subject: |
[PATCH v2 10/23] vfio-user: get device info |
Date: |
Wed, 1 Feb 2023 21:55:46 -0800 |
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
---
hw/vfio/user-protocol.h | 12 ++++++++++
hw/vfio/user.h | 1 +
include/hw/vfio/vfio-common.h | 3 +++
hw/vfio/common.c | 23 +++++++++++-------
hw/vfio/user-pci.c | 6 +++++
hw/vfio/user.c | 55 +++++++++++++++++++++++++++++++++++++++++++
hw/vfio/trace-events | 1 +
7 files changed, 93 insertions(+), 8 deletions(-)
diff --git a/hw/vfio/user-protocol.h b/hw/vfio/user-protocol.h
index 5de5b20..5f9ef17 100644
--- a/hw/vfio/user-protocol.h
+++ b/hw/vfio/user-protocol.h
@@ -113,4 +113,16 @@ typedef struct {
*/
#define VFIO_USER_DEF_MAX_BITMAP (256 * 1024 * 1024)
+/*
+ * VFIO_USER_DEVICE_GET_INFO
+ * imported from struct vfio_device_info
+ */
+typedef struct {
+ VFIOUserHdr hdr;
+ uint32_t argsz;
+ uint32_t flags;
+ uint32_t num_regions;
+ uint32_t num_irqs;
+} VFIOUserDeviceInfo;
+
#endif /* VFIO_USER_PROTOCOL_H */
diff --git a/hw/vfio/user.h b/hw/vfio/user.h
index 038e5e3..d148661 100644
--- a/hw/vfio/user.h
+++ b/hw/vfio/user.h
@@ -90,6 +90,7 @@ void vfio_user_disconnect(VFIOUserProxy *proxy);
void vfio_user_set_handler(VFIODevice *vbasedev,
void (*handler)(void *opaque, VFIOUserMsg *msg),
void *reqarg);
+int vfio_user_get_device(VFIODevice *vbasedev, Error **errp);
int vfio_user_validate_version(VFIOUserProxy *proxy, Error **errp);
#endif /* VFIO_USER_H */
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index e1ee0ac..0962e37 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -254,6 +254,9 @@ void vfio_put_group(VFIOGroup *group);
int vfio_get_device(VFIOGroup *group, const char *name,
VFIODevice *vbasedev, Error **errp);
+void vfio_init_device(VFIODevice *vbasedev, VFIOGroup *group,
+ struct vfio_device_info *info);
+
extern const MemoryRegionOps vfio_region_ops;
typedef QLIST_HEAD(VFIOGroupList, VFIOGroup) VFIOGroupList;
extern VFIOGroupList vfio_group_list;
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 45b950a..792e247 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -2369,6 +2369,20 @@ void vfio_get_all_regions(VFIODevice *vbasedev)
}
}
+void vfio_init_device(VFIODevice *vbasedev, VFIOGroup *group,
+ struct vfio_device_info *info)
+{
+ vbasedev->group = group;
+ QLIST_INSERT_HEAD(&group->device_list, vbasedev, next);
+
+ vbasedev->num_irqs = info->num_irqs;
+ vbasedev->num_regions = info->num_regions;
+ vbasedev->flags = info->flags;
+ vbasedev->reset_works = !!(info->flags & VFIO_DEVICE_FLAGS_RESET);
+
+ vfio_get_all_regions(vbasedev);
+}
+
int vfio_get_device(VFIOGroup *group, const char *name,
VFIODevice *vbasedev, Error **errp)
{
@@ -2414,18 +2428,11 @@ int vfio_get_device(VFIOGroup *group, const char *name,
}
vbasedev->fd = fd;
- vbasedev->group = group;
- QLIST_INSERT_HEAD(&group->device_list, vbasedev, next);
-
- vbasedev->num_irqs = dev_info.num_irqs;
- vbasedev->num_regions = dev_info.num_regions;
- vbasedev->flags = dev_info.flags;
+ vfio_init_device(vbasedev, group, &dev_info);
trace_vfio_get_device(name, dev_info.flags, dev_info.num_regions,
dev_info.num_irqs);
- vfio_get_all_regions(vbasedev);
- vbasedev->reset_works = !!(dev_info.flags & VFIO_DEVICE_FLAGS_RESET);
return 0;
}
diff --git a/hw/vfio/user-pci.c b/hw/vfio/user-pci.c
index 0fe2593..e5a9450 100644
--- a/hw/vfio/user-pci.c
+++ b/hw/vfio/user-pci.c
@@ -77,6 +77,7 @@ static void vfio_user_pci_realize(PCIDevice *pdev, Error
**errp)
VFIODevice *vbasedev = &vdev->vbasedev;
SocketAddress addr;
VFIOUserProxy *proxy;
+ int ret;
Error *err = NULL;
/*
@@ -116,6 +117,11 @@ static void vfio_user_pci_realize(PCIDevice *pdev, Error
**errp)
vbasedev->type = VFIO_DEVICE_TYPE_PCI;
vbasedev->dev = DEVICE(vdev);
+ ret = vfio_user_get_device(vbasedev, errp);
+ if (ret) {
+ goto error;
+ }
+
return;
error:
diff --git a/hw/vfio/user.c b/hw/vfio/user.c
index 2d60f99..d0ec14c 100644
--- a/hw/vfio/user.c
+++ b/hw/vfio/user.c
@@ -32,6 +32,14 @@
#include "user.h"
#include "trace.h"
+
+/*
+ * These are to defend against a malign server trying
+ * to force us to run out of memory.
+ */
+#define VFIO_USER_MAX_REGIONS 100
+#define VFIO_USER_MAX_IRQS 50
+
static int wait_time = 5000; /* wait up to 5 sec for busy servers */
static IOThread *vfio_user_iothread;
@@ -55,6 +63,9 @@ static void vfio_user_send_wait(VFIOUserProxy *proxy,
VFIOUserHdr *hdr,
static void vfio_user_request_msg(VFIOUserHdr *hdr, uint16_t cmd,
uint32_t size, uint32_t flags);
+static int vfio_user_get_info(VFIOUserProxy *proxy,
+ struct vfio_device_info *info);
+
static inline void vfio_user_set_error(VFIOUserHdr *hdr, uint32_t err)
{
hdr->flags |= VFIO_USER_ERROR;
@@ -807,6 +818,30 @@ void vfio_user_disconnect(VFIOUserProxy *proxy)
g_free(proxy);
}
+int vfio_user_get_device(VFIODevice *vbasedev, Error **errp)
+{
+ struct vfio_device_info info = { .argsz = sizeof(info) };
+ int ret;
+
+ ret = vfio_user_get_info(vbasedev->proxy, &info);
+ if (ret) {
+ error_setg_errno(errp, -ret, "get info failure");
+ return ret;
+ }
+
+ /* defend against a malicious server */
+ if (info.num_regions > VFIO_USER_MAX_REGIONS ||
+ info.num_irqs > VFIO_USER_MAX_IRQS) {
+ error_printf("vfio_user_get_info: invalid reply\n");
+ return -EINVAL;
+ }
+
+ vbasedev->fd = -1;
+ vfio_init_device(vbasedev, NULL, &info);
+
+ return 0;
+}
+
static void vfio_user_request_msg(VFIOUserHdr *hdr, uint16_t cmd,
uint32_t size, uint32_t flags)
{
@@ -1088,3 +1123,23 @@ int vfio_user_validate_version(VFIOUserProxy *proxy,
Error **errp)
trace_vfio_user_version(msgp->major, msgp->minor, msgp->capabilities);
return 0;
}
+
+static int vfio_user_get_info(VFIOUserProxy *proxy,
+ struct vfio_device_info *info)
+{
+ VFIOUserDeviceInfo msg;
+ uint32_t argsz = sizeof(msg) - sizeof(msg.hdr);
+
+ memset(&msg, 0, sizeof(msg));
+ vfio_user_request_msg(&msg.hdr, VFIO_USER_DEVICE_GET_INFO, sizeof(msg), 0);
+ msg.argsz = argsz;
+
+ vfio_user_send_wait(proxy, &msg.hdr, NULL, 0, false);
+ if (msg.hdr.flags & VFIO_USER_ERROR) {
+ return -msg.hdr.error_reply;
+ }
+ trace_vfio_user_get_info(msg.num_regions, msg.num_irqs);
+
+ memcpy(info, &msg.argsz, argsz);
+ return 0;
+}
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index e3640bc..ff903c0 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -173,3 +173,4 @@ 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"
+vfio_user_get_info(uint32_t nregions, uint32_t nirqs) " #regions %d #irqs %d"
--
1.9.4
- [PATCH v2 03/23] vfio-user: add container IO ops vector, (continued)
- [PATCH v2 03/23] vfio-user: add container IO ops vector, John Johnson, 2023/02/02
- [PATCH v2 02/23] vfio-user: add VFIO base abstract class, John Johnson, 2023/02/02
- [PATCH v2 04/23] vfio-user: add region cache, John Johnson, 2023/02/02
- [PATCH v2 01/23] vfio-user: introduce vfio-user protocol specification, John Johnson, 2023/02/02
- [PATCH v2 06/23] vfio-user: Define type vfio_user_pci_dev_info, John Johnson, 2023/02/02
- [PATCH v2 05/23] vfio-user: add device IO ops vector, John Johnson, 2023/02/02
- [PATCH v2 08/23] vfio-user: define socket receive functions, John Johnson, 2023/02/02
- [PATCH v2 07/23] vfio-user: connect vfio proxy to remote server, John Johnson, 2023/02/02
- [PATCH v2 10/23] vfio-user: get device info,
John Johnson <=
- [PATCH v2 11/23] vfio-user: get region info, John Johnson, 2023/02/02
- [PATCH v2 09/23] vfio-user: define socket send functions, John Johnson, 2023/02/02
- [PATCH v2 13/23] vfio-user: pci_user_realize PCI setup, John Johnson, 2023/02/02
- [PATCH v2 16/23] vfio-user: proxy container connect/disconnect, John Johnson, 2023/02/02
- [PATCH v2 15/23] vfio-user: forward msix BAR accesses to server, John Johnson, 2023/02/02