arch/arm64/kvm/vgic/vgic-init.c
Source file repositories/reference/linux-study-clean/arch/arm64/kvm/vgic/vgic-init.c
File Facts
- System
- Linux kernel
- Corpus path
arch/arm64/kvm/vgic/vgic-init.c- Extension
.c- Size
- 21911 bytes
- Lines
- 844
- 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.
- 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/uaccess.hlinux/interrupt.hlinux/cpu.hlinux/kvm_host.hkvm/arm_vgic.hasm/kvm_emulate.hasm/kvm_mmu.hvgic.h
Detected Declarations
function Copyrightfunction irqchip_in_kernelfunction kvm_for_each_vcpufunction kvm_for_each_vcpufunction kvm_vgic_dist_initfunction kvm_vgic_vcpu_nv_initfunction vgic_setup_private_irqfunction vgic_v5_setup_private_irqfunction vgic_allocate_private_irqs_lockedfunction vgic_allocate_private_irqsfunction kvm_vgic_vcpu_initfunction kvm_vgic_vcpu_resetfunction vgic_initializedfunction injectionfunction kvm_vgic_dist_destroyfunction __kvm_vgic_vcpu_destroyfunction kvm_vgic_vcpu_destroyfunction kvm_vgic_destroyfunction vgic_lazy_initfunction vgic_initfunction kvm_vgic_finalize_idregsfunction kvm_vgic_cpu_upfunction kvm_vgic_cpu_downfunction vgic_maintenance_handlerfunction vgic_set_kvm_infofunction kvm_vgic_init_cpu_hardwarefunction kvm_vgic_hyp_init
Annotated Snippet
kvm_for_each_vcpu(i, vcpu, kvm) {
struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
kfree(vgic_cpu->private_irqs);
vgic_cpu->private_irqs = NULL;
}
kvm->arch.vgic.vgic_model = 0;
goto out_unlock;
}
if (type == KVM_DEV_TYPE_ARM_VGIC_V3)
kvm->arch.vgic.nassgicap = system_supports_direct_sgis();
/*
* We now know that we have a GICv5. The Arch Timer PPI interrupts may
* have been initialised at this stage, but will have done so assuming
* that we have an older GIC, meaning that the IntIDs won't be
* correct. We init them again, and this time they will be correct.
*/
if (type == KVM_DEV_TYPE_ARM_VGIC_V5)
kvm_timer_init_vm(kvm);
out_unlock:
mutex_unlock(&kvm->arch.config_lock);
kvm_unlock_all_vcpus(kvm);
return ret;
}
/* INIT/DESTROY */
/**
* kvm_vgic_dist_init: initialize the dist data structures
* @kvm: kvm struct pointer
* @nr_spis: number of spis, frozen by caller
*/
static int kvm_vgic_dist_init(struct kvm *kvm, unsigned int nr_spis)
{
struct vgic_dist *dist = &kvm->arch.vgic;
struct kvm_vcpu *vcpu0 = kvm_get_vcpu(kvm, 0);
int i;
dist->active_spis = (atomic_t)ATOMIC_INIT(0);
dist->spis = kzalloc_objs(struct vgic_irq, nr_spis, GFP_KERNEL_ACCOUNT);
if (!dist->spis)
return -ENOMEM;
/*
* In the following code we do not take the irq struct lock since
* no other action on irq structs can happen while the VGIC is
* not initialized yet:
* If someone wants to inject an interrupt or does a MMIO access, we
* require prior initialization in case of a virtual GICv3 or trigger
* initialization when using a virtual GICv2.
*/
for (i = 0; i < nr_spis; i++) {
struct vgic_irq *irq = &dist->spis[i];
irq->intid = i + VGIC_NR_PRIVATE_IRQS;
INIT_LIST_HEAD(&irq->ap_list);
raw_spin_lock_init(&irq->irq_lock);
irq->vcpu = NULL;
irq->target_vcpu = vcpu0;
refcount_set(&irq->refcount, 0);
switch (dist->vgic_model) {
case KVM_DEV_TYPE_ARM_VGIC_V2:
irq->targets = 0;
irq->group = 0;
break;
case KVM_DEV_TYPE_ARM_VGIC_V3:
irq->mpidr = 0;
irq->group = 1;
break;
default:
kfree(dist->spis);
dist->spis = NULL;
return -EINVAL;
}
}
return 0;
}
/* Default GICv3 Maintenance Interrupt INTID, as per SBSA */
#define DEFAULT_MI_INTID 25
int kvm_vgic_vcpu_nv_init(struct kvm_vcpu *vcpu)
{
int ret;
guard(mutex)(&vcpu->kvm->arch.config_lock);
Annotation
- Immediate include surface: `linux/uaccess.h`, `linux/interrupt.h`, `linux/cpu.h`, `linux/kvm_host.h`, `kvm/arm_vgic.h`, `asm/kvm_emulate.h`, `asm/kvm_mmu.h`, `vgic.h`.
- Detected declarations: `function Copyright`, `function irqchip_in_kernel`, `function kvm_for_each_vcpu`, `function kvm_for_each_vcpu`, `function kvm_vgic_dist_init`, `function kvm_vgic_vcpu_nv_init`, `function vgic_setup_private_irq`, `function vgic_v5_setup_private_irq`, `function vgic_allocate_private_irqs_locked`, `function vgic_allocate_private_irqs`.
- 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.
- 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.