aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/Kconfig4
-rw-r--r--arch/x86/include/asm/clocksource.h4
-rw-r--r--arch/x86/include/asm/vvar.h12
-rw-r--r--arch/x86/kernel/Makefile2
-rw-r--r--arch/x86/kernel/hpet.c2
-rw-r--r--arch/x86/kernel/tsc.c2
-rw-r--r--arch/x86/kernel/vmlinux.lds.S3
-rw-r--r--arch/x86/kernel/vsyscall_64.c45
-rw-r--r--arch/x86/kernel/vsyscall_gtod.c59
-rw-r--r--arch/x86/tools/relocs.c2
10 files changed, 72 insertions, 63 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 9122f6bcbe45..ab3ebc8ba3b9 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -107,9 +107,9 @@ config X86
107 select HAVE_ARCH_SOFT_DIRTY 107 select HAVE_ARCH_SOFT_DIRTY
108 select CLOCKSOURCE_WATCHDOG 108 select CLOCKSOURCE_WATCHDOG
109 select GENERIC_CLOCKEVENTS 109 select GENERIC_CLOCKEVENTS
110 select ARCH_CLOCKSOURCE_DATA if X86_64 110 select ARCH_CLOCKSOURCE_DATA
111 select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && X86_LOCAL_APIC) 111 select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && X86_LOCAL_APIC)
112 select GENERIC_TIME_VSYSCALL if X86_64 112 select GENERIC_TIME_VSYSCALL
113 select KTIME_SCALAR if X86_32 113 select KTIME_SCALAR if X86_32
114 select GENERIC_STRNCPY_FROM_USER 114 select GENERIC_STRNCPY_FROM_USER
115 select GENERIC_STRNLEN_USER 115 select GENERIC_STRNLEN_USER
diff --git a/arch/x86/include/asm/clocksource.h b/arch/x86/include/asm/clocksource.h
index 16a57f4ed64d..eda81dc0f4ae 100644
--- a/arch/x86/include/asm/clocksource.h
+++ b/arch/x86/include/asm/clocksource.h
@@ -3,8 +3,6 @@
3#ifndef _ASM_X86_CLOCKSOURCE_H 3#ifndef _ASM_X86_CLOCKSOURCE_H
4#define _ASM_X86_CLOCKSOURCE_H 4#define _ASM_X86_CLOCKSOURCE_H
5 5
6#ifdef CONFIG_X86_64
7
8#define VCLOCK_NONE 0 /* No vDSO clock available. */ 6#define VCLOCK_NONE 0 /* No vDSO clock available. */
9#define VCLOCK_TSC 1 /* vDSO should use vread_tsc. */ 7#define VCLOCK_TSC 1 /* vDSO should use vread_tsc. */
10#define VCLOCK_HPET 2 /* vDSO should use vread_hpet. */ 8#define VCLOCK_HPET 2 /* vDSO should use vread_hpet. */
@@ -14,6 +12,4 @@ struct arch_clocksource_data {
14 int vclock_mode; 12 int vclock_mode;
15}; 13};
16 14
17#endif /* CONFIG_X86_64 */
18
19#endif /* _ASM_X86_CLOCKSOURCE_H */ 15#endif /* _ASM_X86_CLOCKSOURCE_H */
diff --git a/arch/x86/include/asm/vvar.h b/arch/x86/include/asm/vvar.h
index d76ac40da206..0a534eac5f56 100644
--- a/arch/x86/include/asm/vvar.h
+++ b/arch/x86/include/asm/vvar.h
@@ -16,9 +16,6 @@
16 * you mess up, the linker will catch it.) 16 * you mess up, the linker will catch it.)
17 */ 17 */
18 18
19/* Base address of vvars. This is not ABI. */
20#define VVAR_ADDRESS (-10*1024*1024 - 4096)
21
22#if defined(__VVAR_KERNEL_LDS) 19#if defined(__VVAR_KERNEL_LDS)
23 20
24/* The kernel linker script defines its own magic to put vvars in the 21/* The kernel linker script defines its own magic to put vvars in the
@@ -29,6 +26,15 @@
29 26
30#else 27#else
31 28
29extern char __vvar_page;
30
31/* Base address of vvars. This is not ABI. */
32#ifdef CONFIG_X86_64
33#define VVAR_ADDRESS (-10*1024*1024 - 4096)
34#else
35#define VVAR_ADDRESS (&__vvar_page)
36#endif
37
32#define DECLARE_VVAR(offset, type, name) \ 38#define DECLARE_VVAR(offset, type, name) \
33 static type const * const vvaraddr_ ## name = \ 39 static type const * const vvaraddr_ ## name = \
34 (void *)(VVAR_ADDRESS + (offset)); 40 (void *)(VVAR_ADDRESS + (offset));
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index cb648c84b327..f4d96000d33a 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -26,7 +26,7 @@ obj-$(CONFIG_IRQ_WORK) += irq_work.o
26obj-y += probe_roms.o 26obj-y += probe_roms.o
27obj-$(CONFIG_X86_32) += i386_ksyms_32.o 27obj-$(CONFIG_X86_32) += i386_ksyms_32.o
28obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o 28obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o
29obj-y += syscall_$(BITS).o 29obj-y += syscall_$(BITS).o vsyscall_gtod.o
30obj-$(CONFIG_X86_64) += vsyscall_64.o 30obj-$(CONFIG_X86_64) += vsyscall_64.o
31obj-$(CONFIG_X86_64) += vsyscall_emu_64.o 31obj-$(CONFIG_X86_64) += vsyscall_emu_64.o
32obj-$(CONFIG_SYSFS) += ksysfs.o 32obj-$(CONFIG_SYSFS) += ksysfs.o
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index da85a8e830a1..e4b86abd08ca 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -752,9 +752,7 @@ static struct clocksource clocksource_hpet = {
752 .mask = HPET_MASK, 752 .mask = HPET_MASK,
753 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 753 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
754 .resume = hpet_resume_counter, 754 .resume = hpet_resume_counter,
755#ifdef CONFIG_X86_64
756 .archdata = { .vclock_mode = VCLOCK_HPET }, 755 .archdata = { .vclock_mode = VCLOCK_HPET },
757#endif
758}; 756};
759 757
760static int hpet_clocksource_register(void) 758static int hpet_clocksource_register(void)
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index cfbe99f88830..227dcfc0e5e7 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -985,9 +985,7 @@ static struct clocksource clocksource_tsc = {
985 .mask = CLOCKSOURCE_MASK(64), 985 .mask = CLOCKSOURCE_MASK(64),
986 .flags = CLOCK_SOURCE_IS_CONTINUOUS | 986 .flags = CLOCK_SOURCE_IS_CONTINUOUS |
987 CLOCK_SOURCE_MUST_VERIFY, 987 CLOCK_SOURCE_MUST_VERIFY,
988#ifdef CONFIG_X86_64
989 .archdata = { .vclock_mode = VCLOCK_TSC }, 988 .archdata = { .vclock_mode = VCLOCK_TSC },
990#endif
991}; 989};
992 990
993void mark_tsc_unstable(char *reason) 991void mark_tsc_unstable(char *reason)
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index da6b35a98260..1d4897baf1cc 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -147,7 +147,6 @@ SECTIONS
147 _edata = .; 147 _edata = .;
148 } :data 148 } :data
149 149
150#ifdef CONFIG_X86_64
151 150
152 . = ALIGN(PAGE_SIZE); 151 . = ALIGN(PAGE_SIZE);
153 __vvar_page = .; 152 __vvar_page = .;
@@ -169,8 +168,6 @@ SECTIONS
169 168
170 . = ALIGN(__vvar_page + PAGE_SIZE, PAGE_SIZE); 169 . = ALIGN(__vvar_page + PAGE_SIZE, PAGE_SIZE);
171 170
172#endif /* CONFIG_X86_64 */
173
174 /* Init code and data - will be freed after init */ 171 /* Init code and data - will be freed after init */
175 . = ALIGN(PAGE_SIZE); 172 . = ALIGN(PAGE_SIZE);
176 .init.begin : AT(ADDR(.init.begin) - LOAD_OFFSET) { 173 .init.begin : AT(ADDR(.init.begin) - LOAD_OFFSET) {
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 1f96f9347ed9..9ea287666c65 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -47,14 +47,12 @@
47#include <asm/segment.h> 47#include <asm/segment.h>
48#include <asm/desc.h> 48#include <asm/desc.h>
49#include <asm/topology.h> 49#include <asm/topology.h>
50#include <asm/vgtod.h>
51#include <asm/traps.h> 50#include <asm/traps.h>
52 51
53#define CREATE_TRACE_POINTS 52#define CREATE_TRACE_POINTS
54#include "vsyscall_trace.h" 53#include "vsyscall_trace.h"
55 54
56DEFINE_VVAR(int, vgetcpu_mode); 55DEFINE_VVAR(int, vgetcpu_mode);
57DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data);
58 56
59static enum { EMULATE, NATIVE, NONE } vsyscall_mode = EMULATE; 57static enum { EMULATE, NATIVE, NONE } vsyscall_mode = EMULATE;
60 58
@@ -77,48 +75,6 @@ static int __init vsyscall_setup(char *str)
77} 75}
78early_param("vsyscall", vsyscall_setup); 76early_param("vsyscall", vsyscall_setup);
79 77
80void update_vsyscall_tz(void)
81{
82 vsyscall_gtod_data.sys_tz = sys_tz;
83}
84
85void update_vsyscall(struct timekeeper *tk)
86{
87 struct vsyscall_gtod_data *vdata = &vsyscall_gtod_data;
88
89 write_seqcount_begin(&vdata->seq);
90
91 /* copy vsyscall data */
92 vdata->clock.vclock_mode = tk->clock->archdata.vclock_mode;
93 vdata->clock.cycle_last = tk->clock->cycle_last;
94 vdata->clock.mask = tk->clock->mask;
95 vdata->clock.mult = tk->mult;
96 vdata->clock.shift = tk->shift;
97
98 vdata->wall_time_sec = tk->xtime_sec;
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 }
112
113 vdata->wall_time_coarse.tv_sec = tk->xtime_sec;
114 vdata->wall_time_coarse.tv_nsec = (long)(tk->xtime_nsec >> tk->shift);
115
116 vdata->monotonic_time_coarse = timespec_add(vdata->wall_time_coarse,
117 tk->wall_to_monotonic);
118
119 write_seqcount_end(&vdata->seq);
120}
121
122static void warn_bad_vsyscall(const char *level, struct pt_regs *regs, 78static void warn_bad_vsyscall(const char *level, struct pt_regs *regs,
123 const char *message) 79 const char *message)
124{ 80{
@@ -374,7 +330,6 @@ void __init map_vsyscall(void)
374{ 330{
375 extern char __vsyscall_page; 331 extern char __vsyscall_page;
376 unsigned long physaddr_vsyscall = __pa_symbol(&__vsyscall_page); 332 unsigned long physaddr_vsyscall = __pa_symbol(&__vsyscall_page);
377 extern char __vvar_page;
378 unsigned long physaddr_vvar_page = __pa_symbol(&__vvar_page); 333 unsigned long physaddr_vvar_page = __pa_symbol(&__vvar_page);
379 334
380 __set_fixmap(VSYSCALL_FIRST_PAGE, physaddr_vsyscall, 335 __set_fixmap(VSYSCALL_FIRST_PAGE, physaddr_vsyscall,
diff --git a/arch/x86/kernel/vsyscall_gtod.c b/arch/x86/kernel/vsyscall_gtod.c
new file mode 100644
index 000000000000..b5a943dba9f3
--- /dev/null
+++ b/arch/x86/kernel/vsyscall_gtod.c
@@ -0,0 +1,59 @@
1/*
2 * Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE
3 * Copyright 2003 Andi Kleen, SuSE Labs.
4 *
5 * Modified for x86 32 bit architecture by
6 * Stefani Seibold <stefani@seibold.net>
7 *
8 * Thanks to hpa@transmeta.com for some useful hint.
9 * Special thanks to Ingo Molnar for his early experience with
10 * a different vsyscall implementation for Linux/IA32 and for the name.
11 *
12 */
13
14#include <linux/timekeeper_internal.h>
15#include <asm/vgtod.h>
16
17DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data);
18
19void update_vsyscall_tz(void)
20{
21 vsyscall_gtod_data.sys_tz = sys_tz;
22}
23
24void update_vsyscall(struct timekeeper *tk)
25{
26 struct vsyscall_gtod_data *vdata = &vsyscall_gtod_data;
27
28 write_seqcount_begin(&vdata->seq);
29
30 /* copy vsyscall data */
31 vdata->clock.vclock_mode = tk->clock->archdata.vclock_mode;
32 vdata->clock.cycle_last = tk->clock->cycle_last;
33 vdata->clock.mask = tk->clock->mask;
34 vdata->clock.mult = tk->mult;
35 vdata->clock.shift = tk->shift;
36
37 vdata->wall_time_sec = tk->xtime_sec;
38 vdata->wall_time_snsec = tk->xtime_nsec;
39
40 vdata->monotonic_time_sec = tk->xtime_sec
41 + tk->wall_to_monotonic.tv_sec;
42 vdata->monotonic_time_snsec = tk->xtime_nsec
43 + (tk->wall_to_monotonic.tv_nsec
44 << tk->shift);
45 while (vdata->monotonic_time_snsec >=
46 (((u64)NSEC_PER_SEC) << tk->shift)) {
47 vdata->monotonic_time_snsec -=
48 ((u64)NSEC_PER_SEC) << tk->shift;
49 vdata->monotonic_time_sec++;
50 }
51
52 vdata->wall_time_coarse.tv_sec = tk->xtime_sec;
53 vdata->wall_time_coarse.tv_nsec = (long)(tk->xtime_nsec >> tk->shift);
54
55 vdata->monotonic_time_coarse = timespec_add(vdata->wall_time_coarse,
56 tk->wall_to_monotonic);
57
58 write_seqcount_end(&vdata->seq);
59}
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
index cfbdbdb4e173..bbb1d2259ecf 100644
--- a/arch/x86/tools/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -69,8 +69,8 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = {
69 "__per_cpu_load|" 69 "__per_cpu_load|"
70 "init_per_cpu__.*|" 70 "init_per_cpu__.*|"
71 "__end_rodata_hpage_align|" 71 "__end_rodata_hpage_align|"
72 "__vvar_page|"
73#endif 72#endif
73 "__vvar_page|"
74 "_end)$" 74 "_end)$"
75}; 75};
76 76