Skip to content

Commit b020632

Browse files
author
Martin Schwidefsky
committed
[S390] introduce vdso on s390
Add a vdso to speed up gettimeofday and clock_getres/clock_gettime for CLOCK_REALTIME/CLOCK_MONOTONIC. Signed-off-by: Martin Schwidefsky <[email protected]>
1 parent fc5243d commit b020632

24 files changed

+1218
-1
lines changed

arch/s390/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ config GENERIC_HWEIGHT
4343
config GENERIC_TIME
4444
def_bool y
4545

46+
config GENERIC_TIME_VSYSCALL
47+
def_bool y
48+
4649
config GENERIC_CLOCKEVENTS
4750
def_bool y
4851

arch/s390/include/asm/auxvec.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#ifndef __ASMS390_AUXVEC_H
22
#define __ASMS390_AUXVEC_H
33

4+
#define AT_SYSINFO_EHDR 33
5+
46
#endif

arch/s390/include/asm/elf.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ typedef s390_compat_regs compat_elf_gregset_t;
120120
#include <asm/system.h> /* for save_access_regs */
121121
#include <asm/mmu_context.h>
122122

123+
#include <asm/vdso.h>
124+
125+
extern unsigned int vdso_enabled;
126+
123127
/*
124128
* This is used to ensure we don't load something for the wrong architecture.
125129
*/
@@ -191,4 +195,16 @@ do { \
191195
current->mm->context.noexec == 0; \
192196
})
193197

198+
#define ARCH_DLINFO \
199+
do { \
200+
if (vdso_enabled) \
201+
NEW_AUX_ENT(AT_SYSINFO_EHDR, \
202+
(unsigned long)current->mm->context.vdso_base); \
203+
} while (0)
204+
205+
struct linux_binprm;
206+
207+
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
208+
int arch_setup_additional_pages(struct linux_binprm *, int);
209+
194210
#endif

arch/s390/include/asm/mmu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ typedef struct {
66
struct list_head pgtable_list;
77
unsigned long asce_bits;
88
unsigned long asce_limit;
9+
unsigned long vdso_base;
910
int noexec;
1011
int has_pgste; /* The mmu context has extended page tables */
1112
int alloc_pgste; /* cloned contexts will have extended page tables */

arch/s390/include/asm/page.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,4 +152,6 @@ void arch_alloc_page(struct page *page, int order);
152152
#include <asm-generic/memory_model.h>
153153
#include <asm-generic/page.h>
154154

155+
#define __HAVE_ARCH_GATE_AREA 1
156+
155157
#endif /* _S390_PAGE_H */

arch/s390/include/asm/vdso.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#ifndef __S390_VDSO_H__
2+
#define __S390_VDSO_H__
3+
4+
#ifdef __KERNEL__
5+
6+
/* Default link addresses for the vDSOs */
7+
#define VDSO32_LBASE 0
8+
#define VDSO64_LBASE 0
9+
10+
#define VDSO_VERSION_STRING LINUX_2.6.26
11+
12+
#ifndef __ASSEMBLY__
13+
14+
/*
15+
* Note about this structure:
16+
*
17+
* NEVER USE THIS IN USERSPACE CODE DIRECTLY. The layout of this
18+
* structure is supposed to be known only to the function in the vdso
19+
* itself and may change without notice.
20+
*/
21+
22+
struct vdso_data {
23+
__u64 tb_update_count; /* Timebase atomicity ctr 0x00 */
24+
__u64 xtime_tod_stamp; /* TOD clock for xtime 0x08 */
25+
__u64 xtime_clock_sec; /* Kernel time 0x10 */
26+
__u64 xtime_clock_nsec; /* 0x18 */
27+
__u64 wtom_clock_sec; /* Wall to monotonic clock 0x20 */
28+
__u64 wtom_clock_nsec; /* 0x28 */
29+
__u32 tz_minuteswest; /* Minutes west of Greenwich 0x30 */
30+
__u32 tz_dsttime; /* Type of dst correction 0x34 */
31+
};
32+
33+
extern struct vdso_data *vdso_data;
34+
35+
#endif /* __ASSEMBLY__ */
36+
37+
#endif /* __KERNEL__ */
38+
39+
#endif /* __S390_VDSO_H__ */

arch/s390/kernel/Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
1414

1515
obj-y := bitmap.o traps.o time.o process.o base.o early.o \
1616
setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
17-
s390_ext.o debug.o irq.o ipl.o dis.o diag.o mem_detect.o
17+
s390_ext.o debug.o irq.o ipl.o dis.o diag.o mem_detect.o \
18+
vdso.o
1819

1920
obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o)
2021
obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
@@ -39,3 +40,7 @@ S390_KEXEC_OBJS := machine_kexec.o crash.o
3940
S390_KEXEC_OBJS += $(if $(CONFIG_64BIT),relocate_kernel64.o,relocate_kernel.o)
4041
obj-$(CONFIG_KEXEC) += $(S390_KEXEC_OBJS)
4142

43+
# vdso
44+
obj-$(CONFIG_64BIT) += vdso64/
45+
obj-$(CONFIG_32BIT) += vdso32/
46+
obj-$(CONFIG_COMPAT) += vdso32/

arch/s390/kernel/asm-offsets.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <linux/sched.h>
88
#include <linux/kbuild.h>
9+
#include <asm/vdso.h>
910

1011
int main(void)
1112
{
@@ -38,5 +39,19 @@ int main(void)
3839
DEFINE(__SF_BACKCHAIN, offsetof(struct stack_frame, back_chain));
3940
DEFINE(__SF_GPRS, offsetof(struct stack_frame, gprs));
4041
DEFINE(__SF_EMPTY, offsetof(struct stack_frame, empty1));
42+
BLANK();
43+
/* timeval/timezone offsets for use by vdso */
44+
DEFINE(__VDSO_UPD_COUNT, offsetof(struct vdso_data, tb_update_count));
45+
DEFINE(__VDSO_XTIME_STAMP, offsetof(struct vdso_data, xtime_tod_stamp));
46+
DEFINE(__VDSO_XTIME_SEC, offsetof(struct vdso_data, xtime_clock_sec));
47+
DEFINE(__VDSO_XTIME_NSEC, offsetof(struct vdso_data, xtime_clock_nsec));
48+
DEFINE(__VDSO_WTOM_SEC, offsetof(struct vdso_data, wtom_clock_sec));
49+
DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
50+
DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest));
51+
/* constants used by the vdso */
52+
DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
53+
DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
54+
DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
55+
4156
return 0;
4257
}

arch/s390/kernel/time.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <asm/delay.h>
3737
#include <asm/s390_ext.h>
3838
#include <asm/div64.h>
39+
#include <asm/vdso.h>
3940
#include <asm/irq.h>
4041
#include <asm/irq_regs.h>
4142
#include <asm/timer.h>
@@ -223,6 +224,36 @@ static struct clocksource clocksource_tod = {
223224
};
224225

225226

227+
void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
228+
{
229+
if (clock != &clocksource_tod)
230+
return;
231+
232+
/* Make userspace gettimeofday spin until we're done. */
233+
++vdso_data->tb_update_count;
234+
smp_wmb();
235+
vdso_data->xtime_tod_stamp = clock->cycle_last;
236+
vdso_data->xtime_clock_sec = xtime.tv_sec;
237+
vdso_data->xtime_clock_nsec = xtime.tv_nsec;
238+
vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
239+
vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
240+
smp_wmb();
241+
++vdso_data->tb_update_count;
242+
}
243+
244+
extern struct timezone sys_tz;
245+
246+
void update_vsyscall_tz(void)
247+
{
248+
/* Make userspace gettimeofday spin until we're done. */
249+
++vdso_data->tb_update_count;
250+
smp_wmb();
251+
vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
252+
vdso_data->tz_dsttime = sys_tz.tz_dsttime;
253+
smp_wmb();
254+
++vdso_data->tb_update_count;
255+
}
256+
226257
/*
227258
* Initialize the TOD clock and the CPU timer of
228259
* the boot cpu.

0 commit comments

Comments
 (0)