Skip to content

Commit

Permalink
vfio/device: add vfio_disable_irq_from_start
Browse files Browse the repository at this point in the history
To disable (de-assign) one or more IRQs from vfio-pci kernel driver,
irq_set data -1 should be passed to irq_set->data.  uapi <linux/vfio.h>
says that value -1 with DATA_EVENTFD|ACTION_TRIGGER) will de-assign
interrupts if already assigned.

This patch fixes de-assign behavior by replacing DATA_NONE to
DATA_EVENTFD with data -1 along with adding a new API to disable
specific interrupts with start and count.

Signed-off-by: Minwoo Im <[email protected]>
  • Loading branch information
minwooim committed Nov 19, 2024
1 parent d5102dc commit d6d09e1
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 6 deletions.
12 changes: 12 additions & 0 deletions include/vfn/vfio/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ int vfio_set_irq_from_start(struct vfio_device *dev, int *eventfds, int start, i
*/
int vfio_disable_irq(struct vfio_device *dev);

/**
* vfio_disable_irq_from_start - Disable number of count IRQs from given start
* @dev: &struct vfio_device
* @start: start irq number
* @count: number of eventfds
*
* Disable given number of IRQs from start.
*
* Return: ``0`` on success, ``-1`` on error and sets ``errno``.
*/
int vfio_disable_irq_from_start(struct vfio_device *dev, int start, int count);

/**
* vfio_reset - reset vfio device
* @dev: &struct vfio_device to reset
Expand Down
37 changes: 31 additions & 6 deletions src/vfio/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,18 +87,33 @@ int vfio_set_irq_from_start(struct vfio_device *dev, int *eventfds, int start,
return __vfio_set_irq(dev, eventfds, start, count);
}

int vfio_disable_irq(struct vfio_device *dev)
static int __vfio_disable_irq(struct vfio_device *dev, int start, int count)
{
struct vfio_irq_set irq_set;
struct vfio_irq_set *irq_set;
size_t irq_set_size;
int *data;
int ret;

irq_set = (struct vfio_irq_set) {
.argsz = sizeof(irq_set),
.flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_TRIGGER,
irq_set_size = sizeof(*irq_set) + sizeof(int) * count;
irq_set = xmalloc(irq_set_size);

data = xmalloc(sizeof(int) * count);
for (int i = 0; i < count; i++)
data[i] = -1;

*irq_set = (struct vfio_irq_set) {
.argsz = (uint32_t)irq_set_size,
.flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER,
.index = dev->irq_info.index,
.start = start,
.count = count,
};

ret = ioctl(dev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
memcpy(irq_set->data, data, sizeof(int) * count);

ret = ioctl(dev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
free(data);
free(irq_set);

if (ret) {
log_debug("failed to disable device irq\n");
Expand All @@ -108,6 +123,16 @@ int vfio_disable_irq(struct vfio_device *dev)
return 0;
}

int vfio_disable_irq(struct vfio_device *dev)
{
return __vfio_disable_irq(dev, 0, dev->irq_info.count);
}

int vfio_disable_irq_from_start(struct vfio_device *dev, int start, int count)
{
return __vfio_disable_irq(dev, start, count);
}

int vfio_reset(struct vfio_device *dev)
{
if (!(dev->device_info.flags & VFIO_DEVICE_FLAGS_RESET)) {
Expand Down

0 comments on commit d6d09e1

Please sign in to comment.