* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: (21 commits) [S390] dasd: fix race condition in resume code [S390] Add EX_TABLE for addressing exception in usercopy functions. [S390] 64-bit register support for 31-bit processes [S390] hibernate: Use correct place for CPU address in lowcore [S390] pm: ignore time spend in suspended state [S390] zcrypt: Improve some comments [S390] zcrypt: Fix sparse warning. [S390] perf_counter: fix vdso detection [S390] ftrace: drop nmi protection [S390] compat: fix truncate system call wrapper [S390] Provide arch specific mdelay implementation. [S390] Fix enabled udelay for short delays. [S390] cio: allow setting boxed devices offline [S390] cio: make not operational handling consistent [S390] cio: make disconnected handling consistent [S390] Fix memory leak in /proc/cio_ignore [S390] cio: channel path memory leak [S390] module: fix memory leak in s390 module loader [S390] Enable kmemleak on s390. [S390] 3270 console build fix ...
Unified · Split
| @@ -14,10 +14,11 @@ · 13 unmodified lines | ||
| 14 | 14 | #ifndef _S390_DELAY_H |
| 15 | 15 | #define _S390_DELAY_H |
| 16 | 16 | |
| 17 | −extern void __udelay(unsigned long usecs); | |
| 18 | −extern void udelay_simple(unsigned long usecs); | |
| 17 | +extern void __udelay(unsigned long long usecs); | |
| 18 | +extern void udelay_simple(unsigned long long usecs); | |
| 19 | 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 | 24 | #endif /* defined(_S390_DELAY_H) */ |
| @@ -92,6 +92,18 @@ · 91 unmodified lines | ||
| 92 | 92 | /* Keep this the last entry. */ |
| 93 | 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 | 108 | * These are used to set parameters in the core dumps. |
| 97 | 109 | */ |
| @@ -311,6 +311,10 @@ typedef struct · 310 unmodified lines | ||
| 311 | 311 | __u32 orig_gpr2; |
| 312 | 312 | } s390_compat_regs; |
| 313 | 313 | |
| 314 | +typedef struct | |
| 315 | +{ | |
| 316 | + __u32 gprs_high[NUM_GPRS]; | |
| 317 | +} s390_compat_regs_high; | |
| 314 | 318 | |
| 315 | 319 | #ifdef __KERNEL__ |
| 316 | 320 | |
| @@ -9,6 +9,21 @@ · 8 unmodified lines | ||
| 9 | 9 | #ifndef _ASM_S390_UCONTEXT_H |
| 10 | 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 | 27 | struct ucontext { |
| 13 | 28 | unsigned long uc_flags; |
| 14 | 29 | struct ucontext *uc_link; |
| @@ -39,6 +39,7 @@ typedef struct · 38 unmodified lines | ||
| 39 | 39 | struct sigcontext32 sc; |
| 40 | 40 | _sigregs32 sregs; |
| 41 | 41 | int signo; |
| 42 | + __u32 gprs_high[NUM_GPRS]; | |
| 42 | 43 | __u8 retcode[S390_SYSCALL_SIZE]; |
| 43 | 44 | } sigframe32; |
| 44 | 45 | |
| @@ -48,6 +49,7 @@ typedef struct · 3 unmodified lines | ||
| 48 | 49 | __u8 retcode[S390_SYSCALL_SIZE]; |
| 49 | 50 | compat_siginfo_t info; |
| 50 | 51 | struct ucontext32 uc; |
| 52 | + __u32 gprs_high[NUM_GPRS]; | |
| 51 | 53 | } rt_sigframe32; |
| 52 | 54 | |
| 53 | 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) · 290 unmodified lines | ||
| 344 | 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 | 373 | asmlinkage long sys32_sigreturn(void) |
| 348 | 374 | { |
| 349 | 375 | struct pt_regs *regs = task_pt_regs(current); |
| @@ -363,6 +389,8 @@ asmlinkage long sys32_sigreturn(void) · 13 unmodified lines | ||
| 363 | 389 | |
| 364 | 390 | if (restore_sigregs32(regs, &frame->sregs)) |
| 365 | 391 | goto badframe; |
| 392 | + if (restore_sigregs_gprs_high(regs, frame->gprs_high)) | |
| 393 | + goto badframe; | |
| 366 | 394 | |
| 367 | 395 | return regs->gprs[2]; |
| 368 | 396 | |
| @@ -394,6 +422,8 @@ asmlinkage long sys32_rt_sigreturn(void) · 25 unmodified lines | ||
| 394 | 422 | |
| 395 | 423 | if (restore_sigregs32(regs, &frame->uc.uc_mcontext)) |
| 396 | 424 | goto badframe; |
| 425 | + if (restore_sigregs_gprs_high(regs, frame->gprs_high)) | |
| 426 | + goto badframe; | |
| 397 | 427 | |
| 398 | 428 | err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp); |
| 399 | 429 | st.ss_sp = compat_ptr(ss_sp); |
| @@ -474,6 +504,8 @@ static int setup_frame32(int sig, struct k_sigaction *ka, · 74 unmodified lines | ||
| 474 | 504 | |
| 475 | 505 | if (save_sigregs32(regs, &frame->sregs)) |
| 476 | 506 | goto give_sigsegv; |
| 507 | + if (save_sigregs_gprs_high(regs, frame->gprs_high)) | |
| 508 | + goto give_sigsegv; | |
| 477 | 509 | if (__put_user((unsigned long) &frame->sregs, &frame->sc.sregs)) |
| 478 | 510 | goto give_sigsegv; |
| 479 | 511 | |
| @@ -529,13 +561,14 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, · 49 unmodified lines | ||
| 529 | 561 | goto give_sigsegv; |
| 530 | 562 | |
| 531 | 563 | /* Create the ucontext. */ |
| 532 | − err |= __put_user(0, &frame->uc.uc_flags); | |
| 564 | + err |= __put_user(UC_EXTENDED, &frame->uc.uc_flags); | |
| 533 | 565 | err |= __put_user(0, &frame->uc.uc_link); |
| 534 | 566 | err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); |
| 535 | 567 | err |= __put_user(sas_ss_flags(regs->gprs[15]), |
| 536 | 568 | &frame->uc.uc_stack.ss_flags); |
| 537 | 569 | err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); |
| 538 | 570 | err |= save_sigregs32(regs, &frame->uc.uc_mcontext); |
| 571 | + err |= save_sigregs_gprs_high(regs, frame->gprs_high); | |
| 539 | 572 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); |
| 540 | 573 | if (err) |
| 541 | 574 | goto give_sigsegv; |
| @@ -409,7 +409,7 @@ sys32_munmap_wrapper: · 408 unmodified lines | ||
| 409 | 409 | .globl sys32_truncate_wrapper |
| 410 | 410 | sys32_truncate_wrapper: |
| 411 | 411 | llgtr %r2,%r2 # const char * |
| 412 | − llgfr %r3,%r3 # unsigned long | |
| 412 | + lgfr %r3,%r3 # long | |
| 413 | 413 | jg sys_truncate # branch to system call |
| 414 | 414 | |
| 415 | 415 | .globl sys32_ftruncate_wrapper |
| @@ -185,9 +185,6 @@ unsigned long prepare_ftrace_return(unsigned long ip, unsigned long parent) · 184 unmodified lines | ||
| 185 | 185 | { |
| 186 | 186 | struct ftrace_graph_ent trace; |
| 187 | 187 | |
| 188 | − /* Nmi's are currently unsupported. */ | |
| 189 | − if (unlikely(in_nmi())) | |
| 190 | − goto out; | |
| 191 | 188 | if (unlikely(atomic_read(¤t->tracing_graph_pause))) |
| 192 | 189 | goto out; |
| 193 | 190 | if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY) |
| @@ -55,6 +55,8 @@ void *module_alloc(unsigned long size) · 54 unmodified lines | ||
| 55 | 55 | /* Free memory returned from module_alloc */ |
| 56 | 56 | void module_free(struct module *mod, void *module_region) |
| 57 | 57 | { |
| 58 | + vfree(mod->arch.syminfo); | |
| 59 | + mod->arch.syminfo = NULL; | |
| 58 | 60 | vfree(module_region); |
| 59 | 61 | } |
| 60 | 62 | |
| @@ -402,6 +404,7 @@ int module_finalize(const Elf_Ehdr *hdr, · 341 unmodified lines | ||
| 402 | 404 | struct module *me) |
| 403 | 405 | { |
| 404 | 406 | vfree(me->arch.syminfo); |
| 407 | + me->arch.syminfo = NULL; | |
| 405 | 408 | return module_bug_finalize(hdr, sechdrs, me); |
| 406 | 409 | } |
| 407 | 410 | |
| @@ -57,6 +57,7 @@ · 56 unmodified lines | ||
| 57 | 57 | enum s390_regset { |
| 58 | 58 | REGSET_GENERAL, |
| 59 | 59 | REGSET_FP, |
| 60 | + REGSET_GENERAL_EXTENDED, | |
| 60 | 61 | }; |
| 61 | 62 | |
| 62 | 63 | static void |
| @@ -879,6 +880,67 @@ static int s390_compat_regs_set(struct task_struct *target, · 816 unmodified lines | ||
| 879 | 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 | 944 | static const struct user_regset s390_compat_regsets[] = { |
| 883 | 945 | [REGSET_GENERAL] = { |
| 884 | 946 | .core_note_type = NT_PRSTATUS, |
| @@ -896,6 +958,14 @@ static const struct user_regset s390_compat_regsets[] = { · 11 unmodified lines | ||
| 896 | 958 | .get = s390_fpregs_get, |
| 897 | 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 | 971 | static const struct user_regset_view user_s390_compat_view = { |
| @@ -729,7 +729,7 @@ static void __init setup_hwcaps(void) · 728 unmodified lines | ||
| 729 | 729 | |
| 730 | 730 | if ((facility_list & (1UL << (31 - 22))) |
| 731 | 731 | && (facility_list & (1UL << (31 - 30)))) |
| 732 | − elf_hwcap |= 1UL << 8; | |
| 732 | + elf_hwcap |= HWCAP_S390_ETF3EH; | |
| 733 | 733 | |
| 734 | 734 | /* |
| 735 | 735 | * Check for additional facilities with store-facility-list-extended. |
| @@ -748,11 +748,20 @@ static void __init setup_hwcaps(void) · 12 unmodified lines | ||
| 748 | 748 | __stfle(&facility_list_extended, 1) > 0) { |
| 749 | 749 | if ((facility_list_extended & (1ULL << (63 - 42))) |
| 750 | 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 | 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 | 766 | switch (S390_lowcore.cpu_id.machine) { |
| 758 | 767 | case 0x9672: |
| @@ -43,7 +43,7 @@ swsusp_arch_suspend: · 42 unmodified lines | ||
| 43 | 43 | lghi %r1,0x1000 |
| 44 | 44 | |
| 45 | 45 | /* Save CPU address */ |
| 46 | − stap __LC_CPU_ADDRESS(%r1) | |
| 46 | + stap __LC_CPU_ADDRESS(%r0) | |
| 47 | 47 | |
| 48 | 48 | /* Store registers */ |
| 49 | 49 | mvc 0x318(4,%r1),__SF_EMPTY(%r15) /* move prefix to lowcore */ |
| @@ -69,8 +69,21 @@ swsusp_arch_suspend: · 19 unmodified lines | ||
| 69 | 69 | stmg %r0,%r15,0x280(%r1) /* store general registers */ |
| 70 | 70 | |
| 71 | 71 | stpt 0x328(%r1) /* store timer */ |
| 72 | + stck __SF_EMPTY(%r15) /* store clock */ | |
| 72 | 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 | 87 | /* Activate DAT */ |
| 75 | 88 | stosm __SF_EMPTY(%r15),0x04 |
| 76 | 89 | |
| @@ -159,8 +172,7 @@ pgm_check_entry: · 82 unmodified lines | ||
| 159 | 172 | larl %r1,.Lresume_cpu /* Resume CPU address: r2 */ |
| 160 | 173 | stap 0(%r1) |
| 161 | 174 | llgh %r2,0(%r1) |
| 162 | − lghi %r3,0x1000 | |
| 163 | − llgh %r1,__LC_CPU_ADDRESS(%r3) /* Suspend CPU address: r1 */ | |
| 175 | + llgh %r1,__LC_CPU_ADDRESS(%r0) /* Suspend CPU address: r1 */ | |
| 164 | 176 | cgr %r1,%r2 |
| 165 | 177 | je restore_registers /* r1 = r2 -> nothing to do */ |
| 166 | 178 | larl %r4,.Lrestart_suspend_psw /* Set new restart PSW */ |
| @@ -200,8 +212,11 @@ restart_suspend: · 33 unmodified lines | ||
| 200 | 212 | |
| 201 | 213 | restore_registers: |
| 202 | 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 | 220 | spt 0x328(%r13) /* reprogram timer */ |
| 206 | 221 | //sckc 0x330(%r13) /* set clock comparator */ |
| 207 | 222 | |
| @@ -229,9 +244,6 @@ restore_registers: · 21 unmodified lines | ||
| 229 | 244 | /* Load old stack */ |
| 230 | 245 | lg %r15,0x2f8(%r13) |
| 231 | 246 | |
| 232 | − /* Pointer to save area */ | |
| 233 | − lghi %r13,0x1000 | |
| 234 | − | |
| 235 | 247 | /* Restore prefix register */ |
| 236 | 248 | spx 0x318(%r13) |
| 237 | 249 | |
| @@ -246,6 +246,13 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) · 245 unmodified lines | ||
| 246 | 246 | goto out_up; |
| 247 | 247 | } |
| 248 | 248 | |
| 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 | + | |
| 249 | 256 | /* |
| 250 | 257 | * our vma flags don't have VM_WRITE so by default, the process |
| 251 | 258 | * isn't allowed to write those pages. |
| @@ -267,14 +274,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) · 15 unmodified lines | ||
| 267 | 274 | VM_ALWAYSDUMP, |
| 268 | 275 | vdso_pagelist); |
| 269 | 276 | if (rc) |
| 270 | − goto out_up; | |
| 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 | − | |
| 277 | + current->mm->context.vdso_base = 0; | |
| 278 | 278 | out_up: |
| 279 | 279 | up_write(&mm->mmap_sem); |
| 280 | 280 | return rc; |
| @@ -51,6 +51,7 @@ SECTIONS · 50 unmodified lines | ||
| 51 | 51 | |
| 52 | 52 | . = ALIGN(PAGE_SIZE); |
| 53 | 53 | _eshared = .; /* End of shareable data */ |
| 54 | + _sdata = .; /* Start of data section */ | |
| 54 | 55 | |
| 55 | 56 | EXCEPTION_TABLE(16) :data |
| 56 | 57 | |
| @@ -25,13 +25,13 @@ void __delay(unsigned long loops) · 24 unmodified lines | ||
| 25 | 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 | 30 | unsigned long mask, cr0, cr0_saved; |
| 31 | 31 | u64 clock_saved; |
| 32 | 32 | |
| 33 | 33 | clock_saved = local_tick_disable(); |
| 34 | − set_clock_comparator(get_clock() + ((u64) usecs << 12)); | |
| 34 | + set_clock_comparator(get_clock() + (usecs << 12)); | |
| 35 | 35 | __ctl_store(cr0_saved, 0, 0); |
| 36 | 36 | cr0 = (cr0_saved & 0xffff00e0) | 0x00000800; |
| 37 | 37 | __ctl_load(cr0 , 0, 0); |
| @@ -46,20 +46,25 @@ static void __udelay_disabled(unsigned long usecs) · 8 unmodified lines | ||
| 46 | 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 | 51 | unsigned long mask; |
| 52 | − u64 end, time; | |
| 52 | + u64 clock_saved; | |
| 53 | + u64 end; | |
| 53 | 54 | |
| 54 | 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 | 57 | do { |
| 57 | − time = end < S390_lowcore.clock_comparator ? | |
| 58 | − end : S390_lowcore.clock_comparator; | |
| 59 | − set_clock_comparator(time); | |
| 58 | + clock_saved = 0; | |
| 59 | + if (end < S390_lowcore.clock_comparator) { | |
| 60 | + clock_saved = local_tick_disable(); | |
| 61 | + set_clock_comparator(end); | |
| 62 | + } | |
| 60 | 63 | trace_hardirqs_on(); |
| 61 | 64 | __load_psw_mask(mask); |
| 62 | 65 | local_irq_disable(); |
| 66 | + if (clock_saved) | |
| 67 | + local_tick_enable(clock_saved); | |
| 63 | 68 | } while (get_clock() < end); |
| 64 | 69 | set_clock_comparator(S390_lowcore.clock_comparator); |
| 65 | 70 | } |
| @@ -67,7 +72,7 @@ static void __udelay_enabled(unsigned long usecs) · 1 unmodified line | ||
| 67 | 72 | /* |
| 68 | 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 | 77 | unsigned long flags; |
| 73 | 78 | |
| @@ -101,11 +106,11 @@ EXPORT_SYMBOL(__udelay); · 27 unmodified lines | ||
| 101 | 106 | * Simple udelay variant. To be used on startup and reboot |
| 102 | 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 | 111 | u64 end; |
| 107 | 112 | |
| 108 | − end = get_clock() + ((u64) usecs << 12); | |
| 113 | + end = get_clock() + (usecs << 12); | |
| 109 | 114 | while (get_clock() < end) |
| 110 | 115 | cpu_relax(); |
| 111 | 116 | } |
| @@ -36,7 +36,7 @@ static size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) · 35 unmodified lines | ||
| 36 | 36 | tmp1 = -4096UL; |
| 37 | 37 | asm volatile( |
| 38 | 38 | "0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n" |
| 39 | − " jz 7f\n" | |
| 39 | + "9: jz 7f\n" | |
| 40 | 40 | "1:"ALR" %0,%3\n" |
| 41 | 41 | " "SLR" %1,%3\n" |
| 42 | 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) · 4 unmodified lines | ||
| 47 | 47 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ |
| 48 | 48 | " jnh 4f\n" |
| 49 | 49 | "3: .insn ss,0xc80000000000,0(%4,%2),0(%1),0\n" |
| 50 | − " "SLR" %0,%4\n" | |
| 50 | + "10:"SLR" %0,%4\n" | |
| 51 | 51 | " "ALR" %2,%4\n" |
| 52 | 52 | "4:"LHI" %4,-1\n" |
| 53 | 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) · 7 unmodified lines | ||
| 61 | 61 | " j 8f\n" |
| 62 | 62 | "7:"SLR" %0,%0\n" |
| 63 | 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 | 65 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) |
| 66 | 66 | : "d" (reg0) : "cc", "memory"); |
| 67 | 67 | return size; |
| @@ -82,7 +82,7 @@ static size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x) · 14 unmodified lines | ||
| 82 | 82 | tmp1 = -4096UL; |
| 83 | 83 | asm volatile( |
| 84 | 84 | "0: .insn ss,0xc80000000000,0(%0,%1),0(%2),0\n" |
| 85 | − " jz 4f\n" | |
| 85 | + "6: jz 4f\n" | |
| 86 | 86 | "1:"ALR" %0,%3\n" |
| 87 | 87 | " "SLR" %1,%3\n" |
| 88 | 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) · 4 unmodified lines | ||
| 93 | 93 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ |
| 94 | 94 | " jnh 5f\n" |
| 95 | 95 | "3: .insn ss,0xc80000000000,0(%4,%1),0(%2),0\n" |
| 96 | − " "SLR" %0,%4\n" | |
| 96 | + "7:"SLR" %0,%4\n" | |
| 97 | 97 | " j 5f\n" |
| 98 | 98 | "4:"SLR" %0,%0\n" |
| 99 | 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 | 101 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) |
| 102 | 102 | : "d" (reg0) : "cc", "memory"); |
| 103 | 103 | return size; |
| @@ -36,12 +36,12 @@ size_t copy_from_user_std(size_t size, const void __user *ptr, void *x) · 35 unmodified lines | ||
| 36 | 36 | tmp1 = -256UL; |
| 37 | 37 | asm volatile( |
| 38 | 38 | "0: mvcp 0(%0,%2),0(%1),%3\n" |
| 39 | − " jz 8f\n" | |
| 39 | + "10:jz 8f\n" | |
| 40 | 40 | "1:"ALR" %0,%3\n" |
| 41 | 41 | " la %1,256(%1)\n" |
| 42 | 42 | " la %2,256(%2)\n" |
| 43 | 43 | "2: mvcp 0(%0,%2),0(%1),%3\n" |
| 44 | − " jnz 1b\n" | |
| 44 | + "11:jnz 1b\n" | |
| 45 | 45 | " j 8f\n" |
| 46 | 46 | "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ |
| 47 | 47 | " "LHI" %3,-4096\n" |
| @@ -50,7 +50,7 @@ size_t copy_from_user_std(size_t size, const void __user *ptr, void *x) · 2 unmodified lines | ||
| 50 | 50 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ |
| 51 | 51 | " jnh 5f\n" |
| 52 | 52 | "4: mvcp 0(%4,%2),0(%1),%3\n" |
| 53 | − " "SLR" %0,%4\n" | |
| 53 | + "12:"SLR" %0,%4\n" | |
| 54 | 54 | " "ALR" %2,%4\n" |
| 55 | 55 | "5:"LHI" %4,-1\n" |
| 56 | 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) · 8 unmodified lines | ||
| 65 | 65 | "8:"SLR" %0,%0\n" |
| 66 | 66 | "9: \n" |
| 67 | 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 | 69 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) |
| 69 | 70 | : : "cc", "memory"); |
| 70 | 71 | return size; |
| @@ -85,12 +86,12 @@ size_t copy_to_user_std(size_t size, void __user *ptr, const void *x) · 14 unmodified lines | ||
| 85 | 86 | tmp1 = -256UL; |
| 86 | 87 | asm volatile( |
| 87 | 88 | "0: mvcs 0(%0,%1),0(%2),%3\n" |
| 88 | − " jz 5f\n" | |
| 89 | + "7: jz 5f\n" | |
| 89 | 90 | "1:"ALR" %0,%3\n" |
| 90 | 91 | " la %1,256(%1)\n" |
| 91 | 92 | " la %2,256(%2)\n" |
| 92 | 93 | "2: mvcs 0(%0,%1),0(%2),%3\n" |
| 93 | − " jnz 1b\n" | |
| 94 | + "8: jnz 1b\n" | |
| 94 | 95 | " j 5f\n" |
| 95 | 96 | "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ |
| 96 | 97 | " "LHI" %3,-4096\n" |
| @@ -99,11 +100,12 @@ size_t copy_to_user_std(size_t size, void __user *ptr, const void *x) · 2 unmodified lines | ||
| 99 | 100 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ |
| 100 | 101 | " jnh 6f\n" |
| 101 | 102 | "4: mvcs 0(%4,%1),0(%2),%3\n" |
| 102 | − " "SLR" %0,%4\n" | |
| 103 | + "9:"SLR" %0,%4\n" | |
| 103 | 104 | " j 6f\n" |
| 104 | 105 | "5:"SLR" %0,%0\n" |
| 105 | 106 | "6: \n" |
| 106 | 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 | 109 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) |
| 108 | 110 | : : "cc", "memory"); |
| 109 | 111 | return size; |
| @@ -279,7 +279,10 @@ int s390_enable_sie(void) · 278 unmodified lines | ||
| 279 | 279 | /* lets check if we are allowed to replace the mm */ |
| 280 | 280 | task_lock(tsk); |
| 281 | 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 | 286 | task_unlock(tsk); |
| 284 | 287 | return -EINVAL; |
| 285 | 288 | } |
| @@ -295,7 +298,10 @@ int s390_enable_sie(void) · 9 unmodified lines | ||
| 295 | 298 | /* Now lets check again if something happened */ |
| 296 | 299 | task_lock(tsk); |
| 297 | 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 | 305 | mmput(mm); |
| 300 | 306 | task_unlock(tsk); |
| 301 | 307 | return -EINVAL; |
| @@ -2508,8 +2508,6 @@ int dasd_generic_restore_device(struct ccw_device *cdev) · 2507 unmodified lines | ||
| 2508 | 2508 | device->stopped &= ~DASD_UNRESUMED_PM; |
| 2509 | 2509 | |
| 2510 | 2510 | dasd_schedule_device_bh(device); |
| 2511 | − if (device->block) | |
| 2512 | − dasd_schedule_block_bh(device->block); | |
| 2513 | 2511 | |
| 2514 | 2512 | if (device->discipline->restore) |
| 2515 | 2513 | rc = device->discipline->restore(device); |
| @@ -2520,6 +2518,9 @@ int dasd_generic_restore_device(struct ccw_device *cdev) · 4 unmodified lines | ||
| 2520 | 2518 | */ |
| 2521 | 2519 | device->stopped |= DASD_UNRESUMED_PM; |
| 2522 | 2520 | |
| 2521 | + if (device->block) | |
| 2522 | + dasd_schedule_block_bh(device->block); | |
| 2523 | + | |
| 2523 | 2524 | dasd_put_device(device); |
| 2524 | 2525 | return 0; |
| 2525 | 2526 | } |
| @@ -2338,6 +2338,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev, · 2337 unmodified lines | ||
| 2338 | 2338 | /* Calculate number of blocks/records per track. */ |
| 2339 | 2339 | blksize = block->bp_block; |
| 2340 | 2340 | blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize); |
| 2341 | + if (blk_per_trk == 0) | |
| 2342 | + return ERR_PTR(-EINVAL); | |
| 2341 | 2343 | /* Calculate record id of first and last block. */ |
| 2342 | 2344 | first_rec = first_trk = blk_rq_pos(req) >> block->s2b_shift; |
| 2343 | 2345 | first_offs = sector_div(first_trk, blk_per_trk); |
| @@ -3211,6 +3213,7 @@ int dasd_eckd_pm_freeze(struct dasd_device *device) · 867 unmodified lines | ||
| 3211 | 3213 | int dasd_eckd_restore_device(struct dasd_device *device) |
| 3212 | 3214 | { |
| 3213 | 3215 | struct dasd_eckd_private *private; |
| 3216 | + struct dasd_eckd_characteristics temp_rdc_data; | |
| 3214 | 3217 | int is_known, rc; |
| 3215 | 3218 | struct dasd_uid temp_uid; |
| 3216 | 3219 | |
| @@ -3245,15 +3248,17 @@ int dasd_eckd_restore_device(struct dasd_device *device) · 28 unmodified lines | ||
| 3245 | 3248 | dasd_eckd_read_features(device); |
| 3246 | 3249 | |
| 3247 | 3250 | /* Read Device Characteristics */ |
| 3248 | − memset(&private->rdc_data, 0, sizeof(private->rdc_data)); | |
| 3249 | 3251 | rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC, |
| 3250 | − &private->rdc_data, 64); | |
| 3252 | + &temp_rdc_data, 64); | |
| 3251 | 3253 | if (rc) { |
| 3252 | 3254 | DBF_EVENT(DBF_WARNING, |
| 3253 | 3255 | "Read device characteristics failed, rc=%d for " |
| 3254 | 3256 | "device: %s", rc, dev_name(&device->cdev->dev)); |
| 3255 | 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 | 3263 | /* add device to alias management */ |
| 3259 | 3264 | dasd_alias_add_device(device); |
| @@ -1361,11 +1361,13 @@ static int raw3270_pm_start(struct ccw_device *cdev) · 1360 unmodified lines | ||
| 1361 | 1361 | |
| 1362 | 1362 | void raw3270_pm_unfreeze(struct raw3270_view *view) |
| 1363 | 1363 | { |
| 1364 | +#ifdef CONFIG_TN3270_CONSOLE | |
| 1364 | 1365 | struct raw3270 *rp; |
| 1365 | 1366 | |
| 1366 | 1367 | rp = view->dev; |
| 1367 | 1368 | if (rp && test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) |
| 1368 | 1369 | ccw_device_force_console(); |
| 1370 | +#endif | |
| 1369 | 1371 | } |
| 1370 | 1372 | |
| 1371 | 1373 | static struct ccw_device_id raw3270_id[] = { |
| @@ -265,13 +265,11 @@ struct ccwdev_iter { · 264 unmodified lines | ||
| 265 | 265 | static void * |
| 266 | 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 | 270 | if (*offset >= (__MAX_SUBCHANNEL + 1) * (__MAX_SSID + 1)) |
| 271 | 271 | return NULL; |
| 272 | − iter = kzalloc(sizeof(struct ccwdev_iter), GFP_KERNEL); | |
| 273 | − if (!iter) | |
| 274 | − return ERR_PTR(-ENOMEM); | |
| 272 | + memset(iter, 0, sizeof(*iter)); | |
| 275 | 273 | iter->ssid = *offset / (__MAX_SUBCHANNEL + 1); |
| 276 | 274 | iter->devno = *offset % (__MAX_SUBCHANNEL + 1); |
| 277 | 275 | return iter; |
| @@ -280,8 +278,6 @@ cio_ignore_proc_seq_start(struct seq_file *s, loff_t *offset) · 2 unmodified lines | ||
| 280 | 278 | static void |
| 281 | 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 | 283 | static void * |
| @@ -378,14 +374,15 @@ static const struct seq_operations cio_ignore_proc_seq_ops = { · 90 unmodified lines | ||
| 378 | 374 | static int |
| 379 | 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 | 381 | static const struct file_operations cio_ignore_proc_fops = { |
| 385 | 382 | .open = cio_ignore_proc_open, |
| 386 | 383 | .read = seq_read, |
| 387 | 384 | .llseek = seq_lseek, |
| 388 | − .release = seq_release, | |
| 385 | + .release = seq_release_private, | |
| 389 | 386 | .write = cio_ignore_write, |
| 390 | 387 | }; |
| 391 | 388 | |
| @@ -393,7 +393,6 @@ int chp_new(struct chp_id chpid) · 392 unmodified lines | ||
| 393 | 393 | chp->state = 1; |
| 394 | 394 | chp->dev.parent = &channel_subsystems[chpid.cssid]->device; |
| 395 | 395 | chp->dev.release = chp_release; |
| 396 | − dev_set_name(&chp->dev, "chp%x.%02x", chpid.cssid, chpid.id); | |
| 397 | 396 | |
| 398 | 397 | /* Obtain channel path description and fill it in. */ |
| 399 | 398 | ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc); |
| @@ -411,6 +410,7 @@ int chp_new(struct chp_id chpid) · 11 unmodified lines | ||
| 411 | 410 | } else { |
| 412 | 411 | chp->cmg = -1; |
| 413 | 412 | } |
| 413 | + dev_set_name(&chp->dev, "chp%x.%02x", chpid.cssid, chpid.id); | |
| 414 | 414 | |
| 415 | 415 | /* make it known to the system */ |
| 416 | 416 | ret = device_register(&chp->dev); |
| @@ -1609,7 +1609,7 @@ int ccw_purge_blacklisted(void) · 1608 unmodified lines | ||
| 1609 | 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 | 1614 | if (!cdev) |
| 1615 | 1615 | return; |
| @@ -1705,7 +1705,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int slow) · 89 unmodified lines | ||
| 1705 | 1705 | ccw_device_trigger_reprobe(cdev); |
| 1706 | 1706 | break; |
| 1707 | 1707 | case DISC: |
| 1708 | − device_set_disconnected(cdev); | |
| 1708 | + ccw_device_set_disconnected(cdev); | |
| 1709 | 1709 | break; |
| 1710 | 1710 | default: |
| 1711 | 1711 | break; |
| @@ -125,6 +125,7 @@ int ccw_device_stlck(struct ccw_device *); · 124 unmodified lines | ||
| 125 | 125 | void ccw_device_trigger_reprobe(struct ccw_device *); |
| 126 | 126 | void ccw_device_kill_io(struct ccw_device *); |
| 127 | 127 | int ccw_device_notify(struct ccw_device *, int); |
| 128 | +void ccw_device_set_disconnected(struct ccw_device *cdev); | |
| 128 | 129 | void ccw_device_set_notoper(struct ccw_device *cdev); |
| 129 | 130 | |
| 130 | 131 | /* qdio needs this. */ |
| @@ -387,19 +387,35 @@ ccw_device_done(struct ccw_device *cdev, int state) · 386 unmodified lines | ||
| 387 | 387 | |
| 388 | 388 | cdev->private->state = state; |
| 389 | 389 | |
| 390 | − if (state == DEV_STATE_BOXED) { | |
| 390 | + switch (state) { | |
| 391 | + case DEV_STATE_BOXED: | |
| 391 | 392 | CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n", |
| 392 | 393 | cdev->private->dev_id.devno, sch->schid.sch_no); |
| 393 | 394 | if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED)) |
| 394 | 395 | ccw_device_schedule_sch_unregister(cdev); |
| 395 | 396 | cdev->private->flags.donotify = 0; |
| 396 | − } | |
| 397 | − if (state == DEV_STATE_NOT_OPER) { | |
| 397 | + break; | |
| 398 | + case DEV_STATE_NOT_OPER: | |
| 398 | 399 | CIO_MSG_EVENT(0, "Device %04x gone on subchannel %04x\n", |
| 399 | 400 | cdev->private->dev_id.devno, sch->schid.sch_no); |
| 400 | 401 | if (!ccw_device_notify(cdev, CIO_GONE)) |
| 401 | 402 | ccw_device_schedule_sch_unregister(cdev); |
| 403 | + else | |
| 404 | + ccw_device_set_disconnected(cdev); | |
| 402 | 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 | 421 | if (cdev->private->flags.donotify) { |
| @@ -671,6 +687,10 @@ ccw_device_offline(struct ccw_device *cdev) · 265 unmodified lines | ||
| 671 | 687 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); |
| 672 | 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 | 694 | if (ccw_device_is_orphan(cdev)) { |
| 675 | 695 | ccw_device_done(cdev, DEV_STATE_OFFLINE); |
| 676 | 696 | return 0; |
| @@ -730,11 +750,10 @@ ccw_device_recog_notoper(struct ccw_device *cdev, enum dev_event dev_event) · 53 unmodified lines | ||
| 730 | 750 | static void ccw_device_generic_notoper(struct ccw_device *cdev, |
| 731 | 751 | enum dev_event dev_event) |
| 732 | 752 | { |
| 733 | − struct subchannel *sch; | |
| 734 | − | |
| 735 | − ccw_device_set_notoper(cdev); | |
| 736 | − sch = to_subchannel(cdev->dev.parent); | |
| 737 | − css_schedule_eval(sch->schid); | |
| 753 | + if (!ccw_device_notify(cdev, CIO_GONE)) | |
| 754 | + ccw_device_schedule_sch_unregister(cdev); | |
| 755 | + else | |
| 756 | + ccw_device_set_disconnected(cdev); | |
| 738 | 757 | } |
| 739 | 758 | |
| 740 | 759 | /* |
| @@ -361,7 +361,7 @@ static void rng_type6CPRB_msgX(struct ap_device *ap_dev, · 360 unmodified lines | ||
| 361 | 361 | .ToCardLen1 = sizeof *msg - sizeof(msg->hdr), |
| 362 | 362 | .FromCardLen1 = sizeof *msg - sizeof(msg->hdr), |
| 363 | 363 | }; |
| 364 | − static struct CPRBX static_cprbx = { | |
| 364 | + static struct CPRBX local_cprbx = { | |
| 365 | 365 | .cprb_len = 0x00dc, |
| 366 | 366 | .cprb_ver_id = 0x02, |
| 367 | 367 | .func_id = {0x54, 0x32}, |
| @@ -372,7 +372,7 @@ static void rng_type6CPRB_msgX(struct ap_device *ap_dev, · 4 unmodified lines | ||
| 372 | 372 | |
| 373 | 373 | msg->hdr = static_type6_hdrX; |
| 374 | 374 | msg->hdr.FromCardLen2 = random_number_length, |
| 375 | − msg->cprbx = static_cprbx; | |
| 375 | + msg->cprbx = local_cprbx; | |
| 376 | 376 | msg->cprbx.rpl_datal = random_number_length, |
| 377 | 377 | msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid); |
| 378 | 378 | memcpy(msg->function_code, msg->hdr.function_code, 0x02); |
| @@ -561,7 +561,8 @@ static int convert_response_ica(struct zcrypt_device *zdev, · 182 unmodified lines | ||
| 561 | 561 | if (msg->cprbx.cprb_ver_id == 0x02) |
| 562 | 562 | return convert_type86_ica(zdev, reply, |
| 563 | 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 | 566 | default: /* Unknown response type, this should NEVER EVER happen */ |
| 566 | 567 | zdev->online = 0; |
| 567 | 568 | return -EAGAIN; /* repeat the request on a different device. */ |
| @@ -587,7 +588,8 @@ static int convert_response_xcrb(struct zcrypt_device *zdev, · 19 unmodified lines | ||
| 587 | 588 | } |
| 588 | 589 | if (msg->cprbx.cprb_ver_id == 0x02) |
| 589 | 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 | 593 | default: /* Unknown response type, this should NEVER EVER happen */ |
| 592 | 594 | xcRB->status = 0x0008044DL; /* HDD_InvalidParm */ |
| 593 | 595 | zdev->online = 0; |
| @@ -610,7 +612,8 @@ static int convert_response_rng(struct zcrypt_device *zdev, · 16 unmodified lines | ||
| 610 | 612 | return -EINVAL; |
| 611 | 613 | if (msg->cprbx.cprb_ver_id == 0x02) |
| 612 | 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 | 617 | default: /* Unknown response type, this should NEVER EVER happen */ |
| 615 | 618 | zdev->online = 0; |
| 616 | 619 | return -EAGAIN; /* repeat the request on a different device. */ |
| @@ -361,6 +361,7 @@ typedef struct elf64_shdr { · 360 unmodified lines | ||
| 361 | 361 | #define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ |
| 362 | 362 | #define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ |
| 363 | 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 | 367 | /* Note header in a PT_NOTE section */ |
| @@ -346,8 +346,9 @@ config SLUB_STATS · 345 unmodified lines | ||
| 346 | 346 | |
| 347 | 347 | config DEBUG_KMEMLEAK |
| 348 | 348 | bool "Kernel memory leak detector" |
| 349 | − depends on DEBUG_KERNEL && EXPERIMENTAL && (X86 || ARM || PPC) && \ | |
| 350 | − !MEMORY_HOTPLUG | |
| 349 | + depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \ | |
| 350 | + (X86 || ARM || PPC || S390) | |
| 351 | + | |
| 351 | 352 | select DEBUG_FS if SYSFS |
| 352 | 353 | select STACKTRACE if STACKTRACE_SUPPORT |
| 353 | 354 | select KALLSYMS |
| @@ -370,7 +371,7 @@ config DEBUG_KMEMLEAK · 16 unmodified lines | ||
| 370 | 371 | config DEBUG_KMEMLEAK_EARLY_LOG_SIZE |
| 371 | 372 | int "Maximum kmemleak early log entries" |
| 372 | 373 | depends on DEBUG_KMEMLEAK |
| 373 | − range 200 2000 | |
| 374 | + range 200 40000 | |
| 374 | 375 | default 400 |
| 375 | 376 | help |
| 376 | 377 | Kmemleak must track all the memory allocations to avoid |