arch/loongarch/kvm/intc/eiointc.c
Source file repositories/reference/linux-study-clean/arch/loongarch/kvm/intc/eiointc.c
File Facts
- System
- Linux kernel
- Corpus path
arch/loongarch/kvm/intc/eiointc.c- Extension
.c- Size
- 17097 bytes
- Lines
- 694
- Domain
- Architecture Layer
- Bucket
- arch/loongarch
- 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.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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
asm/kvm_eiointc.hasm/kvm_vcpu.hlinux/count_zeros.h
Detected Declarations
function Copyrightfunction eiointc_update_irqfunction eiointc_update_sw_coremapfunction eiointc_set_irqfunction loongarch_eiointc_readfunction kvm_eiointc_readfunction loongarch_eiointc_writefunction kvm_eiointc_writefunction kvm_eiointc_virt_readfunction kvm_eiointc_virt_writefunction kvm_eiointc_ctrl_accessfunction kvm_eiointc_regs_accessfunction kvm_eiointc_sw_status_accessfunction kvm_eiointc_get_attrfunction kvm_eiointc_set_attrfunction kvm_eiointc_createfunction kvm_eiointc_destroyfunction kvm_loongarch_register_eiointc_device
Annotated Snippet
if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) {
ipnum = count_trailing_zeros(ipnum);
ipnum = ipnum < 4 ? ipnum : 0;
}
cpuid = ((u8 *)s->coremap)[irq];
vcpu = kvm_get_vcpu_by_cpuid(s->kvm, cpuid);
if (!vcpu)
continue;
cpu = vcpu->vcpu_id;
if (test_bit(irq, (unsigned long *)s->coreisr[cpu]))
__set_bit(irq, s->sw_coreisr[cpu][ipnum]);
else
__clear_bit(irq, s->sw_coreisr[cpu][ipnum]);
}
}
static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)
{
int ipnum, cpu, found;
struct kvm_vcpu *vcpu;
struct kvm_interrupt vcpu_irq;
ipnum = (s->ipmap >> (irq / 32 * 8)) & 0xff;
if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) {
ipnum = count_trailing_zeros(ipnum);
ipnum = ipnum < 4 ? ipnum : 0;
}
cpu = s->sw_coremap[irq];
vcpu = kvm_get_vcpu_by_id(s->kvm, cpu);
if (unlikely(vcpu == NULL)) {
kvm_err("%s: invalid target cpu: %d\n", __func__, cpu);
return;
}
if (level) {
/* if not enable return false */
if (!test_bit(irq, (unsigned long *)s->enable))
return;
__set_bit(irq, (unsigned long *)s->coreisr[cpu]);
found = find_first_bit(s->sw_coreisr[cpu][ipnum], EIOINTC_IRQS);
__set_bit(irq, s->sw_coreisr[cpu][ipnum]);
} else {
__clear_bit(irq, (unsigned long *)s->coreisr[cpu]);
__clear_bit(irq, s->sw_coreisr[cpu][ipnum]);
found = find_first_bit(s->sw_coreisr[cpu][ipnum], EIOINTC_IRQS);
}
if (found < EIOINTC_IRQS)
return; /* other irq is handling, needn't update parent irq */
vcpu_irq.irq = level ? (INT_HWI0 + ipnum) : -(INT_HWI0 + ipnum);
kvm_vcpu_ioctl_interrupt(vcpu, &vcpu_irq);
}
static inline void eiointc_update_sw_coremap(struct loongarch_eiointc *s,
int irq, u64 val, u32 len, bool notify)
{
int i, cpu, cpuid;
struct kvm_vcpu *vcpu;
for (i = 0; i < len; i++) {
cpuid = val & 0xff;
val = val >> 8;
if (!(s->status & BIT(EIOINTC_ENABLE_CPU_ENCODE))) {
cpuid = ffs(cpuid) - 1;
cpuid = ((cpuid < 0) || (cpuid >= 4)) ? 0 : cpuid;
}
vcpu = kvm_get_vcpu_by_cpuid(s->kvm, cpuid);
if (!vcpu)
continue;
cpu = vcpu->vcpu_id;
if (s->sw_coremap[irq + i] == cpu)
continue;
if (notify && test_bit(irq + i, (unsigned long *)s->isr)) {
/* lower irq at old cpu and raise irq at new cpu */
eiointc_update_irq(s, irq + i, 0);
s->sw_coremap[irq + i] = cpu;
eiointc_update_irq(s, irq + i, 1);
} else {
s->sw_coremap[irq + i] = cpu;
}
}
}
Annotation
- Immediate include surface: `asm/kvm_eiointc.h`, `asm/kvm_vcpu.h`, `linux/count_zeros.h`.
- Detected declarations: `function Copyright`, `function eiointc_update_irq`, `function eiointc_update_sw_coremap`, `function eiointc_set_irq`, `function loongarch_eiointc_read`, `function kvm_eiointc_read`, `function loongarch_eiointc_write`, `function kvm_eiointc_write`, `function kvm_eiointc_virt_read`, `function kvm_eiointc_virt_write`.
- Atlas domain: Architecture Layer / arch/loongarch.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.