From fa1855cdc0210b8cef154dd4a20b4dff3655e771 Mon Sep 17 00:00:00 2001 From: patrick Date: Tue, 19 Dec 2017 18:06:41 +0000 Subject: [PATCH] Pass calibrated TSC frequency to vmm(4) guests. On machines where TSC cannot be calculated from the CPUID register, because the CPU does not support it, but can be calibrated from another timer, the vmm(4) guest doesn't have a chance to read or calibrate its own TSC frequency since it has no access to a precise enough time counter. In that case, fake the existence of the register and supply our calibrated TSC frequency. mlarkin@ tells me this also greatly helps Linux guests. ok mlarkin@ --- sys/arch/amd64/amd64/vmm.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/sys/arch/amd64/amd64/vmm.c b/sys/arch/amd64/amd64/vmm.c index 470306fe0ed..a689ddb4e04 100644 --- a/sys/arch/amd64/amd64/vmm.c +++ b/sys/arch/amd64/amd64/vmm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmm.c,v 1.181 2017/12/17 19:16:02 mlarkin Exp $ */ +/* $OpenBSD: vmm.c,v 1.182 2017/12/19 18:06:41 patrick Exp $ */ /* * Copyright (c) 2014 Mike Larkin * @@ -224,6 +224,9 @@ struct vmm_reg_debug_info { }; #endif /* VMM_DEBUG */ +extern uint64_t tsc_frequency; +extern int tsc_is_invariant; + const char *vmm_hv_signature = VMM_HV_SIGNATURE; const struct kmem_pa_mode vmm_kp_contig = { @@ -5620,7 +5623,10 @@ vmm_handle_cpuid(struct vcpu *vcpu) switch (*rax) { case 0x00: /* Max level and vendor ID */ - *rax = cpuid_level; + if (cpuid_level < 0x15 && tsc_is_invariant) + *rax = 0x15; + else + *rax = cpuid_level; *rbx = *((uint32_t *)&cpu_vendor); *rdx = *((uint32_t *)&cpu_vendor + 1); *rcx = *((uint32_t *)&cpu_vendor + 2); @@ -5753,7 +5759,19 @@ vmm_handle_cpuid(struct vcpu *vcpu) *rdx = 0; break; case 0x15: - CPUID(0x15, *rax, *rbx, *rcx, *rdx); + if (cpuid_level >= 0x15) { + CPUID(0x15, *rax, *rbx, *rcx, *rdx); + } else if (tsc_is_invariant) { + *rax = 1; + *rbx = 100; + *rcx = tsc_frequency / 100; + *rdx = 0; + } else { + *rax = 0; + *rbx = 0; + *rcx = 0; + *rdx = 0; + } break; case 0x16: /* Processor frequency info (not supported) */ DPRINTF("%s: function 0x16 (frequency info) not supported\n", -- 2.20.1