@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
vfio_virqfd-y := virqfd.o
-obj-$(CONFIG_VFIO) += vfio.o
+obj-$(CONFIG_VFIO) += vfio.o vfio_common.o
obj-$(CONFIG_VFIO_VIRQFD) += vfio_virqfd.o
obj-$(CONFIG_VFIO_IOMMU_TYPE1) += vfio_iommu_type1.o
obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o
@@ -561,61 +561,6 @@ static int vfio_pci_set_msi_trigger(struct vfio_pci_device *vdev,
return 0;
}
-static int vfio_pci_set_ctx_trigger_single(struct eventfd_ctx **ctx,
- unsigned int count, uint32_t flags,
- void *data)
-{
- /* DATA_NONE/DATA_BOOL enables loopback testing */
- if (flags & VFIO_IRQ_SET_DATA_NONE) {
- if (*ctx) {
- if (count) {
- eventfd_signal(*ctx, 1);
- } else {
- eventfd_ctx_put(*ctx);
- *ctx = NULL;
- }
- return 0;
- }
- } else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
- uint8_t trigger;
-
- if (!count)
- return -EINVAL;
-
- trigger = *(uint8_t *)data;
- if (trigger && *ctx)
- eventfd_signal(*ctx, 1);
-
- return 0;
- } else if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
- int32_t fd;
-
- if (!count)
- return -EINVAL;
-
- fd = *(int32_t *)data;
- if (fd == -1) {
- if (*ctx)
- eventfd_ctx_put(*ctx);
- *ctx = NULL;
- } else if (fd >= 0) {
- struct eventfd_ctx *efdctx;
-
- efdctx = eventfd_ctx_fdget(fd);
- if (IS_ERR(efdctx))
- return PTR_ERR(efdctx);
-
- if (*ctx)
- eventfd_ctx_put(*ctx);
-
- *ctx = efdctx;
- }
- return 0;
- }
-
- return -EINVAL;
-}
-
static int vfio_pci_set_err_trigger(struct vfio_pci_device *vdev,
unsigned index, unsigned start,
unsigned count, uint32_t flags, void *data)
@@ -623,8 +568,8 @@ static int vfio_pci_set_err_trigger(struct vfio_pci_device *vdev,
if (index != VFIO_PCI_ERR_IRQ_INDEX || start != 0 || count > 1)
return -EINVAL;
- return vfio_pci_set_ctx_trigger_single(&vdev->err_trigger,
- count, flags, data);
+ return vfio_set_ctx_trigger_single(&vdev->err_trigger,
+ count, flags, data);
}
static int vfio_pci_set_req_trigger(struct vfio_pci_device *vdev,
@@ -634,8 +579,8 @@ static int vfio_pci_set_req_trigger(struct vfio_pci_device *vdev,
if (index != VFIO_PCI_REQ_IRQ_INDEX || start != 0 || count > 1)
return -EINVAL;
- return vfio_pci_set_ctx_trigger_single(&vdev->req_trigger,
- count, flags, data);
+ return vfio_set_ctx_trigger_single(&vdev->req_trigger,
+ count, flags, data);
}
int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags,
new file mode 100644
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Intel, Corp. All rights reserved.
+ * Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+ * Author: Alex Williamson <alex.williamson@redhat.com>
+ * VFIO common helper functions
+ */
+
+#include <linux/eventfd.h>
+#include <linux/vfio.h>
+
+/*
+ * Common helper to set single eventfd trigger
+ *
+ * @ctx [out] : address of eventfd ctx to be written to
+ * @count [in] : number of vectors (should be 1)
+ * @flags [in] : VFIO IRQ flags
+ * @data [in] : data from ioctl
+ */
+int vfio_set_ctx_trigger_single(struct eventfd_ctx **ctx,
+ unsigned int count, u32 flags,
+ void *data)
+{
+ /* DATA_NONE/DATA_BOOL enables loopback testing */
+ if (flags & VFIO_IRQ_SET_DATA_NONE) {
+ if (*ctx) {
+ if (count) {
+ eventfd_signal(*ctx, 1);
+ } else {
+ eventfd_ctx_put(*ctx);
+ *ctx = NULL;
+ }
+ return 0;
+ }
+ } else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
+ u8 trigger;
+
+ if (!count)
+ return -EINVAL;
+
+ trigger = *(uint8_t *)data;
+ if (trigger && *ctx)
+ eventfd_signal(*ctx, 1);
+
+ return 0;
+ } else if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
+ s32 fd;
+
+ if (!count)
+ return -EINVAL;
+
+ fd = *(s32 *)data;
+ if (fd == -1) {
+ if (*ctx)
+ eventfd_ctx_put(*ctx);
+ *ctx = NULL;
+ } else if (fd >= 0) {
+ struct eventfd_ctx *efdctx;
+
+ efdctx = eventfd_ctx_fdget(fd);
+ if (IS_ERR(efdctx))
+ return PTR_ERR(efdctx);
+
+ if (*ctx)
+ eventfd_ctx_put(*ctx);
+
+ *ctx = efdctx;
+ }
+ return 0;
+ }
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL(vfio_set_ctx_trigger_single);
@@ -235,4 +235,8 @@ extern int vfio_virqfd_enable(void *opaque,
void *data, struct virqfd **pvirqfd, int fd);
extern void vfio_virqfd_disable(struct virqfd **pvirqfd);
+/* common lib functions */
+extern int vfio_set_ctx_trigger_single(struct eventfd_ctx **ctx,
+ unsigned int count, u32 flags,
+ void *data);
#endif /* VFIO_H */
With mdev needing to also use the same function, move the function to a common place where vfio pci and mdev can both utilize. Signed-off-by: Dave Jiang <dave.jiang@intel.com> --- drivers/vfio/Makefile | 2 + drivers/vfio/pci/vfio_pci_intrs.c | 63 ++------------------------------ drivers/vfio/vfio_common.c | 74 +++++++++++++++++++++++++++++++++++++ include/linux/vfio.h | 4 ++ 4 files changed, 83 insertions(+), 60 deletions(-) create mode 100644 drivers/vfio/vfio_common.c