aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/vfio/platform/vfio_platform_irq.c47
-rw-r--r--drivers/vfio/platform/vfio_platform_private.h2
2 files changed, 45 insertions, 4 deletions
diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
index e0e638841d0b..88bba57b30a8 100644
--- a/drivers/vfio/platform/vfio_platform_irq.c
+++ b/drivers/vfio/platform/vfio_platform_irq.c
@@ -37,6 +37,15 @@ static void vfio_platform_mask(struct vfio_platform_irq *irq_ctx)
37 spin_unlock_irqrestore(&irq_ctx->lock, flags); 37 spin_unlock_irqrestore(&irq_ctx->lock, flags);
38} 38}
39 39
40static int vfio_platform_mask_handler(void *opaque, void *unused)
41{
42 struct vfio_platform_irq *irq_ctx = opaque;
43
44 vfio_platform_mask(irq_ctx);
45
46 return 0;
47}
48
40static int vfio_platform_set_irq_mask(struct vfio_platform_device *vdev, 49static int vfio_platform_set_irq_mask(struct vfio_platform_device *vdev,
41 unsigned index, unsigned start, 50 unsigned index, unsigned start,
42 unsigned count, uint32_t flags, 51 unsigned count, uint32_t flags,
@@ -48,8 +57,18 @@ static int vfio_platform_set_irq_mask(struct vfio_platform_device *vdev,
48 if (!(vdev->irqs[index].flags & VFIO_IRQ_INFO_MASKABLE)) 57 if (!(vdev->irqs[index].flags & VFIO_IRQ_INFO_MASKABLE))
49 return -EINVAL; 58 return -EINVAL;
50 59
51 if (flags & VFIO_IRQ_SET_DATA_EVENTFD) 60 if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
52 return -EINVAL; /* not implemented yet */ 61 int32_t fd = *(int32_t *)data;
62
63 if (fd >= 0)
64 return vfio_virqfd_enable((void *) &vdev->irqs[index],
65 vfio_platform_mask_handler,
66 NULL, NULL,
67 &vdev->irqs[index].mask, fd);
68
69 vfio_virqfd_disable(&vdev->irqs[index].mask);
70 return 0;
71 }
53 72
54 if (flags & VFIO_IRQ_SET_DATA_NONE) { 73 if (flags & VFIO_IRQ_SET_DATA_NONE) {
55 vfio_platform_mask(&vdev->irqs[index]); 74 vfio_platform_mask(&vdev->irqs[index]);
@@ -78,6 +97,15 @@ static void vfio_platform_unmask(struct vfio_platform_irq *irq_ctx)
78 spin_unlock_irqrestore(&irq_ctx->lock, flags); 97 spin_unlock_irqrestore(&irq_ctx->lock, flags);
79} 98}
80 99
100static int vfio_platform_unmask_handler(void *opaque, void *unused)
101{
102 struct vfio_platform_irq *irq_ctx = opaque;
103
104 vfio_platform_unmask(irq_ctx);
105
106 return 0;
107}
108
81static int vfio_platform_set_irq_unmask(struct vfio_platform_device *vdev, 109static int vfio_platform_set_irq_unmask(struct vfio_platform_device *vdev,
82 unsigned index, unsigned start, 110 unsigned index, unsigned start,
83 unsigned count, uint32_t flags, 111 unsigned count, uint32_t flags,
@@ -89,8 +117,19 @@ static int vfio_platform_set_irq_unmask(struct vfio_platform_device *vdev,
89 if (!(vdev->irqs[index].flags & VFIO_IRQ_INFO_MASKABLE)) 117 if (!(vdev->irqs[index].flags & VFIO_IRQ_INFO_MASKABLE))
90 return -EINVAL; 118 return -EINVAL;
91 119
92 if (flags & VFIO_IRQ_SET_DATA_EVENTFD) 120 if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
93 return -EINVAL; /* not implemented yet */ 121 int32_t fd = *(int32_t *)data;
122
123 if (fd >= 0)
124 return vfio_virqfd_enable((void *) &vdev->irqs[index],
125 vfio_platform_unmask_handler,
126 NULL, NULL,
127 &vdev->irqs[index].unmask,
128 fd);
129
130 vfio_virqfd_disable(&vdev->irqs[index].unmask);
131 return 0;
132 }
94 133
95 if (flags & VFIO_IRQ_SET_DATA_NONE) { 134 if (flags & VFIO_IRQ_SET_DATA_NONE) {
96 vfio_platform_unmask(&vdev->irqs[index]); 135 vfio_platform_unmask(&vdev->irqs[index]);
diff --git a/drivers/vfio/platform/vfio_platform_private.h b/drivers/vfio/platform/vfio_platform_private.h
index ff2db1d20a26..5d31e0473406 100644
--- a/drivers/vfio/platform/vfio_platform_private.h
+++ b/drivers/vfio/platform/vfio_platform_private.h
@@ -35,6 +35,8 @@ struct vfio_platform_irq {
35 struct eventfd_ctx *trigger; 35 struct eventfd_ctx *trigger;
36 bool masked; 36 bool masked;
37 spinlock_t lock; 37 spinlock_t lock;
38 struct virqfd *unmask;
39 struct virqfd *mask;
38}; 40};
39 41
40struct vfio_platform_region { 42struct vfio_platform_region {