arch/arm64/kvm/vgic/vgic.c
Source file repositories/reference/linux-study-clean/arch/arm64/kvm/vgic/vgic.c
File Facts
- System
- Linux kernel
- Corpus path
arch/arm64/kvm/vgic/vgic.c- Extension
.c- Size
- 37490 bytes
- Lines
- 1331
- Domain
- Architecture Layer
- Bucket
- arch/arm64
- Inferred role
- Architecture Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/interrupt.hlinux/irq.hlinux/kvm.hlinux/kvm_host.hlinux/list_sort.hlinux/nospec.hasm/kvm_hyp.hvgic.htrace.h
Detected Declarations
struct vgic_sort_infofunction vgic_put_irqfunction vgic_release_lpi_lockedfunction __vgic_put_irqfunction vgic_put_irq_noreleasefunction vgic_put_irqfunction vgic_release_deleted_lpisfunction xa_for_eachfunction vgic_flush_pending_lpisfunction list_for_each_entry_safefunction vgic_irq_set_phys_pendingfunction vgic_get_phys_line_levelfunction vgic_irq_set_phys_activefunction interruptfunction vgic_irq_cmpfunction vgic_sort_ap_listfunction vgic_validate_injectionfunction vgic_model_needs_bcst_kickfunction tofunction kvm_vgic_inject_irqfunction kvm_vgic_set_irq_opsfunction kvm_vgic_clear_irq_opsfunction kvm_vgic_map_irqfunction kvm_vgic_unmap_irqfunction kvm_vgic_map_phys_irqfunction kvm_vgic_reset_mapped_irqfunction kvm_vgic_unmap_phys_irqfunction kvm_vgic_get_mapfunction kvm_vgic_set_ownerfunction vgic_prune_ap_listfunction list_for_each_entry_safefunction vgic_fold_statefunction vgic_populate_lrfunction vgic_clear_lrfunction summarize_ap_listfunction list_for_each_entryfunction dropfunction list_for_each_entryfunction can_access_vgic_from_kernelfunction vgic_save_statefunction kvm_vgic_sync_hwstatefunction kvm_vgic_process_async_updatefunction vgic_restore_statefunction vgic_flush_statefunction kvm_vgic_flush_hwstatefunction kvm_vgic_loadfunction kvm_vgic_putfunction kvm_vgic_vcpu_pending_irq
Annotated Snippet
struct vgic_sort_info {
struct kvm_vcpu *vcpu;
struct vgic_vmcr vmcr;
};
/*
* The order of items in the ap_lists defines how we'll pack things in LRs as
* well, the first items in the list being the first things populated in the
* LRs.
*
* Pending, non-active interrupts must be placed at the head of the list.
* Otherwise things should be sorted by the priority field and the GIC
* hardware support will take care of preemption of priority groups etc.
* Interrupts that are not deliverable should be at the end of the list.
*
* Return negative if "a" sorts before "b", 0 to preserve order, and positive
* to sort "b" before "a".
*/
static int vgic_irq_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct vgic_irq *irqa = container_of(a, struct vgic_irq, ap_list);
struct vgic_irq *irqb = container_of(b, struct vgic_irq, ap_list);
struct vgic_sort_info *info = priv;
struct kvm_vcpu *vcpu = info->vcpu;
bool penda, pendb;
int ret;
/*
* list_sort may call this function with the same element when
* the list is fairly long.
*/
if (unlikely(irqa == irqb))
return 0;
raw_spin_lock(&irqa->irq_lock);
raw_spin_lock_nested(&irqb->irq_lock, SINGLE_DEPTH_NESTING);
/* Undeliverable interrupts should be last */
ret = (int)(vgic_target_oracle(irqb) == vcpu) - (int)(vgic_target_oracle(irqa) == vcpu);
if (ret)
goto out;
/* Same thing for interrupts targeting a disabled group */
ret = (int)(irqb->group ? info->vmcr.grpen1 : info->vmcr.grpen0);
ret -= (int)(irqa->group ? info->vmcr.grpen1 : info->vmcr.grpen0);
if (ret)
goto out;
penda = irqa->enabled && irq_is_pending(irqa) && !irqa->active;
pendb = irqb->enabled && irq_is_pending(irqb) && !irqb->active;
ret = (int)pendb - (int)penda;
if (ret)
goto out;
/* Both pending and enabled, sort by priority (lower number first) */
ret = (int)irqa->priority - (int)irqb->priority;
if (ret)
goto out;
/* Finally, HW bit active interrupts have priority over non-HW ones */
ret = (int)irqb->hw - (int)irqa->hw;
out:
raw_spin_unlock(&irqb->irq_lock);
raw_spin_unlock(&irqa->irq_lock);
return ret;
}
/* Must be called with the ap_list_lock held */
static void vgic_sort_ap_list(struct kvm_vcpu *vcpu)
{
struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
struct vgic_sort_info info = { .vcpu = vcpu, };
lockdep_assert_held(&vgic_cpu->ap_list_lock);
vgic_get_vmcr(vcpu, &info.vmcr);
list_sort(&info, &vgic_cpu->ap_list_head, vgic_irq_cmp);
}
/*
* Only valid injection if changing level for level-triggered IRQs or for a
* rising edge, and in-kernel connected IRQ lines can only be controlled by
* their owner.
*/
static bool vgic_validate_injection(struct vgic_irq *irq, bool level, void *owner)
{
if (irq->owner != owner)
Annotation
- Immediate include surface: `linux/interrupt.h`, `linux/irq.h`, `linux/kvm.h`, `linux/kvm_host.h`, `linux/list_sort.h`, `linux/nospec.h`, `asm/kvm_hyp.h`, `vgic.h`.
- Detected declarations: `struct vgic_sort_info`, `function vgic_put_irq`, `function vgic_release_lpi_locked`, `function __vgic_put_irq`, `function vgic_put_irq_norelease`, `function vgic_put_irq`, `function vgic_release_deleted_lpis`, `function xa_for_each`, `function vgic_flush_pending_lpis`, `function list_for_each_entry_safe`.
- Atlas domain: Architecture Layer / arch/arm64.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.