diff options
28 files changed, 282 insertions, 82 deletions
diff --git a/arch/s390/include/asm/delay.h b/arch/s390/include/asm/delay.h index a356c958e260..8a096b83f51f 100644 --- a/arch/s390/include/asm/delay.h +++ b/arch/s390/include/asm/delay.h | |||
@@ -14,10 +14,11 @@ | |||
14 | #ifndef _S390_DELAY_H | 14 | #ifndef _S390_DELAY_H |
15 | #define _S390_DELAY_H | 15 | #define _S390_DELAY_H |
16 | 16 | ||
17 | extern void __udelay(unsigned long usecs); | 17 | extern void __udelay(unsigned long long usecs); |
18 | extern void udelay_simple(unsigned long usecs); | 18 | extern void udelay_simple(unsigned long long usecs); |
19 | extern void __delay(unsigned long loops); | 19 | extern void __delay(unsigned long loops); |
20 | 20 | ||
21 | #define udelay(n) __udelay(n) | 21 | #define udelay(n) __udelay((unsigned long long) (n)) |
22 | #define mdelay(n) __udelay((unsigned long long) (n) * 1000) | ||
22 | 23 | ||
23 | #endif /* defined(_S390_DELAY_H) */ | 24 | #endif /* defined(_S390_DELAY_H) */ |
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index 74d0bbb7d955..e885442c1dfe 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h | |||
@@ -92,6 +92,18 @@ | |||
92 | /* Keep this the last entry. */ | 92 | /* Keep this the last entry. */ |
93 | #define R_390_NUM 61 | 93 | #define R_390_NUM 61 |
94 | 94 | ||
95 | /* Bits present in AT_HWCAP. */ | ||
96 | #define HWCAP_S390_ESAN3 1 | ||
97 | #define HWCAP_S390_ZARCH 2 | ||
98 | #define HWCAP_S390_STFLE 4 | ||
99 | #define HWCAP_S390_MSA 8 | ||
100 | #define HWCAP_S390_LDISP 16 | ||
101 | #define HWCAP_S390_EIMM 32 | ||
102 | #define HWCAP_S390_DFP 64 | ||
103 | #define HWCAP_S390_HPAGE 128 | ||
104 | #define HWCAP_S390_ETF3EH 256 | ||
105 | #define HWCAP_S390_HIGH_GPRS 512 | ||
106 | |||
95 | /* | 107 | /* |
96 | * These are used to set parameters in the core dumps. | 108 | * These are used to set parameters in the core dumps. |
97 | */ | 109 | */ |
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index 539263fc9ab9..95dcf183a28d 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h | |||
@@ -311,6 +311,10 @@ typedef struct | |||
311 | __u32 orig_gpr2; | 311 | __u32 orig_gpr2; |
312 | } s390_compat_regs; | 312 | } s390_compat_regs; |
313 | 313 | ||
314 | typedef struct | ||
315 | { | ||
316 | __u32 gprs_high[NUM_GPRS]; | ||
317 | } s390_compat_regs_high; | ||
314 | 318 | ||
315 | #ifdef __KERNEL__ | 319 | #ifdef __KERNEL__ |
316 | 320 | ||
diff --git a/arch/s390/include/asm/ucontext.h b/arch/s390/include/asm/ucontext.h index d69bec0b03f5..cfb874e66c9a 100644 --- a/arch/s390/include/asm/ucontext.h +++ b/arch/s390/include/asm/ucontext.h | |||
@@ -9,6 +9,21 @@ | |||
9 | #ifndef _ASM_S390_UCONTEXT_H | 9 | #ifndef _ASM_S390_UCONTEXT_H |
10 | #define _ASM_S390_UCONTEXT_H | 10 | #define _ASM_S390_UCONTEXT_H |
11 | 11 | ||
12 | #define UC_EXTENDED 0x00000001 | ||
13 | |||
14 | #ifndef __s390x__ | ||
15 | |||
16 | struct ucontext_extended { | ||
17 | unsigned long uc_flags; | ||
18 | struct ucontext *uc_link; | ||
19 | stack_t uc_stack; | ||
20 | _sigregs uc_mcontext; | ||
21 | unsigned long uc_sigmask[2]; | ||
22 | unsigned long uc_gprs_high[16]; | ||
23 | }; | ||
24 | |||
25 | #endif | ||
26 | |||
12 | struct ucontext { | 27 | struct ucontext { |
13 | unsigned long uc_flags; | 28 | unsigned long uc_flags; |
14 | struct ucontext *uc_link; | 29 | struct ucontext *uc_link; |
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index b537cb0e9b55..eee999853a7c 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c | |||
@@ -39,6 +39,7 @@ typedef struct | |||
39 | struct sigcontext32 sc; | 39 | struct sigcontext32 sc; |
40 | _sigregs32 sregs; | 40 | _sigregs32 sregs; |
41 | int signo; | 41 | int signo; |
42 | __u32 gprs_high[NUM_GPRS]; | ||
42 | __u8 retcode[S390_SYSCALL_SIZE]; | 43 | __u8 retcode[S390_SYSCALL_SIZE]; |
43 | } sigframe32; | 44 | } sigframe32; |
44 | 45 | ||
@@ -48,6 +49,7 @@ typedef struct | |||
48 | __u8 retcode[S390_SYSCALL_SIZE]; | 49 | __u8 retcode[S390_SYSCALL_SIZE]; |
49 | compat_siginfo_t info; | 50 | compat_siginfo_t info; |
50 | struct ucontext32 uc; | 51 | struct ucontext32 uc; |
52 | __u32 gprs_high[NUM_GPRS]; | ||
51 | } rt_sigframe32; | 53 | } rt_sigframe32; |
52 | 54 | ||
53 | int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) | 55 | int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) |
@@ -344,6 +346,30 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) | |||
344 | return 0; | 346 | return 0; |
345 | } | 347 | } |
346 | 348 | ||
349 | static int save_sigregs_gprs_high(struct pt_regs *regs, __u32 __user *uregs) | ||
350 | { | ||
351 | __u32 gprs_high[NUM_GPRS]; | ||
352 | int i; | ||
353 | |||
354 | for (i = 0; i < NUM_GPRS; i++) | ||
355 | gprs_high[i] = regs->gprs[i] >> 32; | ||
356 | |||
357 | return __copy_to_user(uregs, &gprs_high, sizeof(gprs_high)); | ||
358 | } | ||
359 | |||
360 | static int restore_sigregs_gprs_high(struct pt_regs *regs, __u32 __user *uregs) | ||
361 | { | ||
362 | __u32 gprs_high[NUM_GPRS]; | ||
363 | int err, i; | ||
364 | |||
365 | err = __copy_from_user(&gprs_high, uregs, sizeof(gprs_high)); | ||
366 | if (err) | ||
367 | return err; | ||
368 | for (i = 0; i < NUM_GPRS; i++) | ||
369 | *(__u32 *)®s->gprs[i] = gprs_high[i]; | ||
370 | return 0; | ||
371 | } | ||
372 | |||
347 | asmlinkage long sys32_sigreturn(void) | 373 | asmlinkage long sys32_sigreturn(void) |
348 | { | 374 | { |
349 | struct pt_regs *regs = task_pt_regs(current); | 375 | struct pt_regs *regs = task_pt_regs(current); |
@@ -363,6 +389,8 @@ asmlinkage long sys32_sigreturn(void) | |||
363 | 389 | ||
364 | if (restore_sigregs32(regs, &frame->sregs)) | 390 | if (restore_sigregs32(regs, &frame->sregs)) |
365 | goto badframe; | 391 | goto badframe; |
392 | if (restore_sigregs_gprs_high(regs, frame->gprs_high)) | ||
393 | goto badframe; | ||
366 | 394 | ||
367 | return regs->gprs[2]; | 395 | return regs->gprs[2]; |
368 | 396 | ||
@@ -394,6 +422,8 @@ asmlinkage long sys32_rt_sigreturn(void) | |||
394 | 422 | ||
395 | if (restore_sigregs32(regs, &frame->uc.uc_mcontext)) | 423 | if (restore_sigregs32(regs, &frame->uc.uc_mcontext)) |
396 | goto badframe; | 424 | goto badframe; |
425 | if (restore_sigregs_gprs_high(regs, frame->gprs_high)) | ||
426 | goto badframe; | ||
397 | 427 | ||
398 | err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp); | 428 | err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp); |
399 | st.ss_sp = compat_ptr(ss_sp); | 429 | st.ss_sp = compat_ptr(ss_sp); |
@@ -474,6 +504,8 @@ static int setup_frame32(int sig, struct k_sigaction *ka, | |||
474 | 504 | ||
475 | if (save_sigregs32(regs, &frame->sregs)) | 505 | if (save_sigregs32(regs, &frame->sregs)) |
476 | goto give_sigsegv; | 506 | goto give_sigsegv; |
507 | if (save_sigregs_gprs_high(regs, frame->gprs_high)) | ||
508 | goto give_sigsegv; | ||
477 | if (__put_user((unsigned long) &frame->sregs, &frame->sc.sregs)) | 509 | if (__put_user((unsigned long) &frame->sregs, &frame->sc.sregs)) |
478 | goto give_sigsegv; | 510 | goto give_sigsegv; |
479 | 511 | ||
@@ -529,13 +561,14 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
529 | goto give_sigsegv; | 561 | goto give_sigsegv; |
530 | 562 | ||
531 | /* Create the ucontext. */ | 563 | /* Create the ucontext. */ |
532 | err |= __put_user(0, &frame->uc.uc_flags); | 564 | err |= __put_user(UC_EXTENDED, &frame->uc.uc_flags); |
533 | err |= __put_user(0, &frame->uc.uc_link); | 565 | err |= __put_user(0, &frame->uc.uc_link); |
534 | err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); | 566 | err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); |
535 | err |= __put_user(sas_ss_flags(regs->gprs[15]), | 567 | err |= __put_user(sas_ss_flags(regs->gprs[15]), |
536 | &frame->uc.uc_stack.ss_flags); | 568 | &frame->uc.uc_stack.ss_flags); |
537 | err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); | 569 | err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); |
538 | err |= save_sigregs32(regs, &frame->uc.uc_mcontext); | 570 | err |= save_sigregs32(regs, &frame->uc.uc_mcontext); |
571 | err |= save_sigregs_gprs_high(regs, frame->gprs_high); | ||
539 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | 572 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); |
540 | if (err) | 573 | if (err) |
541 | goto give_sigsegv; | 574 | goto give_sigsegv; |
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 682fb69dba21..cbd9901dc0f8 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S | |||
@@ -409,7 +409,7 @@ sys32_munmap_wrapper: | |||
409 | .globl sys32_truncate_wrapper | 409 | .globl sys32_truncate_wrapper |
410 | sys32_truncate_wrapper: | 410 | sys32_truncate_wrapper: |
411 | llgtr %r2,%r2 # const char * | 411 | llgtr %r2,%r2 # const char * |
412 | llgfr %r3,%r3 # unsigned long | 412 | lgfr %r3,%r3 # long |
413 | jg sys_truncate # branch to system call | 413 | jg sys_truncate # branch to system call |
414 | 414 | ||
415 | .globl sys32_ftruncate_wrapper | 415 | .globl sys32_ftruncate_wrapper |
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index 57bdcb1e3cdf..f5fe34dd821b 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c | |||
@@ -185,9 +185,6 @@ unsigned long prepare_ftrace_return(unsigned long ip, unsigned long parent) | |||
185 | { | 185 | { |
186 | struct ftrace_graph_ent trace; | 186 | struct ftrace_graph_ent trace; |
187 | 187 | ||
188 | /* Nmi's are currently unsupported. */ | ||
189 | if (unlikely(in_nmi())) | ||
190 | goto out; | ||
191 | if (unlikely(atomic_read(¤t->tracing_graph_pause))) | 188 | if (unlikely(atomic_read(¤t->tracing_graph_pause))) |
192 | goto out; | 189 | goto out; |
193 | if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY) | 190 | if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY) |
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index ab2e3ed28abc..639380a0c45c 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c | |||
@@ -55,6 +55,8 @@ void *module_alloc(unsigned long size) | |||
55 | /* Free memory returned from module_alloc */ | 55 | /* Free memory returned from module_alloc */ |
56 | void module_free(struct module *mod, void *module_region) | 56 | void module_free(struct module *mod, void *module_region) |
57 | { | 57 | { |
58 | vfree(mod->arch.syminfo); | ||
59 | mod->arch.syminfo = NULL; | ||
58 | vfree(module_region); | 60 | vfree(module_region); |
59 | } | 61 | } |
60 | 62 | ||
@@ -402,6 +404,7 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
402 | struct module *me) | 404 | struct module *me) |
403 | { | 405 | { |
404 | vfree(me->arch.syminfo); | 406 | vfree(me->arch.syminfo); |
407 | me->arch.syminfo = NULL; | ||
405 | return module_bug_finalize(hdr, sechdrs, me); | 408 | return module_bug_finalize(hdr, sechdrs, me); |
406 | } | 409 | } |
407 | 410 | ||
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index a8738676b26c..653c6a178740 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -57,6 +57,7 @@ | |||
57 | enum s390_regset { | 57 | enum s390_regset { |
58 | REGSET_GENERAL, | 58 | REGSET_GENERAL, |
59 | REGSET_FP, | 59 | REGSET_FP, |
60 | REGSET_GENERAL_EXTENDED, | ||
60 | }; | 61 | }; |
61 | 62 | ||
62 | static void | 63 | static void |
@@ -879,6 +880,67 @@ static int s390_compat_regs_set(struct task_struct *target, | |||
879 | return rc; | 880 | return rc; |
880 | } | 881 | } |
881 | 882 | ||
883 | static int s390_compat_regs_high_get(struct task_struct *target, | ||
884 | const struct user_regset *regset, | ||
885 | unsigned int pos, unsigned int count, | ||
886 | void *kbuf, void __user *ubuf) | ||
887 | { | ||
888 | compat_ulong_t *gprs_high; | ||
889 | |||
890 | gprs_high = (compat_ulong_t *) | ||
891 | &task_pt_regs(target)->gprs[pos / sizeof(compat_ulong_t)]; | ||
892 | if (kbuf) { | ||
893 | compat_ulong_t *k = kbuf; | ||
894 | while (count > 0) { | ||
895 | *k++ = *gprs_high; | ||
896 | gprs_high += 2; | ||
897 | count -= sizeof(*k); | ||
898 | } | ||
899 | } else { | ||
900 | compat_ulong_t __user *u = ubuf; | ||
901 | while (count > 0) { | ||
902 | if (__put_user(*gprs_high, u++)) | ||
903 | return -EFAULT; | ||
904 | gprs_high += 2; | ||
905 | count -= sizeof(*u); | ||
906 | } | ||
907 | } | ||
908 | return 0; | ||
909 | } | ||
910 | |||
911 | static int s390_compat_regs_high_set(struct task_struct *target, | ||
912 | const struct user_regset *regset, | ||
913 | unsigned int pos, unsigned int count, | ||
914 | const void *kbuf, const void __user *ubuf) | ||
915 | { | ||
916 | compat_ulong_t *gprs_high; | ||
917 | int rc = 0; | ||
918 | |||
919 | gprs_high = (compat_ulong_t *) | ||
920 | &task_pt_regs(target)->gprs[pos / sizeof(compat_ulong_t)]; | ||
921 | if (kbuf) { | ||
922 | const compat_ulong_t *k = kbuf; | ||
923 | while (count > 0) { | ||
924 | *gprs_high = *k++; | ||
925 | *gprs_high += 2; | ||
926 | count -= sizeof(*k); | ||
927 | } | ||
928 | } else { | ||
929 | const compat_ulong_t __user *u = ubuf; | ||
930 | while (count > 0 && !rc) { | ||
931 | unsigned long word; | ||
932 | rc = __get_user(word, u++); | ||
933 | if (rc) | ||
934 | break; | ||
935 | *gprs_high = word; | ||
936 | *gprs_high += 2; | ||
937 | count -= sizeof(*u); | ||
938 | } | ||
939 | } | ||
940 | |||
941 | return rc; | ||
942 | } | ||
943 | |||
882 | static const struct user_regset s390_compat_regsets[] = { | 944 | static const struct user_regset s390_compat_regsets[] = { |
883 | [REGSET_GENERAL] = { | 945 | [REGSET_GENERAL] = { |
884 | .core_note_type = NT_PRSTATUS, | 946 | .core_note_type = NT_PRSTATUS, |
@@ -896,6 +958,14 @@ static const struct user_regset s390_compat_regsets[] = { | |||
896 | .get = s390_fpregs_get, | 958 | .get = s390_fpregs_get, |
897 | .set = s390_fpregs_set, | 959 | .set = s390_fpregs_set, |
898 | }, | 960 | }, |
961 | [REGSET_GENERAL_EXTENDED] = { | ||
962 | .core_note_type = NT_PRXSTATUS, | ||
963 | .n = sizeof(s390_compat_regs_high) / sizeof(compat_long_t), | ||
964 | .size = sizeof(compat_long_t), | ||
965 | .align = sizeof(compat_long_t), | ||
966 | .get = s390_compat_regs_high_get, | ||
967 | .set = s390_compat_regs_high_set, | ||
968 | }, | ||
899 | }; | 969 | }; |
900 | 970 | ||
901 | static const struct user_regset_view user_s390_compat_view = { | 971 | static const struct user_regset_view user_s390_compat_view = { |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 9ed13a1ed376..061479ff029f 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -729,7 +729,7 @@ static void __init setup_hwcaps(void) | |||
729 | 729 | ||
730 | if ((facility_list & (1UL << (31 - 22))) | 730 | if ((facility_list & (1UL << (31 - 22))) |
731 | && (facility_list & (1UL << (31 - 30)))) | 731 | && (facility_list & (1UL << (31 - 30)))) |
732 | elf_hwcap |= 1UL << 8; | 732 | elf_hwcap |= HWCAP_S390_ETF3EH; |
733 | 733 | ||
734 | /* | 734 | /* |
735 | * Check for additional facilities with store-facility-list-extended. | 735 | * Check for additional facilities with store-facility-list-extended. |
@@ -748,11 +748,20 @@ static void __init setup_hwcaps(void) | |||
748 | __stfle(&facility_list_extended, 1) > 0) { | 748 | __stfle(&facility_list_extended, 1) > 0) { |
749 | if ((facility_list_extended & (1ULL << (63 - 42))) | 749 | if ((facility_list_extended & (1ULL << (63 - 42))) |
750 | && (facility_list_extended & (1ULL << (63 - 44)))) | 750 | && (facility_list_extended & (1ULL << (63 - 44)))) |
751 | elf_hwcap |= 1UL << 6; | 751 | elf_hwcap |= HWCAP_S390_DFP; |
752 | } | 752 | } |
753 | 753 | ||
754 | /* | ||
755 | * Huge page support HWCAP_S390_HPAGE is bit 7. | ||
756 | */ | ||
754 | if (MACHINE_HAS_HPAGE) | 757 | if (MACHINE_HAS_HPAGE) |
755 | elf_hwcap |= 1UL << 7; | 758 | elf_hwcap |= HWCAP_S390_HPAGE; |
759 | |||
760 | /* | ||
761 | * 64-bit register support for 31-bit processes | ||
762 | * HWCAP_S390_HIGH_GPRS is bit 9. | ||
763 | */ | ||
764 | elf_hwcap |= HWCAP_S390_HIGH_GPRS; | ||
756 | 765 | ||
757 | switch (S390_lowcore.cpu_id.machine) { | 766 | switch (S390_lowcore.cpu_id.machine) { |
758 | case 0x9672: | 767 | case 0x9672: |
diff --git a/arch/s390/kernel/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S index fe927d0bc20b..7c8653e27db6 100644 --- a/arch/s390/kernel/swsusp_asm64.S +++ b/arch/s390/kernel/swsusp_asm64.S | |||
@@ -43,7 +43,7 @@ swsusp_arch_suspend: | |||
43 | lghi %r1,0x1000 | 43 | lghi %r1,0x1000 |
44 | 44 | ||
45 | /* Save CPU address */ | 45 | /* Save CPU address */ |
46 | stap __LC_CPU_ADDRESS(%r1) | 46 | stap __LC_CPU_ADDRESS(%r0) |
47 | 47 | ||
48 | /* Store registers */ | 48 | /* Store registers */ |
49 | mvc 0x318(4,%r1),__SF_EMPTY(%r15) /* move prefix to lowcore */ | 49 | mvc 0x318(4,%r1),__SF_EMPTY(%r15) /* move prefix to lowcore */ |
@@ -69,8 +69,21 @@ swsusp_arch_suspend: | |||
69 | stmg %r0,%r15,0x280(%r1) /* store general registers */ | 69 | stmg %r0,%r15,0x280(%r1) /* store general registers */ |
70 | 70 | ||
71 | stpt 0x328(%r1) /* store timer */ | 71 | stpt 0x328(%r1) /* store timer */ |
72 | stck __SF_EMPTY(%r15) /* store clock */ | ||
72 | stckc 0x330(%r1) /* store clock comparator */ | 73 | stckc 0x330(%r1) /* store clock comparator */ |
73 | 74 | ||
75 | /* Update cputime accounting before going to sleep */ | ||
76 | lg %r0,__LC_LAST_UPDATE_TIMER | ||
77 | slg %r0,0x328(%r1) | ||
78 | alg %r0,__LC_SYSTEM_TIMER | ||
79 | stg %r0,__LC_SYSTEM_TIMER | ||
80 | mvc __LC_LAST_UPDATE_TIMER(8),0x328(%r1) | ||
81 | lg %r0,__LC_LAST_UPDATE_CLOCK | ||
82 | slg %r0,__SF_EMPTY(%r15) | ||
83 | alg %r0,__LC_STEAL_TIMER | ||
84 | stg %r0,__LC_STEAL_TIMER | ||
85 | mvc __LC_LAST_UPDATE_CLOCK(8),__SF_EMPTY(%r15) | ||
86 | |||
74 | /* Activate DAT */ | 87 | /* Activate DAT */ |
75 | stosm __SF_EMPTY(%r15),0x04 | 88 | stosm __SF_EMPTY(%r15),0x04 |
76 | 89 | ||
@@ -159,8 +172,7 @@ pgm_check_entry: | |||
159 | larl %r1,.Lresume_cpu /* Resume CPU address: r2 */ | 172 | larl %r1,.Lresume_cpu /* Resume CPU address: r2 */ |
160 | stap 0(%r1) | 173 | stap 0(%r1) |
161 | llgh %r2,0(%r1) | 174 | llgh %r2,0(%r1) |
162 | lghi %r3,0x1000 | 175 | llgh %r1,__LC_CPU_ADDRESS(%r0) /* Suspend CPU address: r1 */ |
163 | llgh %r1,__LC_CPU_ADDRESS(%r3) /* Suspend CPU address: r1 */ | ||
164 | cgr %r1,%r2 | 176 | cgr %r1,%r2 |
165 | je restore_registers /* r1 = r2 -> nothing to do */ | 177 | je restore_registers /* r1 = r2 -> nothing to do */ |
166 | larl %r4,.Lrestart_suspend_psw /* Set new restart PSW */ | 178 | larl %r4,.Lrestart_suspend_psw /* Set new restart PSW */ |
@@ -200,8 +212,11 @@ restart_suspend: | |||
200 | 212 | ||
201 | restore_registers: | 213 | restore_registers: |
202 | /* Restore registers */ | 214 | /* Restore registers */ |
203 | lghi %r13,0x1000 /* %r1 = pointer to save arae */ | 215 | lghi %r13,0x1000 /* %r1 = pointer to save area */ |
204 | 216 | ||
217 | /* Ignore time spent in suspended state. */ | ||
218 | llgf %r1,0x318(%r13) | ||
219 | stck __LC_LAST_UPDATE_CLOCK(%r1) | ||
205 | spt 0x328(%r13) /* reprogram timer */ | 220 | spt 0x328(%r13) /* reprogram timer */ |
206 | //sckc 0x330(%r13) /* set clock comparator */ | 221 | //sckc 0x330(%r13) /* set clock comparator */ |
207 | 222 | ||
@@ -229,9 +244,6 @@ restore_registers: | |||
229 | /* Load old stack */ | 244 | /* Load old stack */ |
230 | lg %r15,0x2f8(%r13) | 245 | lg %r15,0x2f8(%r13) |
231 | 246 | ||
232 | /* Pointer to save area */ | ||
233 | lghi %r13,0x1000 | ||
234 | |||
235 | /* Restore prefix register */ | 247 | /* Restore prefix register */ |
236 | spx 0x318(%r13) | 248 | spx 0x318(%r13) |
237 | 249 | ||
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index 45a3e9a7ae21..adfb32aa6d59 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c | |||
@@ -247,6 +247,13 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) | |||
247 | } | 247 | } |
248 | 248 | ||
249 | /* | 249 | /* |
250 | * Put vDSO base into mm struct. We need to do this before calling | ||
251 | * install_special_mapping or the perf counter mmap tracking code | ||
252 | * will fail to recognise it as a vDSO (since arch_vma_name fails). | ||
253 | */ | ||
254 | current->mm->context.vdso_base = vdso_base; | ||
255 | |||
256 | /* | ||
250 | * our vma flags don't have VM_WRITE so by default, the process | 257 | * our vma flags don't have VM_WRITE so by default, the process |
251 | * isn't allowed to write those pages. | 258 | * isn't allowed to write those pages. |
252 | * gdb can break that with ptrace interface, and thus trigger COW | 259 | * gdb can break that with ptrace interface, and thus trigger COW |
@@ -267,14 +274,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) | |||
267 | VM_ALWAYSDUMP, | 274 | VM_ALWAYSDUMP, |
268 | vdso_pagelist); | 275 | vdso_pagelist); |
269 | if (rc) | 276 | if (rc) |
270 | goto out_up; | 277 | current->mm->context.vdso_base = 0; |
271 | |||
272 | /* Put vDSO base into mm struct */ | ||
273 | current->mm->context.vdso_base = vdso_base; | ||
274 | |||
275 | up_write(&mm->mmap_sem); | ||
276 | return 0; | ||
277 | |||
278 | out_up: | 278 | out_up: |
279 | up_write(&mm->mmap_sem); | 279 | up_write(&mm->mmap_sem); |
280 | return rc; | 280 | return rc; |
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index bc15ef93e656..a68ac10213b2 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S | |||
@@ -51,6 +51,7 @@ SECTIONS | |||
51 | 51 | ||
52 | . = ALIGN(PAGE_SIZE); | 52 | . = ALIGN(PAGE_SIZE); |
53 | _eshared = .; /* End of shareable data */ | 53 | _eshared = .; /* End of shareable data */ |
54 | _sdata = .; /* Start of data section */ | ||
54 | 55 | ||
55 | EXCEPTION_TABLE(16) :data | 56 | EXCEPTION_TABLE(16) :data |
56 | 57 | ||
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index 97c1eca83cc2..752b362bf651 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c | |||
@@ -25,13 +25,13 @@ void __delay(unsigned long loops) | |||
25 | asm volatile("0: brct %0,0b" : : "d" ((loops/2) + 1)); | 25 | asm volatile("0: brct %0,0b" : : "d" ((loops/2) + 1)); |
26 | } | 26 | } |
27 | 27 | ||
28 | static void __udelay_disabled(unsigned long usecs) | 28 | static void __udelay_disabled(unsigned long long usecs) |
29 | { | 29 | { |
30 | unsigned long mask, cr0, cr0_saved; | 30 | unsigned long mask, cr0, cr0_saved; |
31 | u64 clock_saved; | 31 | u64 clock_saved; |
32 | 32 | ||
33 | clock_saved = local_tick_disable(); | 33 | clock_saved = local_tick_disable(); |
34 | set_clock_comparator(get_clock() + ((u64) usecs << 12)); | 34 | set_clock_comparator(get_clock() + (usecs << 12)); |
35 | __ctl_store(cr0_saved, 0, 0); | 35 | __ctl_store(cr0_saved, 0, 0); |
36 | cr0 = (cr0_saved & 0xffff00e0) | 0x00000800; | 36 | cr0 = (cr0_saved & 0xffff00e0) | 0x00000800; |
37 | __ctl_load(cr0 , 0, 0); | 37 | __ctl_load(cr0 , 0, 0); |
@@ -46,20 +46,25 @@ static void __udelay_disabled(unsigned long usecs) | |||
46 | set_clock_comparator(S390_lowcore.clock_comparator); | 46 | set_clock_comparator(S390_lowcore.clock_comparator); |
47 | } | 47 | } |
48 | 48 | ||
49 | static void __udelay_enabled(unsigned long usecs) | 49 | static void __udelay_enabled(unsigned long long usecs) |
50 | { | 50 | { |
51 | unsigned long mask; | 51 | unsigned long mask; |
52 | u64 end, time; | 52 | u64 clock_saved; |
53 | u64 end; | ||
53 | 54 | ||
54 | mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT | PSW_MASK_IO; | 55 | mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT | PSW_MASK_IO; |
55 | end = get_clock() + ((u64) usecs << 12); | 56 | end = get_clock() + (usecs << 12); |
56 | do { | 57 | do { |
57 | time = end < S390_lowcore.clock_comparator ? | 58 | clock_saved = 0; |
58 | end : S390_lowcore.clock_comparator; | 59 | if (end < S390_lowcore.clock_comparator) { |
59 | set_clock_comparator(time); | 60 | clock_saved = local_tick_disable(); |
61 | set_clock_comparator(end); | ||
62 | } | ||
60 | trace_hardirqs_on(); | 63 | trace_hardirqs_on(); |
61 | __load_psw_mask(mask); | 64 | __load_psw_mask(mask); |
62 | local_irq_disable(); | 65 | local_irq_disable(); |
66 | if (clock_saved) | ||
67 | local_tick_enable(clock_saved); | ||
63 | } while (get_clock() < end); | 68 | } while (get_clock() < end); |
64 | set_clock_comparator(S390_lowcore.clock_comparator); | 69 | set_clock_comparator(S390_lowcore.clock_comparator); |
65 | } | 70 | } |
@@ -67,7 +72,7 @@ static void __udelay_enabled(unsigned long usecs) | |||
67 | /* | 72 | /* |
68 | * Waits for 'usecs' microseconds using the TOD clock comparator. | 73 | * Waits for 'usecs' microseconds using the TOD clock comparator. |
69 | */ | 74 | */ |
70 | void __udelay(unsigned long usecs) | 75 | void __udelay(unsigned long long usecs) |
71 | { | 76 | { |
72 | unsigned long flags; | 77 | unsigned long flags; |
73 | 78 | ||
@@ -101,11 +106,11 @@ EXPORT_SYMBOL(__udelay); | |||
101 | * Simple udelay variant. To be used on startup and reboot | 106 | * Simple udelay variant. To be used on startup and reboot |
102 | * when the interrupt handler isn't working. | 107 | * when the interrupt handler isn't working. |
103 | */ | 108 | */ |
104 | void udelay_simple(unsigned long usecs) | 109 | void udelay_simple(unsigned long long usecs) |
105 | { | 110 | { |
106 | u64 end; | 111 | u64 end; |
107 | 112 | ||
108 | end = get_clock() + ((u64) usecs << 12); | 113 | end = get_clock() + (usecs << 12); |
109 | while (get_clock() < end) | 114 | while (get_clock() < end) |
110 | cpu_relax(); | 115 | cpu_relax(); |
111 | } | 116 | } |
diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c index 3f15aaf54855..58da3f461214 100644 --- a/arch/s390/lib/uaccess_mvcos.c +++ b/arch/s390/lib/uaccess_mvcos.c | |||
@@ -36,7 +36,7 @@ static size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) | |||
36 | tmp1 = -4096UL; | 36 | tmp1 = -4096UL; |
37 | asm volatile( | 37 | asm volatile( |
38 | "0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n" | 38 | "0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n" |
39 | " jz 7f\n" | 39 | "9: jz 7f\n" |
40 | "1:"ALR" %0,%3\n" | 40 | "1:"ALR" %0,%3\n" |
41 | " "SLR" %1,%3\n" | 41 | " "SLR" %1,%3\n" |
42 | " "SLR" %2,%3\n" | 42 | " "SLR" %2,%3\n" |
@@ -47,7 +47,7 @@ static size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) | |||
47 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ | 47 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ |
48 | " jnh 4f\n" | 48 | " jnh 4f\n" |
49 | "3: .insn ss,0xc80000000000,0(%4,%2),0(%1),0\n" | 49 | "3: .insn ss,0xc80000000000,0(%4,%2),0(%1),0\n" |
50 | " "SLR" %0,%4\n" | 50 | "10:"SLR" %0,%4\n" |
51 | " "ALR" %2,%4\n" | 51 | " "ALR" %2,%4\n" |
52 | "4:"LHI" %4,-1\n" | 52 | "4:"LHI" %4,-1\n" |
53 | " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ | 53 | " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ |
@@ -61,7 +61,7 @@ static size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) | |||
61 | " j 8f\n" | 61 | " j 8f\n" |
62 | "7:"SLR" %0,%0\n" | 62 | "7:"SLR" %0,%0\n" |
63 | "8: \n" | 63 | "8: \n" |
64 | EX_TABLE(0b,2b) EX_TABLE(3b,4b) | 64 | EX_TABLE(0b,2b) EX_TABLE(3b,4b) EX_TABLE(9b,2b) EX_TABLE(10b,4b) |
65 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) | 65 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) |
66 | : "d" (reg0) : "cc", "memory"); | 66 | : "d" (reg0) : "cc", "memory"); |
67 | return size; | 67 | return size; |
@@ -82,7 +82,7 @@ static size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x) | |||
82 | tmp1 = -4096UL; | 82 | tmp1 = -4096UL; |
83 | asm volatile( | 83 | asm volatile( |
84 | "0: .insn ss,0xc80000000000,0(%0,%1),0(%2),0\n" | 84 | "0: .insn ss,0xc80000000000,0(%0,%1),0(%2),0\n" |
85 | " jz 4f\n" | 85 | "6: jz 4f\n" |
86 | "1:"ALR" %0,%3\n" | 86 | "1:"ALR" %0,%3\n" |
87 | " "SLR" %1,%3\n" | 87 | " "SLR" %1,%3\n" |
88 | " "SLR" %2,%3\n" | 88 | " "SLR" %2,%3\n" |
@@ -93,11 +93,11 @@ static size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x) | |||
93 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ | 93 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ |
94 | " jnh 5f\n" | 94 | " jnh 5f\n" |
95 | "3: .insn ss,0xc80000000000,0(%4,%1),0(%2),0\n" | 95 | "3: .insn ss,0xc80000000000,0(%4,%1),0(%2),0\n" |
96 | " "SLR" %0,%4\n" | 96 | "7:"SLR" %0,%4\n" |
97 | " j 5f\n" | 97 | " j 5f\n" |
98 | "4:"SLR" %0,%0\n" | 98 | "4:"SLR" %0,%0\n" |
99 | "5: \n" | 99 | "5: \n" |
100 | EX_TABLE(0b,2b) EX_TABLE(3b,5b) | 100 | EX_TABLE(0b,2b) EX_TABLE(3b,5b) EX_TABLE(6b,2b) EX_TABLE(7b,5b) |
101 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) | 101 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) |
102 | : "d" (reg0) : "cc", "memory"); | 102 | : "d" (reg0) : "cc", "memory"); |
103 | return size; | 103 | return size; |
diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c index d2ffbadb51a7..07deaeee14c8 100644 --- a/arch/s390/lib/uaccess_std.c +++ b/arch/s390/lib/uaccess_std.c | |||
@@ -36,12 +36,12 @@ size_t copy_from_user_std(size_t size, const void __user *ptr, void *x) | |||
36 | tmp1 = -256UL; | 36 | tmp1 = -256UL; |
37 | asm volatile( | 37 | asm volatile( |
38 | "0: mvcp 0(%0,%2),0(%1),%3\n" | 38 | "0: mvcp 0(%0,%2),0(%1),%3\n" |
39 | " jz 8f\n" | 39 | "10:jz 8f\n" |
40 | "1:"ALR" %0,%3\n" | 40 | "1:"ALR" %0,%3\n" |
41 | " la %1,256(%1)\n" | 41 | " la %1,256(%1)\n" |
42 | " la %2,256(%2)\n" | 42 | " la %2,256(%2)\n" |
43 | "2: mvcp 0(%0,%2),0(%1),%3\n" | 43 | "2: mvcp 0(%0,%2),0(%1),%3\n" |
44 | " jnz 1b\n" | 44 | "11:jnz 1b\n" |
45 | " j 8f\n" | 45 | " j 8f\n" |
46 | "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ | 46 | "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ |
47 | " "LHI" %3,-4096\n" | 47 | " "LHI" %3,-4096\n" |
@@ -50,7 +50,7 @@ size_t copy_from_user_std(size_t size, const void __user *ptr, void *x) | |||
50 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ | 50 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ |
51 | " jnh 5f\n" | 51 | " jnh 5f\n" |
52 | "4: mvcp 0(%4,%2),0(%1),%3\n" | 52 | "4: mvcp 0(%4,%2),0(%1),%3\n" |
53 | " "SLR" %0,%4\n" | 53 | "12:"SLR" %0,%4\n" |
54 | " "ALR" %2,%4\n" | 54 | " "ALR" %2,%4\n" |
55 | "5:"LHI" %4,-1\n" | 55 | "5:"LHI" %4,-1\n" |
56 | " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ | 56 | " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ |
@@ -65,6 +65,7 @@ size_t copy_from_user_std(size_t size, const void __user *ptr, void *x) | |||
65 | "8:"SLR" %0,%0\n" | 65 | "8:"SLR" %0,%0\n" |
66 | "9: \n" | 66 | "9: \n" |
67 | EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,5b) | 67 | EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,5b) |
68 | EX_TABLE(10b,3b) EX_TABLE(11b,3b) EX_TABLE(12b,5b) | ||
68 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) | 69 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) |
69 | : : "cc", "memory"); | 70 | : : "cc", "memory"); |
70 | return size; | 71 | return size; |
@@ -85,12 +86,12 @@ size_t copy_to_user_std(size_t size, void __user *ptr, const void *x) | |||
85 | tmp1 = -256UL; | 86 | tmp1 = -256UL; |
86 | asm volatile( | 87 | asm volatile( |
87 | "0: mvcs 0(%0,%1),0(%2),%3\n" | 88 | "0: mvcs 0(%0,%1),0(%2),%3\n" |
88 | " jz 5f\n" | 89 | "7: jz 5f\n" |
89 | "1:"ALR" %0,%3\n" | 90 | "1:"ALR" %0,%3\n" |
90 | " la %1,256(%1)\n" | 91 | " la %1,256(%1)\n" |
91 | " la %2,256(%2)\n" | 92 | " la %2,256(%2)\n" |
92 | "2: mvcs 0(%0,%1),0(%2),%3\n" | 93 | "2: mvcs 0(%0,%1),0(%2),%3\n" |
93 | " jnz 1b\n" | 94 | "8: jnz 1b\n" |
94 | " j 5f\n" | 95 | " j 5f\n" |
95 | "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ | 96 | "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ |
96 | " "LHI" %3,-4096\n" | 97 | " "LHI" %3,-4096\n" |
@@ -99,11 +100,12 @@ size_t copy_to_user_std(size_t size, void __user *ptr, const void *x) | |||
99 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ | 100 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ |
100 | " jnh 6f\n" | 101 | " jnh 6f\n" |
101 | "4: mvcs 0(%4,%1),0(%2),%3\n" | 102 | "4: mvcs 0(%4,%1),0(%2),%3\n" |
102 | " "SLR" %0,%4\n" | 103 | "9:"SLR" %0,%4\n" |
103 | " j 6f\n" | 104 | " j 6f\n" |
104 | "5:"SLR" %0,%0\n" | 105 | "5:"SLR" %0,%0\n" |
105 | "6: \n" | 106 | "6: \n" |
106 | EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b) | 107 | EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b) |
108 | EX_TABLE(7b,3b) EX_TABLE(8b,3b) EX_TABLE(9b,6b) | ||
107 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) | 109 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) |
108 | : : "cc", "memory"); | 110 | : : "cc", "memory"); |
109 | return size; | 111 | return size; |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index c60bfb309ce6..2757c5616a07 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
@@ -279,7 +279,10 @@ int s390_enable_sie(void) | |||
279 | /* lets check if we are allowed to replace the mm */ | 279 | /* lets check if we are allowed to replace the mm */ |
280 | task_lock(tsk); | 280 | task_lock(tsk); |
281 | if (!tsk->mm || atomic_read(&tsk->mm->mm_users) > 1 || | 281 | if (!tsk->mm || atomic_read(&tsk->mm->mm_users) > 1 || |
282 | tsk->mm != tsk->active_mm || !hlist_empty(&tsk->mm->ioctx_list)) { | 282 | #ifdef CONFIG_AIO |
283 | !hlist_empty(&tsk->mm->ioctx_list) || | ||
284 | #endif | ||
285 | tsk->mm != tsk->active_mm) { | ||
283 | task_unlock(tsk); | 286 | task_unlock(tsk); |
284 | return -EINVAL; | 287 | return -EINVAL; |
285 | } | 288 | } |
@@ -295,7 +298,10 @@ int s390_enable_sie(void) | |||
295 | /* Now lets check again if something happened */ | 298 | /* Now lets check again if something happened */ |
296 | task_lock(tsk); | 299 | task_lock(tsk); |
297 | if (!tsk->mm || atomic_read(&tsk->mm->mm_users) > 1 || | 300 | if (!tsk->mm || atomic_read(&tsk->mm->mm_users) > 1 || |
298 | tsk->mm != tsk->active_mm || !hlist_empty(&tsk->mm->ioctx_list)) { | 301 | #ifdef CONFIG_AIO |
302 | !hlist_empty(&tsk->mm->ioctx_list) || | ||
303 | #endif | ||
304 | tsk->mm != tsk->active_mm) { | ||
299 | mmput(mm); | 305 | mmput(mm); |
300 | task_unlock(tsk); | 306 | task_unlock(tsk); |
301 | return -EINVAL; | 307 | return -EINVAL; |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index dad0449475b6..53b8c255360a 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -2508,8 +2508,6 @@ int dasd_generic_restore_device(struct ccw_device *cdev) | |||
2508 | device->stopped &= ~DASD_UNRESUMED_PM; | 2508 | device->stopped &= ~DASD_UNRESUMED_PM; |
2509 | 2509 | ||
2510 | dasd_schedule_device_bh(device); | 2510 | dasd_schedule_device_bh(device); |
2511 | if (device->block) | ||
2512 | dasd_schedule_block_bh(device->block); | ||
2513 | 2511 | ||
2514 | if (device->discipline->restore) | 2512 | if (device->discipline->restore) |
2515 | rc = device->discipline->restore(device); | 2513 | rc = device->discipline->restore(device); |
@@ -2520,6 +2518,9 @@ int dasd_generic_restore_device(struct ccw_device *cdev) | |||
2520 | */ | 2518 | */ |
2521 | device->stopped |= DASD_UNRESUMED_PM; | 2519 | device->stopped |= DASD_UNRESUMED_PM; |
2522 | 2520 | ||
2521 | if (device->block) | ||
2522 | dasd_schedule_block_bh(device->block); | ||
2523 | |||
2523 | dasd_put_device(device); | 2524 | dasd_put_device(device); |
2524 | return 0; | 2525 | return 0; |
2525 | } | 2526 | } |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index ab3521755588..0be7c15f45c5 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -2338,6 +2338,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev, | |||
2338 | /* Calculate number of blocks/records per track. */ | 2338 | /* Calculate number of blocks/records per track. */ |
2339 | blksize = block->bp_block; | 2339 | blksize = block->bp_block; |
2340 | blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize); | 2340 | blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize); |
2341 | if (blk_per_trk == 0) | ||
2342 | return ERR_PTR(-EINVAL); | ||
2341 | /* Calculate record id of first and last block. */ | 2343 | /* Calculate record id of first and last block. */ |
2342 | first_rec = first_trk = blk_rq_pos(req) >> block->s2b_shift; | 2344 | first_rec = first_trk = blk_rq_pos(req) >> block->s2b_shift; |
2343 | first_offs = sector_div(first_trk, blk_per_trk); | 2345 | first_offs = sector_div(first_trk, blk_per_trk); |
@@ -3211,6 +3213,7 @@ int dasd_eckd_pm_freeze(struct dasd_device *device) | |||
3211 | int dasd_eckd_restore_device(struct dasd_device *device) | 3213 | int dasd_eckd_restore_device(struct dasd_device *device) |
3212 | { | 3214 | { |
3213 | struct dasd_eckd_private *private; | 3215 | struct dasd_eckd_private *private; |
3216 | struct dasd_eckd_characteristics temp_rdc_data; | ||
3214 | int is_known, rc; | 3217 | int is_known, rc; |
3215 | struct dasd_uid temp_uid; | 3218 | struct dasd_uid temp_uid; |
3216 | 3219 | ||
@@ -3245,15 +3248,17 @@ int dasd_eckd_restore_device(struct dasd_device *device) | |||
3245 | dasd_eckd_read_features(device); | 3248 | dasd_eckd_read_features(device); |
3246 | 3249 | ||
3247 | /* Read Device Characteristics */ | 3250 | /* Read Device Characteristics */ |
3248 | memset(&private->rdc_data, 0, sizeof(private->rdc_data)); | ||
3249 | rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC, | 3251 | rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC, |
3250 | &private->rdc_data, 64); | 3252 | &temp_rdc_data, 64); |
3251 | if (rc) { | 3253 | if (rc) { |
3252 | DBF_EVENT(DBF_WARNING, | 3254 | DBF_EVENT(DBF_WARNING, |
3253 | "Read device characteristics failed, rc=%d for " | 3255 | "Read device characteristics failed, rc=%d for " |
3254 | "device: %s", rc, dev_name(&device->cdev->dev)); | 3256 | "device: %s", rc, dev_name(&device->cdev->dev)); |
3255 | goto out_err; | 3257 | goto out_err; |
3256 | } | 3258 | } |
3259 | spin_lock(get_ccwdev_lock(device->cdev)); | ||
3260 | memcpy(&private->rdc_data, &temp_rdc_data, sizeof(temp_rdc_data)); | ||
3261 | spin_unlock(get_ccwdev_lock(device->cdev)); | ||
3257 | 3262 | ||
3258 | /* add device to alias management */ | 3263 | /* add device to alias management */ |
3259 | dasd_alias_add_device(device); | 3264 | dasd_alias_add_device(device); |
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index d6a022f55e92..62ddf5202b79 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c | |||
@@ -1361,11 +1361,13 @@ static int raw3270_pm_start(struct ccw_device *cdev) | |||
1361 | 1361 | ||
1362 | void raw3270_pm_unfreeze(struct raw3270_view *view) | 1362 | void raw3270_pm_unfreeze(struct raw3270_view *view) |
1363 | { | 1363 | { |
1364 | #ifdef CONFIG_TN3270_CONSOLE | ||
1364 | struct raw3270 *rp; | 1365 | struct raw3270 *rp; |
1365 | 1366 | ||
1366 | rp = view->dev; | 1367 | rp = view->dev; |
1367 | if (rp && test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) | 1368 | if (rp && test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) |
1368 | ccw_device_force_console(); | 1369 | ccw_device_force_console(); |
1370 | #endif | ||
1369 | } | 1371 | } |
1370 | 1372 | ||
1371 | static struct ccw_device_id raw3270_id[] = { | 1373 | static struct ccw_device_id raw3270_id[] = { |
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c index 6565f027791e..7eab9ab9f406 100644 --- a/drivers/s390/cio/blacklist.c +++ b/drivers/s390/cio/blacklist.c | |||
@@ -265,13 +265,11 @@ struct ccwdev_iter { | |||
265 | static void * | 265 | static void * |
266 | cio_ignore_proc_seq_start(struct seq_file *s, loff_t *offset) | 266 | cio_ignore_proc_seq_start(struct seq_file *s, loff_t *offset) |
267 | { | 267 | { |
268 | struct ccwdev_iter *iter; | 268 | struct ccwdev_iter *iter = s->private; |
269 | 269 | ||
270 | if (*offset >= (__MAX_SUBCHANNEL + 1) * (__MAX_SSID + 1)) | 270 | if (*offset >= (__MAX_SUBCHANNEL + 1) * (__MAX_SSID + 1)) |
271 | return NULL; | 271 | return NULL; |
272 | iter = kzalloc(sizeof(struct ccwdev_iter), GFP_KERNEL); | 272 | memset(iter, 0, sizeof(*iter)); |
273 | if (!iter) | ||
274 | return ERR_PTR(-ENOMEM); | ||
275 | iter->ssid = *offset / (__MAX_SUBCHANNEL + 1); | 273 | iter->ssid = *offset / (__MAX_SUBCHANNEL + 1); |
276 | iter->devno = *offset % (__MAX_SUBCHANNEL + 1); | 274 | iter->devno = *offset % (__MAX_SUBCHANNEL + 1); |
277 | return iter; | 275 | return iter; |
@@ -280,8 +278,6 @@ cio_ignore_proc_seq_start(struct seq_file *s, loff_t *offset) | |||
280 | static void | 278 | static void |
281 | cio_ignore_proc_seq_stop(struct seq_file *s, void *it) | 279 | cio_ignore_proc_seq_stop(struct seq_file *s, void *it) |
282 | { | 280 | { |
283 | if (!IS_ERR(it)) | ||
284 | kfree(it); | ||
285 | } | 281 | } |
286 | 282 | ||
287 | static void * | 283 | static void * |
@@ -378,14 +374,15 @@ static const struct seq_operations cio_ignore_proc_seq_ops = { | |||
378 | static int | 374 | static int |
379 | cio_ignore_proc_open(struct inode *inode, struct file *file) | 375 | cio_ignore_proc_open(struct inode *inode, struct file *file) |
380 | { | 376 | { |
381 | return seq_open(file, &cio_ignore_proc_seq_ops); | 377 | return seq_open_private(file, &cio_ignore_proc_seq_ops, |
378 | sizeof(struct ccwdev_iter)); | ||
382 | } | 379 | } |
383 | 380 | ||
384 | static const struct file_operations cio_ignore_proc_fops = { | 381 | static const struct file_operations cio_ignore_proc_fops = { |
385 | .open = cio_ignore_proc_open, | 382 | .open = cio_ignore_proc_open, |
386 | .read = seq_read, | 383 | .read = seq_read, |
387 | .llseek = seq_lseek, | 384 | .llseek = seq_lseek, |
388 | .release = seq_release, | 385 | .release = seq_release_private, |
389 | .write = cio_ignore_write, | 386 | .write = cio_ignore_write, |
390 | }; | 387 | }; |
391 | 388 | ||
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 40002830d48a..8ab51608da55 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c | |||
@@ -393,7 +393,6 @@ int chp_new(struct chp_id chpid) | |||
393 | chp->state = 1; | 393 | chp->state = 1; |
394 | chp->dev.parent = &channel_subsystems[chpid.cssid]->device; | 394 | chp->dev.parent = &channel_subsystems[chpid.cssid]->device; |
395 | chp->dev.release = chp_release; | 395 | chp->dev.release = chp_release; |
396 | dev_set_name(&chp->dev, "chp%x.%02x", chpid.cssid, chpid.id); | ||
397 | 396 | ||
398 | /* Obtain channel path description and fill it in. */ | 397 | /* Obtain channel path description and fill it in. */ |
399 | ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc); | 398 | ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc); |
@@ -411,6 +410,7 @@ int chp_new(struct chp_id chpid) | |||
411 | } else { | 410 | } else { |
412 | chp->cmg = -1; | 411 | chp->cmg = -1; |
413 | } | 412 | } |
413 | dev_set_name(&chp->dev, "chp%x.%02x", chpid.cssid, chpid.id); | ||
414 | 414 | ||
415 | /* make it known to the system */ | 415 | /* make it known to the system */ |
416 | ret = device_register(&chp->dev); | 416 | ret = device_register(&chp->dev); |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index f780bdd3a04e..2ee093ec86e4 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -1609,7 +1609,7 @@ int ccw_purge_blacklisted(void) | |||
1609 | return 0; | 1609 | return 0; |
1610 | } | 1610 | } |
1611 | 1611 | ||
1612 | static void device_set_disconnected(struct ccw_device *cdev) | 1612 | void ccw_device_set_disconnected(struct ccw_device *cdev) |
1613 | { | 1613 | { |
1614 | if (!cdev) | 1614 | if (!cdev) |
1615 | return; | 1615 | return; |
@@ -1705,7 +1705,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int slow) | |||
1705 | ccw_device_trigger_reprobe(cdev); | 1705 | ccw_device_trigger_reprobe(cdev); |
1706 | break; | 1706 | break; |
1707 | case DISC: | 1707 | case DISC: |
1708 | device_set_disconnected(cdev); | 1708 | ccw_device_set_disconnected(cdev); |
1709 | break; | 1709 | break; |
1710 | default: | 1710 | default: |
1711 | break; | 1711 | break; |
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h index ed39a2caaf47..246c6482842c 100644 --- a/drivers/s390/cio/device.h +++ b/drivers/s390/cio/device.h | |||
@@ -125,6 +125,7 @@ int ccw_device_stlck(struct ccw_device *); | |||
125 | void ccw_device_trigger_reprobe(struct ccw_device *); | 125 | void ccw_device_trigger_reprobe(struct ccw_device *); |
126 | void ccw_device_kill_io(struct ccw_device *); | 126 | void ccw_device_kill_io(struct ccw_device *); |
127 | int ccw_device_notify(struct ccw_device *, int); | 127 | int ccw_device_notify(struct ccw_device *, int); |
128 | void ccw_device_set_disconnected(struct ccw_device *cdev); | ||
128 | void ccw_device_set_notoper(struct ccw_device *cdev); | 129 | void ccw_device_set_notoper(struct ccw_device *cdev); |
129 | 130 | ||
130 | /* qdio needs this. */ | 131 | /* qdio needs this. */ |
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index e728ce447f6e..b9613d7df9ef 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -387,19 +387,35 @@ ccw_device_done(struct ccw_device *cdev, int state) | |||
387 | 387 | ||
388 | cdev->private->state = state; | 388 | cdev->private->state = state; |
389 | 389 | ||
390 | if (state == DEV_STATE_BOXED) { | 390 | switch (state) { |
391 | case DEV_STATE_BOXED: | ||
391 | CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n", | 392 | CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n", |
392 | cdev->private->dev_id.devno, sch->schid.sch_no); | 393 | cdev->private->dev_id.devno, sch->schid.sch_no); |
393 | if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED)) | 394 | if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED)) |
394 | ccw_device_schedule_sch_unregister(cdev); | 395 | ccw_device_schedule_sch_unregister(cdev); |
395 | cdev->private->flags.donotify = 0; | 396 | cdev->private->flags.donotify = 0; |
396 | } | 397 | break; |
397 | if (state == DEV_STATE_NOT_OPER) { | 398 | case DEV_STATE_NOT_OPER: |
398 | CIO_MSG_EVENT(0, "Device %04x gone on subchannel %04x\n", | 399 | CIO_MSG_EVENT(0, "Device %04x gone on subchannel %04x\n", |
399 | cdev->private->dev_id.devno, sch->schid.sch_no); | 400 | cdev->private->dev_id.devno, sch->schid.sch_no); |
400 | if (!ccw_device_notify(cdev, CIO_GONE)) | 401 | if (!ccw_device_notify(cdev, CIO_GONE)) |
401 | ccw_device_schedule_sch_unregister(cdev); | 402 | ccw_device_schedule_sch_unregister(cdev); |
403 | else | ||
404 | ccw_device_set_disconnected(cdev); | ||
402 | cdev->private->flags.donotify = 0; | 405 | cdev->private->flags.donotify = 0; |
406 | break; | ||
407 | case DEV_STATE_DISCONNECTED: | ||
408 | CIO_MSG_EVENT(0, "Disconnected device %04x on subchannel " | ||
409 | "%04x\n", cdev->private->dev_id.devno, | ||
410 | sch->schid.sch_no); | ||
411 | if (!ccw_device_notify(cdev, CIO_NO_PATH)) | ||
412 | ccw_device_schedule_sch_unregister(cdev); | ||
413 | else | ||
414 | ccw_device_set_disconnected(cdev); | ||
415 | cdev->private->flags.donotify = 0; | ||
416 | break; | ||
417 | default: | ||
418 | break; | ||
403 | } | 419 | } |
404 | 420 | ||
405 | if (cdev->private->flags.donotify) { | 421 | if (cdev->private->flags.donotify) { |
@@ -671,6 +687,10 @@ ccw_device_offline(struct ccw_device *cdev) | |||
671 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); | 687 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); |
672 | return 0; | 688 | return 0; |
673 | } | 689 | } |
690 | if (cdev->private->state == DEV_STATE_BOXED) { | ||
691 | ccw_device_done(cdev, DEV_STATE_BOXED); | ||
692 | return 0; | ||
693 | } | ||
674 | if (ccw_device_is_orphan(cdev)) { | 694 | if (ccw_device_is_orphan(cdev)) { |
675 | ccw_device_done(cdev, DEV_STATE_OFFLINE); | 695 | ccw_device_done(cdev, DEV_STATE_OFFLINE); |
676 | return 0; | 696 | return 0; |
@@ -730,11 +750,10 @@ ccw_device_recog_notoper(struct ccw_device *cdev, enum dev_event dev_event) | |||
730 | static void ccw_device_generic_notoper(struct ccw_device *cdev, | 750 | static void ccw_device_generic_notoper(struct ccw_device *cdev, |
731 | enum dev_event dev_event) | 751 | enum dev_event dev_event) |
732 | { | 752 | { |
733 | struct subchannel *sch; | 753 | if (!ccw_device_notify(cdev, CIO_GONE)) |
734 | 754 | ccw_device_schedule_sch_unregister(cdev); | |
735 | ccw_device_set_notoper(cdev); | 755 | else |
736 | sch = to_subchannel(cdev->dev.parent); | 756 | ccw_device_set_disconnected(cdev); |
737 | css_schedule_eval(sch->schid); | ||
738 | } | 757 | } |
739 | 758 | ||
740 | /* | 759 | /* |
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c index c20d4790258e..5677b40e4ac0 100644 --- a/drivers/s390/crypto/zcrypt_pcixcc.c +++ b/drivers/s390/crypto/zcrypt_pcixcc.c | |||
@@ -361,7 +361,7 @@ static void rng_type6CPRB_msgX(struct ap_device *ap_dev, | |||
361 | .ToCardLen1 = sizeof *msg - sizeof(msg->hdr), | 361 | .ToCardLen1 = sizeof *msg - sizeof(msg->hdr), |
362 | .FromCardLen1 = sizeof *msg - sizeof(msg->hdr), | 362 | .FromCardLen1 = sizeof *msg - sizeof(msg->hdr), |
363 | }; | 363 | }; |
364 | static struct CPRBX static_cprbx = { | 364 | static struct CPRBX local_cprbx = { |
365 | .cprb_len = 0x00dc, | 365 | .cprb_len = 0x00dc, |
366 | .cprb_ver_id = 0x02, | 366 | .cprb_ver_id = 0x02, |
367 | .func_id = {0x54, 0x32}, | 367 | .func_id = {0x54, 0x32}, |
@@ -372,7 +372,7 @@ static void rng_type6CPRB_msgX(struct ap_device *ap_dev, | |||
372 | 372 | ||
373 | msg->hdr = static_type6_hdrX; | 373 | msg->hdr = static_type6_hdrX; |
374 | msg->hdr.FromCardLen2 = random_number_length, | 374 | msg->hdr.FromCardLen2 = random_number_length, |
375 | msg->cprbx = static_cprbx; | 375 | msg->cprbx = local_cprbx; |
376 | msg->cprbx.rpl_datal = random_number_length, | 376 | msg->cprbx.rpl_datal = random_number_length, |
377 | msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid); | 377 | msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid); |
378 | memcpy(msg->function_code, msg->hdr.function_code, 0x02); | 378 | memcpy(msg->function_code, msg->hdr.function_code, 0x02); |
@@ -561,7 +561,8 @@ static int convert_response_ica(struct zcrypt_device *zdev, | |||
561 | if (msg->cprbx.cprb_ver_id == 0x02) | 561 | if (msg->cprbx.cprb_ver_id == 0x02) |
562 | return convert_type86_ica(zdev, reply, | 562 | return convert_type86_ica(zdev, reply, |
563 | outputdata, outputdatalength); | 563 | outputdata, outputdatalength); |
564 | /* no break, incorrect cprb version is an unknown response */ | 564 | /* Fall through, no break, incorrect cprb version is an unknown |
565 | * response */ | ||
565 | default: /* Unknown response type, this should NEVER EVER happen */ | 566 | default: /* Unknown response type, this should NEVER EVER happen */ |
566 | zdev->online = 0; | 567 | zdev->online = 0; |
567 | return -EAGAIN; /* repeat the request on a different device. */ | 568 | return -EAGAIN; /* repeat the request on a different device. */ |
@@ -587,7 +588,8 @@ static int convert_response_xcrb(struct zcrypt_device *zdev, | |||
587 | } | 588 | } |
588 | if (msg->cprbx.cprb_ver_id == 0x02) | 589 | if (msg->cprbx.cprb_ver_id == 0x02) |
589 | return convert_type86_xcrb(zdev, reply, xcRB); | 590 | return convert_type86_xcrb(zdev, reply, xcRB); |
590 | /* no break, incorrect cprb version is an unknown response */ | 591 | /* Fall through, no break, incorrect cprb version is an unknown |
592 | * response */ | ||
591 | default: /* Unknown response type, this should NEVER EVER happen */ | 593 | default: /* Unknown response type, this should NEVER EVER happen */ |
592 | xcRB->status = 0x0008044DL; /* HDD_InvalidParm */ | 594 | xcRB->status = 0x0008044DL; /* HDD_InvalidParm */ |
593 | zdev->online = 0; | 595 | zdev->online = 0; |
@@ -610,7 +612,8 @@ static int convert_response_rng(struct zcrypt_device *zdev, | |||
610 | return -EINVAL; | 612 | return -EINVAL; |
611 | if (msg->cprbx.cprb_ver_id == 0x02) | 613 | if (msg->cprbx.cprb_ver_id == 0x02) |
612 | return convert_type86_rng(zdev, reply, data); | 614 | return convert_type86_rng(zdev, reply, data); |
613 | /* no break, incorrect cprb version is an unknown response */ | 615 | /* Fall through, no break, incorrect cprb version is an unknown |
616 | * response */ | ||
614 | default: /* Unknown response type, this should NEVER EVER happen */ | 617 | default: /* Unknown response type, this should NEVER EVER happen */ |
615 | zdev->online = 0; | 618 | zdev->online = 0; |
616 | return -EAGAIN; /* repeat the request on a different device. */ | 619 | return -EAGAIN; /* repeat the request on a different device. */ |
diff --git a/include/linux/elf.h b/include/linux/elf.h index 45a937be6d38..90a4ed0ea0e5 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h | |||
@@ -361,6 +361,7 @@ typedef struct elf64_shdr { | |||
361 | #define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ | 361 | #define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ |
362 | #define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ | 362 | #define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ |
363 | #define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ | 363 | #define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ |
364 | #define NT_PRXSTATUS 0x300 /* s390 upper register halves */ | ||
364 | 365 | ||
365 | 366 | ||
366 | /* Note header in a PT_NOTE section */ | 367 | /* Note header in a PT_NOTE section */ |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 891155817bc6..30df5865ecbe 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -346,8 +346,9 @@ config SLUB_STATS | |||
346 | 346 | ||
347 | config DEBUG_KMEMLEAK | 347 | config DEBUG_KMEMLEAK |
348 | bool "Kernel memory leak detector" | 348 | bool "Kernel memory leak detector" |
349 | depends on DEBUG_KERNEL && EXPERIMENTAL && (X86 || ARM || PPC) && \ | 349 | depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \ |
350 | !MEMORY_HOTPLUG | 350 | (X86 || ARM || PPC || S390) |
351 | |||
351 | select DEBUG_FS if SYSFS | 352 | select DEBUG_FS if SYSFS |
352 | select STACKTRACE if STACKTRACE_SUPPORT | 353 | select STACKTRACE if STACKTRACE_SUPPORT |
353 | select KALLSYMS | 354 | select KALLSYMS |
@@ -370,7 +371,7 @@ config DEBUG_KMEMLEAK | |||
370 | config DEBUG_KMEMLEAK_EARLY_LOG_SIZE | 371 | config DEBUG_KMEMLEAK_EARLY_LOG_SIZE |
371 | int "Maximum kmemleak early log entries" | 372 | int "Maximum kmemleak early log entries" |
372 | depends on DEBUG_KMEMLEAK | 373 | depends on DEBUG_KMEMLEAK |
373 | range 200 2000 | 374 | range 200 40000 |
374 | default 400 | 375 | default 400 |
375 | help | 376 | help |
376 | Kmemleak must track all the memory allocations to avoid | 377 | Kmemleak must track all the memory allocations to avoid |