lkml.org 
[lkml]   [2024]   [Apr]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 07/10] KVM: x86: Avoid NTP frequency skew for KVM clock on 32-bit host
    Date
    From: David Woodhouse <dwmw@amazon.co.uk>

    Commit 53fafdbb8b21 ("KVM: x86: switch KVMCLOCK base to monotonic raw
    clock") did so only for 64-bit hosts, by capturing the boot offset from
    within the existing clocksource notifier update_pvclock_gtod().

    That notifier was added in commit 16e8d74d2da9 ("KVM: x86: notifier for
    clocksource changes") but only on x86_64, because its original purpose
    was just to disable the "master clock" mode which is only supported on
    x86_64.

    Now that the notifier is used for more than disabling master clock mode,
    (well, OK, more than a decade later but clocks are hard), enable it for
    the 32-bit build too so that get_kvmclock_base_ns() can be unaffected by
    NTP sync on 32-bit too.

    Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
    ---
    arch/x86/kvm/x86.c | 18 ++++++------------
    1 file changed, 6 insertions(+), 12 deletions(-)

    diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
    index 00a7c1188dec..44b3d2a0da5b 100644
    --- a/arch/x86/kvm/x86.c
    +++ b/arch/x86/kvm/x86.c
    @@ -2245,7 +2245,6 @@ static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data)
    return kvm_set_msr_ignored_check(vcpu, index, *data, true);
    }

    -#ifdef CONFIG_X86_64
    struct pvclock_clock {
    int vclock_mode;
    u64 cycle_last;
    @@ -2303,13 +2302,6 @@ static s64 get_kvmclock_base_ns(void)
    /* Count up from boot time, but with the frequency of the raw clock. */
    return ktime_to_ns(ktime_add(ktime_get_raw(), pvclock_gtod_data.offs_boot));
    }
    -#else
    -static s64 get_kvmclock_base_ns(void)
    -{
    - /* Master clock not used, so we can just use CLOCK_BOOTTIME. */
    - return ktime_get_boottime_ns();
    -}
    -#endif

    static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock, int sec_hi_ofs)
    {
    @@ -9819,6 +9811,7 @@ static void pvclock_irq_work_fn(struct irq_work *w)
    }

    static DEFINE_IRQ_WORK(pvclock_irq_work, pvclock_irq_work_fn);
    +#endif

    /*
    * Notification about pvclock gtod data update.
    @@ -9826,26 +9819,26 @@ static DEFINE_IRQ_WORK(pvclock_irq_work, pvclock_irq_work_fn);
    static int pvclock_gtod_notify(struct notifier_block *nb, unsigned long unused,
    void *priv)
    {
    - struct pvclock_gtod_data *gtod = &pvclock_gtod_data;
    struct timekeeper *tk = priv;

    update_pvclock_gtod(tk);

    +#ifdef CONFIG_X86_64
    /*
    * Disable master clock if host does not trust, or does not use,
    * TSC based clocksource. Delegate queue_work() to irq_work as
    * this is invoked with tk_core.seq write held.
    */
    - if (!gtod_is_based_on_tsc(gtod->clock.vclock_mode) &&
    + if (!gtod_is_based_on_tsc(pvclock_gtod_data.clock.vclock_mode) &&
    atomic_read(&kvm_guest_has_master_clock) != 0)
    irq_work_queue(&pvclock_irq_work);
    +#endif
    return 0;
    }

    static struct notifier_block pvclock_gtod_notifier = {
    .notifier_call = pvclock_gtod_notify,
    };
    -#endif

    static inline void kvm_ops_update(struct kvm_x86_init_ops *ops)
    {
    @@ -9984,9 +9977,10 @@ int kvm_x86_vendor_init(struct kvm_x86_init_ops *ops)

    if (pi_inject_timer == -1)
    pi_inject_timer = housekeeping_enabled(HK_TYPE_TIMER);
    -#ifdef CONFIG_X86_64
    +
    pvclock_gtod_register_notifier(&pvclock_gtod_notifier);

    +#ifdef CONFIG_X86_64
    if (hypervisor_is_type(X86_HYPER_MS_HYPERV))
    set_hv_tscchange_cb(kvm_hyperv_tsc_notifier);
    #endif
    --
    2.44.0

    \
     
     \ /
      Last update: 2024-05-27 16:46    [W:2.475 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site