aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntonios Motakis <a.motakis@virtualopensystems.com>2015-03-16 16:08:55 -0400
committerAlex Williamson <alex.williamson@redhat.com>2015-03-16 16:08:55 -0400
commita7fa7c77cf15fb22d0f33fcc88770de0246c5588 (patch)
tree36d38f48496c5f67f73bbbe15d30a7cf11a99b51
parent42ac9bd18d4fc28c36c7927847f0f6e90ecd7710 (diff)
vfio/platform: implement IRQ masking/unmasking via an eventfd
With this patch the VFIO user will be able to set an eventfd that can be used in order to mask and unmask IRQs of platform devices. Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com> Signed-off-by: Baptiste Reynal <b.reynal@virtualopensystems.com> Reviewed-by: Eric Auger <eric.auger@linaro.org> Tested-by: Eric Auger <eric.auger@linaro.org> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
-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 {