Index | Thread | Search

From:
Mike Larkin <mlarkin@nested.page>
Subject:
Re: vmm: Expose pvclock only if tsc frequency is known
To:
Stefan Fritsch <sf@sfritsch.de>
Cc:
tech@openbsd.org, Dave Voutila <dv@sisu.io>, Jan Klemkow <j.klemkow@wemelug.de>
Date:
Sat, 7 Feb 2026 11:34:21 -0800

Download raw body.

Thread
On Sat, Jan 24, 2026 at 10:59:30AM +0100, Stefan Fritsch wrote:
> Hi,
>
> Jan had some problems with a linux VM running in nested virtualization on
> opembsd/vmm which was running on linux/KVM. The VM would hang during boot.
> Not exposing both CLOCKSOURCE feature flags fixed the problem. Only
> omitting the KVM_FEATURE_CLOCKSOURCE_STABLE_BIT did not fix the issue. Not
> all linux versions showed the problem.
>
> I think offering pvclock if the tsc frequency is not known is wrong in
> general and not only for linux guests. If the tsc frequency is unknown,
> tsc_frequency == 0 and vmm will set vc_pvclock_system_tsc_mul = 0 which
> will cause the guest's pvclock to not advance until vmm updates the struct
> pvclock_time_info on the next vmentry.
>
> Therefore, if tsc_frequency == 0, we should not expose the pvclock feature
> bits, both in the KVM and in the VMM hypervisor signature.
>
> We should also try to fix that the TSC frequency cannot be determined, but
> that is a different issue.
>
> What do you think? ok?
>

I am ok with this change.

ok mlarkin

-ml

> Cheers,
> Stefan
>
> diff --git a/sys/arch/amd64/amd64/vmm_machdep.c b/sys/arch/amd64/amd64/vmm_machdep.c
> index 4b86c73c8c2..7bd3fc007eb 100644
> --- a/sys/arch/amd64/amd64/vmm_machdep.c
> +++ b/sys/arch/amd64/amd64/vmm_machdep.c
> @@ -6499,8 +6499,11 @@ vmm_handle_cpuid(struct vcpu *vcpu)
>  		*rdx = *((uint32_t *)&vmm_hv_signature[8]);
>  		break;
>  	case 0x40000001:	/* KVM hypervisor features */
> -		*rax = (1 << KVM_FEATURE_CLOCKSOURCE2) |
> -		    (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT);
> +		if (tsc_frequency > 0)
> +			*rax = (1 << KVM_FEATURE_CLOCKSOURCE2) |
> +			    (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT);
> +		else
> +			*rax = 0;
>  		*rbx = 0;
>  		*rcx = 0;
>  		*rdx = 0;
> @@ -6512,9 +6515,10 @@ vmm_handle_cpuid(struct vcpu *vcpu)
>  		*rdx = *((uint32_t *)&kvm_hv_signature[8]);
>  		break;
>  	case 0x40000101:	/* KVM hypervisor features */
> -		*rax = (1 << KVM_FEATURE_CLOCKSOURCE2) |
> -		    (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT) |
> -		    (1 << KVM_FEATURE_NOP_IO_DELAY);
> +		*rax = 1 << KVM_FEATURE_NOP_IO_DELAY;
> +		if (tsc_frequency > 0)
> +			*rax |= (1 << KVM_FEATURE_CLOCKSOURCE2) |
> +			    (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT);
>  		*rbx = 0;
>  		*rcx = 0;
>  		*rdx = 0;
>