Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vfio/device: add support enabling/disabling specific IRQ(s) #26

Merged
merged 1 commit into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

``nvme_pci_init`` has been deprecated and will generate a warning.

``vfio_set_irq`` has been updated to receive ``start`` parameter to specify
start irq number to enable. With this, ``vfio_disable_irq`` has been updated
to disable specific one or more irqs from ``start`` for ``count`` of irqs.
``vfio_disable_irq_all`` has been newly added to disable all the enabled irqs.

## v5.2.0: (unreleased)

### ``nvme_ctrl``
Expand Down
2 changes: 1 addition & 1 deletion examples/eventfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ int main(int argc, char **argv)
if (efd < 0)
err(1, "failed to create eventfd");

if (vfio_set_irq(&ctrl.pci.dev, efds, 2))
if (vfio_set_irq(&ctrl.pci.dev, efds, 0, 2))
err(1, "failed to set irqs");

if (nvme_create_ioqpair(&ctrl, 1, 64, 1, 0x0))
Expand Down
19 changes: 16 additions & 3 deletions include/vfn/vfio/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,37 @@ struct vfio_device {
* vfio_set_irq - Enable IRQs through eventfds
* @dev: &struct vfio_device
* @eventfds: array of eventfds
* @start: start irq number
* @count: number of eventfds
*
* Enable interrupts for a range of vectors. See linux/vfio.h for documentation
* on the format of @eventfds.
*
* Return: ``0`` on success, ``-1`` on error and sets ``errno``.
*/
int vfio_set_irq(struct vfio_device *dev, int *eventfds, int count);
int vfio_set_irq(struct vfio_device *dev, int *eventfds, int start, int count);

/**
* vfio_disable_irq - Disable all IRQs
* vfio_disable_irq - 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(struct vfio_device *dev, int start, int count);

/**
* vfio_disable_irq_all - Disable all IRQs
* @dev: &struct vfio_device
*
* Disable all IRQs.
*
* Return: ``0`` on success, ``-1`` on error and sets ``errno``.
*/
int vfio_disable_irq(struct vfio_device *dev);
int vfio_disable_irq_all(struct vfio_device *dev);

/**
* vfio_reset - reset vfio device
Expand Down
36 changes: 28 additions & 8 deletions src/vfio/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
#include "ccan/minmax/minmax.h"
#include "ccan/str/str.h"

int vfio_set_irq(struct vfio_device *dev, int *eventfds, int count)
int vfio_set_irq(struct vfio_device *dev, int *eventfds, int start, int count)
{
struct vfio_irq_set *irq_set;
size_t irq_set_size;
Expand All @@ -59,7 +59,7 @@ int vfio_set_irq(struct vfio_device *dev, int *eventfds, int count)
.argsz = (uint32_t)irq_set_size,
.flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER,
.index = dev->irq_info.index,
.start = 0,
.start = start,
.count = count,
};

Expand All @@ -76,18 +76,33 @@ int vfio_set_irq(struct vfio_device *dev, int *eventfds, int count)
return 0;
}

int vfio_disable_irq(struct vfio_device *dev)
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 @@ -97,6 +112,11 @@ int vfio_disable_irq(struct vfio_device *dev)
return 0;
}

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

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