Re: kvmclock doesn't work, help?

Marcelo Tosatti
2015-12-14T22:01:51Z

On Mon, Dec 14, 2015 at 02:44:15PM +0100, Paolo Bonzini wrote:
>
>
> On 11/12/2015 22:57, Andy Lutomirski wrote:
> > I'm still not seeing the issue.
> >
> > The formula is:
> >
> > (((rdtsc - pvti->tsc_timestamp) * pvti->tsc_to_system_mul) >>
> > pvti->tsc_shift) + pvti->system_time
> >
> > Obviously, if you reset pvti->tsc_timestamp to the current tsc value
> > after suspend/resume, you would also need to update system_time.
> >
> > I don't see what this has to do with suspend/resume or with whether
> > the effective scale factor is greater than or less than one. The only
> > suspend/resume interaction I can see is that, if the host allows the
> > guest-observed TSC value to jump (which is arguably a bug, what that's
> > not important here), it needs to update pvti before resuming the
> > guest.
>
> Which is not an issue, since freezing obviously gets all CPUs out of
> guest mode.
>
> Marcelo, can you provide an example with made-up values for tsc and pvti?

I meant "systemtime" at ^^^^^.

guest visible clock = systemtime (updated at time 0, guest initialization) + scaled tsc reads=LARGE VALUE.
^^^^^^^^^^
guest reads clock to memory at location A = scaled tsc read.
-> suspend resume event
guest visible clock = systemtime (updated at time AFTER SUSPEND) + scaled tsc reads=0.
guest reads clock to memory at location B.

So before the suspend/resume event, the clock is the RAW TSC values
(scaled by kvmclock, but the frequency of the RAW TSC).

After suspend/resume event, the clock is updated from the host
via get_kernel_ns(), which reads the corrected NTP frequency TSC.

So you switch the timebase, from a clock running at a given frequency,
to a clock running at another frequency (effective frequency).

Example:

RAW TSC NTP corrected TSC
t0 10 10
t1 20 19.99
t2 30 29.98
t3 40 39.97
t4 50 49.96

...

if you suddenly switch from RAW TSC to NTP corrected TSC,
you can see what will happen.

Does that make sense?

> > suspend/resume event.
> > guest visible clock = tsc_timestamp (updated at time N) + scaled tsc
> > reads=0.

>
> > Can you clarify concretely what goes wrong here?
> >
> > (I'm also at a bit of a loss as to why this needs both system_time and
> > tsc_timestamp. They're redundant in the sense that you could set
> > tsc_timestamp to zero and subtract (tsc_timestamp * tsc_to_system_mul) >>
> > tsc_shift to system_time without changing the result of the
> > calculation.)
>
> You would have to ensure that all elements of pvti are rounded correctly
> whenever the base TSC is updated. Doable, but it does seem simpler to
> keep subtract-TSC and add-nanoseconds separate.
>
> Paolo