On 17/06/2016 17:48, Arnd Bergmann wrote:
KVM reads the current boottime value as a struct timespec in order to calculate the guest wallclock time, resulting in an overflow in 2038 on 32-bit systems.
The data then gets passed as an unsigned 32-bit number to the guest, and that in turn overflows in 2106.
We cannot do much about the second overflow, which affects both 32-bit and 64-bit hosts, but we can ensure that they both behave the same way and don't overflow until 2106, by using getboottime64() to read a timespec64 value.
Signed-off-by: Arnd Bergmann arnd@arndb.de
arch/x86/kvm/x86.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 53241618e3c9..f79c86510408 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1163,7 +1163,7 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) int version; int r; struct pvclock_wall_clock wc;
- struct timespec boot;
- struct timespec64 boot;
if (!wall_clock) return; @@ -1186,13 +1186,13 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) * wall clock specified here. guest system time equals host * system time for us, thus we must fill in host boot time here. */
- getboottime(&boot);
- getboottime64(&boot);
if (kvm->arch.kvmclock_offset) {
struct timespec ts = ns_to_timespec(kvm->arch.kvmclock_offset);
boot = timespec_sub(boot, ts);
struct timespec64 ts = ns_to_timespec64(kvm->arch.kvmclock_offset);
}boot = timespec64_sub(boot, ts);
- wc.sec = boot.tv_sec;
- wc.sec = (u32)boot.tv_sec; /* overflow in 2106 guest time */ wc.nsec = boot.tv_nsec; wc.version = version;
Queued, thanks.
Paolo