]>
Commit | Line | Data |
---|---|---|
8b570cdf GKH |
1 | From b5179ec4187251a751832193693d6e474d3445ac Mon Sep 17 00:00:00 2001 |
2 | From: Pavel Tatashin <pasha.tatashin@soleen.com> | |
3 | Date: Sat, 26 Jan 2019 12:49:56 -0500 | |
4 | Subject: x86/kvmclock: set offset for kvm unstable clock | |
5 | ||
6 | From: Pavel Tatashin <pasha.tatashin@soleen.com> | |
7 | ||
8 | commit b5179ec4187251a751832193693d6e474d3445ac upstream. | |
9 | ||
10 | VMs may show incorrect uptime and dmesg printk offsets on hypervisors with | |
11 | unstable clock. The problem is produced when VM is rebooted without exiting | |
12 | from qemu. | |
13 | ||
14 | The fix is to calculate clock offset not only for stable clock but for | |
15 | unstable clock as well, and use kvm_sched_clock_read() which substracts | |
16 | the offset for both clocks. | |
17 | ||
18 | This is safe, because pvclock_clocksource_read() does the right thing and | |
19 | makes sure that clock always goes forward, so once offset is calculated | |
20 | with unstable clock, we won't get new reads that are smaller than offset, | |
21 | and thus won't get negative results. | |
22 | ||
23 | Thank you Jon DeVree for helping to reproduce this issue. | |
24 | ||
25 | Fixes: 857baa87b642 ("sched/clock: Enable sched clock early") | |
26 | Cc: stable@vger.kernel.org | |
27 | Reported-by: Dominique Martinet <asmadeus@codewreck.org> | |
28 | Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com> | |
29 | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> | |
30 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
31 | ||
32 | --- | |
33 | arch/x86/kernel/kvmclock.c | 6 +----- | |
34 | 1 file changed, 1 insertion(+), 5 deletions(-) | |
35 | ||
36 | --- a/arch/x86/kernel/kvmclock.c | |
37 | +++ b/arch/x86/kernel/kvmclock.c | |
38 | @@ -104,12 +104,8 @@ static u64 kvm_sched_clock_read(void) | |
39 | ||
40 | static inline void kvm_sched_clock_init(bool stable) | |
41 | { | |
42 | - if (!stable) { | |
43 | - pv_ops.time.sched_clock = kvm_clock_read; | |
44 | + if (!stable) | |
45 | clear_sched_clock_stable(); | |
46 | - return; | |
47 | - } | |
48 | - | |
49 | kvm_sched_clock_offset = kvm_clock_read(); | |
50 | pv_ops.time.sched_clock = kvm_sched_clock_read; | |
51 |