aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/vsyscall_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/vsyscall_64.c')
-rw-r--r--arch/x86/kernel/vsyscall_64.c49
1 files changed, 29 insertions, 20 deletions
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 8d141b309046..3a3e8c9e280d 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -28,7 +28,7 @@
28#include <linux/jiffies.h> 28#include <linux/jiffies.h>
29#include <linux/sysctl.h> 29#include <linux/sysctl.h>
30#include <linux/topology.h> 30#include <linux/topology.h>
31#include <linux/clocksource.h> 31#include <linux/timekeeper_internal.h>
32#include <linux/getcpu.h> 32#include <linux/getcpu.h>
33#include <linux/cpu.h> 33#include <linux/cpu.h>
34#include <linux/smp.h> 34#include <linux/smp.h>
@@ -82,32 +82,41 @@ void update_vsyscall_tz(void)
82 vsyscall_gtod_data.sys_tz = sys_tz; 82 vsyscall_gtod_data.sys_tz = sys_tz;
83} 83}
84 84
85void update_vsyscall(struct timespec *wall_time, struct timespec *wtm, 85void update_vsyscall(struct timekeeper *tk)
86 struct clocksource *clock, u32 mult)
87{ 86{
88 struct timespec monotonic; 87 struct vsyscall_gtod_data *vdata = &vsyscall_gtod_data;
89 88
90 write_seqcount_begin(&vsyscall_gtod_data.seq); 89 write_seqcount_begin(&vdata->seq);
91 90
92 /* copy vsyscall data */ 91 /* copy vsyscall data */
93 vsyscall_gtod_data.clock.vclock_mode = clock->archdata.vclock_mode; 92 vdata->clock.vclock_mode = tk->clock->archdata.vclock_mode;
94 vsyscall_gtod_data.clock.cycle_last = clock->cycle_last; 93 vdata->clock.cycle_last = tk->clock->cycle_last;
95 vsyscall_gtod_data.clock.mask = clock->mask; 94 vdata->clock.mask = tk->clock->mask;
96 vsyscall_gtod_data.clock.mult = mult; 95 vdata->clock.mult = tk->mult;
97 vsyscall_gtod_data.clock.shift = clock->shift; 96 vdata->clock.shift = tk->shift;
98 97
99 vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec; 98 vdata->wall_time_sec = tk->xtime_sec;
100 vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec; 99 vdata->wall_time_snsec = tk->xtime_nsec;
100
101 vdata->monotonic_time_sec = tk->xtime_sec
102 + tk->wall_to_monotonic.tv_sec;
103 vdata->monotonic_time_snsec = tk->xtime_nsec
104 + (tk->wall_to_monotonic.tv_nsec
105 << tk->shift);
106 while (vdata->monotonic_time_snsec >=
107 (((u64)NSEC_PER_SEC) << tk->shift)) {
108 vdata->monotonic_time_snsec -=
109 ((u64)NSEC_PER_SEC) << tk->shift;
110 vdata->monotonic_time_sec++;
111 }
101 112
102 monotonic = timespec_add(*wall_time, *wtm); 113 vdata->wall_time_coarse.tv_sec = tk->xtime_sec;
103 vsyscall_gtod_data.monotonic_time_sec = monotonic.tv_sec; 114 vdata->wall_time_coarse.tv_nsec = (long)(tk->xtime_nsec >> tk->shift);
104 vsyscall_gtod_data.monotonic_time_nsec = monotonic.tv_nsec;
105 115
106 vsyscall_gtod_data.wall_time_coarse = __current_kernel_time(); 116 vdata->monotonic_time_coarse = timespec_add(vdata->wall_time_coarse,
107 vsyscall_gtod_data.monotonic_time_coarse = 117 tk->wall_to_monotonic);
108 timespec_add(vsyscall_gtod_data.wall_time_coarse, *wtm);
109 118
110 write_seqcount_end(&vsyscall_gtod_data.seq); 119 write_seqcount_end(&vdata->seq);
111} 120}
112 121
113static void warn_bad_vsyscall(const char *level, struct pt_regs *regs, 122static void warn_bad_vsyscall(const char *level, struct pt_regs *regs,