Re: [PATCH v3 13/21] KVM: selftests: Use KVM's reported TSC KHz as L0's frequency (sanity checked)
From: Sean Christopherson
Date: Wed Oct 07 2026 - 02:04:21 EST
On Tue, Oct 06, 2026, Jim Mattson wrote:
> On Wed, Sep 30, 2026 at 12:04 PM Sean Christopherson <seanjc@xxxxxxxxxx> wrote:
> >
> > Use KVM's reported default TSC frequency as L0's frequency instead of
> > calibrating L0's frequency using RDTSC. Trying to calibrate the frequency
> > in userspace is all but guaranteed to be wildly inaccurate, e.g. due to
> > interrupts, preemption, etc, and no known CPU supports TSC scaling without
> > also having a constant TSC. I.e. there's no need to calibrate the current
> > frequency, as it should also be the same as KVM's default frequency.
> >
> > Opportunistically sanity check KVM's reported frequency against what is
> > observed via RDTSC, e.g. so that KVM_GET_TSC_KHZ or platform issues show up
> > much earlier in the test, before VMs get involved.
> >
> > Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
> > ---
> > .../kvm/x86/nested_tsc_scaling_test.c | 25 +++++++++++++------
> > 1 file changed, 17 insertions(+), 8 deletions(-)
> >
> > diff --git a/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c b/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c
> > index d790ab36a198..a78585af0ffd 100644
> > --- a/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c
> > +++ b/tools/testing/selftests/kvm/x86/nested_tsc_scaling_test.c
> > @@ -137,7 +137,7 @@ static void l1_guest_code(void *data)
> >
> > static void test_tsc_scaling(u64 l0_tsc_freq, u64 l1_scale_factor, u64 l2_scale_factor)
> > {
> > - u64 tsc_khz, l1_tsc_freq, l2_tsc_freq;
> > + u64 l1_tsc_freq, l2_tsc_freq;
> > struct kvm_vcpu *vcpu;
> > struct kvm_vm *vm;
> > gva_t guest_gva;
> > @@ -159,11 +159,8 @@ static void test_tsc_scaling(u64 l0_tsc_freq, u64 l1_scale_factor, u64 l2_scale_
> >
> > vcpu_args_set(vcpu, 1, guest_gva);
> >
> > - tsc_khz = __vcpu_ioctl(vcpu, KVM_GET_TSC_KHZ, NULL);
> > - TEST_ASSERT(tsc_khz != -1, "vcpu ioctl KVM_GET_TSC_KHZ failed");
> > -
> > /* scale down L1's TSC frequency */
> > - vcpu_ioctl(vcpu, KVM_SET_TSC_KHZ, (void *) (tsc_khz / l1_scale_factor));
> > + vcpu_ioctl(vcpu, KVM_SET_TSC_KHZ, (void *) (l0_tsc_freq / l1_scale_factor));
>
> Our internal Sashiko complains:
>
> [Severity: Medium]
> Is l0_tsc_freq passed to KVM_SET_TSC_KHZ in Hz rather than KHz?
>
> In main(), l0_tsc_freq is calculated in Hz by multiplying the KVM_GET_TSC_KHZ
> result by 1000. Passing this value divided by l1_scale_factor into
> KVM_SET_TSC_KHZ configures the guest TSC frequency 1000x larger than
> intended, since the ioctl expects a value in KHz.
>
> I concur.
Drat, I thought I had fixed all of those goofs.