History

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

Linus Torvalds committed 12 years ago

Commit 033dbbd2 parents dc418f6 127581b14 files · +87 −88Browse files

Unified · Split

14 files
  1. arch/s390/Kconfig +1 −1
  2. arch/s390/include/asm/page.h +13 −25
  3. arch/s390/include/asm/vdso.h +3 −2
  4. arch/s390/kernel/asm-offsets.c +2 −1
  5. arch/s390/kernel/compat_signal.c +1 −1
  6. arch/s390/kernel/pgm_check.S +1 −1
  7. arch/s390/kernel/signal.c +1 −1
  8. arch/s390/kernel/time.c +22 −24
  9. arch/s390/kernel/vdso32/clock_gettime.S +16 −14
  10. arch/s390/kernel/vdso32/gettimeofday.S +5 −4
  11. arch/s390/kernel/vdso64/clock_gettime.S +12 −10
  12. arch/s390/kernel/vdso64/gettimeofday.S +5 −4
  13. arch/s390/lib/uaccess_pt.c +3 −0
  14. drivers/s390/block/dasd_eckd.c +2 −0
arch/s390/Kconfig+1−1
@@ -101,7 +101,7 @@ config S390 · 100 unmodified lines
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+13−25
@@ -48,33 +48,21 @@ static inline void clear_page(void *page) · 47 unmodified lines
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+3−2
@@ -26,8 +26,9 @@ struct vdso_data { · 25 unmodified lines
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+2−1
@@ -65,7 +65,8 @@ int main(void) · 64 unmodified lines
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+1−1
@@ -194,7 +194,7 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) · 193 unmodified lines
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+1−1
@@ -78,7 +78,7 @@ PGM_CHECK_DEFAULT /* 34 */ · 77 unmodified lines
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+1−1
@@ -94,7 +94,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) · 93 unmodified lines
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+22−24
@@ -108,20 +108,10 @@ static void fixup_clock_comparator(unsigned long long delta) · 107 unmodified lines
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) · 18 unmodified lines
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) · 60 unmodified lines
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+16−14
@@ -38,25 +38,26 @@ __kernel_clock_gettime: · 37 unmodified lines
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: · 23 unmodified lines
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+5−4
@@ -35,15 +35,14 @@ __kernel_gettimeofday: · 34 unmodified lines
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
@@ -51,6 +50,8 @@ __kernel_gettimeofday: · 1 unmodified line
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+12−10
@@ -34,14 +34,15 @@ __kernel_clock_gettime: · 33 unmodified lines
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: · 14 unmodified lines
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+5−4
@@ -31,12 +31,13 @@ __kernel_gettimeofday: · 30 unmodified lines
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+3−0
@@ -78,11 +78,14 @@ static size_t copy_in_kernel(size_t count, void __user *to, · 77 unmodified lines
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+2−0
@@ -3224,6 +3224,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev, · 3223 unmodified lines
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;