Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 4092

kernel-2.6.18-194.11.1.el5.src.rpm

From: Glauber Costa <glommer@redhat.com>
Date: Mon, 14 Dec 2009 17:41:25 -0500
Subject: [x86_64] disable vsyscall in kvm guests
Message-id: <1260812485-23408-1-git-send-email-glommer@redhat.com>
Patchwork-id: 21925
O-Subject: [PATCH] RHEL5.5 BZ542612 Disable vsyscall in kvm guests (v2)
Bugzilla: 542612
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Prarit Bhargava <prarit@redhat.com>

Upstream kernels feature the vread system call, that when unimplemented,
automatically disables vgettimeofday for the running kernel.

In RHEL5, we don't have that, so we ended up with vgettimeofday enabled
for kvm guests. We managed to get time increasingly monotonic for vGTOD
using a fix already included in our RHEL build.

However, this means GTOD and clock_monotonic will effectively use two
different time sources: GTOD will use a tsc based time source that
synchronizes with pvclock from time to time, and clock_monotonic
and entirely pvclock based timing.

The solution for a working 100 % pvclock-based vgettimeofday is to map
the vcpu_time page into the vsyscall area. But this is still ongoing work
upstream.

To fix our bug right now, we disallow vGTOD to happen with kvm guests.

[ v2: Prarit points out an extra space ]

Signed-off-by: Glauber Costa <glommer@redhat.com>
RH-Bugzilla: 542612
RH-Upstream-status: N/A.

diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c
index b511d73..5a61f98 100644
--- a/arch/x86_64/kernel/vsyscall.c
+++ b/arch/x86_64/kernel/vsyscall.c
@@ -76,16 +76,7 @@ static __always_inline void do_vgettimeofday(struct timeval * tv)
 		sec = __xtime.tv_sec;
 		nsec = __xtime.tv_nsec +
 			(__jiffies - __wall_jiffies) * (NSEC_PER_SEC / HZ);
-		if (__vxtime.mode == VXTIME_KVM) {
-			long delta;
-			t = get_cycles_sync();
-			if (t < __vxtime.last_tsc)
-				t = __vxtime.last_tsc;
-
-			delta = ((t * __vxtime.tsc_quot) >> NS_SCALE) - __vxtime.last_kvm;
-			if (delta > 0)
-				nsec += delta;
-		} else if (__vxtime.mode != VXTIME_HPET) {
+		if (__vxtime.mode != VXTIME_HPET) {
 			t = get_cycles_sync();
 			if (t < __vxtime.last_tsc)
 				t = __vxtime.last_tsc;
@@ -132,7 +123,7 @@ static __always_inline long time_syscall(long *t)
 
 int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz)
 {
-	if (!__sysctl_vsyscall)
+	if (!__sysctl_vsyscall || (__vxtime.mode == VXTIME_KVM))
 		return gettimeofday(tv,tz);
 	if (tv)
 		do_vgettimeofday(tv);