NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: port-amd64/59424 (hardclock ticks run at breakneck pace under qemu)



Synopsis: hardclock ticks run at breakneck pace under qemu

State-Changed-From-To: feedback->analyzed
State-Changed-By: riastradh%NetBSD.org@localhost
State-Changed-When: Fri, 01 May 2026 00:38:18 +0000
State-Changed-Why:
I can still reproduce this with identcpu_subr.c 1.15.

I believe the problem is that nvmm reports the _physical_ lapic
frequency through the new CPUID[EAX=0x40000010] leaf, but the qemu
_virtual_ lapic unconditionally ticks at 1 GHz, since it works in
nanoseconds (shifted according to whatever divisor the OS has
configured):

uint32_t apic_get_current_count(APICCommonState *s)
{
    int64_t d;
    uint32_t val;
    d = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->initial_count_load_time) >>
        s->count_shift;
    if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
        /* periodic */
        val = s->initial_count - (d % ((uint64_t)s->initial_count + 1));
    } else {
        if (d >= s->initial_count) {
            val = 0;
        } else {
            val = s->initial_count - d;
        }
    }
    return val;
}

https://gitlab.com/qemu-project/qemu/-/blob/3d626609ccae61a2e552bccd59c7a0931bab8261/hw/intc/apic_common.c#L162-180

I think we need to revert this change, or at least zero out the lapic
part of it.  The following patch in nvmm fixes the problem for me:

--- a/sys/dev/nvmm/x86/nvmm_x86_vmx.c
+++ b/sys/dev/nvmm/x86/nvmm_x86_vmx.c
@@ -1457,7 +1457,7 @@ vmx_inkernel_handle_cpuid(struct nvmm_machine *mach, struct nvmm_cpu *vcpu,
 		break;
 	case 0x40000010: /* VMware-style TSC and LAPIC freq */
 		cpudata->gprs[NVMM_X64_GPR_RAX] = curcpu()->ci_data.cpu_cc_freq / 1000;
-		if (has_lapic())
+		if (/*PR 59424*/0 && has_lapic())
 			cpudata->gprs[NVMM_X64_GPR_RBX] = lapic_per_second / 1000;
 		else
 			cpudata->gprs[NVMM_X64_GPR_RBX] = 0;

It might also work to set rbx in this case to 1000000, since the true
value of `lapic_per_second' _as implemented by qemu_ is 1e9, but of
course we need some way for qemu to convey that to nvmm, not just to
hard-code some qemu parameter inside nvmm.






Home | Main Index | Thread Index | Old Index