aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2014-07-16 17:04:54 -0400
committerJohn Stultz <john.stultz@linaro.org>2014-07-23 18:01:46 -0400
commitcbcf2dd3b3d4d990610259e8d878fc8dc1f17d80 (patch)
tree56a7086ddb4b6af2df797a2ad94581d258e42d16 /arch/x86/kvm
parentbb0b58127c5add364cb597d58b1cf66eb279eae8 (diff)
x86: kvm: Make kvm_get_time_and_clockread() nanoseconds based
Convert the relevant base data right away to nanoseconds instead of doing the conversion on every readout. Reduces text size by 160 bytes. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Gleb Natapov <gleb@kernel.org> Cc: kvm@vger.kernel.org Acked-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: John Stultz <john.stultz@linaro.org>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/x86.c44
1 files changed, 14 insertions, 30 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 65c430512132..63832f5110b6 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -984,9 +984,8 @@ struct pvclock_gtod_data {
984 u32 shift; 984 u32 shift;
985 } clock; 985 } clock;
986 986
987 /* open coded 'struct timespec' */ 987 u64 boot_ns;
988 u64 monotonic_time_snsec; 988 u64 nsec_base;
989 time_t monotonic_time_sec;
990}; 989};
991 990
992static struct pvclock_gtod_data pvclock_gtod_data; 991static struct pvclock_gtod_data pvclock_gtod_data;
@@ -994,6 +993,9 @@ static struct pvclock_gtod_data pvclock_gtod_data;
994static void update_pvclock_gtod(struct timekeeper *tk) 993static void update_pvclock_gtod(struct timekeeper *tk)
995{ 994{
996 struct pvclock_gtod_data *vdata = &pvclock_gtod_data; 995 struct pvclock_gtod_data *vdata = &pvclock_gtod_data;
996 u64 boot_ns;
997
998 boot_ns = ktime_to_ns(ktime_add(tk->base_mono, tk->offs_boot));
997 999
998 write_seqcount_begin(&vdata->seq); 1000 write_seqcount_begin(&vdata->seq);
999 1001
@@ -1004,17 +1006,8 @@ static void update_pvclock_gtod(struct timekeeper *tk)
1004 vdata->clock.mult = tk->mult; 1006 vdata->clock.mult = tk->mult;
1005 vdata->clock.shift = tk->shift; 1007 vdata->clock.shift = tk->shift;
1006 1008
1007 vdata->monotonic_time_sec = tk->xtime_sec 1009 vdata->boot_ns = boot_ns;
1008 + tk->wall_to_monotonic.tv_sec; 1010 vdata->nsec_base = tk->xtime_nsec;
1009 vdata->monotonic_time_snsec = tk->xtime_nsec
1010 + (tk->wall_to_monotonic.tv_nsec
1011 << tk->shift);
1012 while (vdata->monotonic_time_snsec >=
1013 (((u64)NSEC_PER_SEC) << tk->shift)) {
1014 vdata->monotonic_time_snsec -=
1015 ((u64)NSEC_PER_SEC) << tk->shift;
1016 vdata->monotonic_time_sec++;
1017 }
1018 1011
1019 write_seqcount_end(&vdata->seq); 1012 write_seqcount_end(&vdata->seq);
1020} 1013}
@@ -1371,23 +1364,22 @@ static inline u64 vgettsc(cycle_t *cycle_now)
1371 return v * gtod->clock.mult; 1364 return v * gtod->clock.mult;
1372} 1365}
1373 1366
1374static int do_monotonic(struct timespec *ts, cycle_t *cycle_now) 1367static int do_monotonic_boot(s64 *t, cycle_t *cycle_now)
1375{ 1368{
1369 struct pvclock_gtod_data *gtod = &pvclock_gtod_data;
1376 unsigned long seq; 1370 unsigned long seq;
1377 u64 ns;
1378 int mode; 1371 int mode;
1379 struct pvclock_gtod_data *gtod = &pvclock_gtod_data; 1372 u64 ns;
1380 1373
1381 ts->tv_nsec = 0;
1382 do { 1374 do {
1383 seq = read_seqcount_begin(&gtod->seq); 1375 seq = read_seqcount_begin(&gtod->seq);
1384 mode = gtod->clock.vclock_mode; 1376 mode = gtod->clock.vclock_mode;
1385 ts->tv_sec = gtod->monotonic_time_sec; 1377 ns = gtod->nsec_base;
1386 ns = gtod->monotonic_time_snsec;
1387 ns += vgettsc(cycle_now); 1378 ns += vgettsc(cycle_now);
1388 ns >>= gtod->clock.shift; 1379 ns >>= gtod->clock.shift;
1380 ns += gtod->boot_ns;
1389 } while (unlikely(read_seqcount_retry(&gtod->seq, seq))); 1381 } while (unlikely(read_seqcount_retry(&gtod->seq, seq)));
1390 timespec_add_ns(ts, ns); 1382 *t = ns;
1391 1383
1392 return mode; 1384 return mode;
1393} 1385}
@@ -1395,19 +1387,11 @@ static int do_monotonic(struct timespec *ts, cycle_t *cycle_now)
1395/* returns true if host is using tsc clocksource */ 1387/* returns true if host is using tsc clocksource */
1396static bool kvm_get_time_and_clockread(s64 *kernel_ns, cycle_t *cycle_now) 1388static bool kvm_get_time_and_clockread(s64 *kernel_ns, cycle_t *cycle_now)
1397{ 1389{
1398 struct timespec ts;
1399
1400 /* checked again under seqlock below */ 1390 /* checked again under seqlock below */
1401 if (pvclock_gtod_data.clock.vclock_mode != VCLOCK_TSC) 1391 if (pvclock_gtod_data.clock.vclock_mode != VCLOCK_TSC)
1402 return false; 1392 return false;
1403 1393
1404 if (do_monotonic(&ts, cycle_now) != VCLOCK_TSC) 1394 return do_monotonic_boot(kernel_ns, cycle_now) == VCLOCK_TSC;
1405 return false;
1406
1407 monotonic_to_bootbased(&ts);
1408 *kernel_ns = timespec_to_ns(&ts);
1409
1410 return true;
1411} 1395}
1412#endif 1396#endif
1413 1397