diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-10-15 02:07:26 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-10-15 02:07:30 -0400 |
| commit | a0738a688d1105cbf8d71868a1e020c6cdf42d4c (patch) | |
| tree | 2cad553a9def773ce79b8fc793f89c0634187109 /arch/s390 | |
| parent | 89ccf465abe6b20d804a63ae20307970c441369d (diff) | |
| parent | a3ccf63ee643ef243cbf8918da8b3f9238f10029 (diff) | |
Merge branch 'linus' into x86/urgent
Merge reason: pull in latest, to be able to revert a patch there.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/s390')
| -rw-r--r-- | arch/s390/hypfs/hypfs_diag.c | 2 | ||||
| -rw-r--r-- | arch/s390/include/asm/delay.h | 7 | ||||
| -rw-r--r-- | arch/s390/include/asm/elf.h | 12 | ||||
| -rw-r--r-- | arch/s390/include/asm/ptrace.h | 4 | ||||
| -rw-r--r-- | arch/s390/include/asm/ucontext.h | 15 | ||||
| -rw-r--r-- | arch/s390/kernel/compat_signal.c | 35 | ||||
| -rw-r--r-- | arch/s390/kernel/compat_wrapper.S | 2 | ||||
| -rw-r--r-- | arch/s390/kernel/ftrace.c | 3 | ||||
| -rw-r--r-- | arch/s390/kernel/module.c | 3 | ||||
| -rw-r--r-- | arch/s390/kernel/processor.c | 6 | ||||
| -rw-r--r-- | arch/s390/kernel/ptrace.c | 70 | ||||
| -rw-r--r-- | arch/s390/kernel/setup.c | 15 | ||||
| -rw-r--r-- | arch/s390/kernel/swsusp_asm64.S | 26 | ||||
| -rw-r--r-- | arch/s390/kernel/vdso.c | 16 | ||||
| -rw-r--r-- | arch/s390/kernel/vmlinux.lds.S | 1 | ||||
| -rw-r--r-- | arch/s390/lib/delay.c | 27 | ||||
| -rw-r--r-- | arch/s390/lib/uaccess_mvcos.c | 12 | ||||
| -rw-r--r-- | arch/s390/lib/uaccess_std.c | 14 | ||||
| -rw-r--r-- | arch/s390/mm/pgtable.c | 10 |
19 files changed, 225 insertions, 55 deletions
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c index 704dd396257b..77df726180ba 100644 --- a/arch/s390/hypfs/hypfs_diag.c +++ b/arch/s390/hypfs/hypfs_diag.c | |||
| @@ -438,7 +438,7 @@ static int diag204_probe(void) | |||
| 438 | } | 438 | } |
| 439 | if (diag204((unsigned long)SUBC_STIB6 | | 439 | if (diag204((unsigned long)SUBC_STIB6 | |
| 440 | (unsigned long)INFO_EXT, pages, buf) >= 0) { | 440 | (unsigned long)INFO_EXT, pages, buf) >= 0) { |
| 441 | diag204_store_sc = SUBC_STIB7; | 441 | diag204_store_sc = SUBC_STIB6; |
| 442 | diag204_info_type = INFO_EXT; | 442 | diag204_info_type = INFO_EXT; |
| 443 | goto out; | 443 | goto out; |
| 444 | } | 444 | } |
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/processor.c b/arch/s390/kernel/processor.c index 802c8ab247f3..0729f36c2fe3 100644 --- a/arch/s390/kernel/processor.c +++ b/arch/s390/kernel/processor.c | |||
| @@ -31,9 +31,9 @@ void __cpuinit print_cpu_info(void) | |||
| 31 | 31 | ||
| 32 | static int show_cpuinfo(struct seq_file *m, void *v) | 32 | static int show_cpuinfo(struct seq_file *m, void *v) |
| 33 | { | 33 | { |
| 34 | static const char *hwcap_str[9] = { | 34 | static const char *hwcap_str[10] = { |
| 35 | "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", | 35 | "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", |
| 36 | "edat", "etf3eh" | 36 | "edat", "etf3eh", "highgprs" |
| 37 | }; | 37 | }; |
| 38 | struct _lowcore *lc; | 38 | struct _lowcore *lc; |
| 39 | unsigned long n = (unsigned long) v - 1; | 39 | unsigned long n = (unsigned long) v - 1; |
| @@ -48,7 +48,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
| 48 | num_online_cpus(), loops_per_jiffy/(500000/HZ), | 48 | num_online_cpus(), loops_per_jiffy/(500000/HZ), |
| 49 | (loops_per_jiffy/(5000/HZ))%100); | 49 | (loops_per_jiffy/(5000/HZ))%100); |
| 50 | seq_puts(m, "features\t: "); | 50 | seq_puts(m, "features\t: "); |
| 51 | for (i = 0; i < 9; i++) | 51 | for (i = 0; i < 10; i++) |
| 52 | if (hwcap_str[i] && (elf_hwcap & (1UL << i))) | 52 | if (hwcap_str[i] && (elf_hwcap & (1UL << i))) |
| 53 | seq_printf(m, "%s ", hwcap_str[i]); | 53 | seq_printf(m, "%s ", hwcap_str[i]); |
| 54 | seq_puts(m, "\n"); | 54 | seq_puts(m, "\n"); |
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; |
