Skip to content

Commit

Permalink
vfio/platform: implement IRQ masking/unmasking via an eventfd
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Antonios Motakis authored and awilliam committed Mar 16, 2015
1 parent 42ac9bd commit a7fa7c7
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 4 deletions.
47 changes: 43 additions & 4 deletions drivers/vfio/platform/vfio_platform_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ static void vfio_platform_mask(struct vfio_platform_irq *irq_ctx)
spin_unlock_irqrestore(&irq_ctx->lock, flags);
}

static int vfio_platform_mask_handler(void *opaque, void *unused)
{
struct vfio_platform_irq *irq_ctx = opaque;

vfio_platform_mask(irq_ctx);

return 0;
}

static int vfio_platform_set_irq_mask(struct vfio_platform_device *vdev,
unsigned index, unsigned start,
unsigned count, uint32_t flags,
Expand All @@ -48,8 +57,18 @@ static int vfio_platform_set_irq_mask(struct vfio_platform_device *vdev,
if (!(vdev->irqs[index].flags & VFIO_IRQ_INFO_MASKABLE))
return -EINVAL;

if (flags & VFIO_IRQ_SET_DATA_EVENTFD)
return -EINVAL; /* not implemented yet */
if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
int32_t fd = *(int32_t *)data;

if (fd >= 0)
return vfio_virqfd_enable((void *) &vdev->irqs[index],
vfio_platform_mask_handler,
NULL, NULL,
&vdev->irqs[index].mask, fd);

vfio_virqfd_disable(&vdev->irqs[index].mask);
return 0;
}

if (flags & VFIO_IRQ_SET_DATA_NONE) {
vfio_platform_mask(&vdev->irqs[index]);
Expand Down Expand Up @@ -78,6 +97,15 @@ static void vfio_platform_unmask(struct vfio_platform_irq *irq_ctx)
spin_unlock_irqrestore(&irq_ctx->lock, flags);
}

static int vfio_platform_unmask_handler(void *opaque, void *unused)
{
struct vfio_platform_irq *irq_ctx = opaque;

vfio_platform_unmask(irq_ctx);

return 0;
}

static int vfio_platform_set_irq_unmask(struct vfio_platform_device *vdev,
unsigned index, unsigned start,
unsigned count, uint32_t flags,
Expand All @@ -89,8 +117,19 @@ static int vfio_platform_set_irq_unmask(struct vfio_platform_device *vdev,
if (!(vdev->irqs[index].flags & VFIO_IRQ_INFO_MASKABLE))
return -EINVAL;

if (flags & VFIO_IRQ_SET_DATA_EVENTFD)
return -EINVAL; /* not implemented yet */
if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
int32_t fd = *(int32_t *)data;

if (fd >= 0)
return vfio_virqfd_enable((void *) &vdev->irqs[index],
vfio_platform_unmask_handler,
NULL, NULL,
&vdev->irqs[index].unmask,
fd);

vfio_virqfd_disable(&vdev->irqs[index].unmask);
return 0;
}

if (flags & VFIO_IRQ_SET_DATA_NONE) {
vfio_platform_unmask(&vdev->irqs[index]);
Expand Down
2 changes: 2 additions & 0 deletions drivers/vfio/platform/vfio_platform_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ struct vfio_platform_irq {
struct eventfd_ctx *trigger;
bool masked;
spinlock_t lock;
struct virqfd *unmask;
struct virqfd *mask;
};

struct vfio_platform_region {
Expand Down

0 comments on commit a7fa7c7

Please sign in to comment.