When TSC calibration fails and userspace never programs a tsc khz, vcpu->arch.virtual_tsc_khz stays zero, but the lapic timer's software-mode expiry path still calls adjust_lapic_timer_advance() unconditionally on every timer expiration (unlike __wait_lapic_expire(), this path is not gated on tsc_scaling_ratio). Both the "too early" and "too late" branches do_div() by virtual_tsc_khz, so a zero khz crashes the host with #DE as soon as the timer advance drifts outside the adjust window. Bail out before either division. Signed-off-by: Peng Hao --- arch/x86/kvm/lapic.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 13e32c4915e2..4dcbc66c8e07 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1991,6 +1991,9 @@ static inline void adjust_lapic_timer_advance(struct kvm_vcpu *vcpu, abs(advance_expire_delta) < LAPIC_TIMER_ADVANCE_ADJUST_MIN) return; + if (unlikely(!vcpu->arch.virtual_tsc_khz)) + return; + /* too early */ if (advance_expire_delta < 0) { ns = -advance_expire_delta * 1000000ULL; -- 2.43.7