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 | |||
