diff options
-rw-r--r-- | arch/s390/include/asm/futex.h | 6 | ||||
-rw-r--r-- | arch/s390/include/asm/pgtable.h | 2 | ||||
-rw-r--r-- | arch/s390/include/asm/uaccess.h | 23 | ||||
-rw-r--r-- | arch/s390/kernel/compat_signal.c | 14 | ||||
-rw-r--r-- | arch/s390/kernel/dis.c | 4 | ||||
-rw-r--r-- | arch/s390/kernel/module.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/signal.c | 8 | ||||
-rw-r--r-- | arch/s390/lib/uaccess_mvcos.c | 26 | ||||
-rw-r--r-- | arch/s390/lib/uaccess_pt.c | 129 | ||||
-rw-r--r-- | arch/s390/lib/uaccess_std.c | 48 | ||||
-rw-r--r-- | arch/s390/mm/dump_pagetables.c | 25 | ||||
-rw-r--r-- | arch/s390/mm/vmem.c | 3 | ||||
-rw-r--r-- | drivers/input/serio/Kconfig | 2 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 10 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_debug.c | 9 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_debug.h | 3 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_main.c | 2 |
17 files changed, 172 insertions, 144 deletions
diff --git a/arch/s390/include/asm/futex.h b/arch/s390/include/asm/futex.h index 96bc83ea5c90..51bcaa0fdeef 100644 --- a/arch/s390/include/asm/futex.h +++ b/arch/s390/include/asm/futex.h | |||
@@ -16,9 +16,6 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | |||
16 | if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | 16 | if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) |
17 | oparg = 1 << oparg; | 17 | oparg = 1 << oparg; |
18 | 18 | ||
19 | if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) | ||
20 | return -EFAULT; | ||
21 | |||
22 | pagefault_disable(); | 19 | pagefault_disable(); |
23 | ret = uaccess.futex_atomic_op(op, uaddr, oparg, &oldval); | 20 | ret = uaccess.futex_atomic_op(op, uaddr, oparg, &oldval); |
24 | pagefault_enable(); | 21 | pagefault_enable(); |
@@ -40,9 +37,6 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | |||
40 | static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | 37 | static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, |
41 | u32 oldval, u32 newval) | 38 | u32 oldval, u32 newval) |
42 | { | 39 | { |
43 | if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) | ||
44 | return -EFAULT; | ||
45 | |||
46 | return uaccess.futex_atomic_cmpxchg(uval, uaddr, oldval, newval); | 40 | return uaccess.futex_atomic_cmpxchg(uval, uaddr, oldval, newval); |
47 | } | 41 | } |
48 | 42 | ||
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 97de1200c849..4a2930844d43 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -340,6 +340,8 @@ extern unsigned long MODULES_END; | |||
340 | #define _REGION3_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INV) | 340 | #define _REGION3_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INV) |
341 | 341 | ||
342 | #define _REGION3_ENTRY_LARGE 0x400 /* RTTE-format control, large page */ | 342 | #define _REGION3_ENTRY_LARGE 0x400 /* RTTE-format control, large page */ |
343 | #define _REGION3_ENTRY_RO 0x200 /* page protection bit */ | ||
344 | #define _REGION3_ENTRY_CO 0x100 /* change-recording override */ | ||
343 | 345 | ||
344 | /* Bits in the segment table entry */ | 346 | /* Bits in the segment table entry */ |
345 | #define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */ | 347 | #define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */ |
diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h index 34268df959a3..9c33ed4e666f 100644 --- a/arch/s390/include/asm/uaccess.h +++ b/arch/s390/include/asm/uaccess.h | |||
@@ -252,9 +252,7 @@ static inline unsigned long __must_check | |||
252 | copy_to_user(void __user *to, const void *from, unsigned long n) | 252 | copy_to_user(void __user *to, const void *from, unsigned long n) |
253 | { | 253 | { |
254 | might_fault(); | 254 | might_fault(); |
255 | if (access_ok(VERIFY_WRITE, to, n)) | 255 | return __copy_to_user(to, from, n); |
256 | n = __copy_to_user(to, from, n); | ||
257 | return n; | ||
258 | } | 256 | } |
259 | 257 | ||
260 | /** | 258 | /** |
@@ -315,11 +313,7 @@ copy_from_user(void *to, const void __user *from, unsigned long n) | |||
315 | copy_from_user_overflow(); | 313 | copy_from_user_overflow(); |
316 | return n; | 314 | return n; |
317 | } | 315 | } |
318 | if (access_ok(VERIFY_READ, from, n)) | 316 | return __copy_from_user(to, from, n); |
319 | n = __copy_from_user(to, from, n); | ||
320 | else | ||
321 | memset(to, 0, n); | ||
322 | return n; | ||
323 | } | 317 | } |
324 | 318 | ||
325 | static inline unsigned long __must_check | 319 | static inline unsigned long __must_check |
@@ -332,9 +326,7 @@ static inline unsigned long __must_check | |||
332 | copy_in_user(void __user *to, const void __user *from, unsigned long n) | 326 | copy_in_user(void __user *to, const void __user *from, unsigned long n) |
333 | { | 327 | { |
334 | might_fault(); | 328 | might_fault(); |
335 | if (__access_ok(from,n) && __access_ok(to,n)) | 329 | return __copy_in_user(to, from, n); |
336 | n = __copy_in_user(to, from, n); | ||
337 | return n; | ||
338 | } | 330 | } |
339 | 331 | ||
340 | /* | 332 | /* |
@@ -343,11 +335,8 @@ copy_in_user(void __user *to, const void __user *from, unsigned long n) | |||
343 | static inline long __must_check | 335 | static inline long __must_check |
344 | strncpy_from_user(char *dst, const char __user *src, long count) | 336 | strncpy_from_user(char *dst, const char __user *src, long count) |
345 | { | 337 | { |
346 | long res = -EFAULT; | ||
347 | might_fault(); | 338 | might_fault(); |
348 | if (access_ok(VERIFY_READ, src, 1)) | 339 | return uaccess.strncpy_from_user(count, src, dst); |
349 | res = uaccess.strncpy_from_user(count, src, dst); | ||
350 | return res; | ||
351 | } | 340 | } |
352 | 341 | ||
353 | static inline unsigned long | 342 | static inline unsigned long |
@@ -387,9 +376,7 @@ static inline unsigned long __must_check | |||
387 | clear_user(void __user *to, unsigned long n) | 376 | clear_user(void __user *to, unsigned long n) |
388 | { | 377 | { |
389 | might_fault(); | 378 | might_fault(); |
390 | if (access_ok(VERIFY_WRITE, to, n)) | 379 | return uaccess.clear_user(n, to); |
391 | n = uaccess.clear_user(n, to); | ||
392 | return n; | ||
393 | } | 380 | } |
394 | 381 | ||
395 | extern int copy_to_user_real(void __user *dest, void *src, size_t count); | 382 | extern int copy_to_user_real(void __user *dest, void *src, size_t count); |
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index 3e71194c1902..6de049fbe62d 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c | |||
@@ -53,9 +53,6 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) | |||
53 | { | 53 | { |
54 | int err; | 54 | int err; |
55 | 55 | ||
56 | if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t))) | ||
57 | return -EFAULT; | ||
58 | |||
59 | /* If you change siginfo_t structure, please be sure | 56 | /* If you change siginfo_t structure, please be sure |
60 | this code is fixed accordingly. | 57 | this code is fixed accordingly. |
61 | It should never copy any pad contained in the structure | 58 | It should never copy any pad contained in the structure |
@@ -110,9 +107,6 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) | |||
110 | int err; | 107 | int err; |
111 | u32 tmp; | 108 | u32 tmp; |
112 | 109 | ||
113 | if (!access_ok (VERIFY_READ, from, sizeof(compat_siginfo_t))) | ||
114 | return -EFAULT; | ||
115 | |||
116 | err = __get_user(to->si_signo, &from->si_signo); | 110 | err = __get_user(to->si_signo, &from->si_signo); |
117 | err |= __get_user(to->si_errno, &from->si_errno); | 111 | err |= __get_user(to->si_errno, &from->si_errno); |
118 | err |= __get_user(to->si_code, &from->si_code); | 112 | err |= __get_user(to->si_code, &from->si_code); |
@@ -244,8 +238,6 @@ asmlinkage long sys32_sigreturn(void) | |||
244 | sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15]; | 238 | sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15]; |
245 | sigset_t set; | 239 | sigset_t set; |
246 | 240 | ||
247 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | ||
248 | goto badframe; | ||
249 | if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32)) | 241 | if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32)) |
250 | goto badframe; | 242 | goto badframe; |
251 | set_current_blocked(&set); | 243 | set_current_blocked(&set); |
@@ -265,8 +257,6 @@ asmlinkage long sys32_rt_sigreturn(void) | |||
265 | rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15]; | 257 | rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15]; |
266 | sigset_t set; | 258 | sigset_t set; |
267 | 259 | ||
268 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | ||
269 | goto badframe; | ||
270 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) | 260 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) |
271 | goto badframe; | 261 | goto badframe; |
272 | set_current_blocked(&set); | 262 | set_current_blocked(&set); |
@@ -325,8 +315,6 @@ static int setup_frame32(int sig, struct k_sigaction *ka, | |||
325 | sigset_t *set, struct pt_regs * regs) | 315 | sigset_t *set, struct pt_regs * regs) |
326 | { | 316 | { |
327 | sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(sigframe32)); | 317 | sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(sigframe32)); |
328 | if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe32))) | ||
329 | goto give_sigsegv; | ||
330 | 318 | ||
331 | if (frame == (void __user *) -1UL) | 319 | if (frame == (void __user *) -1UL) |
332 | goto give_sigsegv; | 320 | goto give_sigsegv; |
@@ -391,8 +379,6 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
391 | { | 379 | { |
392 | int err = 0; | 380 | int err = 0; |
393 | rt_sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32)); | 381 | rt_sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32)); |
394 | if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe32))) | ||
395 | goto give_sigsegv; | ||
396 | 382 | ||
397 | if (frame == (void __user *) -1UL) | 383 | if (frame == (void __user *) -1UL) |
398 | goto give_sigsegv; | 384 | goto give_sigsegv; |
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c index c50665fe9435..3ad5e9540160 100644 --- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c | |||
@@ -1711,10 +1711,10 @@ int insn_to_mnemonic(unsigned char *instruction, char buf[8]) | |||
1711 | if (!insn) | 1711 | if (!insn) |
1712 | return -ENOENT; | 1712 | return -ENOENT; |
1713 | if (insn->name[0] == '\0') | 1713 | if (insn->name[0] == '\0') |
1714 | snprintf(buf, sizeof(buf), "%s", | 1714 | snprintf(buf, 8, "%s", |
1715 | long_insn_name[(int) insn->name[1]]); | 1715 | long_insn_name[(int) insn->name[1]]); |
1716 | else | 1716 | else |
1717 | snprintf(buf, sizeof(buf), "%.5s", insn->name); | 1717 | snprintf(buf, 8, "%.5s", insn->name); |
1718 | return 0; | 1718 | return 0; |
1719 | } | 1719 | } |
1720 | EXPORT_SYMBOL_GPL(insn_to_mnemonic); | 1720 | EXPORT_SYMBOL_GPL(insn_to_mnemonic); |
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index f750bd7bd2c2..7845e15a17df 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c | |||
@@ -222,7 +222,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab, | |||
222 | struct mod_arch_syminfo *info; | 222 | struct mod_arch_syminfo *info; |
223 | Elf_Addr loc, val; | 223 | Elf_Addr loc, val; |
224 | int r_type, r_sym; | 224 | int r_type, r_sym; |
225 | int rc; | 225 | int rc = -ENOEXEC; |
226 | 226 | ||
227 | /* This is where to make the change */ | 227 | /* This is where to make the change */ |
228 | loc = base + rela->r_offset; | 228 | loc = base + rela->r_offset; |
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 9c6e747a5e1e..c45becf82e01 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c | |||
@@ -116,8 +116,6 @@ SYSCALL_DEFINE0(sigreturn) | |||
116 | sigframe __user *frame = (sigframe __user *)regs->gprs[15]; | 116 | sigframe __user *frame = (sigframe __user *)regs->gprs[15]; |
117 | sigset_t set; | 117 | sigset_t set; |
118 | 118 | ||
119 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | ||
120 | goto badframe; | ||
121 | if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE)) | 119 | if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE)) |
122 | goto badframe; | 120 | goto badframe; |
123 | set_current_blocked(&set); | 121 | set_current_blocked(&set); |
@@ -135,8 +133,6 @@ SYSCALL_DEFINE0(rt_sigreturn) | |||
135 | rt_sigframe __user *frame = (rt_sigframe __user *)regs->gprs[15]; | 133 | rt_sigframe __user *frame = (rt_sigframe __user *)regs->gprs[15]; |
136 | sigset_t set; | 134 | sigset_t set; |
137 | 135 | ||
138 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | ||
139 | goto badframe; | ||
140 | if (__copy_from_user(&set.sig, &frame->uc.uc_sigmask, sizeof(set))) | 136 | if (__copy_from_user(&set.sig, &frame->uc.uc_sigmask, sizeof(set))) |
141 | goto badframe; | 137 | goto badframe; |
142 | set_current_blocked(&set); | 138 | set_current_blocked(&set); |
@@ -195,8 +191,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, | |||
195 | sigframe __user *frame; | 191 | sigframe __user *frame; |
196 | 192 | ||
197 | frame = get_sigframe(ka, regs, sizeof(sigframe)); | 193 | frame = get_sigframe(ka, regs, sizeof(sigframe)); |
198 | if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe))) | ||
199 | goto give_sigsegv; | ||
200 | 194 | ||
201 | if (frame == (void __user *) -1UL) | 195 | if (frame == (void __user *) -1UL) |
202 | goto give_sigsegv; | 196 | goto give_sigsegv; |
@@ -264,8 +258,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
264 | rt_sigframe __user *frame; | 258 | rt_sigframe __user *frame; |
265 | 259 | ||
266 | frame = get_sigframe(ka, regs, sizeof(rt_sigframe)); | 260 | frame = get_sigframe(ka, regs, sizeof(rt_sigframe)); |
267 | if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe))) | ||
268 | goto give_sigsegv; | ||
269 | 261 | ||
270 | if (frame == (void __user *) -1UL) | 262 | if (frame == (void __user *) -1UL) |
271 | goto give_sigsegv; | 263 | goto give_sigsegv; |
diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c index 2443ae476e33..1829742bf479 100644 --- a/arch/s390/lib/uaccess_mvcos.c +++ b/arch/s390/lib/uaccess_mvcos.c | |||
@@ -162,19 +162,19 @@ static size_t clear_user_mvcos(size_t size, void __user *to) | |||
162 | 162 | ||
163 | static size_t strnlen_user_mvcos(size_t count, const char __user *src) | 163 | static size_t strnlen_user_mvcos(size_t count, const char __user *src) |
164 | { | 164 | { |
165 | size_t done, len, offset, len_str; | ||
165 | char buf[256]; | 166 | char buf[256]; |
166 | int rc; | ||
167 | size_t done, len, len_str; | ||
168 | 167 | ||
169 | done = 0; | 168 | done = 0; |
170 | do { | 169 | do { |
171 | len = min(count - done, (size_t) 256); | 170 | offset = (size_t)src & ~PAGE_MASK; |
172 | rc = uaccess.copy_from_user(len, src + done, buf); | 171 | len = min(256UL, PAGE_SIZE - offset); |
173 | if (unlikely(rc == len)) | 172 | len = min(count - done, len); |
173 | if (copy_from_user_mvcos(len, src, buf)) | ||
174 | return 0; | 174 | return 0; |
175 | len -= rc; | ||
176 | len_str = strnlen(buf, len); | 175 | len_str = strnlen(buf, len); |
177 | done += len_str; | 176 | done += len_str; |
177 | src += len_str; | ||
178 | } while ((len_str == len) && (done < count)); | 178 | } while ((len_str == len) && (done < count)); |
179 | return done + 1; | 179 | return done + 1; |
180 | } | 180 | } |
@@ -182,18 +182,20 @@ static size_t strnlen_user_mvcos(size_t count, const char __user *src) | |||
182 | static size_t strncpy_from_user_mvcos(size_t count, const char __user *src, | 182 | static size_t strncpy_from_user_mvcos(size_t count, const char __user *src, |
183 | char *dst) | 183 | char *dst) |
184 | { | 184 | { |
185 | int rc; | 185 | size_t done, len, offset, len_str; |
186 | size_t done, len, len_str; | ||
187 | 186 | ||
187 | if (unlikely(!count)) | ||
188 | return 0; | ||
188 | done = 0; | 189 | done = 0; |
189 | do { | 190 | do { |
190 | len = min(count - done, (size_t) 4096); | 191 | offset = (size_t)src & ~PAGE_MASK; |
191 | rc = uaccess.copy_from_user(len, src + done, dst); | 192 | len = min(count - done, PAGE_SIZE - offset); |
192 | if (unlikely(rc == len)) | 193 | if (copy_from_user_mvcos(len, src, dst)) |
193 | return -EFAULT; | 194 | return -EFAULT; |
194 | len -= rc; | ||
195 | len_str = strnlen(dst, len); | 195 | len_str = strnlen(dst, len); |
196 | done += len_str; | 196 | done += len_str; |
197 | src += len_str; | ||
198 | dst += len_str; | ||
197 | } while ((len_str == len) && (done < count)); | 199 | } while ((len_str == len) && (done < count)); |
198 | return done; | 200 | return done; |
199 | } | 201 | } |
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c index a70ee84c0241..dff631d34b45 100644 --- a/arch/s390/lib/uaccess_pt.c +++ b/arch/s390/lib/uaccess_pt.c | |||
@@ -14,6 +14,63 @@ | |||
14 | #include <asm/futex.h> | 14 | #include <asm/futex.h> |
15 | #include "uaccess.h" | 15 | #include "uaccess.h" |
16 | 16 | ||
17 | #ifndef CONFIG_64BIT | ||
18 | #define AHI "ahi" | ||
19 | #define SLR "slr" | ||
20 | #else | ||
21 | #define AHI "aghi" | ||
22 | #define SLR "slgr" | ||
23 | #endif | ||
24 | |||
25 | static size_t strnlen_kernel(size_t count, const char __user *src) | ||
26 | { | ||
27 | register unsigned long reg0 asm("0") = 0UL; | ||
28 | unsigned long tmp1, tmp2; | ||
29 | |||
30 | asm volatile( | ||
31 | " la %2,0(%1)\n" | ||
32 | " la %3,0(%0,%1)\n" | ||
33 | " "SLR" %0,%0\n" | ||
34 | "0: srst %3,%2\n" | ||
35 | " jo 0b\n" | ||
36 | " la %0,1(%3)\n" /* strnlen_kernel results includes \0 */ | ||
37 | " "SLR" %0,%1\n" | ||
38 | "1:\n" | ||
39 | EX_TABLE(0b,1b) | ||
40 | : "+a" (count), "+a" (src), "=a" (tmp1), "=a" (tmp2) | ||
41 | : "d" (reg0) : "cc", "memory"); | ||
42 | return count; | ||
43 | } | ||
44 | |||
45 | static size_t copy_in_kernel(size_t count, void __user *to, | ||
46 | const void __user *from) | ||
47 | { | ||
48 | unsigned long tmp1; | ||
49 | |||
50 | asm volatile( | ||
51 | " "AHI" %0,-1\n" | ||
52 | " jo 5f\n" | ||
53 | " bras %3,3f\n" | ||
54 | "0:"AHI" %0,257\n" | ||
55 | "1: mvc 0(1,%1),0(%2)\n" | ||
56 | " la %1,1(%1)\n" | ||
57 | " la %2,1(%2)\n" | ||
58 | " "AHI" %0,-1\n" | ||
59 | " jnz 1b\n" | ||
60 | " j 5f\n" | ||
61 | "2: mvc 0(256,%1),0(%2)\n" | ||
62 | " la %1,256(%1)\n" | ||
63 | " la %2,256(%2)\n" | ||
64 | "3:"AHI" %0,-256\n" | ||
65 | " jnm 2b\n" | ||
66 | "4: ex %0,1b-0b(%3)\n" | ||
67 | "5:"SLR" %0,%0\n" | ||
68 | "6:\n" | ||
69 | EX_TABLE(1b,6b) EX_TABLE(2b,0b) EX_TABLE(4b,0b) | ||
70 | : "+a" (count), "+a" (to), "+a" (from), "=a" (tmp1) | ||
71 | : : "cc", "memory"); | ||
72 | return count; | ||
73 | } | ||
17 | 74 | ||
18 | /* | 75 | /* |
19 | * Returns kernel address for user virtual address. If the returned address is | 76 | * Returns kernel address for user virtual address. If the returned address is |
@@ -123,10 +180,8 @@ size_t copy_from_user_pt(size_t n, const void __user *from, void *to) | |||
123 | { | 180 | { |
124 | size_t rc; | 181 | size_t rc; |
125 | 182 | ||
126 | if (segment_eq(get_fs(), KERNEL_DS)) { | 183 | if (segment_eq(get_fs(), KERNEL_DS)) |
127 | memcpy(to, (void __kernel __force *) from, n); | 184 | return copy_in_kernel(n, (void __user *) to, from); |
128 | return 0; | ||
129 | } | ||
130 | rc = __user_copy_pt((unsigned long) from, to, n, 0); | 185 | rc = __user_copy_pt((unsigned long) from, to, n, 0); |
131 | if (unlikely(rc)) | 186 | if (unlikely(rc)) |
132 | memset(to + n - rc, 0, rc); | 187 | memset(to + n - rc, 0, rc); |
@@ -135,30 +190,28 @@ size_t copy_from_user_pt(size_t n, const void __user *from, void *to) | |||
135 | 190 | ||
136 | size_t copy_to_user_pt(size_t n, void __user *to, const void *from) | 191 | size_t copy_to_user_pt(size_t n, void __user *to, const void *from) |
137 | { | 192 | { |
138 | if (segment_eq(get_fs(), KERNEL_DS)) { | 193 | if (segment_eq(get_fs(), KERNEL_DS)) |
139 | memcpy((void __kernel __force *) to, from, n); | 194 | return copy_in_kernel(n, to, (void __user *) from); |
140 | return 0; | ||
141 | } | ||
142 | return __user_copy_pt((unsigned long) to, (void *) from, n, 1); | 195 | return __user_copy_pt((unsigned long) to, (void *) from, n, 1); |
143 | } | 196 | } |
144 | 197 | ||
145 | static size_t clear_user_pt(size_t n, void __user *to) | 198 | static size_t clear_user_pt(size_t n, void __user *to) |
146 | { | 199 | { |
200 | void *zpage = &empty_zero_page; | ||
147 | long done, size, ret; | 201 | long done, size, ret; |
148 | 202 | ||
149 | if (segment_eq(get_fs(), KERNEL_DS)) { | ||
150 | memset((void __kernel __force *) to, 0, n); | ||
151 | return 0; | ||
152 | } | ||
153 | done = 0; | 203 | done = 0; |
154 | do { | 204 | do { |
155 | if (n - done > PAGE_SIZE) | 205 | if (n - done > PAGE_SIZE) |
156 | size = PAGE_SIZE; | 206 | size = PAGE_SIZE; |
157 | else | 207 | else |
158 | size = n - done; | 208 | size = n - done; |
159 | ret = __user_copy_pt((unsigned long) to + done, | 209 | if (segment_eq(get_fs(), KERNEL_DS)) |
160 | &empty_zero_page, size, 1); | 210 | ret = copy_in_kernel(n, to, (void __user *) zpage); |
211 | else | ||
212 | ret = __user_copy_pt((unsigned long) to, zpage, size, 1); | ||
161 | done += size; | 213 | done += size; |
214 | to += size; | ||
162 | if (ret) | 215 | if (ret) |
163 | return ret + n - done; | 216 | return ret + n - done; |
164 | } while (done < n); | 217 | } while (done < n); |
@@ -172,8 +225,10 @@ static size_t strnlen_user_pt(size_t count, const char __user *src) | |||
172 | unsigned long offset, done, len, kaddr; | 225 | unsigned long offset, done, len, kaddr; |
173 | size_t len_str; | 226 | size_t len_str; |
174 | 227 | ||
228 | if (unlikely(!count)) | ||
229 | return 0; | ||
175 | if (segment_eq(get_fs(), KERNEL_DS)) | 230 | if (segment_eq(get_fs(), KERNEL_DS)) |
176 | return strnlen((const char __kernel __force *) src, count) + 1; | 231 | return strnlen_kernel(count, src); |
177 | done = 0; | 232 | done = 0; |
178 | retry: | 233 | retry: |
179 | spin_lock(&mm->page_table_lock); | 234 | spin_lock(&mm->page_table_lock); |
@@ -200,25 +255,27 @@ fault: | |||
200 | static size_t strncpy_from_user_pt(size_t count, const char __user *src, | 255 | static size_t strncpy_from_user_pt(size_t count, const char __user *src, |
201 | char *dst) | 256 | char *dst) |
202 | { | 257 | { |
203 | size_t n = strnlen_user_pt(count, src); | 258 | size_t done, len, offset, len_str; |
204 | 259 | ||
205 | if (!n) | 260 | if (unlikely(!count)) |
206 | return -EFAULT; | 261 | return 0; |
207 | if (n > count) | 262 | done = 0; |
208 | n = count; | 263 | do { |
209 | if (segment_eq(get_fs(), KERNEL_DS)) { | 264 | offset = (size_t)src & ~PAGE_MASK; |
210 | memcpy(dst, (const char __kernel __force *) src, n); | 265 | len = min(count - done, PAGE_SIZE - offset); |
211 | if (dst[n-1] == '\0') | 266 | if (segment_eq(get_fs(), KERNEL_DS)) { |
212 | return n-1; | 267 | if (copy_in_kernel(len, (void __user *) dst, src)) |
213 | else | 268 | return -EFAULT; |
214 | return n; | 269 | } else { |
215 | } | 270 | if (__user_copy_pt((unsigned long) src, dst, len, 0)) |
216 | if (__user_copy_pt((unsigned long) src, dst, n, 0)) | 271 | return -EFAULT; |
217 | return -EFAULT; | 272 | } |
218 | if (dst[n-1] == '\0') | 273 | len_str = strnlen(dst, len); |
219 | return n-1; | 274 | done += len_str; |
220 | else | 275 | src += len_str; |
221 | return n; | 276 | dst += len_str; |
277 | } while ((len_str == len) && (done < count)); | ||
278 | return done; | ||
222 | } | 279 | } |
223 | 280 | ||
224 | static size_t copy_in_user_pt(size_t n, void __user *to, | 281 | static size_t copy_in_user_pt(size_t n, void __user *to, |
@@ -231,10 +288,8 @@ static size_t copy_in_user_pt(size_t n, void __user *to, | |||
231 | unsigned long kaddr_to, kaddr_from; | 288 | unsigned long kaddr_to, kaddr_from; |
232 | int write_user; | 289 | int write_user; |
233 | 290 | ||
234 | if (segment_eq(get_fs(), KERNEL_DS)) { | 291 | if (segment_eq(get_fs(), KERNEL_DS)) |
235 | memcpy((void __force *) to, (void __force *) from, n); | 292 | return copy_in_kernel(n, to, from); |
236 | return 0; | ||
237 | } | ||
238 | done = 0; | 293 | done = 0; |
239 | retry: | 294 | retry: |
240 | spin_lock(&mm->page_table_lock); | 295 | spin_lock(&mm->page_table_lock); |
diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c index 6fbd06338270..4a75d475b06a 100644 --- a/arch/s390/lib/uaccess_std.c +++ b/arch/s390/lib/uaccess_std.c | |||
@@ -188,6 +188,8 @@ size_t strnlen_user_std(size_t size, const char __user *src) | |||
188 | register unsigned long reg0 asm("0") = 0UL; | 188 | register unsigned long reg0 asm("0") = 0UL; |
189 | unsigned long tmp1, tmp2; | 189 | unsigned long tmp1, tmp2; |
190 | 190 | ||
191 | if (unlikely(!size)) | ||
192 | return 0; | ||
191 | asm volatile( | 193 | asm volatile( |
192 | " la %2,0(%1)\n" | 194 | " la %2,0(%1)\n" |
193 | " la %3,0(%0,%1)\n" | 195 | " la %3,0(%0,%1)\n" |
@@ -204,38 +206,24 @@ size_t strnlen_user_std(size_t size, const char __user *src) | |||
204 | return size; | 206 | return size; |
205 | } | 207 | } |
206 | 208 | ||
207 | size_t strncpy_from_user_std(size_t size, const char __user *src, char *dst) | 209 | size_t strncpy_from_user_std(size_t count, const char __user *src, char *dst) |
208 | { | 210 | { |
209 | register unsigned long reg0 asm("0") = 0UL; | 211 | size_t done, len, offset, len_str; |
210 | unsigned long tmp1, tmp2; | ||
211 | 212 | ||
212 | asm volatile( | 213 | if (unlikely(!count)) |
213 | " la %3,0(%1)\n" | 214 | return 0; |
214 | " la %4,0(%0,%1)\n" | 215 | done = 0; |
215 | " sacf 256\n" | 216 | do { |
216 | "0: srst %4,%3\n" | 217 | offset = (size_t)src & ~PAGE_MASK; |
217 | " jo 0b\n" | 218 | len = min(count - done, PAGE_SIZE - offset); |
218 | " sacf 0\n" | 219 | if (copy_from_user_std(len, src, dst)) |
219 | " la %0,0(%4)\n" | 220 | return -EFAULT; |
220 | " jh 1f\n" /* found \0 in string ? */ | 221 | len_str = strnlen(dst, len); |
221 | " "AHI" %4,1\n" /* include \0 in copy */ | 222 | done += len_str; |
222 | "1:"SLR" %0,%1\n" /* %0 = return length (without \0) */ | 223 | src += len_str; |
223 | " "SLR" %4,%1\n" /* %4 = copy length (including \0) */ | 224 | dst += len_str; |
224 | "2: mvcp 0(%4,%2),0(%1),%5\n" | 225 | } while ((len_str == len) && (done < count)); |
225 | " jz 9f\n" | 226 | return done; |
226 | "3:"AHI" %4,-256\n" | ||
227 | " la %1,256(%1)\n" | ||
228 | " la %2,256(%2)\n" | ||
229 | "4: mvcp 0(%4,%2),0(%1),%5\n" | ||
230 | " jnz 3b\n" | ||
231 | " j 9f\n" | ||
232 | "7: sacf 0\n" | ||
233 | "8:"LHI" %0,%6\n" | ||
234 | "9:\n" | ||
235 | EX_TABLE(0b,7b) EX_TABLE(2b,8b) EX_TABLE(4b,8b) | ||
236 | : "+a" (size), "+a" (src), "+d" (dst), "=a" (tmp1), "=a" (tmp2) | ||
237 | : "d" (reg0), "K" (-EFAULT) : "cc", "memory"); | ||
238 | return size; | ||
239 | } | 227 | } |
240 | 228 | ||
241 | #define __futex_atomic_op(insn, ret, oldval, newval, uaddr, oparg) \ | 229 | #define __futex_atomic_op(insn, ret, oldval, newval, uaddr, oparg) \ |
diff --git a/arch/s390/mm/dump_pagetables.c b/arch/s390/mm/dump_pagetables.c index 04e4892247d2..3ad65b04ac15 100644 --- a/arch/s390/mm/dump_pagetables.c +++ b/arch/s390/mm/dump_pagetables.c | |||
@@ -49,10 +49,13 @@ static void print_prot(struct seq_file *m, unsigned int pr, int level) | |||
49 | { "ASCE", "PGD", "PUD", "PMD", "PTE" }; | 49 | { "ASCE", "PGD", "PUD", "PMD", "PTE" }; |
50 | 50 | ||
51 | seq_printf(m, "%s ", level_name[level]); | 51 | seq_printf(m, "%s ", level_name[level]); |
52 | if (pr & _PAGE_INVALID) | 52 | if (pr & _PAGE_INVALID) { |
53 | seq_printf(m, "I\n"); | 53 | seq_printf(m, "I\n"); |
54 | else | 54 | return; |
55 | seq_printf(m, "%s\n", pr & _PAGE_RO ? "RO" : "RW"); | 55 | } |
56 | seq_printf(m, "%s", pr & _PAGE_RO ? "RO " : "RW "); | ||
57 | seq_printf(m, "%s", pr & _PAGE_CO ? "CO " : " "); | ||
58 | seq_putc(m, '\n'); | ||
56 | } | 59 | } |
57 | 60 | ||
58 | static void note_page(struct seq_file *m, struct pg_state *st, | 61 | static void note_page(struct seq_file *m, struct pg_state *st, |
@@ -125,6 +128,12 @@ static void walk_pte_level(struct seq_file *m, struct pg_state *st, | |||
125 | } | 128 | } |
126 | } | 129 | } |
127 | 130 | ||
131 | #ifdef CONFIG_64BIT | ||
132 | #define _PMD_PROT_MASK (_SEGMENT_ENTRY_RO | _SEGMENT_ENTRY_CO) | ||
133 | #else | ||
134 | #define _PMD_PROT_MASK 0 | ||
135 | #endif | ||
136 | |||
128 | static void walk_pmd_level(struct seq_file *m, struct pg_state *st, | 137 | static void walk_pmd_level(struct seq_file *m, struct pg_state *st, |
129 | pud_t *pud, unsigned long addr) | 138 | pud_t *pud, unsigned long addr) |
130 | { | 139 | { |
@@ -137,7 +146,7 @@ static void walk_pmd_level(struct seq_file *m, struct pg_state *st, | |||
137 | pmd = pmd_offset(pud, addr); | 146 | pmd = pmd_offset(pud, addr); |
138 | if (!pmd_none(*pmd)) { | 147 | if (!pmd_none(*pmd)) { |
139 | if (pmd_large(*pmd)) { | 148 | if (pmd_large(*pmd)) { |
140 | prot = pmd_val(*pmd) & _SEGMENT_ENTRY_RO; | 149 | prot = pmd_val(*pmd) & _PMD_PROT_MASK; |
141 | note_page(m, st, prot, 3); | 150 | note_page(m, st, prot, 3); |
142 | } else | 151 | } else |
143 | walk_pte_level(m, st, pmd, addr); | 152 | walk_pte_level(m, st, pmd, addr); |
@@ -147,6 +156,12 @@ static void walk_pmd_level(struct seq_file *m, struct pg_state *st, | |||
147 | } | 156 | } |
148 | } | 157 | } |
149 | 158 | ||
159 | #ifdef CONFIG_64BIT | ||
160 | #define _PUD_PROT_MASK (_REGION3_ENTRY_RO | _REGION3_ENTRY_CO) | ||
161 | #else | ||
162 | #define _PUD_PROT_MASK 0 | ||
163 | #endif | ||
164 | |||
150 | static void walk_pud_level(struct seq_file *m, struct pg_state *st, | 165 | static void walk_pud_level(struct seq_file *m, struct pg_state *st, |
151 | pgd_t *pgd, unsigned long addr) | 166 | pgd_t *pgd, unsigned long addr) |
152 | { | 167 | { |
@@ -159,7 +174,7 @@ static void walk_pud_level(struct seq_file *m, struct pg_state *st, | |||
159 | pud = pud_offset(pgd, addr); | 174 | pud = pud_offset(pgd, addr); |
160 | if (!pud_none(*pud)) | 175 | if (!pud_none(*pud)) |
161 | if (pud_large(*pud)) { | 176 | if (pud_large(*pud)) { |
162 | prot = pud_val(*pud) & _PAGE_RO; | 177 | prot = pud_val(*pud) & _PUD_PROT_MASK; |
163 | note_page(m, st, prot, 2); | 178 | note_page(m, st, prot, 2); |
164 | } else | 179 | } else |
165 | walk_pmd_level(m, st, pud, addr); | 180 | walk_pmd_level(m, st, pud, addr); |
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index e21aaf4f5cb6..ffab84db6907 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c | |||
@@ -236,7 +236,8 @@ int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node) | |||
236 | if (!new_page) | 236 | if (!new_page) |
237 | goto out; | 237 | goto out; |
238 | pmd_val(*pm_dir) = __pa(new_page) | | 238 | pmd_val(*pm_dir) = __pa(new_page) | |
239 | _SEGMENT_ENTRY | _SEGMENT_ENTRY_LARGE; | 239 | _SEGMENT_ENTRY | _SEGMENT_ENTRY_LARGE | |
240 | _SEGMENT_ENTRY_CO; | ||
240 | address = (address + PMD_SIZE) & PMD_MASK; | 241 | address = (address + PMD_SIZE) & PMD_MASK; |
241 | continue; | 242 | continue; |
242 | } | 243 | } |
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index 6e9cc765e0dc..3ec5ef2dd443 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig | |||
@@ -22,7 +22,7 @@ config SERIO_I8042 | |||
22 | tristate "i8042 PC Keyboard controller" if EXPERT || !X86 | 22 | tristate "i8042 PC Keyboard controller" if EXPERT || !X86 |
23 | default y | 23 | default y |
24 | depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \ | 24 | depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \ |
25 | (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN | 25 | (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN && !S390 |
26 | help | 26 | help |
27 | i8042 is the chip over which the standard AT keyboard and PS/2 | 27 | i8042 is the chip over which the standard AT keyboard and PS/2 |
28 | mouse are connected to the computer. If you use these devices, | 28 | mouse are connected to the computer. If you use these devices, |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 33f26bfa62f2..6999fd919e94 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -1573,7 +1573,10 @@ static void dasd_eckd_do_validate_server(struct work_struct *work) | |||
1573 | { | 1573 | { |
1574 | struct dasd_device *device = container_of(work, struct dasd_device, | 1574 | struct dasd_device *device = container_of(work, struct dasd_device, |
1575 | kick_validate); | 1575 | kick_validate); |
1576 | if (dasd_eckd_validate_server(device, DASD_CQR_FLAGS_FAILFAST) | 1576 | unsigned long flags = 0; |
1577 | |||
1578 | set_bit(DASD_CQR_FLAGS_FAILFAST, &flags); | ||
1579 | if (dasd_eckd_validate_server(device, flags) | ||
1577 | == -EAGAIN) { | 1580 | == -EAGAIN) { |
1578 | /* schedule worker again if failed */ | 1581 | /* schedule worker again if failed */ |
1579 | schedule_work(&device->kick_validate); | 1582 | schedule_work(&device->kick_validate); |
@@ -4157,6 +4160,7 @@ static int dasd_eckd_restore_device(struct dasd_device *device) | |||
4157 | int rc; | 4160 | int rc; |
4158 | struct dasd_uid temp_uid; | 4161 | struct dasd_uid temp_uid; |
4159 | unsigned long flags; | 4162 | unsigned long flags; |
4163 | unsigned long cqr_flags = 0; | ||
4160 | 4164 | ||
4161 | private = (struct dasd_eckd_private *) device->private; | 4165 | private = (struct dasd_eckd_private *) device->private; |
4162 | 4166 | ||
@@ -4178,7 +4182,9 @@ static int dasd_eckd_restore_device(struct dasd_device *device) | |||
4178 | rc = dasd_alias_make_device_known_to_lcu(device); | 4182 | rc = dasd_alias_make_device_known_to_lcu(device); |
4179 | if (rc) | 4183 | if (rc) |
4180 | return rc; | 4184 | return rc; |
4181 | dasd_eckd_validate_server(device, DASD_CQR_FLAGS_FAILFAST); | 4185 | |
4186 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr_flags); | ||
4187 | dasd_eckd_validate_server(device, cqr_flags); | ||
4182 | 4188 | ||
4183 | /* RE-Read Configuration Data */ | 4189 | /* RE-Read Configuration Data */ |
4184 | dasd_eckd_read_conf(device); | 4190 | dasd_eckd_read_conf(device); |
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c index 749b72739c4a..ccaae9d63d27 100644 --- a/drivers/s390/cio/qdio_debug.c +++ b/drivers/s390/cio/qdio_debug.c | |||
@@ -232,7 +232,8 @@ static struct file_operations debugfs_perf_fops = { | |||
232 | .llseek = seq_lseek, | 232 | .llseek = seq_lseek, |
233 | .release = single_release, | 233 | .release = single_release, |
234 | }; | 234 | }; |
235 | static void setup_debugfs_entry(struct qdio_q *q, struct ccw_device *cdev) | 235 | |
236 | static void setup_debugfs_entry(struct qdio_q *q) | ||
236 | { | 237 | { |
237 | char name[QDIO_DEBUGFS_NAME_LEN]; | 238 | char name[QDIO_DEBUGFS_NAME_LEN]; |
238 | 239 | ||
@@ -263,12 +264,12 @@ void qdio_setup_debug_entries(struct qdio_irq *irq_ptr, struct ccw_device *cdev) | |||
263 | irq_ptr->debugfs_perf = NULL; | 264 | irq_ptr->debugfs_perf = NULL; |
264 | 265 | ||
265 | for_each_input_queue(irq_ptr, q, i) | 266 | for_each_input_queue(irq_ptr, q, i) |
266 | setup_debugfs_entry(q, cdev); | 267 | setup_debugfs_entry(q); |
267 | for_each_output_queue(irq_ptr, q, i) | 268 | for_each_output_queue(irq_ptr, q, i) |
268 | setup_debugfs_entry(q, cdev); | 269 | setup_debugfs_entry(q); |
269 | } | 270 | } |
270 | 271 | ||
271 | void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr, struct ccw_device *cdev) | 272 | void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr) |
272 | { | 273 | { |
273 | struct qdio_q *q; | 274 | struct qdio_q *q; |
274 | int i; | 275 | int i; |
diff --git a/drivers/s390/cio/qdio_debug.h b/drivers/s390/cio/qdio_debug.h index 7f8b973da298..647b422bb22a 100644 --- a/drivers/s390/cio/qdio_debug.h +++ b/drivers/s390/cio/qdio_debug.h | |||
@@ -85,8 +85,7 @@ void qdio_allocate_dbf(struct qdio_initialize *init_data, | |||
85 | struct qdio_irq *irq_ptr); | 85 | struct qdio_irq *irq_ptr); |
86 | void qdio_setup_debug_entries(struct qdio_irq *irq_ptr, | 86 | void qdio_setup_debug_entries(struct qdio_irq *irq_ptr, |
87 | struct ccw_device *cdev); | 87 | struct ccw_device *cdev); |
88 | void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr, | 88 | void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr); |
89 | struct ccw_device *cdev); | ||
90 | int qdio_debug_init(void); | 89 | int qdio_debug_init(void); |
91 | void qdio_debug_exit(void); | 90 | void qdio_debug_exit(void); |
92 | 91 | ||
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index abc550e5dd35..843051bc20f1 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c | |||
@@ -1226,7 +1226,7 @@ int qdio_shutdown(struct ccw_device *cdev, int how) | |||
1226 | 1226 | ||
1227 | tiqdio_remove_input_queues(irq_ptr); | 1227 | tiqdio_remove_input_queues(irq_ptr); |
1228 | qdio_shutdown_queues(cdev); | 1228 | qdio_shutdown_queues(cdev); |
1229 | qdio_shutdown_debug_entries(irq_ptr, cdev); | 1229 | qdio_shutdown_debug_entries(irq_ptr); |
1230 | 1230 | ||
1231 | /* cleanup subchannel */ | 1231 | /* cleanup subchannel */ |
1232 | spin_lock_irqsave(get_ccwdev_lock(cdev), flags); | 1232 | spin_lock_irqsave(get_ccwdev_lock(cdev), flags); |