drivers/vfio/pci/vfio_pci_intrs.c
Source file repositories/reference/linux-study-clean/drivers/vfio/pci/vfio_pci_intrs.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/vfio/pci/vfio_pci_intrs.c- Extension
.c- Size
- 21358 bytes
- Lines
- 881
- Domain
- Driver Families
- Bucket
- drivers/vfio
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/device.hlinux/interrupt.hlinux/eventfd.hlinux/msi.hlinux/pci.hlinux/file.hlinux/vfio.hlinux/wait.hlinux/slab.hvfio_pci_priv.h
Detected Declarations
struct vfio_pci_irq_ctxfunction irq_isfunction is_intxfunction is_irq_nonefunction vfio_irq_ctx_freefunction vfio_irq_ctx_allocfunction vfio_send_intx_eventfdfunction __vfio_pci_intx_maskfunction vfio_pci_intx_maskfunction vfio_pci_intx_unmask_handlerfunction __vfio_pci_intx_unmaskfunction vfio_pci_intx_unmaskfunction vfio_intx_handlerfunction pci_check_and_mask_intxfunction vfio_intx_enablefunction vfio_intx_set_signalfunction vfio_intx_disablefunction vfio_msihandlerfunction vfio_msi_enablefunction vfio_msi_alloc_irqfunction vfio_msi_set_vector_signalfunction vfio_msi_set_blockfunction vfio_msi_disablefunction xa_for_eachfunction vfio_pci_set_intx_unmaskfunction vfio_pci_set_intx_maskfunction vfio_pci_set_intx_triggerfunction vfio_pci_set_msi_triggerfunction vfio_pci_set_ctx_trigger_singlefunction vfio_pci_set_err_triggerfunction vfio_pci_set_req_triggerfunction vfio_pci_set_irqs_ioctl
Annotated Snippet
struct vfio_pci_irq_ctx {
struct vfio_pci_core_device *vdev;
struct eventfd_ctx *trigger;
struct virqfd *unmask;
struct virqfd *mask;
char *name;
bool masked;
struct irq_bypass_producer producer;
};
static bool irq_is(struct vfio_pci_core_device *vdev, int type)
{
return vdev->irq_type == type;
}
static bool is_intx(struct vfio_pci_core_device *vdev)
{
return vdev->irq_type == VFIO_PCI_INTX_IRQ_INDEX;
}
static bool is_irq_none(struct vfio_pci_core_device *vdev)
{
return !(vdev->irq_type == VFIO_PCI_INTX_IRQ_INDEX ||
vdev->irq_type == VFIO_PCI_MSI_IRQ_INDEX ||
vdev->irq_type == VFIO_PCI_MSIX_IRQ_INDEX);
}
static
struct vfio_pci_irq_ctx *vfio_irq_ctx_get(struct vfio_pci_core_device *vdev,
unsigned long index)
{
return xa_load(&vdev->ctx, index);
}
static void vfio_irq_ctx_free(struct vfio_pci_core_device *vdev,
struct vfio_pci_irq_ctx *ctx, unsigned long index)
{
xa_erase(&vdev->ctx, index);
kfree(ctx);
}
static struct vfio_pci_irq_ctx *
vfio_irq_ctx_alloc(struct vfio_pci_core_device *vdev, unsigned long index)
{
struct vfio_pci_irq_ctx *ctx;
int ret;
ctx = kzalloc_obj(*ctx, GFP_KERNEL_ACCOUNT);
if (!ctx)
return NULL;
ret = xa_insert(&vdev->ctx, index, ctx, GFP_KERNEL_ACCOUNT);
if (ret) {
kfree(ctx);
return NULL;
}
return ctx;
}
/*
* INTx
*/
static void vfio_send_intx_eventfd(void *opaque, void *data)
{
struct vfio_pci_core_device *vdev = opaque;
if (likely(is_intx(vdev) && !vdev->virq_disabled)) {
struct vfio_pci_irq_ctx *ctx = data;
struct eventfd_ctx *trigger = READ_ONCE(ctx->trigger);
if (likely(trigger))
eventfd_signal(trigger);
}
}
/* Returns true if the INTx vfio_pci_irq_ctx.masked value is changed. */
static bool __vfio_pci_intx_mask(struct vfio_pci_core_device *vdev)
{
struct pci_dev *pdev = vdev->pdev;
struct vfio_pci_irq_ctx *ctx;
unsigned long flags;
bool masked_changed = false;
lockdep_assert_held(&vdev->igate);
spin_lock_irqsave(&vdev->irqlock, flags);
/*
* Masking can come from interrupt, ioctl, or config space
Annotation
- Immediate include surface: `linux/device.h`, `linux/interrupt.h`, `linux/eventfd.h`, `linux/msi.h`, `linux/pci.h`, `linux/file.h`, `linux/vfio.h`, `linux/wait.h`.
- Detected declarations: `struct vfio_pci_irq_ctx`, `function irq_is`, `function is_intx`, `function is_irq_none`, `function vfio_irq_ctx_free`, `function vfio_irq_ctx_alloc`, `function vfio_send_intx_eventfd`, `function __vfio_pci_intx_mask`, `function vfio_pci_intx_mask`, `function vfio_pci_intx_unmask_handler`.
- Atlas domain: Driver Families / drivers/vfio.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.