@ -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 ,
@ -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 ] ) ;
@ -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 ,
@ -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 ] ) ;