arch/arm64/kvm/arch_timer.c
Source file repositories/reference/linux-study-clean/arch/arm64/kvm/arch_timer.c
File Facts
- System
- Linux kernel
- Corpus path
arch/arm64/kvm/arch_timer.c- Extension
.c- Size
- 45408 bytes
- Lines
- 1758
- 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.
- 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.
- 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/cpu.hlinux/kvm.hlinux/kvm_host.hlinux/interrupt.hlinux/irq.hlinux/irqdomain.hlinux/uaccess.hclocksource/arm_arch_timer.hasm/arch_timer.hasm/kvm_emulate.hasm/kvm_hyp.hasm/kvm_nested.hkvm/arm_vgic.hkvm/arm_arch_timer.htrace.h
Detected Declarations
function kvm_arch_timer_get_irq_flagsfunction nr_timersfunction timer_get_ctlfunction timer_get_cvalfunction timer_set_ctlfunction timer_set_cvalfunction kvm_phys_timer_readfunction get_timer_mapfunction userspace_irqchipfunction soft_timer_startfunction soft_timer_cancelfunction kvm_arch_timer_handlerfunction kvm_counter_compute_deltafunction kvm_timer_compute_deltafunction kvm_timer_enabledfunction vcpu_has_wfit_activefunction wfit_delay_nsfunction kvm_timer_earliest_expfunction kvm_bg_timer_expirefunction kvm_hrtimer_expirefunction kvm_timer_pendingfunction kvm_cpu_has_pending_timerfunction kvm_timer_needs_notifyfunction kvm_timer_should_notify_userfunction kvm_timer_update_runfunction kvm_timer_update_statusfunction kvm_timer_update_irqfunction timer_emulatefunction set_cntvofffunction set_cntpofffunction timer_save_statefunction kvm_timer_blockingfunction kvm_timer_unblockingfunction timer_restore_statefunction set_timer_irq_phys_activefunction kvm_timer_vcpu_load_gicfunction kvm_timer_vcpu_load_nogicfunction kvm_timer_vcpu_load_nested_switchfunction timer_set_trapsfunction guestfunction kvm_timer_vcpu_loadfunction kvm_timer_vcpu_putfunction kvm_timer_sync_nestedfunction unmask_vtimer_irq_userfunction kvm_timer_sync_userfunction kvm_timer_vcpu_resetfunction timer_context_initfunction kvm_timer_vcpu_init
Annotated Snippet
if (is_hyp_ctxt(vcpu)) {
map->direct_vtimer = vcpu_hvtimer(vcpu);
map->direct_ptimer = vcpu_hptimer(vcpu);
map->emul_vtimer = vcpu_vtimer(vcpu);
map->emul_ptimer = vcpu_ptimer(vcpu);
} else {
map->direct_vtimer = vcpu_vtimer(vcpu);
map->direct_ptimer = vcpu_ptimer(vcpu);
map->emul_vtimer = vcpu_hvtimer(vcpu);
map->emul_ptimer = vcpu_hptimer(vcpu);
}
} else if (has_vhe()) {
map->direct_vtimer = vcpu_vtimer(vcpu);
map->direct_ptimer = vcpu_ptimer(vcpu);
map->emul_vtimer = NULL;
map->emul_ptimer = NULL;
} else {
map->direct_vtimer = vcpu_vtimer(vcpu);
map->direct_ptimer = NULL;
map->emul_vtimer = NULL;
map->emul_ptimer = vcpu_ptimer(vcpu);
}
trace_kvm_get_timer_map(vcpu->vcpu_id, map);
}
static inline bool userspace_irqchip(struct kvm *kvm)
{
return unlikely(!irqchip_in_kernel(kvm));
}
static void soft_timer_start(struct hrtimer *hrt, u64 ns)
{
hrtimer_start(hrt, ktime_add_ns(ktime_get(), ns),
HRTIMER_MODE_ABS_HARD);
}
static void soft_timer_cancel(struct hrtimer *hrt)
{
hrtimer_cancel(hrt);
}
static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id)
{
struct kvm_vcpu *vcpu = *(struct kvm_vcpu **)dev_id;
struct arch_timer_context *ctx;
struct timer_map map;
/*
* We may see a timer interrupt after vcpu_put() has been called which
* sets the CPU's vcpu pointer to NULL, because even though the timer
* has been disabled in timer_save_state(), the hardware interrupt
* signal may not have been retired from the interrupt controller yet.
*/
if (!vcpu)
return IRQ_HANDLED;
get_timer_map(vcpu, &map);
if (irq == host_vtimer_irq)
ctx = map.direct_vtimer;
else
ctx = map.direct_ptimer;
if (kvm_timer_pending(ctx))
kvm_timer_update_irq(vcpu, true, ctx);
if (userspace_irqchip(vcpu->kvm) &&
!static_branch_unlikely(&has_gic_active_state))
disable_percpu_irq(host_vtimer_irq);
return IRQ_HANDLED;
}
static u64 kvm_counter_compute_delta(struct arch_timer_context *timer_ctx,
u64 val)
{
u64 now = kvm_phys_timer_read() - timer_get_offset(timer_ctx);
if (now < val) {
u64 ns;
ns = cyclecounter_cyc2ns(timecounter->cc,
val - now,
timecounter->mask,
&timer_ctx->ns_frac);
return ns;
}
return 0;
Annotation
- Immediate include surface: `linux/cpu.h`, `linux/kvm.h`, `linux/kvm_host.h`, `linux/interrupt.h`, `linux/irq.h`, `linux/irqdomain.h`, `linux/uaccess.h`, `clocksource/arm_arch_timer.h`.
- Detected declarations: `function kvm_arch_timer_get_irq_flags`, `function nr_timers`, `function timer_get_ctl`, `function timer_get_cval`, `function timer_set_ctl`, `function timer_set_cval`, `function kvm_phys_timer_read`, `function get_timer_map`, `function userspace_irqchip`, `function soft_timer_start`.
- Atlas domain: Architecture Layer / arch/arm64.
- 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.
- 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.