arch/loongarch/kernel/paravirt.c
Source file repositories/reference/linux-study-clean/arch/loongarch/kernel/paravirt.c
File Facts
- System
- Linux kernel
- Corpus path
arch/loongarch/kernel/paravirt.c- Extension
.c- Size
- 7140 bytes
- Lines
- 334
- 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.
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/types.hlinux/interrupt.hlinux/irq_work.hlinux/jump_label.hlinux/kvm_para.hlinux/reboot.hlinux/static_call.hlinux/sched/cputime.hasm/paravirt.h
Detected Declarations
function parse_no_stealaccfunction paravt_steal_clockfunction pv_send_ipi_singlefunction pv_send_ipi_maskfunction pv_ipi_interruptfunction pv_init_ipifunction kvm_para_availablefunction kvm_arch_para_featuresfunction pv_ipi_initfunction pv_enable_steal_timefunction pv_disable_steal_timefunction pv_time_cpu_onlinefunction pv_time_cpu_down_preparefunction pv_cpu_rebootfunction pv_reboot_notifyfunction pv_time_initfunction pv_spinlock_init
Annotated Snippet
if (!bitmap) {
min = max = cpu;
} else if (cpu < min && cpu > (max - KVM_IPI_CLUSTER_SIZE)) {
/* cpu < min, and bitmap still enough */
bitmap <<= min - cpu;
min = cpu;
} else if (cpu > min && cpu < (min + KVM_IPI_CLUSTER_SIZE)) {
/* cpu > min, and bitmap still enough */
max = cpu > max ? cpu : max;
} else {
/*
* With cpu, bitmap will exceed KVM_IPI_CLUSTER_SIZE,
* send IPI here directly and skip the remaining CPUs.
*/
kvm_hypercall3(KVM_HCALL_FUNC_IPI, (unsigned long)bitmap,
(unsigned long)(bitmap >> BITS_PER_LONG), min);
min = max = cpu;
bitmap = 0;
}
__set_bit(cpu - min, (unsigned long *)&bitmap);
}
if (bitmap)
kvm_hypercall3(KVM_HCALL_FUNC_IPI, (unsigned long)bitmap,
(unsigned long)(bitmap >> BITS_PER_LONG), min);
}
static irqreturn_t pv_ipi_interrupt(int irq, void *dev)
{
u32 action;
irq_cpustat_t *info;
/* Clear SWI interrupt */
clear_csr_estat(1 << INT_SWI0);
info = this_cpu_ptr(&irq_stat);
action = atomic_xchg(&info->message, 0);
if (action & SMP_RESCHEDULE) {
scheduler_ipi();
info->ipi_irqs[IPI_RESCHEDULE]++;
}
if (action & SMP_CALL_FUNCTION) {
generic_smp_call_function_interrupt();
info->ipi_irqs[IPI_CALL_FUNCTION]++;
}
if (action & SMP_IRQ_WORK) {
irq_work_run();
info->ipi_irqs[IPI_IRQ_WORK]++;
}
if (action & SMP_CLEAR_VECTOR) {
complete_irq_moving();
info->ipi_irqs[IPI_CLEAR_VECTOR]++;
}
return IRQ_HANDLED;
}
static void pv_init_ipi(void)
{
int r, swi;
/* Init native ipi irq for ACTION_BOOT_CPU */
native_ops.init_ipi();
swi = get_percpu_irq(INT_SWI0);
if (swi < 0)
panic("SWI0 IRQ mapping failed\n");
irq_set_percpu_devid(swi);
r = request_percpu_irq(swi, pv_ipi_interrupt, "SWI0-IPI", &irq_stat);
if (r < 0)
panic("SWI0 IRQ request failed\n");
}
#endif
bool kvm_para_available(void)
{
int config;
static int hypervisor_type;
if (!cpu_has_hypervisor)
return false;
if (!hypervisor_type) {
config = read_cpucfg(CPUCFG_KVM_SIG);
if (!memcmp(&config, KVM_SIGNATURE, 4))
hypervisor_type = HYPERVISOR_KVM;
}
Annotation
- Immediate include surface: `linux/types.h`, `linux/interrupt.h`, `linux/irq_work.h`, `linux/jump_label.h`, `linux/kvm_para.h`, `linux/reboot.h`, `linux/static_call.h`, `linux/sched/cputime.h`.
- Detected declarations: `function parse_no_stealacc`, `function paravt_steal_clock`, `function pv_send_ipi_single`, `function pv_send_ipi_mask`, `function pv_ipi_interrupt`, `function pv_init_ipi`, `function kvm_para_available`, `function kvm_arch_para_features`, `function pv_ipi_init`, `function pv_enable_steal_time`.
- Atlas domain: Architecture Layer / arch/loongarch.
- 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.