diff options
Diffstat (limited to 'arch/x86/kernel/vsyscall_64.c')
| -rw-r--r-- | arch/x86/kernel/vsyscall_64.c | 49 |
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 | ||
| 85 | void update_vsyscall(struct timespec *wall_time, struct timespec *wtm, | 85 | void 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 | ||
| 113 | static void warn_bad_vsyscall(const char *level, struct pt_regs *regs, | 122 | static void warn_bad_vsyscall(const char *level, struct pt_regs *regs, |
