diff options
-rw-r--r-- | arch/s390/include/asm/vdso.h | 18 | ||||
-rw-r--r-- | arch/s390/kernel/asm-offsets.c | 7 | ||||
-rw-r--r-- | arch/s390/kernel/time.c | 13 | ||||
-rw-r--r-- | arch/s390/kernel/vdso32/clock_getres.S | 11 | ||||
-rw-r--r-- | arch/s390/kernel/vdso32/clock_gettime.S | 24 | ||||
-rw-r--r-- | arch/s390/kernel/vdso64/clock_getres.S | 8 | ||||
-rw-r--r-- | arch/s390/kernel/vdso64/clock_gettime.S | 24 |
7 files changed, 95 insertions, 10 deletions
diff --git a/arch/s390/include/asm/vdso.h b/arch/s390/include/asm/vdso.h index bc9746a7d47c..a62526d09201 100644 --- a/arch/s390/include/asm/vdso.h +++ b/arch/s390/include/asm/vdso.h | |||
@@ -22,13 +22,17 @@ struct vdso_data { | |||
22 | __u64 xtime_tod_stamp; /* TOD clock for xtime 0x08 */ | 22 | __u64 xtime_tod_stamp; /* TOD clock for xtime 0x08 */ |
23 | __u64 xtime_clock_sec; /* Kernel time 0x10 */ | 23 | __u64 xtime_clock_sec; /* Kernel time 0x10 */ |
24 | __u64 xtime_clock_nsec; /* 0x18 */ | 24 | __u64 xtime_clock_nsec; /* 0x18 */ |
25 | __u64 wtom_clock_sec; /* Wall to monotonic clock 0x20 */ | 25 | __u64 xtime_coarse_sec; /* Coarse kernel time 0x20 */ |
26 | __u64 wtom_clock_nsec; /* 0x28 */ | 26 | __u64 xtime_coarse_nsec; /* 0x28 */ |
27 | __u32 tz_minuteswest; /* Minutes west of Greenwich 0x30 */ | 27 | __u64 wtom_clock_sec; /* Wall to monotonic clock 0x30 */ |
28 | __u32 tz_dsttime; /* Type of dst correction 0x34 */ | 28 | __u64 wtom_clock_nsec; /* 0x38 */ |
29 | __u32 ectg_available; /* ECTG instruction present 0x38 */ | 29 | __u64 wtom_coarse_sec; /* Coarse wall to monotonic 0x40 */ |
30 | __u32 tk_mult; /* Mult. used for xtime_nsec 0x3c */ | 30 | __u64 wtom_coarse_nsec; /* 0x48 */ |
31 | __u32 tk_shift; /* Shift used for xtime_nsec 0x40 */ | 31 | __u32 tz_minuteswest; /* Minutes west of Greenwich 0x50 */ |
32 | __u32 tz_dsttime; /* Type of dst correction 0x54 */ | ||
33 | __u32 ectg_available; /* ECTG instruction present 0x58 */ | ||
34 | __u32 tk_mult; /* Mult. used for xtime_nsec 0x5c */ | ||
35 | __u32 tk_shift; /* Shift used for xtime_nsec 0x60 */ | ||
32 | }; | 36 | }; |
33 | 37 | ||
34 | struct vdso_per_cpu_data { | 38 | struct vdso_per_cpu_data { |
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index afe1715a4eb7..3e9e479d9b49 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c | |||
@@ -62,8 +62,12 @@ int main(void) | |||
62 | DEFINE(__VDSO_XTIME_STAMP, offsetof(struct vdso_data, xtime_tod_stamp)); | 62 | DEFINE(__VDSO_XTIME_STAMP, offsetof(struct vdso_data, xtime_tod_stamp)); |
63 | DEFINE(__VDSO_XTIME_SEC, offsetof(struct vdso_data, xtime_clock_sec)); | 63 | DEFINE(__VDSO_XTIME_SEC, offsetof(struct vdso_data, xtime_clock_sec)); |
64 | DEFINE(__VDSO_XTIME_NSEC, offsetof(struct vdso_data, xtime_clock_nsec)); | 64 | DEFINE(__VDSO_XTIME_NSEC, offsetof(struct vdso_data, xtime_clock_nsec)); |
65 | DEFINE(__VDSO_XTIME_CRS_SEC, offsetof(struct vdso_data, xtime_coarse_sec)); | ||
66 | DEFINE(__VDSO_XTIME_CRS_NSEC, offsetof(struct vdso_data, xtime_coarse_nsec)); | ||
65 | DEFINE(__VDSO_WTOM_SEC, offsetof(struct vdso_data, wtom_clock_sec)); | 67 | DEFINE(__VDSO_WTOM_SEC, offsetof(struct vdso_data, wtom_clock_sec)); |
66 | DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec)); | 68 | DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec)); |
69 | DEFINE(__VDSO_WTOM_CRS_SEC, offsetof(struct vdso_data, wtom_coarse_sec)); | ||
70 | DEFINE(__VDSO_WTOM_CRS_NSEC, offsetof(struct vdso_data, wtom_coarse_nsec)); | ||
67 | DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest)); | 71 | DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest)); |
68 | DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available)); | 72 | DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available)); |
69 | DEFINE(__VDSO_TK_MULT, offsetof(struct vdso_data, tk_mult)); | 73 | DEFINE(__VDSO_TK_MULT, offsetof(struct vdso_data, tk_mult)); |
@@ -73,8 +77,11 @@ int main(void) | |||
73 | /* constants used by the vdso */ | 77 | /* constants used by the vdso */ |
74 | DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME); | 78 | DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME); |
75 | DEFINE(__CLOCK_MONOTONIC, CLOCK_MONOTONIC); | 79 | DEFINE(__CLOCK_MONOTONIC, CLOCK_MONOTONIC); |
80 | DEFINE(__CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE); | ||
81 | DEFINE(__CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE); | ||
76 | DEFINE(__CLOCK_THREAD_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID); | 82 | DEFINE(__CLOCK_THREAD_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID); |
77 | DEFINE(__CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC); | 83 | DEFINE(__CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC); |
84 | DEFINE(__CLOCK_COARSE_RES, LOW_RES_NSEC); | ||
78 | BLANK(); | 85 | BLANK(); |
79 | /* idle data offsets */ | 86 | /* idle data offsets */ |
80 | DEFINE(__CLOCK_IDLE_ENTER, offsetof(struct s390_idle_data, clock_idle_enter)); | 87 | DEFINE(__CLOCK_IDLE_ENTER, offsetof(struct s390_idle_data, clock_idle_enter)); |
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 4cef607f3711..69e980de0f62 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
@@ -232,6 +232,19 @@ void update_vsyscall(struct timekeeper *tk) | |||
232 | vdso_data->wtom_clock_nsec -= nsecps; | 232 | vdso_data->wtom_clock_nsec -= nsecps; |
233 | vdso_data->wtom_clock_sec++; | 233 | vdso_data->wtom_clock_sec++; |
234 | } | 234 | } |
235 | |||
236 | vdso_data->xtime_coarse_sec = tk->xtime_sec; | ||
237 | vdso_data->xtime_coarse_nsec = | ||
238 | (long)(tk->tkr.xtime_nsec >> tk->tkr.shift); | ||
239 | vdso_data->wtom_coarse_sec = | ||
240 | vdso_data->xtime_coarse_sec + tk->wall_to_monotonic.tv_sec; | ||
241 | vdso_data->wtom_coarse_nsec = | ||
242 | vdso_data->xtime_coarse_nsec + tk->wall_to_monotonic.tv_nsec; | ||
243 | while (vdso_data->wtom_coarse_nsec >= NSEC_PER_SEC) { | ||
244 | vdso_data->wtom_coarse_nsec -= NSEC_PER_SEC; | ||
245 | vdso_data->wtom_coarse_sec++; | ||
246 | } | ||
247 | |||
235 | vdso_data->tk_mult = tk->tkr.mult; | 248 | vdso_data->tk_mult = tk->tkr.mult; |
236 | vdso_data->tk_shift = tk->tkr.shift; | 249 | vdso_data->tk_shift = tk->tkr.shift; |
237 | smp_wmb(); | 250 | smp_wmb(); |
diff --git a/arch/s390/kernel/vdso32/clock_getres.S b/arch/s390/kernel/vdso32/clock_getres.S index 36aaa25d05da..eca3f001f081 100644 --- a/arch/s390/kernel/vdso32/clock_getres.S +++ b/arch/s390/kernel/vdso32/clock_getres.S | |||
@@ -19,14 +19,20 @@ | |||
19 | .type __kernel_clock_getres,@function | 19 | .type __kernel_clock_getres,@function |
20 | __kernel_clock_getres: | 20 | __kernel_clock_getres: |
21 | .cfi_startproc | 21 | .cfi_startproc |
22 | basr %r1,0 | ||
23 | la %r1,4f-.(%r1) | ||
22 | chi %r2,__CLOCK_REALTIME | 24 | chi %r2,__CLOCK_REALTIME |
23 | je 0f | 25 | je 0f |
24 | chi %r2,__CLOCK_MONOTONIC | 26 | chi %r2,__CLOCK_MONOTONIC |
27 | je 0f | ||
28 | la %r1,5f-4f(%r1) | ||
29 | chi %r2,__CLOCK_REALTIME_COARSE | ||
30 | je 0f | ||
31 | chi %r2,__CLOCK_MONOTONIC_COARSE | ||
25 | jne 3f | 32 | jne 3f |
26 | 0: ltr %r3,%r3 | 33 | 0: ltr %r3,%r3 |
27 | jz 2f /* res == NULL */ | 34 | jz 2f /* res == NULL */ |
28 | basr %r1,0 | 35 | 1: l %r0,0(%r1) |
29 | 1: l %r0,4f-1b(%r1) | ||
30 | xc 0(4,%r3),0(%r3) /* set tp->tv_sec to zero */ | 36 | xc 0(4,%r3),0(%r3) /* set tp->tv_sec to zero */ |
31 | st %r0,4(%r3) /* store tp->tv_usec */ | 37 | st %r0,4(%r3) /* store tp->tv_usec */ |
32 | 2: lhi %r2,0 | 38 | 2: lhi %r2,0 |
@@ -35,5 +41,6 @@ __kernel_clock_getres: | |||
35 | svc 0 | 41 | svc 0 |
36 | br %r14 | 42 | br %r14 |
37 | 4: .long __CLOCK_REALTIME_RES | 43 | 4: .long __CLOCK_REALTIME_RES |
44 | 5: .long __CLOCK_COARSE_RES | ||
38 | .cfi_endproc | 45 | .cfi_endproc |
39 | .size __kernel_clock_getres,.-__kernel_clock_getres | 46 | .size __kernel_clock_getres,.-__kernel_clock_getres |
diff --git a/arch/s390/kernel/vdso32/clock_gettime.S b/arch/s390/kernel/vdso32/clock_gettime.S index 4e20a9365bb7..48c2206a3956 100644 --- a/arch/s390/kernel/vdso32/clock_gettime.S +++ b/arch/s390/kernel/vdso32/clock_gettime.S | |||
@@ -21,8 +21,12 @@ __kernel_clock_gettime: | |||
21 | .cfi_startproc | 21 | .cfi_startproc |
22 | basr %r5,0 | 22 | basr %r5,0 |
23 | 0: al %r5,21f-0b(%r5) /* get &_vdso_data */ | 23 | 0: al %r5,21f-0b(%r5) /* get &_vdso_data */ |
24 | chi %r2,__CLOCK_REALTIME_COARSE | ||
25 | je 10f | ||
24 | chi %r2,__CLOCK_REALTIME | 26 | chi %r2,__CLOCK_REALTIME |
25 | je 11f | 27 | je 11f |
28 | chi %r2,__CLOCK_MONOTONIC_COARSE | ||
29 | je 9f | ||
26 | chi %r2,__CLOCK_MONOTONIC | 30 | chi %r2,__CLOCK_MONOTONIC |
27 | jne 19f | 31 | jne 19f |
28 | 32 | ||
@@ -68,6 +72,26 @@ __kernel_clock_gettime: | |||
68 | lhi %r2,0 | 72 | lhi %r2,0 |
69 | br %r14 | 73 | br %r14 |
70 | 74 | ||
75 | /* CLOCK_MONOTONIC_COARSE */ | ||
76 | 9: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ | ||
77 | tml %r4,0x0001 /* pending update ? loop */ | ||
78 | jnz 9b | ||
79 | l %r2,__VDSO_WTOM_CRS_SEC+4(%r5) | ||
80 | l %r1,__VDSO_WTOM_CRS_NSEC+4(%r5) | ||
81 | cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ | ||
82 | jne 9b | ||
83 | j 8b | ||
84 | |||
85 | /* CLOCK_REALTIME_COARSE */ | ||
86 | 10: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ | ||
87 | tml %r4,0x0001 /* pending update ? loop */ | ||
88 | jnz 10b | ||
89 | l %r2,__VDSO_XTIME_CRS_SEC+4(%r5) | ||
90 | l %r1,__VDSO_XTIME_CRS_NSEC+4(%r5) | ||
91 | cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ | ||
92 | jne 10b | ||
93 | j 17f | ||
94 | |||
71 | /* CLOCK_REALTIME */ | 95 | /* CLOCK_REALTIME */ |
72 | 11: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ | 96 | 11: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ |
73 | tml %r4,0x0001 /* pending update ? loop */ | 97 | tml %r4,0x0001 /* pending update ? loop */ |
diff --git a/arch/s390/kernel/vdso64/clock_getres.S b/arch/s390/kernel/vdso64/clock_getres.S index 34deba7c7ed1..c8513deb8c66 100644 --- a/arch/s390/kernel/vdso64/clock_getres.S +++ b/arch/s390/kernel/vdso64/clock_getres.S | |||
@@ -19,6 +19,12 @@ | |||
19 | .type __kernel_clock_getres,@function | 19 | .type __kernel_clock_getres,@function |
20 | __kernel_clock_getres: | 20 | __kernel_clock_getres: |
21 | .cfi_startproc | 21 | .cfi_startproc |
22 | larl %r1,4f | ||
23 | cghi %r2,__CLOCK_REALTIME_COARSE | ||
24 | je 0f | ||
25 | cghi %r2,__CLOCK_MONOTONIC_COARSE | ||
26 | je 0f | ||
27 | larl %r1,3f | ||
22 | cghi %r2,__CLOCK_REALTIME | 28 | cghi %r2,__CLOCK_REALTIME |
23 | je 0f | 29 | je 0f |
24 | cghi %r2,__CLOCK_MONOTONIC | 30 | cghi %r2,__CLOCK_MONOTONIC |
@@ -32,7 +38,6 @@ __kernel_clock_getres: | |||
32 | jz 2f | 38 | jz 2f |
33 | 0: ltgr %r3,%r3 | 39 | 0: ltgr %r3,%r3 |
34 | jz 1f /* res == NULL */ | 40 | jz 1f /* res == NULL */ |
35 | larl %r1,3f | ||
36 | lg %r0,0(%r1) | 41 | lg %r0,0(%r1) |
37 | xc 0(8,%r3),0(%r3) /* set tp->tv_sec to zero */ | 42 | xc 0(8,%r3),0(%r3) /* set tp->tv_sec to zero */ |
38 | stg %r0,8(%r3) /* store tp->tv_usec */ | 43 | stg %r0,8(%r3) /* store tp->tv_usec */ |
@@ -42,5 +47,6 @@ __kernel_clock_getres: | |||
42 | svc 0 | 47 | svc 0 |
43 | br %r14 | 48 | br %r14 |
44 | 3: .quad __CLOCK_REALTIME_RES | 49 | 3: .quad __CLOCK_REALTIME_RES |
50 | 4: .quad __CLOCK_COARSE_RES | ||
45 | .cfi_endproc | 51 | .cfi_endproc |
46 | .size __kernel_clock_getres,.-__kernel_clock_getres | 52 | .size __kernel_clock_getres,.-__kernel_clock_getres |
diff --git a/arch/s390/kernel/vdso64/clock_gettime.S b/arch/s390/kernel/vdso64/clock_gettime.S index 4add40b78ed5..9d9761f8e110 100644 --- a/arch/s390/kernel/vdso64/clock_gettime.S +++ b/arch/s390/kernel/vdso64/clock_gettime.S | |||
@@ -20,12 +20,16 @@ | |||
20 | __kernel_clock_gettime: | 20 | __kernel_clock_gettime: |
21 | .cfi_startproc | 21 | .cfi_startproc |
22 | larl %r5,_vdso_data | 22 | larl %r5,_vdso_data |
23 | cghi %r2,__CLOCK_REALTIME_COARSE | ||
24 | je 4f | ||
23 | cghi %r2,__CLOCK_REALTIME | 25 | cghi %r2,__CLOCK_REALTIME |
24 | je 5f | 26 | je 5f |
25 | cghi %r2,__CLOCK_THREAD_CPUTIME_ID | 27 | cghi %r2,__CLOCK_THREAD_CPUTIME_ID |
26 | je 9f | 28 | je 9f |
27 | cghi %r2,-2 /* Per-thread CPUCLOCK with PID=0, VIRT=1 */ | 29 | cghi %r2,-2 /* Per-thread CPUCLOCK with PID=0, VIRT=1 */ |
28 | je 9f | 30 | je 9f |
31 | cghi %r2,__CLOCK_MONOTONIC_COARSE | ||
32 | je 3f | ||
29 | cghi %r2,__CLOCK_MONOTONIC | 33 | cghi %r2,__CLOCK_MONOTONIC |
30 | jne 12f | 34 | jne 12f |
31 | 35 | ||
@@ -54,6 +58,26 @@ __kernel_clock_gettime: | |||
54 | lghi %r2,0 | 58 | lghi %r2,0 |
55 | br %r14 | 59 | br %r14 |
56 | 60 | ||
61 | /* CLOCK_MONOTONIC_COARSE */ | ||
62 | 3: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ | ||
63 | tmll %r4,0x0001 /* pending update ? loop */ | ||
64 | jnz 3b | ||
65 | lg %r0,__VDSO_WTOM_CRS_SEC(%r5) | ||
66 | lg %r1,__VDSO_WTOM_CRS_NSEC(%r5) | ||
67 | clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ | ||
68 | jne 3b | ||
69 | j 2b | ||
70 | |||
71 | /* CLOCK_REALTIME_COARSE */ | ||
72 | 4: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ | ||
73 | tmll %r4,0x0001 /* pending update ? loop */ | ||
74 | jnz 4b | ||
75 | lg %r0,__VDSO_XTIME_CRS_SEC(%r5) | ||
76 | lg %r1,__VDSO_XTIME_CRS_NSEC(%r5) | ||
77 | clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ | ||
78 | jne 4b | ||
79 | j 7f | ||
80 | |||
57 | /* CLOCK_REALTIME */ | 81 | /* CLOCK_REALTIME */ |
58 | 5: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ | 82 | 5: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ |
59 | tmll %r4,0x0001 /* pending update ? loop */ | 83 | tmll %r4,0x0001 /* pending update ? loop */ |