arch/arm64/kvm/vgic/vgic-v5.c
Source file repositories/reference/linux-study-clean/arch/arm64/kvm/vgic/vgic-v5.c
File Facts
- System
- Linux kernel
- Corpus path
arch/arm64/kvm/vgic/vgic-v5.c- Extension
.c- Size
- 14172 bytes
- Lines
- 519
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
kvm/arm_vgic.hlinux/bitops.hlinux/irqchip/arm-vgic-info.hvgic.h
Detected Declarations
function Copyrightfunction vgic_v5_probefunction vgic_v5_resetfunction vgic_v5_initfunction kvm_for_each_vcpufunction vgic_v5_map_resourcesfunction vgic_v5_finalize_ppi_statefunction for_each_set_bitfunction scoped_guardfunction vgic_v5_get_effective_priority_maskfunction vgic_v5_ppi_queue_irq_unlockfunction vgic_v5_set_ppi_dvifunction vgic_v5_set_ppi_opsfunction guestfunction vgic_v5_has_pending_ppifunction for_each_visible_v5_ppifunction vgic_v5_fold_ppi_statefunction for_each_visible_v5_ppifunction scoped_guardfunction vgic_v5_flush_ppi_statefunction scoped_guardfunction vgic_v5_loadfunction vgic_v5_putfunction vgic_v5_get_vmcrfunction vgic_v5_set_vmcrfunction vgic_v5_restore_statefunction vgic_v5_save_state
Annotated Snippet
if (vcpu_has_nv(vcpu)) {
kvm_err("Nested GICv5 VMs are currently unsupported\n");
return -EINVAL;
}
}
/* We only allow userspace to drive the SW_PPI, if it is implemented. */
bitmap_zero(kvm->arch.vgic.gicv5_vm.userspace_ppis,
VGIC_V5_NR_PRIVATE_IRQS);
__set_bit(GICV5_ARCH_PPI_SW_PPI, kvm->arch.vgic.gicv5_vm.userspace_ppis);
bitmap_and(kvm->arch.vgic.gicv5_vm.userspace_ppis,
kvm->arch.vgic.gicv5_vm.userspace_ppis,
ppi_caps.impl_ppi_mask, VGIC_V5_NR_PRIVATE_IRQS);
return 0;
}
int vgic_v5_map_resources(struct kvm *kvm)
{
if (!vgic_initialized(kvm))
return -EBUSY;
return 0;
}
int vgic_v5_finalize_ppi_state(struct kvm *kvm)
{
struct kvm_vcpu *vcpu0;
int i;
if (!vgic_is_v5(kvm))
return 0;
guard(mutex)(&kvm->arch.config_lock);
/*
* If SW_PPI has been advertised, then we know we already
* initialised the whole thing, and we can return early. Yes,
* this is pretty hackish as far as state tracking goes...
*/
if (test_bit(GICV5_ARCH_PPI_SW_PPI, kvm->arch.vgic.gicv5_vm.vgic_ppi_mask))
return 0;
/* The PPI state for all VCPUs should be the same. Pick the first. */
vcpu0 = kvm_get_vcpu(kvm, 0);
bitmap_zero(kvm->arch.vgic.gicv5_vm.vgic_ppi_mask, VGIC_V5_NR_PRIVATE_IRQS);
bitmap_zero(kvm->arch.vgic.gicv5_vm.vgic_ppi_hmr, VGIC_V5_NR_PRIVATE_IRQS);
for_each_set_bit(i, ppi_caps.impl_ppi_mask, VGIC_V5_NR_PRIVATE_IRQS) {
const u32 intid = vgic_v5_make_ppi(i);
struct vgic_irq *irq;
irq = vgic_get_vcpu_irq(vcpu0, intid);
/* Expose PPIs with an owner or the SW_PPI, only */
scoped_guard(raw_spinlock_irqsave, &irq->irq_lock) {
if (irq->owner || i == GICV5_ARCH_PPI_SW_PPI) {
__set_bit(i, kvm->arch.vgic.gicv5_vm.vgic_ppi_mask);
__assign_bit(i, kvm->arch.vgic.gicv5_vm.vgic_ppi_hmr,
irq->config == VGIC_CONFIG_LEVEL);
}
}
vgic_put_irq(vcpu0->kvm, irq);
}
return 0;
}
static u32 vgic_v5_get_effective_priority_mask(struct kvm_vcpu *vcpu)
{
struct vgic_v5_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v5;
u32 highest_ap, priority_mask, apr;
/*
* If the guest's CPU has not opted to receive interrupts, then the
* effective running priority is the highest priority. Just return 0
* (the highest priority).
*/
if (!FIELD_GET(FEAT_GCIE_ICH_VMCR_EL2_EN, cpu_if->vgic_vmcr))
return 0;
/*
* Counting the number of trailing zeros gives the current active
* priority. Explicitly use the 32-bit version here as we have 32
* priorities. 32 then means that there are no active priorities.
*/
apr = cpu_if->vgic_apr;
highest_ap = apr ? __builtin_ctz(apr) : 32;
Annotation
- Immediate include surface: `kvm/arm_vgic.h`, `linux/bitops.h`, `linux/irqchip/arm-vgic-info.h`, `vgic.h`.
- Detected declarations: `function Copyright`, `function vgic_v5_probe`, `function vgic_v5_reset`, `function vgic_v5_init`, `function kvm_for_each_vcpu`, `function vgic_v5_map_resources`, `function vgic_v5_finalize_ppi_state`, `function for_each_set_bit`, `function scoped_guard`, `function vgic_v5_get_effective_priority_mask`.
- Atlas domain: Architecture Layer / arch/arm64.
- Implementation status: source implementation candidate.
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.