*/
 static uint32_t kvm_mips_read_count_running(struct kvm_vcpu *vcpu, ktime_t now)
 {
-       ktime_t expires;
+       struct mips_coproc *cop0 = vcpu->arch.cop0;
+       ktime_t expires, threshold;
+       uint32_t count, compare;
        int running;
 
-       /* Is the hrtimer pending? */
+       /* Calculate the biased and scaled guest CP0_Count */
+       count = vcpu->arch.count_bias + kvm_mips_ktime_to_count(vcpu, now);
+       compare = kvm_read_c0_guest_compare(cop0);
+
+       /*
+        * Find whether CP0_Count has reached the closest timer interrupt. If
+        * not, we shouldn't inject it.
+        */
+       if ((int32_t)(count - compare) < 0)
+               return count;
+
+       /*
+        * The CP0_Count we're going to return has already reached the closest
+        * timer interrupt. Quickly check if it really is a new interrupt by
+        * looking at whether the interval until the hrtimer expiry time is
+        * less than 1/4 of the timer period.
+        */
        expires = hrtimer_get_expires(&vcpu->arch.comparecount_timer);
-       if (ktime_compare(now, expires) >= 0) {
+       threshold = ktime_add_ns(now, vcpu->arch.count_period / 4);
+       if (ktime_before(expires, threshold)) {
                /*
                 * Cancel it while we handle it so there's no chance of
                 * interference with the timeout handler.
                }
        }
 
-       /* Return the biased and scaled guest CP0_Count */
-       return vcpu->arch.count_bias + kvm_mips_ktime_to_count(vcpu, now);
+       return count;
 }
 
 /**