aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJag Raman <jag.raman@oracle.com>2022-06-07 16:21:40 -0400
committerGitHub <noreply@github.com>2022-06-07 21:21:40 +0100
commita767ebd126157c4aa55ff0fe5786681507fb7ea8 (patch)
tree6876e347860a2ab1871d0e413312fe507fd006d6 /lib
parentd307dbcab74aef3680ba99d7f836f2bc0b4bc81e (diff)
downloadlibvfio-user-a767ebd126157c4aa55ff0fe5786681507fb7ea8.zip
libvfio-user-a767ebd126157c4aa55ff0fe5786681507fb7ea8.tar.gz
libvfio-user-a767ebd126157c4aa55ff0fe5786681507fb7ea8.tar.bz2
irq: inform device of IRQ mask & unmask via callback (#694)
Client masks or unmasks a device IRQ using the VFIO_USER_DEVICE_SET_IRQS message. Inform the device of such changes to the IRQ state. Signed-off-by: Jagannathan Raman <jag.raman@oracle.com> Reviewed-by: John Levon <john.levon@nutanix.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/irq.c29
-rw-r--r--lib/libvfio-user.c16
-rw-r--r--lib/private.h1
3 files changed, 44 insertions, 2 deletions
diff --git a/lib/irq.c b/lib/irq.c
index c7820aa..eadad7b 100644
--- a/lib/irq.c
+++ b/lib/irq.c
@@ -154,6 +154,32 @@ irqs_reset(vfu_ctx_t *vfu_ctx)
}
}
+static void
+irqs_set_state(vfu_ctx_t *vfu_ctx, struct vfio_irq_set *irq_set)
+{
+ vfu_dev_irq_state_cb_t *cb = NULL;
+ uint32_t irq_action;
+ bool mask = false;
+
+ assert(irq_set->index < VFU_DEV_NUM_IRQS);
+ cb = vfu_ctx->irq_state_cbs[irq_set->index];
+ if (cb == NULL) {
+ return;
+ }
+
+ assert((irq_set->start + irq_set->count) <=
+ vfu_ctx->irq_count[irq_set->index]);
+
+ irq_action = irq_set->flags & VFIO_IRQ_SET_ACTION_TYPE_MASK;
+
+ assert((irq_action & VFIO_IRQ_SET_ACTION_MASK) ||
+ (irq_action & VFIO_IRQ_SET_ACTION_UNMASK));
+
+ mask = (irq_action & VFIO_IRQ_SET_ACTION_MASK) ? true : false;
+
+ cb(vfu_ctx, irq_set->start, irq_set->count, mask);
+}
+
static int
irqs_set_data_none(vfu_ctx_t *vfu_ctx, struct vfio_irq_set *irq_set)
{
@@ -345,8 +371,7 @@ handle_device_set_irqs(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg)
switch (irq_set->flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) {
case VFIO_IRQ_SET_ACTION_MASK:
case VFIO_IRQ_SET_ACTION_UNMASK:
- // We're always edge-triggered without un/mask support.
- // FIXME: return an error? We don't report MASKABLE
+ irqs_set_state(vfu_ctx, irq_set);
return 0;
case VFIO_IRQ_SET_ACTION_TRIGGER:
break;
diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c
index 47e3572..c45ceeb 100644
--- a/lib/libvfio-user.c
+++ b/lib/libvfio-user.c
@@ -1968,6 +1968,22 @@ vfu_setup_device_nr_irqs(vfu_ctx_t *vfu_ctx, enum vfu_dev_irq_type type,
}
EXPORT int
+vfu_setup_irq_state_callback(vfu_ctx_t *vfu_ctx, enum vfu_dev_irq_type type,
+ vfu_dev_irq_state_cb_t *cb)
+{
+ assert(vfu_ctx != NULL);
+
+ if (type >= VFU_DEV_NUM_IRQS) {
+ vfu_log(vfu_ctx, LOG_ERR, "Invalid IRQ type index %u", type);
+ return ERROR_INT(EINVAL);
+ }
+
+ vfu_ctx->irq_state_cbs[type] = cb;
+
+ return 0;
+}
+
+EXPORT int
vfu_setup_device_migration_callbacks(vfu_ctx_t *vfu_ctx,
const vfu_migration_callbacks_t *callbacks,
uint64_t data_offset)
diff --git a/lib/private.h b/lib/private.h
index 4c483f2..7ffd6be 100644
--- a/lib/private.h
+++ b/lib/private.h
@@ -172,6 +172,7 @@ struct vfu_ctx {
struct migration *migration;
uint32_t irq_count[VFU_DEV_NUM_IRQS];
+ vfu_dev_irq_state_cb_t *irq_state_cbs[VFU_DEV_NUM_IRQS];
vfu_irqs_t *irqs;
bool realized;
vfu_dev_type_t dev_type;