Skip to content

Commit 033dbbd

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky: "One performance improvement and a few bug fixes. Two of the fixes deal with the clock related problems we have seen on recent kernels" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/mm: handle asce-type exceptions as normal page fault s390,time: revert direct ktime path for s390 clockevent device s390/time,vdso: convert to the new update_vsyscall interface s390/uaccess: add missing page table walk range check s390/mm: optimize copy_page s390/dasd: validate request size before building CCW/TCW request s390/signal: always restore saved runtime instrumentation psw bit
2 parents dc418f6 + 127581b commit 033dbbd

File tree

14 files changed

+87
-88
lines changed

14 files changed

+87
-88
lines changed

arch/s390/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ config S390
101101
select GENERIC_CPU_DEVICES if !SMP
102102
select GENERIC_FIND_FIRST_BIT
103103
select GENERIC_SMP_IDLE_THREAD
104-
select GENERIC_TIME_VSYSCALL_OLD
104+
select GENERIC_TIME_VSYSCALL
105105
select HAVE_ALIGNED_STRUCT_PAGE if SLUB
106106
select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
107107
select HAVE_ARCH_SECCOMP_FILTER

arch/s390/include/asm/page.h

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -48,33 +48,21 @@ static inline void clear_page(void *page)
4848
: "memory", "cc");
4949
}
5050

51+
/*
52+
* copy_page uses the mvcl instruction with 0xb0 padding byte in order to
53+
* bypass caches when copying a page. Especially when copying huge pages
54+
* this keeps L1 and L2 data caches alive.
55+
*/
5156
static inline void copy_page(void *to, void *from)
5257
{
53-
if (MACHINE_HAS_MVPG) {
54-
register unsigned long reg0 asm ("0") = 0;
55-
asm volatile(
56-
" mvpg %0,%1"
57-
: : "a" (to), "a" (from), "d" (reg0)
58-
: "memory", "cc");
59-
} else
60-
asm volatile(
61-
" mvc 0(256,%0),0(%1)\n"
62-
" mvc 256(256,%0),256(%1)\n"
63-
" mvc 512(256,%0),512(%1)\n"
64-
" mvc 768(256,%0),768(%1)\n"
65-
" mvc 1024(256,%0),1024(%1)\n"
66-
" mvc 1280(256,%0),1280(%1)\n"
67-
" mvc 1536(256,%0),1536(%1)\n"
68-
" mvc 1792(256,%0),1792(%1)\n"
69-
" mvc 2048(256,%0),2048(%1)\n"
70-
" mvc 2304(256,%0),2304(%1)\n"
71-
" mvc 2560(256,%0),2560(%1)\n"
72-
" mvc 2816(256,%0),2816(%1)\n"
73-
" mvc 3072(256,%0),3072(%1)\n"
74-
" mvc 3328(256,%0),3328(%1)\n"
75-
" mvc 3584(256,%0),3584(%1)\n"
76-
" mvc 3840(256,%0),3840(%1)\n"
77-
: : "a" (to), "a" (from) : "memory");
58+
register void *reg2 asm ("2") = to;
59+
register unsigned long reg3 asm ("3") = 0x1000;
60+
register void *reg4 asm ("4") = from;
61+
register unsigned long reg5 asm ("5") = 0xb0001000;
62+
asm volatile(
63+
" mvcl 2,4"
64+
: "+d" (reg2), "+d" (reg3), "+d" (reg4), "+d" (reg5)
65+
: : "memory", "cc");
7866
}
7967

8068
#define clear_user_page(page, vaddr, pg) clear_page(page)

arch/s390/include/asm/vdso.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ struct vdso_data {
2626
__u64 wtom_clock_nsec; /* 0x28 */
2727
__u32 tz_minuteswest; /* Minutes west of Greenwich 0x30 */
2828
__u32 tz_dsttime; /* Type of dst correction 0x34 */
29-
__u32 ectg_available;
30-
__u32 ntp_mult; /* NTP adjusted multiplier 0x3C */
29+
__u32 ectg_available; /* ECTG instruction present 0x38 */
30+
__u32 tk_mult; /* Mult. used for xtime_nsec 0x3c */
31+
__u32 tk_shift; /* Shift used for xtime_nsec 0x40 */
3132
};
3233

3334
struct vdso_per_cpu_data {

arch/s390/kernel/asm-offsets.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ int main(void)
6565
DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
6666
DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest));
6767
DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available));
68-
DEFINE(__VDSO_NTP_MULT, offsetof(struct vdso_data, ntp_mult));
68+
DEFINE(__VDSO_TK_MULT, offsetof(struct vdso_data, tk_mult));
69+
DEFINE(__VDSO_TK_SHIFT, offsetof(struct vdso_data, tk_shift));
6970
DEFINE(__VDSO_ECTG_BASE, offsetof(struct vdso_per_cpu_data, ectg_timer_base));
7071
DEFINE(__VDSO_ECTG_USER, offsetof(struct vdso_per_cpu_data, ectg_user_time));
7172
/* constants used by the vdso */

arch/s390/kernel/compat_signal.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
194194
return -EINVAL;
195195

196196
/* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
197-
regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
197+
regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) |
198198
(__u64)(user_sregs.regs.psw.mask & PSW32_MASK_USER) << 32 |
199199
(__u64)(user_sregs.regs.psw.mask & PSW32_MASK_RI) << 32 |
200200
(__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_AMODE);

arch/s390/kernel/pgm_check.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ PGM_CHECK_DEFAULT /* 34 */
7878
PGM_CHECK_DEFAULT /* 35 */
7979
PGM_CHECK_DEFAULT /* 36 */
8080
PGM_CHECK_DEFAULT /* 37 */
81-
PGM_CHECK_DEFAULT /* 38 */
81+
PGM_CHECK_64BIT(do_dat_exception) /* 38 */
8282
PGM_CHECK_64BIT(do_dat_exception) /* 39 */
8383
PGM_CHECK_64BIT(do_dat_exception) /* 3a */
8484
PGM_CHECK_64BIT(do_dat_exception) /* 3b */

arch/s390/kernel/signal.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
9494
return -EINVAL;
9595

9696
/* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
97-
regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
97+
regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) |
9898
(user_sregs.regs.psw.mask & (PSW_MASK_USER | PSW_MASK_RI));
9999
/* Check for invalid user address space control. */
100100
if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME)

arch/s390/kernel/time.c

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -108,20 +108,10 @@ static void fixup_clock_comparator(unsigned long long delta)
108108
set_clock_comparator(S390_lowcore.clock_comparator);
109109
}
110110

111-
static int s390_next_ktime(ktime_t expires,
111+
static int s390_next_event(unsigned long delta,
112112
struct clock_event_device *evt)
113113
{
114-
struct timespec ts;
115-
u64 nsecs;
116-
117-
ts.tv_sec = ts.tv_nsec = 0;
118-
monotonic_to_bootbased(&ts);
119-
nsecs = ktime_to_ns(ktime_add(timespec_to_ktime(ts), expires));
120-
do_div(nsecs, 125);
121-
S390_lowcore.clock_comparator = sched_clock_base_cc + (nsecs << 9);
122-
/* Program the maximum value if we have an overflow (== year 2042) */
123-
if (unlikely(S390_lowcore.clock_comparator < sched_clock_base_cc))
124-
S390_lowcore.clock_comparator = -1ULL;
114+
S390_lowcore.clock_comparator = get_tod_clock() + delta;
125115
set_clock_comparator(S390_lowcore.clock_comparator);
126116
return 0;
127117
}
@@ -146,15 +136,14 @@ void init_cpu_timer(void)
146136
cpu = smp_processor_id();
147137
cd = &per_cpu(comparators, cpu);
148138
cd->name = "comparator";
149-
cd->features = CLOCK_EVT_FEAT_ONESHOT |
150-
CLOCK_EVT_FEAT_KTIME;
139+
cd->features = CLOCK_EVT_FEAT_ONESHOT;
151140
cd->mult = 16777;
152141
cd->shift = 12;
153142
cd->min_delta_ns = 1;
154143
cd->max_delta_ns = LONG_MAX;
155144
cd->rating = 400;
156145
cd->cpumask = cpumask_of(cpu);
157-
cd->set_next_ktime = s390_next_ktime;
146+
cd->set_next_event = s390_next_event;
158147
cd->set_mode = s390_set_mode;
159148

160149
clockevents_register_device(cd);
@@ -221,21 +210,30 @@ struct clocksource * __init clocksource_default_clock(void)
221210
return &clocksource_tod;
222211
}
223212

224-
void update_vsyscall_old(struct timespec *wall_time, struct timespec *wtm,
225-
struct clocksource *clock, u32 mult)
213+
void update_vsyscall(struct timekeeper *tk)
226214
{
227-
if (clock != &clocksource_tod)
215+
u64 nsecps;
216+
217+
if (tk->clock != &clocksource_tod)
228218
return;
229219

230220
/* Make userspace gettimeofday spin until we're done. */
231221
++vdso_data->tb_update_count;
232222
smp_wmb();
233-
vdso_data->xtime_tod_stamp = clock->cycle_last;
234-
vdso_data->xtime_clock_sec = wall_time->tv_sec;
235-
vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
236-
vdso_data->wtom_clock_sec = wtm->tv_sec;
237-
vdso_data->wtom_clock_nsec = wtm->tv_nsec;
238-
vdso_data->ntp_mult = mult;
223+
vdso_data->xtime_tod_stamp = tk->clock->cycle_last;
224+
vdso_data->xtime_clock_sec = tk->xtime_sec;
225+
vdso_data->xtime_clock_nsec = tk->xtime_nsec;
226+
vdso_data->wtom_clock_sec =
227+
tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
228+
vdso_data->wtom_clock_nsec = tk->xtime_nsec +
229+
+ (tk->wall_to_monotonic.tv_nsec << tk->shift);
230+
nsecps = (u64) NSEC_PER_SEC << tk->shift;
231+
while (vdso_data->wtom_clock_nsec >= nsecps) {
232+
vdso_data->wtom_clock_nsec -= nsecps;
233+
vdso_data->wtom_clock_sec++;
234+
}
235+
vdso_data->tk_mult = tk->mult;
236+
vdso_data->tk_shift = tk->shift;
239237
smp_wmb();
240238
++vdso_data->tb_update_count;
241239
}

arch/s390/kernel/vdso32/clock_gettime.S

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,25 +38,26 @@ __kernel_clock_gettime:
3838
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
3939
brc 3,2f
4040
ahi %r0,-1
41-
2: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
41+
2: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */
4242
lr %r2,%r0
43-
l %r0,__VDSO_NTP_MULT(%r5)
43+
l %r0,__VDSO_TK_MULT(%r5)
4444
ltr %r1,%r1
4545
mr %r0,%r0
4646
jnm 3f
47-
a %r0,__VDSO_NTP_MULT(%r5)
47+
a %r0,__VDSO_TK_MULT(%r5)
4848
3: alr %r0,%r2
49-
srdl %r0,12
50-
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
49+
al %r0,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
5150
al %r1,__VDSO_XTIME_NSEC+4(%r5)
5251
brc 12,4f
5352
ahi %r0,1
54-
4: l %r2,__VDSO_XTIME_SEC+4(%r5)
55-
al %r0,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic */
53+
4: al %r0,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic.nsec */
5654
al %r1,__VDSO_WTOM_NSEC+4(%r5)
5755
brc 12,5f
5856
ahi %r0,1
59-
5: al %r2,__VDSO_WTOM_SEC+4(%r5)
57+
5: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
58+
srdl %r0,0(%r2) /* >> tk->shift */
59+
l %r2,__VDSO_XTIME_SEC+4(%r5)
60+
al %r2,__VDSO_WTOM_SEC+4(%r5)
6061
cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
6162
jne 1b
6263
basr %r5,0
@@ -86,20 +87,21 @@ __kernel_clock_gettime:
8687
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
8788
brc 3,12f
8889
ahi %r0,-1
89-
12: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
90+
12: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */
9091
lr %r2,%r0
91-
l %r0,__VDSO_NTP_MULT(%r5)
92+
l %r0,__VDSO_TK_MULT(%r5)
9293
ltr %r1,%r1
9394
mr %r0,%r0
9495
jnm 13f
95-
a %r0,__VDSO_NTP_MULT(%r5)
96+
a %r0,__VDSO_TK_MULT(%r5)
9697
13: alr %r0,%r2
97-
srdl %r0,12
98-
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
98+
al %r0,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
9999
al %r1,__VDSO_XTIME_NSEC+4(%r5)
100100
brc 12,14f
101101
ahi %r0,1
102-
14: l %r2,__VDSO_XTIME_SEC+4(%r5)
102+
14: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
103+
srdl %r0,0(%r2) /* >> tk->shift */
104+
l %r2,__VDSO_XTIME_SEC+4(%r5)
103105
cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
104106
jne 11b
105107
basr %r5,0

arch/s390/kernel/vdso32/gettimeofday.S

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,23 @@ __kernel_gettimeofday:
3535
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
3636
brc 3,3f
3737
ahi %r0,-1
38-
3: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
38+
3: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */
3939
st %r0,24(%r15)
40-
l %r0,__VDSO_NTP_MULT(%r5)
40+
l %r0,__VDSO_TK_MULT(%r5)
4141
ltr %r1,%r1
4242
mr %r0,%r0
4343
jnm 4f
44-
a %r0,__VDSO_NTP_MULT(%r5)
44+
a %r0,__VDSO_TK_MULT(%r5)
4545
4: al %r0,24(%r15)
46-
srdl %r0,12
4746
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
4847
al %r1,__VDSO_XTIME_NSEC+4(%r5)
4948
brc 12,5f
5049
ahi %r0,1
5150
5: mvc 24(4,%r15),__VDSO_XTIME_SEC+4(%r5)
5251
cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
5352
jne 1b
53+
l %r4,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
54+
srdl %r0,0(%r4) /* >> tk->shift */
5455
l %r4,24(%r15) /* get tv_sec from stack */
5556
basr %r5,0
5657
6: ltr %r0,%r0

arch/s390/kernel/vdso64/clock_gettime.S

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,15 @@ __kernel_clock_gettime:
3434
tmll %r4,0x0001 /* pending update ? loop */
3535
jnz 0b
3636
stck 48(%r15) /* Store TOD clock */
37+
lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
38+
lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */
39+
alg %r0,__VDSO_WTOM_SEC(%r5) /* + wall_to_monotonic.sec */
3740
lg %r1,48(%r15)
3841
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
39-
msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
40-
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
41-
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */
42-
lg %r0,__VDSO_XTIME_SEC(%r5)
43-
alg %r1,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic */
44-
alg %r0,__VDSO_WTOM_SEC(%r5)
42+
msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */
43+
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
44+
alg %r1,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic.nsec */
45+
srlg %r1,%r1,0(%r2) /* >> tk->shift */
4546
clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */
4647
jne 0b
4748
larl %r5,13f
@@ -62,12 +63,13 @@ __kernel_clock_gettime:
6263
tmll %r4,0x0001 /* pending update ? loop */
6364
jnz 5b
6465
stck 48(%r15) /* Store TOD clock */
66+
lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
6567
lg %r1,48(%r15)
6668
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
67-
msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
68-
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
69-
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */
70-
lg %r0,__VDSO_XTIME_SEC(%r5)
69+
msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */
70+
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
71+
srlg %r1,%r1,0(%r2) /* >> tk->shift */
72+
lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */
7173
clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */
7274
jne 5b
7375
larl %r5,13f

arch/s390/kernel/vdso64/gettimeofday.S

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ __kernel_gettimeofday:
3131
stck 48(%r15) /* Store TOD clock */
3232
lg %r1,48(%r15)
3333
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
34-
msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
35-
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
36-
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime.tv_nsec */
37-
lg %r0,__VDSO_XTIME_SEC(%r5) /* xtime.tv_sec */
34+
msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */
35+
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
36+
lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */
3837
clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */
3938
jne 0b
39+
lgf %r5,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
40+
srlg %r1,%r1,0(%r5) /* >> tk->shift */
4041
larl %r5,5f
4142
2: clg %r1,0(%r5)
4243
jl 3f

arch/s390/lib/uaccess_pt.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,14 @@ static size_t copy_in_kernel(size_t count, void __user *to,
7878
* contains the (negative) exception code.
7979
*/
8080
#ifdef CONFIG_64BIT
81+
8182
static unsigned long follow_table(struct mm_struct *mm,
8283
unsigned long address, int write)
8384
{
8485
unsigned long *table = (unsigned long *)__pa(mm->pgd);
8586

87+
if (unlikely(address > mm->context.asce_limit - 1))
88+
return -0x38UL;
8689
switch (mm->context.asce_bits & _ASCE_TYPE_MASK) {
8790
case _ASCE_TYPE_REGION1:
8891
table = table + ((address >> 53) & 0x7ff);

drivers/s390/block/dasd_eckd.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3224,6 +3224,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
32243224

32253225
fcx_multitrack = private->features.feature[40] & 0x20;
32263226
data_size = blk_rq_bytes(req);
3227+
if (data_size % blksize)
3228+
return ERR_PTR(-EINVAL);
32273229
/* tpm write request add CBC data on each track boundary */
32283230
if (rq_data_dir(req) == WRITE)
32293231
data_size += (last_trk - first_trk) * 4;

0 commit comments

Comments
 (0)