arch/arm64/kvm/hyp/nvhe/clock.c
Source file repositories/reference/linux-study-clean/arch/arm64/kvm/hyp/nvhe/clock.c
File Facts
- System
- Linux kernel
- Corpus path
arch/arm64/kvm/hyp/nvhe/clock.c- Extension
.c- Size
- 1513 bytes
- Lines
- 69
- 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
nvhe/clock.hasm/arch_timer.hasm/div64.h
Detected Declarations
function __clock_mult_uint128function trace_clock_updatefunction trace_clock
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2025 Google LLC
* Author: Vincent Donnefort <vdonnefort@google.com>
*/
#include <nvhe/clock.h>
#include <asm/arch_timer.h>
#include <asm/div64.h>
static struct clock_data {
struct {
u32 mult;
u32 shift;
u64 epoch_ns;
u64 epoch_cyc;
u64 cyc_overflow64;
} data[2];
u64 cur;
} trace_clock_data;
static u64 __clock_mult_uint128(u64 cyc, u32 mult, u32 shift)
{
__uint128_t ns = (__uint128_t)cyc * mult;
ns >>= shift;
return (u64)ns;
}
/* Does not guarantee no reader on the modified bank. */
void trace_clock_update(u32 mult, u32 shift, u64 epoch_ns, u64 epoch_cyc)
{
struct clock_data *clock = &trace_clock_data;
u64 bank = clock->cur ^ 1;
if (!mult || shift >= 64)
return;
clock->data[bank].mult = mult;
clock->data[bank].shift = shift;
clock->data[bank].epoch_ns = epoch_ns;
clock->data[bank].epoch_cyc = epoch_cyc;
clock->data[bank].cyc_overflow64 = ULONG_MAX / mult;
smp_store_release(&clock->cur, bank);
}
/* Use untrusted host data */
u64 trace_clock(void)
{
struct clock_data *clock = &trace_clock_data;
u64 bank = smp_load_acquire(&clock->cur);
u64 cyc, ns;
cyc = __arch_counter_get_cntvct() - clock->data[bank].epoch_cyc;
if (likely(cyc < clock->data[bank].cyc_overflow64)) {
ns = cyc * clock->data[bank].mult;
ns >>= clock->data[bank].shift;
} else {
ns = __clock_mult_uint128(cyc, clock->data[bank].mult,
clock->data[bank].shift);
}
return (u64)ns + clock->data[bank].epoch_ns;
}
Annotation
- Immediate include surface: `nvhe/clock.h`, `asm/arch_timer.h`, `asm/div64.h`.
- Detected declarations: `function __clock_mult_uint128`, `function trace_clock_update`, `function trace_clock`.
- 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.