summaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-05 20:46:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-05 20:46:42 -0400
commite7fda6c4c3c1a7d6996dd75fd84670fa0b5d448f (patch)
treedaa51c16462c318b890acf7f01fba5827275dd74 /arch/x86/kvm
parent08d69a25714429850cf9ef71f22d8cdc9189d93f (diff)
parent953dec21aed4038464fec02f96a2f1b8701a5bce (diff)
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer and time updates from Thomas Gleixner: "A rather large update of timers, timekeeping & co - Core timekeeping code is year-2038 safe now for 32bit machines. Now we just need to fix all in kernel users and the gazillion of user space interfaces which rely on timespec/timeval :) - Better cache layout for the timekeeping internal data structures. - Proper nanosecond based interfaces for in kernel users. - Tree wide cleanup of code which wants nanoseconds but does hoops and loops to convert back and forth from timespecs. Some of it definitely belongs into the ugly code museum. - Consolidation of the timekeeping interface zoo. - A fast NMI safe accessor to clock monotonic for tracing. This is a long standing request to support correlated user/kernel space traces. With proper NTP frequency correction it's also suitable for correlation of traces accross separate machines. - Checkpoint/restart support for timerfd. - A few NOHZ[_FULL] improvements in the [hr]timer code. - Code move from kernel to kernel/time of all time* related code. - New clocksource/event drivers from the ARM universe. I'm really impressed that despite an architected timer in the newer chips SoC manufacturers insist on inventing new and differently broken SoC specific timers. [ Ed. "Impressed"? I don't think that word means what you think it means ] - Another round of code move from arch to drivers. Looks like most of the legacy mess in ARM regarding timers is sorted out except for a few obnoxious strongholds. - The usual updates and fixlets all over the place" * 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (114 commits) timekeeping: Fixup typo in update_vsyscall_old definition clocksource: document some basic timekeeping concepts timekeeping: Use cached ntp_tick_length when accumulating error timekeeping: Rework frequency adjustments to work better w/ nohz timekeeping: Minor fixup for timespec64->timespec assignment ftrace: Provide trace clocks monotonic timekeeping: Provide fast and NMI safe access to CLOCK_MONOTONIC seqcount: Add raw_write_seqcount_latch() seqcount: Provide raw_read_seqcount() timekeeping: Use tk_read_base as argument for timekeeping_get_ns() timekeeping: Create struct tk_read_base and use it in struct timekeeper timekeeping: Restructure the timekeeper some more clocksource: Get rid of cycle_last clocksource: Move cycle_last validation to core code clocksource: Make delta calculation a function wireless: ath9k: Get rid of timespec conversions drm: vmwgfx: Use nsec based interfaces drm: i915: Use nsec based interfaces timekeeping: Provide ktime_get_raw() hangcheck-timer: Use ktime_get_ns() ...
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/x86.c62
1 files changed, 21 insertions, 41 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index b86d329b953a..ca3d760dd581 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1020,9 +1020,8 @@ struct pvclock_gtod_data {
1020 u32 shift; 1020 u32 shift;
1021 } clock; 1021 } clock;
1022 1022
1023 /* open coded 'struct timespec' */ 1023 u64 boot_ns;
1024 u64 monotonic_time_snsec; 1024 u64 nsec_base;
1025 time_t monotonic_time_sec;
1026}; 1025};
1027 1026
1028static struct pvclock_gtod_data pvclock_gtod_data; 1027static struct pvclock_gtod_data pvclock_gtod_data;
@@ -1030,27 +1029,21 @@ static struct pvclock_gtod_data pvclock_gtod_data;
1030static void update_pvclock_gtod(struct timekeeper *tk) 1029static void update_pvclock_gtod(struct timekeeper *tk)
1031{ 1030{
1032 struct pvclock_gtod_data *vdata = &pvclock_gtod_data; 1031 struct pvclock_gtod_data *vdata = &pvclock_gtod_data;
1032 u64 boot_ns;
1033
1034 boot_ns = ktime_to_ns(ktime_add(tk->tkr.base_mono, tk->offs_boot));
1033 1035
1034 write_seqcount_begin(&vdata->seq); 1036 write_seqcount_begin(&vdata->seq);
1035 1037
1036 /* copy pvclock gtod data */ 1038 /* copy pvclock gtod data */
1037 vdata->clock.vclock_mode = tk->clock->archdata.vclock_mode; 1039 vdata->clock.vclock_mode = tk->tkr.clock->archdata.vclock_mode;
1038 vdata->clock.cycle_last = tk->clock->cycle_last; 1040 vdata->clock.cycle_last = tk->tkr.cycle_last;
1039 vdata->clock.mask = tk->clock->mask; 1041 vdata->clock.mask = tk->tkr.mask;
1040 vdata->clock.mult = tk->mult; 1042 vdata->clock.mult = tk->tkr.mult;
1041 vdata->clock.shift = tk->shift; 1043 vdata->clock.shift = tk->tkr.shift;
1042 1044
1043 vdata->monotonic_time_sec = tk->xtime_sec 1045 vdata->boot_ns = boot_ns;
1044 + tk->wall_to_monotonic.tv_sec; 1046 vdata->nsec_base = tk->tkr.xtime_nsec;
1045 vdata->monotonic_time_snsec = tk->xtime_nsec
1046 + (tk->wall_to_monotonic.tv_nsec
1047 << tk->shift);
1048 while (vdata->monotonic_time_snsec >=
1049 (((u64)NSEC_PER_SEC) << tk->shift)) {
1050 vdata->monotonic_time_snsec -=
1051 ((u64)NSEC_PER_SEC) << tk->shift;
1052 vdata->monotonic_time_sec++;
1053 }
1054 1047
1055 write_seqcount_end(&vdata->seq); 1048 write_seqcount_end(&vdata->seq);
1056} 1049}
@@ -1145,11 +1138,7 @@ static void kvm_get_time_scale(uint32_t scaled_khz, uint32_t base_khz,
1145 1138
1146static inline u64 get_kernel_ns(void) 1139static inline u64 get_kernel_ns(void)
1147{ 1140{
1148 struct timespec ts; 1141 return ktime_get_boot_ns();
1149
1150 ktime_get_ts(&ts);
1151 monotonic_to_bootbased(&ts);
1152 return timespec_to_ns(&ts);
1153} 1142}
1154 1143
1155#ifdef CONFIG_X86_64 1144#ifdef CONFIG_X86_64
@@ -1414,23 +1403,22 @@ static inline u64 vgettsc(cycle_t *cycle_now)
1414 return v * gtod->clock.mult; 1403 return v * gtod->clock.mult;
1415} 1404}
1416 1405
1417static int do_monotonic(struct timespec *ts, cycle_t *cycle_now) 1406static int do_monotonic_boot(s64 *t, cycle_t *cycle_now)
1418{ 1407{
1408 struct pvclock_gtod_data *gtod = &pvclock_gtod_data;
1419 unsigned long seq; 1409 unsigned long seq;
1420 u64 ns;
1421 int mode; 1410 int mode;
1422 struct pvclock_gtod_data *gtod = &pvclock_gtod_data; 1411 u64 ns;
1423 1412
1424 ts->tv_nsec = 0;
1425 do { 1413 do {
1426 seq = read_seqcount_begin(&gtod->seq); 1414 seq = read_seqcount_begin(&gtod->seq);
1427 mode = gtod->clock.vclock_mode; 1415 mode = gtod->clock.vclock_mode;
1428 ts->tv_sec = gtod->monotonic_time_sec; 1416 ns = gtod->nsec_base;
1429 ns = gtod->monotonic_time_snsec;
1430 ns += vgettsc(cycle_now); 1417 ns += vgettsc(cycle_now);
1431 ns >>= gtod->clock.shift; 1418 ns >>= gtod->clock.shift;
1419 ns += gtod->boot_ns;
1432 } while (unlikely(read_seqcount_retry(&gtod->seq, seq))); 1420 } while (unlikely(read_seqcount_retry(&gtod->seq, seq)));
1433 timespec_add_ns(ts, ns); 1421 *t = ns;
1434 1422
1435 return mode; 1423 return mode;
1436} 1424}
@@ -1438,19 +1426,11 @@ static int do_monotonic(struct timespec *ts, cycle_t *cycle_now)
1438/* returns true if host is using tsc clocksource */ 1426/* returns true if host is using tsc clocksource */
1439static bool kvm_get_time_and_clockread(s64 *kernel_ns, cycle_t *cycle_now) 1427static bool kvm_get_time_and_clockread(s64 *kernel_ns, cycle_t *cycle_now)
1440{ 1428{
1441 struct timespec ts;
1442
1443 /* checked again under seqlock below */ 1429 /* checked again under seqlock below */
1444 if (pvclock_gtod_data.clock.vclock_mode != VCLOCK_TSC) 1430 if (pvclock_gtod_data.clock.vclock_mode != VCLOCK_TSC)
1445 return false; 1431 return false;
1446 1432
1447 if (do_monotonic(&ts, cycle_now) != VCLOCK_TSC) 1433 return do_monotonic_boot(kernel_ns, cycle_now) == VCLOCK_TSC;
1448 return false;
1449
1450 monotonic_to_bootbased(&ts);
1451 *kernel_ns = timespec_to_ns(&ts);
1452
1453 return true;
1454} 1434}
1455#endif 1435#endif
1456 1436