I have encountered this build error with this patch.

Perhaps it is because all usage of "flags" are removed.

$ make -j32 > /dev/null
arch/x86/kvm/x86.c: In function ‘kvm_guest_time_update’:
arch/x86/kvm/x86.c:3359:23: error: unused variable ‘flags’ 
[-Werror=unused-variable]
 3359 |         unsigned long flags;
      |                       ^~~~~
cc1: all warnings being treated as errors
make[4]: *** [scripts/Makefile.build:289: arch/x86/kvm/x86.o] Error 1
make[3]: *** [scripts/Makefile.build:548: arch/x86/kvm] Error 2
make[2]: *** [scripts/Makefile.build:548: arch/x86] Error 2
make[1]: *** [/home/opc/ext4/mainline-linux/Makefile:2143: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2

Thank you very much!

Dongli Zhang

On 2026-05-09 3:46 PM, David Woodhouse wrote:
> From: David Woodhouse <[email protected]>
> 
> Restructure kvm_guest_time_update() so that kernel_ns/host_tsc are
> always "now" when doing TSC catchup, then swap in the master clock
> reference values afterward for the hv_clock.
> 
> This makes the TSC upscaling code considerably simpler: the catchup
> adjustment is computed as the delta between what the guest TSC *should*
> be at "now" and what it actually is, rather than mixing "now" and
> "master clock reference" timestamps.
> 
> The seqcount loop now also contains the kvm_get_time_and_clockread()
> call (matching get_kvmclock's pattern), with the same WARN for
> unexpected failure.
> 
> Based on a suggestion by Sean Christopherson.
> 
> Signed-off-by: David Woodhouse <[email protected]>
> ---
>  arch/x86/kvm/x86.c | 67 ++++++++++++++++++++++++++++++++--------------
>  1 file changed, 47 insertions(+), 20 deletions(-)
> 
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index e281c49561fa..8e4993ef4f6b 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -3363,39 +3363,51 @@ int kvm_guest_time_update(struct kvm_vcpu *v)
>       struct kvm_arch *ka = &v->kvm->arch;
>       s64 kernel_ns;
>       u64 tsc_timestamp, host_tsc;
> +     u64 master_host_tsc = 0;
> +     s64 master_kernel_ns = 0;
>       bool use_master_clock;
>  
> -     kernel_ns = 0;
> -     host_tsc = 0;
> -
>       /*
>        * If the host uses TSC clock, then passthrough TSC as stable
>        * to the guest.
>        */
>       do {
>               seq = read_seqcount_begin(&ka->pvclock_sc);
> +
>               use_master_clock = ka->use_master_clock;
> -             if (use_master_clock) {
> -                     host_tsc = ka->master_cycle_now;
> -                     kernel_ns = ka->master_kernel_ns;
> -             }
> +
> +             /*
> +              * The TSC read and the call to get_cpu_tsc_khz() must happen
> +              * on the same CPU.
> +              */
> +             get_cpu();
> +
> +             tgt_tsc_hz = (u64)get_cpu_tsc_khz() * 1000;
> +
> +             if (use_master_clock &&
> +                 !kvm_get_time_and_clockread(&kernel_ns, &host_tsc) &&
> +                 WARN_ON_ONCE(!read_seqcount_retry(&ka->pvclock_sc, seq)))
> +                     use_master_clock = false;
> +
> +             put_cpu();
> +
> +             if (!use_master_clock)
> +                     break;
> +
> +             master_host_tsc = ka->master_cycle_now;
> +             master_kernel_ns = ka->master_kernel_ns;
>       } while (read_seqcount_retry(&ka->pvclock_sc, seq));
>  
> -     /* Keep irq disabled to prevent changes to the clock */
> -     local_irq_save(flags);
> -     tgt_tsc_hz = (u64)get_cpu_tsc_khz() * 1000;
>       if (unlikely(tgt_tsc_hz == 0)) {
> -             local_irq_restore(flags);
>               kvm_make_request(KVM_REQ_CLOCK_UPDATE, v);
>               return 1;
>       }
> +
>       if (!use_master_clock) {
>               host_tsc = rdtsc();
>               kernel_ns = get_kvmclock_base_ns();
>       }
>  
> -     tsc_timestamp = kvm_read_l1_tsc(v, host_tsc);
> -
>       /*
>        * We may have to catch up the TSC to match elapsed wall clock
>        * time for two reasons, even if kvmclock is used.
> @@ -3404,17 +3416,32 @@ int kvm_guest_time_update(struct kvm_vcpu *v)
>        *      entry to avoid unknown leaps of TSC even when running
>        *      again on the same CPU.  This may cause apparent elapsed
>        *      time to disappear, and the guest to stand still or run
> -      *      very slowly.
> +      *      very slowly.
>        */
>       if (vcpu->tsc_catchup) {
> -             u64 tsc = compute_guest_tsc(v, kernel_ns);
> -             if (tsc > tsc_timestamp) {
> -                     adjust_tsc_offset_guest(v, tsc - tsc_timestamp);
> -                     tsc_timestamp = tsc;
> -             }
> +             s64 adjustment;
> +
> +             /*
> +              * Calculate the delta between what the guest TSC *should* be
> +              * and what it actually is according to kvm_read_l1_tsc().
> +              */
> +             adjustment = compute_guest_tsc(v, kernel_ns) -
> +                          kvm_read_l1_tsc(v, host_tsc);
> +             if (adjustment > 0)
> +                     adjust_tsc_offset_guest(v, adjustment);
>       }
>  
> -     local_irq_restore(flags);
> +     /*
> +      * Now that TSC upscaling is out of the way, the remaining calculations
> +      * are all relative to the reference time that's placed in hv_clock.
> +      * If the master clock is NOT in use, the reference time is "now".  If
> +      * master clock is in use, the reference time comes from there.
> +      */
> +     if (use_master_clock) {
> +             host_tsc = master_host_tsc;
> +             kernel_ns = master_kernel_ns;
> +     }
> +     tsc_timestamp = kvm_read_l1_tsc(v, host_tsc);
>  
>       /* With all the info we got, fill in the values */
>  


Reply via email to