arch/riscv/kvm/aia_aplic.c
Source file repositories/reference/linux-study-clean/arch/riscv/kvm/aia_aplic.c
File Facts
- System
- Linux kernel
- Corpus path
arch/riscv/kvm/aia_aplic.c- Extension
.c- Size
- 16320 bytes
- Lines
- 637
- Domain
- Architecture Layer
- Bucket
- arch/riscv
- 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/irqchip/riscv-aplic.hlinux/kvm_host.hlinux/math.hlinux/nospec.hlinux/spinlock.hlinux/swab.hkvm/iodev.h
Detected Declarations
struct aplic_irqstruct aplicfunction aplic_read_sourcecfgfunction aplic_write_sourcecfgfunction aplic_read_targetfunction aplic_write_targetfunction aplic_read_pendingfunction aplic_write_pendingfunction aplic_read_enabledfunction aplic_write_enabledfunction aplic_read_inputfunction aplic_inject_msifunction aplic_update_irq_rangefunction kvm_riscv_aia_aplic_injectfunction aplic_read_input_wordfunction aplic_read_pending_wordfunction aplic_write_pending_wordfunction aplic_read_enabled_wordfunction aplic_write_enabled_wordfunction aplic_mmio_read_offsetfunction aplic_mmio_readfunction aplic_mmio_write_offsetfunction aplic_mmio_writefunction kvm_riscv_aia_aplic_set_attrfunction kvm_riscv_aia_aplic_get_attrfunction kvm_riscv_aia_aplic_has_attrfunction kvm_riscv_aia_aplic_initfunction kvm_riscv_aia_aplic_cleanup
Annotated Snippet
struct aplic_irq {
raw_spinlock_t lock;
u32 sourcecfg;
u32 state;
#define APLIC_IRQ_STATE_PENDING BIT(0)
#define APLIC_IRQ_STATE_ENABLED BIT(1)
#define APLIC_IRQ_STATE_ENPEND (APLIC_IRQ_STATE_PENDING | \
APLIC_IRQ_STATE_ENABLED)
#define APLIC_IRQ_STATE_INPUT BIT(8)
u32 target;
};
struct aplic {
struct kvm_io_device iodev;
u32 domaincfg;
u32 genmsi;
u32 nr_irqs;
u32 nr_words;
struct aplic_irq irqs[] __counted_by(nr_irqs);
};
static u32 aplic_read_sourcecfg(struct aplic *aplic, u32 irq)
{
u32 ret;
unsigned long flags;
struct aplic_irq *irqd;
if (!irq || aplic->nr_irqs <= irq)
return 0;
irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)];
raw_spin_lock_irqsave(&irqd->lock, flags);
ret = irqd->sourcecfg;
raw_spin_unlock_irqrestore(&irqd->lock, flags);
return ret;
}
static void aplic_write_sourcecfg(struct aplic *aplic, u32 irq, u32 val)
{
unsigned long flags;
struct aplic_irq *irqd;
if (!irq || aplic->nr_irqs <= irq)
return;
irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)];
if (val & APLIC_SOURCECFG_D)
val = 0;
else
val &= APLIC_SOURCECFG_SM_MASK;
raw_spin_lock_irqsave(&irqd->lock, flags);
irqd->sourcecfg = val;
raw_spin_unlock_irqrestore(&irqd->lock, flags);
}
static u32 aplic_read_target(struct aplic *aplic, u32 irq)
{
u32 ret;
unsigned long flags;
struct aplic_irq *irqd;
if (!irq || aplic->nr_irqs <= irq)
return 0;
irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)];
raw_spin_lock_irqsave(&irqd->lock, flags);
ret = irqd->target;
raw_spin_unlock_irqrestore(&irqd->lock, flags);
return ret;
}
static void aplic_write_target(struct aplic *aplic, u32 irq, u32 val)
{
unsigned long flags;
struct aplic_irq *irqd;
if (!irq || aplic->nr_irqs <= irq)
return;
irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)];
val &= APLIC_TARGET_EIID_MASK |
(APLIC_TARGET_HART_IDX_MASK << APLIC_TARGET_HART_IDX_SHIFT) |
(APLIC_TARGET_GUEST_IDX_MASK << APLIC_TARGET_GUEST_IDX_SHIFT);
raw_spin_lock_irqsave(&irqd->lock, flags);
Annotation
- Immediate include surface: `linux/irqchip/riscv-aplic.h`, `linux/kvm_host.h`, `linux/math.h`, `linux/nospec.h`, `linux/spinlock.h`, `linux/swab.h`, `kvm/iodev.h`.
- Detected declarations: `struct aplic_irq`, `struct aplic`, `function aplic_read_sourcecfg`, `function aplic_write_sourcecfg`, `function aplic_read_target`, `function aplic_write_target`, `function aplic_read_pending`, `function aplic_write_pending`, `function aplic_read_enabled`, `function aplic_write_enabled`.
- Atlas domain: Architecture Layer / arch/riscv.
- 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.