Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86, vdso: Make vsyscall_gtod_data handling x86 generic

This patch move the vsyscall_gtod_data handling out of vsyscall_64.c
into an additonal file vsyscall_gtod.c to make the functionality
available for x86 32 bit kernel.

It also adds a new vsyscall_32.c which setup the VVAR page.

Reviewed-by: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: Stefani Seibold <stefani@seibold.net>
Link: http://lkml.kernel.org/r/1395094933-14252-2-git-send-email-stefani@seibold.net
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>

authored by

Stefani Seibold and committed by
H. Peter Anvin
d2312e33 1f2cbcf6

+72 -63
+2 -2
arch/x86/Kconfig
··· 107 107 select HAVE_ARCH_SOFT_DIRTY 108 108 select CLOCKSOURCE_WATCHDOG 109 109 select GENERIC_CLOCKEVENTS 110 - select ARCH_CLOCKSOURCE_DATA if X86_64 110 + select ARCH_CLOCKSOURCE_DATA 111 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 113 select KTIME_SCALAR if X86_32 114 114 select GENERIC_STRNCPY_FROM_USER 115 115 select GENERIC_STRNLEN_USER
-4
arch/x86/include/asm/clocksource.h
··· 3 3 #ifndef _ASM_X86_CLOCKSOURCE_H 4 4 #define _ASM_X86_CLOCKSOURCE_H 5 5 6 - #ifdef CONFIG_X86_64 7 - 8 6 #define VCLOCK_NONE 0 /* No vDSO clock available. */ 9 7 #define VCLOCK_TSC 1 /* vDSO should use vread_tsc. */ 10 8 #define VCLOCK_HPET 2 /* vDSO should use vread_hpet. */ ··· 11 13 struct arch_clocksource_data { 12 14 int vclock_mode; 13 15 }; 14 - 15 - #endif /* CONFIG_X86_64 */ 16 16 17 17 #endif /* _ASM_X86_CLOCKSOURCE_H */
+9 -3
arch/x86/include/asm/vvar.h
··· 16 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 19 #if defined(__VVAR_KERNEL_LDS) 23 20 24 21 /* The kernel linker script defines its own magic to put vvars in the ··· 25 28 EMIT_VVAR(name, offset) 26 29 27 30 #else 31 + 32 + extern char __vvar_page; 33 + 34 + /* Base address of vvars. This is not ABI. */ 35 + #ifdef CONFIG_X86_64 36 + #define VVAR_ADDRESS (-10*1024*1024 - 4096) 37 + #else 38 + #define VVAR_ADDRESS (&__vvar_page) 39 + #endif 28 40 29 41 #define DECLARE_VVAR(offset, type, name) \ 30 42 static type const * const vvaraddr_ ## name = \
+1 -1
arch/x86/kernel/Makefile
··· 26 26 obj-y += probe_roms.o 27 27 obj-$(CONFIG_X86_32) += i386_ksyms_32.o 28 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 30 obj-$(CONFIG_X86_64) += vsyscall_64.o 31 31 obj-$(CONFIG_X86_64) += vsyscall_emu_64.o 32 32 obj-$(CONFIG_SYSFS) += ksysfs.o
-2
arch/x86/kernel/hpet.c
··· 752 752 .mask = HPET_MASK, 753 753 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 754 754 .resume = hpet_resume_counter, 755 - #ifdef CONFIG_X86_64 756 755 .archdata = { .vclock_mode = VCLOCK_HPET }, 757 - #endif 758 756 }; 759 757 760 758 static int hpet_clocksource_register(void)
-2
arch/x86/kernel/tsc.c
··· 985 985 .mask = CLOCKSOURCE_MASK(64), 986 986 .flags = CLOCK_SOURCE_IS_CONTINUOUS | 987 987 CLOCK_SOURCE_MUST_VERIFY, 988 - #ifdef CONFIG_X86_64 989 988 .archdata = { .vclock_mode = VCLOCK_TSC }, 990 - #endif 991 989 }; 992 990 993 991 void mark_tsc_unstable(char *reason)
-3
arch/x86/kernel/vmlinux.lds.S
··· 147 147 _edata = .; 148 148 } :data 149 149 150 - #ifdef CONFIG_X86_64 151 150 152 151 . = ALIGN(PAGE_SIZE); 153 152 __vvar_page = .; ··· 167 168 } :data 168 169 169 170 . = ALIGN(__vvar_page + PAGE_SIZE, PAGE_SIZE); 170 - 171 - #endif /* CONFIG_X86_64 */ 172 171 173 172 /* Init code and data - will be freed after init */ 174 173 . = ALIGN(PAGE_SIZE);
-45
arch/x86/kernel/vsyscall_64.c
··· 47 47 #include <asm/segment.h> 48 48 #include <asm/desc.h> 49 49 #include <asm/topology.h> 50 - #include <asm/vgtod.h> 51 50 #include <asm/traps.h> 52 51 53 52 #define CREATE_TRACE_POINTS 54 53 #include "vsyscall_trace.h" 55 54 56 55 DEFINE_VVAR(int, vgetcpu_mode); 57 - DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data); 58 56 59 57 static enum { EMULATE, NATIVE, NONE } vsyscall_mode = EMULATE; 60 58 ··· 74 76 return -EINVAL; 75 77 } 76 78 early_param("vsyscall", vsyscall_setup); 77 - 78 - void update_vsyscall_tz(void) 79 - { 80 - vsyscall_gtod_data.sys_tz = sys_tz; 81 - } 82 - 83 - void update_vsyscall(struct timekeeper *tk) 84 - { 85 - struct vsyscall_gtod_data *vdata = &vsyscall_gtod_data; 86 - 87 - write_seqcount_begin(&vdata->seq); 88 - 89 - /* copy vsyscall data */ 90 - vdata->clock.vclock_mode = tk->clock->archdata.vclock_mode; 91 - vdata->clock.cycle_last = tk->clock->cycle_last; 92 - vdata->clock.mask = tk->clock->mask; 93 - vdata->clock.mult = tk->mult; 94 - vdata->clock.shift = tk->shift; 95 - 96 - vdata->wall_time_sec = tk->xtime_sec; 97 - vdata->wall_time_snsec = tk->xtime_nsec; 98 - 99 - vdata->monotonic_time_sec = tk->xtime_sec 100 - + tk->wall_to_monotonic.tv_sec; 101 - vdata->monotonic_time_snsec = tk->xtime_nsec 102 - + (tk->wall_to_monotonic.tv_nsec 103 - << tk->shift); 104 - while (vdata->monotonic_time_snsec >= 105 - (((u64)NSEC_PER_SEC) << tk->shift)) { 106 - vdata->monotonic_time_snsec -= 107 - ((u64)NSEC_PER_SEC) << tk->shift; 108 - vdata->monotonic_time_sec++; 109 - } 110 - 111 - vdata->wall_time_coarse.tv_sec = tk->xtime_sec; 112 - vdata->wall_time_coarse.tv_nsec = (long)(tk->xtime_nsec >> tk->shift); 113 - 114 - vdata->monotonic_time_coarse = timespec_add(vdata->wall_time_coarse, 115 - tk->wall_to_monotonic); 116 - 117 - write_seqcount_end(&vdata->seq); 118 - } 119 79 120 80 static void warn_bad_vsyscall(const char *level, struct pt_regs *regs, 121 81 const char *message) ··· 330 374 { 331 375 extern char __vsyscall_page; 332 376 unsigned long physaddr_vsyscall = __pa_symbol(&__vsyscall_page); 333 - extern char __vvar_page; 334 377 unsigned long physaddr_vvar_page = __pa_symbol(&__vvar_page); 335 378 336 379 __set_fixmap(VSYSCALL_FIRST_PAGE, physaddr_vsyscall,
+59
arch/x86/kernel/vsyscall_gtod.c
··· 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 + 17 + DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data); 18 + 19 + void update_vsyscall_tz(void) 20 + { 21 + vsyscall_gtod_data.sys_tz = sys_tz; 22 + } 23 + 24 + void 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 + }
+1 -1
arch/x86/tools/relocs.c
··· 69 69 "__per_cpu_load|" 70 70 "init_per_cpu__.*|" 71 71 "__end_rodata_hpage_align|" 72 - "__vvar_page|" 73 72 #endif 73 + "__vvar_page|" 74 74 "_end)$" 75 75 }; 76 76