diff options
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/x86/kernel/hpet.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/tsc.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/vmlinux.lds.S | 8 | ||||
-rw-r--r-- | arch/x86/kernel/vsyscall_64.c | 45 | ||||
-rw-r--r-- | arch/x86/kernel/vsyscall_gtod.c | 69 |
6 files changed, 75 insertions, 53 deletions
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 | |||
26 | obj-y += probe_roms.o | 26 | obj-y += probe_roms.o |
27 | obj-$(CONFIG_X86_32) += i386_ksyms_32.o | 27 | obj-$(CONFIG_X86_32) += i386_ksyms_32.o |
28 | obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o | 28 | obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o |
29 | obj-y += syscall_$(BITS).o | 29 | obj-y += syscall_$(BITS).o vsyscall_gtod.o |
30 | obj-$(CONFIG_X86_64) += vsyscall_64.o | 30 | obj-$(CONFIG_X86_64) += vsyscall_64.o |
31 | obj-$(CONFIG_X86_64) += vsyscall_emu_64.o | 31 | obj-$(CONFIG_X86_64) += vsyscall_emu_64.o |
32 | obj-$(CONFIG_SYSFS) += ksysfs.o | 32 | obj-$(CONFIG_SYSFS) += ksysfs.o |
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 014618dbaa7b..93eed15a8fd4 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 | ||
760 | static int hpet_clocksource_register(void) | 758 | static int hpet_clocksource_register(void) |
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 7a9296ab8834..57e5ce126d5a 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
@@ -984,9 +984,7 @@ static struct clocksource clocksource_tsc = { | |||
984 | .mask = CLOCKSOURCE_MASK(64), | 984 | .mask = CLOCKSOURCE_MASK(64), |
985 | .flags = CLOCK_SOURCE_IS_CONTINUOUS | | 985 | .flags = CLOCK_SOURCE_IS_CONTINUOUS | |
986 | CLOCK_SOURCE_MUST_VERIFY, | 986 | CLOCK_SOURCE_MUST_VERIFY, |
987 | #ifdef CONFIG_X86_64 | ||
988 | .archdata = { .vclock_mode = VCLOCK_TSC }, | 987 | .archdata = { .vclock_mode = VCLOCK_TSC }, |
989 | #endif | ||
990 | }; | 988 | }; |
991 | 989 | ||
992 | void mark_tsc_unstable(char *reason) | 990 | void mark_tsc_unstable(char *reason) |
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index da6b35a98260..49edf2dd3613 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 = .; |
@@ -165,12 +164,15 @@ SECTIONS | |||
165 | #undef __VVAR_KERNEL_LDS | 164 | #undef __VVAR_KERNEL_LDS |
166 | #undef EMIT_VVAR | 165 | #undef EMIT_VVAR |
167 | 166 | ||
167 | /* | ||
168 | * Pad the rest of the page with zeros. Otherwise the loader | ||
169 | * can leave garbage here. | ||
170 | */ | ||
171 | . = __vvar_beginning_hack + PAGE_SIZE; | ||
168 | } :data | 172 | } :data |
169 | 173 | ||
170 | . = ALIGN(__vvar_page + PAGE_SIZE, PAGE_SIZE); | 174 | . = ALIGN(__vvar_page + PAGE_SIZE, PAGE_SIZE); |
171 | 175 | ||
172 | #endif /* CONFIG_X86_64 */ | ||
173 | |||
174 | /* Init code and data - will be freed after init */ | 176 | /* Init code and data - will be freed after init */ |
175 | . = ALIGN(PAGE_SIZE); | 177 | . = ALIGN(PAGE_SIZE); |
176 | .init.begin : AT(ADDR(.init.begin) - LOAD_OFFSET) { | 178 | .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 | ||
56 | DEFINE_VVAR(int, vgetcpu_mode); | 55 | DEFINE_VVAR(int, vgetcpu_mode); |
57 | DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data); | ||
58 | 56 | ||
59 | static enum { EMULATE, NATIVE, NONE } vsyscall_mode = EMULATE; | 57 | static enum { EMULATE, NATIVE, NONE } vsyscall_mode = EMULATE; |
60 | 58 | ||
@@ -77,48 +75,6 @@ static int __init vsyscall_setup(char *str) | |||
77 | } | 75 | } |
78 | early_param("vsyscall", vsyscall_setup); | 76 | early_param("vsyscall", vsyscall_setup); |
79 | 77 | ||
80 | void update_vsyscall_tz(void) | ||
81 | { | ||
82 | vsyscall_gtod_data.sys_tz = sys_tz; | ||
83 | } | ||
84 | |||
85 | void 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 | |||
122 | static void warn_bad_vsyscall(const char *level, struct pt_regs *regs, | 78 | static 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..f9c6e56e14b5 --- /dev/null +++ b/arch/x86/kernel/vsyscall_gtod.c | |||
@@ -0,0 +1,69 @@ | |||
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 | * sponsored by Rohde & Schwarz GmbH & Co. KG Munich/Germany | ||
8 | * | ||
9 | * Thanks to hpa@transmeta.com for some useful hint. | ||
10 | * Special thanks to Ingo Molnar for his early experience with | ||
11 | * a different vsyscall implementation for Linux/IA32 and for the name. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/timekeeper_internal.h> | ||
16 | #include <asm/vgtod.h> | ||
17 | #include <asm/vvar.h> | ||
18 | |||
19 | DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data); | ||
20 | |||
21 | void update_vsyscall_tz(void) | ||
22 | { | ||
23 | vsyscall_gtod_data.tz_minuteswest = sys_tz.tz_minuteswest; | ||
24 | vsyscall_gtod_data.tz_dsttime = sys_tz.tz_dsttime; | ||
25 | } | ||
26 | |||
27 | void update_vsyscall(struct timekeeper *tk) | ||
28 | { | ||
29 | struct vsyscall_gtod_data *vdata = &vsyscall_gtod_data; | ||
30 | |||
31 | gtod_write_begin(vdata); | ||
32 | |||
33 | /* copy vsyscall data */ | ||
34 | vdata->vclock_mode = tk->clock->archdata.vclock_mode; | ||
35 | vdata->cycle_last = tk->clock->cycle_last; | ||
36 | vdata->mask = tk->clock->mask; | ||
37 | vdata->mult = tk->mult; | ||
38 | vdata->shift = tk->shift; | ||
39 | |||
40 | vdata->wall_time_sec = tk->xtime_sec; | ||
41 | vdata->wall_time_snsec = tk->xtime_nsec; | ||
42 | |||
43 | vdata->monotonic_time_sec = tk->xtime_sec | ||
44 | + tk->wall_to_monotonic.tv_sec; | ||
45 | vdata->monotonic_time_snsec = tk->xtime_nsec | ||
46 | + (tk->wall_to_monotonic.tv_nsec | ||
47 | << tk->shift); | ||
48 | while (vdata->monotonic_time_snsec >= | ||
49 | (((u64)NSEC_PER_SEC) << tk->shift)) { | ||
50 | vdata->monotonic_time_snsec -= | ||
51 | ((u64)NSEC_PER_SEC) << tk->shift; | ||
52 | vdata->monotonic_time_sec++; | ||
53 | } | ||
54 | |||
55 | vdata->wall_time_coarse_sec = tk->xtime_sec; | ||
56 | vdata->wall_time_coarse_nsec = (long)(tk->xtime_nsec >> tk->shift); | ||
57 | |||
58 | vdata->monotonic_time_coarse_sec = | ||
59 | vdata->wall_time_coarse_sec + tk->wall_to_monotonic.tv_sec; | ||
60 | vdata->monotonic_time_coarse_nsec = | ||
61 | vdata->wall_time_coarse_nsec + tk->wall_to_monotonic.tv_nsec; | ||
62 | |||
63 | while (vdata->monotonic_time_coarse_nsec >= NSEC_PER_SEC) { | ||
64 | vdata->monotonic_time_coarse_nsec -= NSEC_PER_SEC; | ||
65 | vdata->monotonic_time_coarse_sec++; | ||
66 | } | ||
67 | |||
68 | gtod_write_end(vdata); | ||
69 | } | ||