tools/testing/selftests/kvm/x86/hyperv_clock.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/x86/hyperv_clock.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/kvm/x86/hyperv_clock.c- Extension
.c- Size
- 6472 bytes
- Lines
- 264
- Domain
- Support Tooling And Documentation
- Bucket
- tools
- Inferred role
- Support Tooling And Documentation: implementation source
- Status
- source implementation candidate
Why This File Exists
Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
test_util.hkvm_util.hprocessor.hhyperv.h
Detected Declarations
struct ms_hyperv_tsc_pagefunction mul_u64_u64_shr64function nop_loopfunction check_tsc_msr_rdtscfunction get_tscpage_tsfunction check_tsc_msr_tsc_pagefunction guest_mainfunction host_check_tsc_msr_rdtscfunction main
Annotated Snippet
struct ms_hyperv_tsc_page {
volatile u32 tsc_sequence;
u32 reserved1;
volatile u64 tsc_scale;
volatile s64 tsc_offset;
} __packed;
/* Simplified mul_u64_u64_shr() */
static inline u64 mul_u64_u64_shr64(u64 a, u64 b)
{
union {
u64 ll;
struct {
u32 low, high;
} l;
} rm, rn, rh, a0, b0;
u64 c;
a0.ll = a;
b0.ll = b;
rm.ll = (u64)a0.l.low * b0.l.high;
rn.ll = (u64)a0.l.high * b0.l.low;
rh.ll = (u64)a0.l.high * b0.l.high;
rh.l.low = c = rm.l.high + rn.l.high + rh.l.low;
rh.l.high = (c >> 32) + rh.l.high;
return rh.ll;
}
static inline void nop_loop(void)
{
int i;
for (i = 0; i < 100000000; i++)
asm volatile("nop");
}
static inline void check_tsc_msr_rdtsc(void)
{
u64 tsc_freq, r1, r2, t1, t2;
s64 delta_ns;
tsc_freq = rdmsr(HV_X64_MSR_TSC_FREQUENCY);
GUEST_ASSERT(tsc_freq > 0);
/* For increased accuracy, take mean rdtsc() before and afrer rdmsr() */
r1 = rdtsc();
t1 = rdmsr(HV_X64_MSR_TIME_REF_COUNT);
r1 = (r1 + rdtsc()) / 2;
nop_loop();
r2 = rdtsc();
t2 = rdmsr(HV_X64_MSR_TIME_REF_COUNT);
r2 = (r2 + rdtsc()) / 2;
GUEST_ASSERT(r2 > r1 && t2 > t1);
/* HV_X64_MSR_TIME_REF_COUNT is in 100ns */
delta_ns = ((t2 - t1) * 100) - ((r2 - r1) * 1000000000 / tsc_freq);
if (delta_ns < 0)
delta_ns = -delta_ns;
/* 1% tolerance */
GUEST_ASSERT(delta_ns * 100 < (t2 - t1) * 100);
}
static inline u64 get_tscpage_ts(struct ms_hyperv_tsc_page *tsc_page)
{
return mul_u64_u64_shr64(rdtsc(), tsc_page->tsc_scale) + tsc_page->tsc_offset;
}
static inline void check_tsc_msr_tsc_page(struct ms_hyperv_tsc_page *tsc_page)
{
u64 r1, r2, t1, t2;
/* Compare TSC page clocksource with HV_X64_MSR_TIME_REF_COUNT */
t1 = get_tscpage_ts(tsc_page);
r1 = rdmsr(HV_X64_MSR_TIME_REF_COUNT);
/* 10 ms tolerance */
GUEST_ASSERT(r1 >= t1 && r1 - t1 < 100000);
nop_loop();
t2 = get_tscpage_ts(tsc_page);
r2 = rdmsr(HV_X64_MSR_TIME_REF_COUNT);
GUEST_ASSERT(r2 >= t1 && r2 - t2 < 100000);
}
static void guest_main(struct ms_hyperv_tsc_page *tsc_page, gpa_t tsc_page_gpa)
Annotation
- Immediate include surface: `test_util.h`, `kvm_util.h`, `processor.h`, `hyperv.h`.
- Detected declarations: `struct ms_hyperv_tsc_page`, `function mul_u64_u64_shr64`, `function nop_loop`, `function check_tsc_msr_rdtsc`, `function get_tscpage_ts`, `function check_tsc_msr_tsc_page`, `function guest_main`, `function host_check_tsc_msr_rdtsc`, `function main`.
- Atlas domain: Support Tooling And Documentation / tools.
- 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.