virt/kvm/irqchip.c
Source file repositories/reference/linux-study-clean/virt/kvm/irqchip.c
File Facts
- System
- Linux kernel
- Corpus path
virt/kvm/irqchip.c- Extension
.c- Size
- 6202 bytes
- Lines
- 262
- Domain
- Kernel Services
- Bucket
- virt
- Inferred role
- Kernel Services: implementation source
- Status
- source implementation candidate
Why This File Exists
Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- 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/kvm_host.hlinux/slab.hlinux/srcu.hlinux/export.htrace/events/kvm.h
Detected Declarations
function Copyrightfunction hlist_for_each_entryfunction kvm_irq_map_chip_pinfunction kvm_send_userspace_msifunction kvm_set_irqfunction free_irq_routing_tablefunction hlist_for_each_entry_safefunction kvm_free_irq_routingfunction setup_routing_entryfunction __attribute__function kvm_set_irq_routingfunction kvm_init_irq_routing
Annotated Snippet
hlist_for_each_entry(e, &irq_rt->map[gsi], link) {
entries[n] = *e;
++n;
}
}
return n;
}
int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin)
{
struct kvm_irq_routing_table *irq_rt;
irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
return irq_rt->chip[irqchip][pin];
}
int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi)
{
struct kvm_kernel_irq_routing_entry route;
if (!kvm_arch_irqchip_in_kernel(kvm) || (msi->flags & ~KVM_MSI_VALID_DEVID))
return -EINVAL;
route.msi.address_lo = msi->address_lo;
route.msi.address_hi = msi->address_hi;
route.msi.data = msi->data;
route.msi.flags = msi->flags;
route.msi.devid = msi->devid;
return kvm_set_msi(&route, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, false);
}
/*
* Return value:
* < 0 Interrupt was ignored (masked or not delivered for other reasons)
* = 0 Interrupt was coalesced (previous irq is still pending)
* > 0 Number of CPUs interrupt was delivered to
*/
int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
bool line_status)
{
struct kvm_kernel_irq_routing_entry irq_set[KVM_NR_IRQCHIPS];
int ret = -1, i, idx;
trace_kvm_set_irq(irq, level, irq_source_id);
/* Not possible to detect if the guest uses the PIC or the
* IOAPIC. So set the bit in both. The guest will ignore
* writes to the unused one.
*/
idx = srcu_read_lock(&kvm->irq_srcu);
i = kvm_irq_map_gsi(kvm, irq_set, irq);
srcu_read_unlock(&kvm->irq_srcu, idx);
while (i--) {
int r;
r = irq_set[i].set(&irq_set[i], kvm, irq_source_id, level,
line_status);
if (r < 0)
continue;
ret = r + ((ret < 0) ? 0 : ret);
}
return ret;
}
static void free_irq_routing_table(struct kvm_irq_routing_table *rt)
{
int i;
if (!rt)
return;
for (i = 0; i < rt->nr_rt_entries; ++i) {
struct kvm_kernel_irq_routing_entry *e;
struct hlist_node *n;
hlist_for_each_entry_safe(e, n, &rt->map[i], link) {
hlist_del(&e->link);
kfree(e);
}
}
kfree(rt);
}
void kvm_free_irq_routing(struct kvm *kvm)
{
Annotation
- Immediate include surface: `linux/kvm_host.h`, `linux/slab.h`, `linux/srcu.h`, `linux/export.h`, `trace/events/kvm.h`.
- Detected declarations: `function Copyright`, `function hlist_for_each_entry`, `function kvm_irq_map_chip_pin`, `function kvm_send_userspace_msi`, `function kvm_set_irq`, `function free_irq_routing_table`, `function hlist_for_each_entry_safe`, `function kvm_free_irq_routing`, `function setup_routing_entry`, `function __attribute__`.
- Atlas domain: Kernel Services / virt.
- 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.