Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] s390: Add support for new syscalls/TIF_RESTORE_SIGMASK

Add support for the new *at, pselect6 and ppoll system calls. This includes
adding required support for TIF_RESTORE_SIGMASK.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Heiko Carstens and committed by
Linus Torvalds
54dfe5dd 1ab865c1

+296 -265
+22 -78
arch/s390/kernel/compat_signal.c
··· 1 1 /* 2 - * arch/s390/kernel/signal32.c 2 + * arch/s390/kernel/compat_signal.c 3 3 * 4 - * S390 version 5 - * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation 4 + * Copyright (C) IBM Corp. 2000,2006 6 5 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) 7 6 * Gerhard Tonn (ton@de.ibm.com) 8 7 * ··· 50 51 compat_siginfo_t info; 51 52 struct ucontext32 uc; 52 53 } rt_sigframe32; 53 - 54 - asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset)); 55 54 56 55 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) 57 56 { ··· 156 159 } 157 160 } 158 161 return err; 159 - } 160 - 161 - /* 162 - * Atomically swap in the new signal mask, and wait for a signal. 163 - */ 164 - asmlinkage int 165 - sys32_sigsuspend(struct pt_regs * regs,int history0, int history1, old_sigset_t mask) 166 - { 167 - sigset_t saveset; 168 - 169 - mask &= _BLOCKABLE; 170 - spin_lock_irq(&current->sighand->siglock); 171 - saveset = current->blocked; 172 - siginitset(&current->blocked, mask); 173 - recalc_sigpending(); 174 - spin_unlock_irq(&current->sighand->siglock); 175 - regs->gprs[2] = -EINTR; 176 - 177 - while (1) { 178 - set_current_state(TASK_INTERRUPTIBLE); 179 - schedule(); 180 - if (do_signal(regs, &saveset)) 181 - return -EINTR; 182 - } 183 - } 184 - 185 - asmlinkage int 186 - sys32_rt_sigsuspend(struct pt_regs * regs, compat_sigset_t __user *unewset, 187 - size_t sigsetsize) 188 - { 189 - sigset_t saveset, newset; 190 - compat_sigset_t set32; 191 - 192 - /* XXX: Don't preclude handling different sized sigset_t's. */ 193 - if (sigsetsize != sizeof(sigset_t)) 194 - return -EINVAL; 195 - 196 - if (copy_from_user(&set32, unewset, sizeof(set32))) 197 - return -EFAULT; 198 - switch (_NSIG_WORDS) { 199 - case 4: newset.sig[3] = set32.sig[6] + (((long)set32.sig[7]) << 32); 200 - case 3: newset.sig[2] = set32.sig[4] + (((long)set32.sig[5]) << 32); 201 - case 2: newset.sig[1] = set32.sig[2] + (((long)set32.sig[3]) << 32); 202 - case 1: newset.sig[0] = set32.sig[0] + (((long)set32.sig[1]) << 32); 203 - } 204 - sigdelsetmask(&newset, ~_BLOCKABLE); 205 - 206 - spin_lock_irq(&current->sighand->siglock); 207 - saveset = current->blocked; 208 - current->blocked = newset; 209 - recalc_sigpending(); 210 - spin_unlock_irq(&current->sighand->siglock); 211 - regs->gprs[2] = -EINTR; 212 - 213 - while (1) { 214 - set_current_state(TASK_INTERRUPTIBLE); 215 - schedule(); 216 - if (do_signal(regs, &saveset)) 217 - return -EINTR; 218 - } 219 162 } 220 163 221 164 asmlinkage long ··· 457 520 return sig; 458 521 } 459 522 460 - static void setup_frame32(int sig, struct k_sigaction *ka, 523 + static int setup_frame32(int sig, struct k_sigaction *ka, 461 524 sigset_t *set, struct pt_regs * regs) 462 525 { 463 526 sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(sigframe32)); ··· 502 565 /* Place signal number on stack to allow backtrace from handler. */ 503 566 if (__put_user(regs->gprs[2], (int __user *) &frame->signo)) 504 567 goto give_sigsegv; 505 - return; 568 + return 0; 506 569 507 570 give_sigsegv: 508 571 force_sigsegv(sig, current); 572 + return -EFAULT; 509 573 } 510 574 511 - static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, 575 + static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, 512 576 sigset_t *set, struct pt_regs * regs) 513 577 { 514 578 int err = 0; ··· 553 615 regs->gprs[2] = map_signal(sig); 554 616 regs->gprs[3] = (__u64) &frame->info; 555 617 regs->gprs[4] = (__u64) &frame->uc; 556 - return; 618 + return 0; 557 619 558 620 give_sigsegv: 559 621 force_sigsegv(sig, current); 622 + return -EFAULT; 560 623 } 561 624 562 625 /* 563 626 * OK, we're invoking a handler 564 627 */ 565 628 566 - void 629 + int 567 630 handle_signal32(unsigned long sig, struct k_sigaction *ka, 568 631 siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) 569 632 { 633 + int ret; 634 + 570 635 /* Set up the stack frame */ 571 636 if (ka->sa.sa_flags & SA_SIGINFO) 572 - setup_rt_frame32(sig, ka, info, oldset, regs); 637 + ret = setup_rt_frame32(sig, ka, info, oldset, regs); 573 638 else 574 - setup_frame32(sig, ka, oldset, regs); 639 + ret = setup_frame32(sig, ka, oldset, regs); 575 640 576 - spin_lock_irq(&current->sighand->siglock); 577 - sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 578 - if (!(ka->sa.sa_flags & SA_NODEFER)) 579 - sigaddset(&current->blocked,sig); 580 - recalc_sigpending(); 581 - spin_unlock_irq(&current->sighand->siglock); 641 + if (ret == 0) { 642 + spin_lock_irq(&current->sighand->siglock); 643 + sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 644 + if (!(ka->sa.sa_flags & SA_NODEFER)) 645 + sigaddset(&current->blocked,sig); 646 + recalc_sigpending(); 647 + spin_unlock_irq(&current->sighand->siglock); 648 + } 649 + return ret; 582 650 } 583 651
+132 -5
arch/s390/kernel/compat_wrapper.S
··· 1 1 /* 2 - * arch/s390/kernel/sys_wrapper31.S 2 + * arch/s390/kernel/compat_wrapper.S 3 3 * wrapper for 31 bit compatible system calls. 4 4 * 5 - * S390 version 6 - * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 + * Copyright (C) IBM Corp. 2000,2006 7 6 * Author(s): Gerhard Tonn (ton@de.ibm.com), 8 7 * Thomas Spatzier (tspat@de.ibm.com) 9 8 */ ··· 287 288 llgfr %r3,%r3 # __kernel_old_gid_emu31_t 288 289 jg sys32_setregid16 # branch to system call 289 290 290 - #sys32_sigsuspend_wrapper # done in sigsuspend_glue 291 + .globl sys_sigsuspend_wrapper 292 + sys_sigsuspend_wrapper: 293 + lgfr %r2,%r2 # int 294 + lgfr %r3,%r3 # int 295 + llgfr %r4,%r4 # old_sigset_t 296 + jg sys_sigsuspend 291 297 292 298 .globl compat_sys_sigpending_wrapper 293 299 compat_sys_sigpending_wrapper: ··· 859 855 llgtr %r4,%r4 # siginfo_emu31_t * 860 856 jg sys32_rt_sigqueueinfo # branch to system call 861 857 862 - #sys32_rt_sigsuspend_wrapper # done in rt_sigsuspend_glue 858 + .globl compat_sys_rt_sigsuspend_wrapper 859 + compat_sys_rt_sigsuspend_wrapper: 860 + llgtr %r2,%r2 # compat_sigset_t * 861 + llgfr %r3,%r3 # compat_size_t 862 + jg compat_sys_rt_sigsuspend 863 863 864 864 .globl sys32_pread64_wrapper 865 865 sys32_pread64_wrapper: ··· 1483 1475 lgfr %r2,%r2 # int 1484 1476 llgfr %r3,%r3 # u32 1485 1477 jg sys_inotify_rm_watch 1478 + 1479 + .globl compat_sys_openat_wrapper 1480 + compat_sys_openat_wrapper: 1481 + lgfr %r2,%r2 # int 1482 + llgtr %r3,%r3 # const char * 1483 + lgfr %r4,%r4 # int 1484 + lgfr %r5,%r5 # int 1485 + jg compat_sys_openat 1486 + 1487 + .globl sys_mkdirat_wrapper 1488 + sys_mkdirat_wrapper: 1489 + lgfr %r2,%r2 # int 1490 + llgtr %r3,%r3 # const char * 1491 + lgfr %r4,%r4 # int 1492 + jg sys_mkdirat 1493 + 1494 + .globl sys_mknodat_wrapper 1495 + sys_mknodat_wrapper: 1496 + lgfr %r2,%r2 # int 1497 + llgtr %r3,%r3 # const char * 1498 + lgfr %r4,%r4 # int 1499 + llgfr %r5,%r5 # unsigned int 1500 + jg sys_mknodat 1501 + 1502 + .globl sys_fchownat_wrapper 1503 + sys_fchownat_wrapper: 1504 + lgfr %r2,%r2 # int 1505 + llgtr %r3,%r3 # const char * 1506 + llgfr %r4,%r4 # uid_t 1507 + llgfr %r5,%r5 # gid_t 1508 + lgfr %r6,%r6 # int 1509 + jg sys_fchownat 1510 + 1511 + .globl compat_sys_futimesat_wrapper 1512 + compat_sys_futimesat_wrapper: 1513 + lgfr %r2,%r2 # int 1514 + llgtr %r3,%r3 # char * 1515 + llgtr %r4,%r4 # struct timeval * 1516 + jg compat_sys_futimesat 1517 + 1518 + .globl compat_sys_newfstatat_wrapper 1519 + compat_sys_newfstatat_wrapper: 1520 + lgfr %r2,%r2 # int 1521 + llgtr %r3,%r3 # char * 1522 + llgtr %r4,%r4 # struct stat * 1523 + lgfr %r5,%r5 # int 1524 + jg compat_sys_newfstatat 1525 + 1526 + .globl sys_unlinkat_wrapper 1527 + sys_unlinkat_wrapper: 1528 + lgfr %r2,%r2 # int 1529 + llgtr %r3,%r3 # const char * 1530 + lgfr %r4,%r4 # int 1531 + jg sys_unlinkat 1532 + 1533 + .globl sys_renameat_wrapper 1534 + sys_renameat_wrapper: 1535 + lgfr %r2,%r2 # int 1536 + llgtr %r3,%r3 # const char * 1537 + lgfr %r4,%r4 # int 1538 + llgtr %r5,%r5 # const char * 1539 + jg sys_renameat 1540 + 1541 + .globl sys_linkat_wrapper 1542 + sys_linkat_wrapper: 1543 + lgfr %r2,%r2 # int 1544 + llgtr %r3,%r3 # const char * 1545 + lgfr %r4,%r4 # int 1546 + llgtr %r5,%r5 # const char * 1547 + jg sys_linkat 1548 + 1549 + .globl sys_symlinkat_wrapper 1550 + sys_symlinkat_wrapper: 1551 + llgtr %r2,%r2 # const char * 1552 + lgfr %r3,%r3 # int 1553 + llgtr %r4,%r4 # const char * 1554 + jg sys_symlinkat 1555 + 1556 + .globl sys_readlinkat_wrapper 1557 + sys_readlinkat_wrapper: 1558 + lgfr %r2,%r2 # int 1559 + llgtr %r3,%r3 # const char * 1560 + llgtr %r4,%r4 # char * 1561 + lgfr %r5,%r5 # int 1562 + jg sys_readlinkat 1563 + 1564 + .globl sys_fchmodat_wrapper 1565 + sys_fchmodat_wrapper: 1566 + lgfr %r2,%r2 # int 1567 + llgtr %r3,%r3 # const char * 1568 + llgfr %r4,%r4 # mode_t 1569 + jg sys_fchmodat 1570 + 1571 + .globl sys_faccessat_wrapper 1572 + sys_faccessat_wrapper: 1573 + lgfr %r2,%r2 # int 1574 + llgtr %r3,%r3 # const char * 1575 + lgfr %r4,%r4 # int 1576 + jg sys_faccessat 1577 + 1578 + .globl compat_sys_pselect6_wrapper 1579 + compat_sys_pselect6_wrapper: 1580 + lgfr %r2,%r2 # int 1581 + llgtr %r3,%r3 # fd_set * 1582 + llgtr %r4,%r4 # fd_set * 1583 + llgtr %r5,%r5 # fd_set * 1584 + llgtr %r6,%r6 # struct timespec * 1585 + llgt %r0,164(%r15) # void * 1586 + stg %r0,160(%r15) 1587 + jg compat_sys_pselect6 1588 + 1589 + .globl compat_sys_ppoll_wrapper 1590 + compat_sys_ppoll_wrapper: 1591 + llgtr %r2,%r2 # struct pollfd * 1592 + llgfr %r3,%r3 # unsigned int 1593 + llgtr %r4,%r4 # struct timespec * 1594 + llgtr %r5,%r5 # const sigset_t * 1595 + llgfr %r6,%r6 # size_t 1596 + jg compat_sys_ppoll
+13 -38
arch/s390/kernel/entry.S
··· 2 2 * arch/s390/kernel/entry.S 3 3 * S390 low-level entry points. 4 4 * 5 - * S390 version 6 - * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 + * Copyright (C) IBM Corp. 1999,2006 7 6 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), 8 7 * Hartmut Penner (hp@de.ibm.com), 9 8 * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), ··· 49 50 SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP 50 51 SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE 51 52 52 - _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING | \ 53 - _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) 54 - _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) 53 + _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ 54 + _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) 55 + _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ 56 + _TIF_MCCK_PENDING) 55 57 56 58 STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER 57 59 STACK_SIZE = 1 << STACK_SHIFT ··· 251 251 bo BASED(sysc_mcck_pending) 252 252 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED 253 253 bo BASED(sysc_reschedule) 254 - tm __TI_flags+3(%r9),_TIF_SIGPENDING 255 - bo BASED(sysc_sigpending) 254 + tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) 255 + bnz BASED(sysc_sigpending) 256 256 tm __TI_flags+3(%r9),_TIF_RESTART_SVC 257 257 bo BASED(sysc_restart) 258 258 tm __TI_flags+3(%r9),_TIF_SINGLE_STEP ··· 276 276 br %r1 # TIF bit will be cleared by handler 277 277 278 278 # 279 - # _TIF_SIGPENDING is set, call do_signal 279 + # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal 280 280 # 281 281 sysc_sigpending: 282 282 ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP 283 283 la %r2,SP_PTREGS(%r15) # load pt_regs 284 - sr %r3,%r3 # clear *oldset 285 284 l %r1,BASED(.Ldo_signal) 286 285 basr %r14,%r1 # call do_signal 287 286 tm __TI_flags+3(%r9),_TIF_RESTART_SVC ··· 395 396 la %r2,SP_PTREGS(%r15) # load pt_regs as parameter 396 397 l %r1,BASED(.Lrt_sigreturn) 397 398 br %r1 # branch to sys_sigreturn 398 - 399 - # 400 - # sigsuspend and rt_sigsuspend need pt_regs as an additional 401 - # parameter and they have to skip the store of %r2 into the 402 - # user register %r2 because the return value was set in 403 - # sigsuspend and rt_sigsuspend already and must not be overwritten! 404 - # 405 - 406 - sys_sigsuspend_glue: 407 - lr %r5,%r4 # move mask back 408 - lr %r4,%r3 # move history1 parameter 409 - lr %r3,%r2 # move history0 parameter 410 - la %r2,SP_PTREGS(%r15) # load pt_regs as first parameter 411 - l %r1,BASED(.Lsigsuspend) 412 - la %r14,4(%r14) # skip store of return value 413 - br %r1 # branch to sys_sigsuspend 414 - 415 - sys_rt_sigsuspend_glue: 416 - lr %r4,%r3 # move sigsetsize parameter 417 - lr %r3,%r2 # move unewset parameter 418 - la %r2,SP_PTREGS(%r15) # load pt_regs as first parameter 419 - l %r1,BASED(.Lrt_sigsuspend) 420 - la %r14,4(%r14) # skip store of return value 421 - br %r1 # branch to sys_rt_sigsuspend 422 399 423 400 sys_sigaltstack_glue: 424 401 la %r4,SP_PTREGS(%r15) # load pt_regs as parameter ··· 579 604 lr %r15,%r1 580 605 # 581 606 # One of the work bits is on. Find out which one. 582 - # Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED and _TIF_MCCK_PENDING 607 + # Checked are: _TIF_SIGPENDING, _TIF_RESTORE_SIGMASK, _TIF_NEED_RESCHED 608 + # and _TIF_MCCK_PENDING 583 609 # 584 610 io_work_loop: 585 611 tm __TI_flags+3(%r9),_TIF_MCCK_PENDING 586 612 bo BASED(io_mcck_pending) 587 613 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED 588 614 bo BASED(io_reschedule) 589 - tm __TI_flags+3(%r9),_TIF_SIGPENDING 590 - bo BASED(io_sigpending) 615 + tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) 616 + bnz BASED(io_sigpending) 591 617 b BASED(io_leave) 592 618 593 619 # ··· 612 636 b BASED(io_work_loop) 613 637 614 638 # 615 - # _TIF_SIGPENDING is set, call do_signal 639 + # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal 616 640 # 617 641 io_sigpending: 618 642 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 619 643 la %r2,SP_PTREGS(%r15) # load pt_regs 620 - sr %r3,%r3 # clear *oldset 621 644 l %r1,BASED(.Ldo_signal) 622 645 basr %r14,%r1 # call do_signal 623 646 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
+14 -61
arch/s390/kernel/entry64.S
··· 1 1 /* 2 - * arch/s390/kernel/entry.S 2 + * arch/s390/kernel/entry64.S 3 3 * S390 low-level entry points. 4 4 * 5 - * S390 version 6 - * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 + * Copyright (C) IBM Corp. 1999,2006 7 6 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), 8 7 * Hartmut Penner (hp@de.ibm.com), 9 8 * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), ··· 52 53 STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER 53 54 STACK_SIZE = 1 << STACK_SHIFT 54 55 55 - _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING | \ 56 - _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) 57 - _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) 56 + _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ 57 + _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) 58 + _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ 59 + _TIF_MCCK_PENDING) 58 60 59 61 #define BASED(name) name-system_call(%r13) 60 62 ··· 249 249 jo sysc_mcck_pending 250 250 tm __TI_flags+7(%r9),_TIF_NEED_RESCHED 251 251 jo sysc_reschedule 252 - tm __TI_flags+7(%r9),_TIF_SIGPENDING 253 - jo sysc_sigpending 252 + tm __TI_flags+7(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) 253 + jnz sysc_sigpending 254 254 tm __TI_flags+7(%r9),_TIF_RESTART_SVC 255 255 jo sysc_restart 256 256 tm __TI_flags+7(%r9),_TIF_SINGLE_STEP ··· 272 272 jg s390_handle_mcck # TIF bit will be cleared by handler 273 273 274 274 # 275 - # _TIF_SIGPENDING is set, call do_signal 275 + # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal 276 276 # 277 277 sysc_sigpending: 278 278 ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP 279 279 la %r2,SP_PTREGS(%r15) # load pt_regs 280 - sgr %r3,%r3 # clear *oldset 281 280 brasl %r14,do_signal # call do_signal 282 281 tm __TI_flags+7(%r9),_TIF_RESTART_SVC 283 282 jo sysc_restart ··· 411 412 sys32_rt_sigreturn_glue: 412 413 la %r2,SP_PTREGS(%r15) # load pt_regs as parameter 413 414 jg sys32_rt_sigreturn # branch to sys32_sigreturn 414 - #endif 415 - 416 - # 417 - # sigsuspend and rt_sigsuspend need pt_regs as an additional 418 - # parameter and they have to skip the store of %r2 into the 419 - # user register %r2 because the return value was set in 420 - # sigsuspend and rt_sigsuspend already and must not be overwritten! 421 - # 422 - 423 - sys_sigsuspend_glue: 424 - lgr %r5,%r4 # move mask back 425 - lgr %r4,%r3 # move history1 parameter 426 - lgr %r3,%r2 # move history0 parameter 427 - la %r2,SP_PTREGS(%r15) # load pt_regs as first parameter 428 - la %r14,6(%r14) # skip store of return value 429 - jg sys_sigsuspend # branch to sys_sigsuspend 430 - 431 - #ifdef CONFIG_COMPAT 432 - sys32_sigsuspend_glue: 433 - llgfr %r4,%r4 # unsigned long 434 - lgr %r5,%r4 # move mask back 435 - lgfr %r3,%r3 # int 436 - lgr %r4,%r3 # move history1 parameter 437 - lgfr %r2,%r2 # int 438 - lgr %r3,%r2 # move history0 parameter 439 - la %r2,SP_PTREGS(%r15) # load pt_regs as first parameter 440 - la %r14,6(%r14) # skip store of return value 441 - jg sys32_sigsuspend # branch to sys32_sigsuspend 442 - #endif 443 - 444 - sys_rt_sigsuspend_glue: 445 - lgr %r4,%r3 # move sigsetsize parameter 446 - lgr %r3,%r2 # move unewset parameter 447 - la %r2,SP_PTREGS(%r15) # load pt_regs as first parameter 448 - la %r14,6(%r14) # skip store of return value 449 - jg sys_rt_sigsuspend # branch to sys_rt_sigsuspend 450 - 451 - #ifdef CONFIG_COMPAT 452 - sys32_rt_sigsuspend_glue: 453 - llgfr %r3,%r3 # size_t 454 - lgr %r4,%r3 # move sigsetsize parameter 455 - llgtr %r2,%r2 # sigset_emu31_t * 456 - lgr %r3,%r2 # move unewset parameter 457 - la %r2,SP_PTREGS(%r15) # load pt_regs as first parameter 458 - la %r14,6(%r14) # skip store of return value 459 - jg sys32_rt_sigsuspend # branch to sys32_rt_sigsuspend 460 415 #endif 461 416 462 417 sys_sigaltstack_glue: ··· 599 646 lgr %r15,%r1 600 647 # 601 648 # One of the work bits is on. Find out which one. 602 - # Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED and _TIF_MCCK_PENDING 649 + # Checked are: _TIF_SIGPENDING, _TIF_RESTORE_SIGPENDING, _TIF_NEED_RESCHED 650 + # and _TIF_MCCK_PENDING 603 651 # 604 652 io_work_loop: 605 653 tm __TI_flags+7(%r9),_TIF_MCCK_PENDING 606 654 jo io_mcck_pending 607 655 tm __TI_flags+7(%r9),_TIF_NEED_RESCHED 608 656 jo io_reschedule 609 - tm __TI_flags+7(%r9),_TIF_SIGPENDING 610 - jo io_sigpending 657 + tm __TI_flags+7(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) 658 + jnz io_sigpending 611 659 j io_leave 612 660 613 661 # ··· 630 676 j io_work_loop 631 677 632 678 # 633 - # _TIF_SIGPENDING is set, call do_signal 679 + # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal 634 680 # 635 681 io_sigpending: 636 682 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 637 683 la %r2,SP_PTREGS(%r15) # load pt_regs 638 - slgr %r3,%r3 # clear *oldset 639 684 brasl %r14,do_signal # call do_signal 640 685 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 641 686 j io_work_loop
+71 -75
arch/s390/kernel/signal.c
··· 1 1 /* 2 2 * arch/s390/kernel/signal.c 3 3 * 4 - * S390 version 5 - * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation 4 + * Copyright (C) IBM Corp. 1999,2006 6 5 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) 7 6 * 8 7 * Based on Intel version ··· 50 51 struct ucontext uc; 51 52 } rt_sigframe; 52 53 53 - int do_signal(struct pt_regs *regs, sigset_t *oldset); 54 - 55 54 /* 56 55 * Atomically swap in the new signal mask, and wait for a signal. 57 56 */ 58 57 asmlinkage int 59 - sys_sigsuspend(struct pt_regs * regs, int history0, int history1, 60 - old_sigset_t mask) 58 + sys_sigsuspend(int history0, int history1, old_sigset_t mask) 61 59 { 62 - sigset_t saveset; 63 - 64 60 mask &= _BLOCKABLE; 65 61 spin_lock_irq(&current->sighand->siglock); 66 - saveset = current->blocked; 62 + current->saved_sigmask = current->blocked; 67 63 siginitset(&current->blocked, mask); 68 64 recalc_sigpending(); 69 65 spin_unlock_irq(&current->sighand->siglock); 70 - regs->gprs[2] = -EINTR; 71 66 72 - while (1) { 73 - set_current_state(TASK_INTERRUPTIBLE); 74 - schedule(); 75 - if (do_signal(regs, &saveset)) 76 - return -EINTR; 77 - } 78 - } 67 + current->state = TASK_INTERRUPTIBLE; 68 + schedule(); 69 + set_thread_flag(TIF_RESTORE_SIGMASK); 79 70 80 - asmlinkage long 81 - sys_rt_sigsuspend(struct pt_regs *regs, sigset_t __user *unewset, 82 - size_t sigsetsize) 83 - { 84 - sigset_t saveset, newset; 85 - 86 - /* XXX: Don't preclude handling different sized sigset_t's. */ 87 - if (sigsetsize != sizeof(sigset_t)) 88 - return -EINVAL; 89 - 90 - if (copy_from_user(&newset, unewset, sizeof(newset))) 91 - return -EFAULT; 92 - sigdelsetmask(&newset, ~_BLOCKABLE); 93 - 94 - spin_lock_irq(&current->sighand->siglock); 95 - saveset = current->blocked; 96 - current->blocked = newset; 97 - recalc_sigpending(); 98 - spin_unlock_irq(&current->sighand->siglock); 99 - regs->gprs[2] = -EINTR; 100 - 101 - while (1) { 102 - set_current_state(TASK_INTERRUPTIBLE); 103 - schedule(); 104 - if (do_signal(regs, &saveset)) 105 - return -EINTR; 106 - } 71 + return -ERESTARTNOHAND; 107 72 } 108 73 109 74 asmlinkage long ··· 269 306 return sig; 270 307 } 271 308 272 - static void setup_frame(int sig, struct k_sigaction *ka, 273 - sigset_t *set, struct pt_regs * regs) 309 + static int setup_frame(int sig, struct k_sigaction *ka, 310 + sigset_t *set, struct pt_regs * regs) 274 311 { 275 312 sigframe __user *frame; 276 313 ··· 318 355 /* Place signal number on stack to allow backtrace from handler. */ 319 356 if (__put_user(regs->gprs[2], (int __user *) &frame->signo)) 320 357 goto give_sigsegv; 321 - return; 358 + return 0; 322 359 323 360 give_sigsegv: 324 361 force_sigsegv(sig, current); 362 + return -EFAULT; 325 363 } 326 364 327 - static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 365 + static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 328 366 sigset_t *set, struct pt_regs * regs) 329 367 { 330 368 int err = 0; ··· 373 409 regs->gprs[2] = map_signal(sig); 374 410 regs->gprs[3] = (unsigned long) &frame->info; 375 411 regs->gprs[4] = (unsigned long) &frame->uc; 376 - return; 412 + return 0; 377 413 378 414 give_sigsegv: 379 415 force_sigsegv(sig, current); 416 + return -EFAULT; 380 417 } 381 418 382 419 /* 383 420 * OK, we're invoking a handler 384 421 */ 385 422 386 - static void 423 + static int 387 424 handle_signal(unsigned long sig, struct k_sigaction *ka, 388 425 siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) 389 426 { 427 + int ret; 428 + 390 429 /* Set up the stack frame */ 391 430 if (ka->sa.sa_flags & SA_SIGINFO) 392 - setup_rt_frame(sig, ka, info, oldset, regs); 431 + ret = setup_rt_frame(sig, ka, info, oldset, regs); 393 432 else 394 - setup_frame(sig, ka, oldset, regs); 433 + ret = setup_frame(sig, ka, oldset, regs); 395 434 396 - spin_lock_irq(&current->sighand->siglock); 397 - sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 398 - if (!(ka->sa.sa_flags & SA_NODEFER)) 399 - sigaddset(&current->blocked,sig); 400 - recalc_sigpending(); 401 - spin_unlock_irq(&current->sighand->siglock); 435 + if (ret == 0) { 436 + spin_lock_irq(&current->sighand->siglock); 437 + sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 438 + if (!(ka->sa.sa_flags & SA_NODEFER)) 439 + sigaddset(&current->blocked,sig); 440 + recalc_sigpending(); 441 + spin_unlock_irq(&current->sighand->siglock); 442 + } 443 + 444 + return ret; 402 445 } 403 446 404 447 /* ··· 417 446 * the kernel can handle, and then we build all the user-level signal handling 418 447 * stack-frames in one go after that. 419 448 */ 420 - int do_signal(struct pt_regs *regs, sigset_t *oldset) 449 + void do_signal(struct pt_regs *regs) 421 450 { 422 451 unsigned long retval = 0, continue_addr = 0, restart_addr = 0; 423 452 siginfo_t info; 424 453 int signr; 425 454 struct k_sigaction ka; 455 + sigset_t *oldset; 426 456 427 457 /* 428 458 * We want the common case to go fast, which ··· 432 460 * if so. 433 461 */ 434 462 if (!user_mode(regs)) 435 - return 1; 463 + return; 436 464 437 - if (!oldset) 465 + if (test_thread_flag(TIF_RESTORE_SIGMASK)) 466 + oldset = &current->saved_sigmask; 467 + else 438 468 oldset = &current->blocked; 439 469 440 470 /* Are we from a system call? */ ··· 447 473 448 474 /* Prepare for system call restart. We do this here so that a 449 475 debugger will see the already changed PSW. */ 450 - if (retval == -ERESTARTNOHAND || 451 - retval == -ERESTARTSYS || 452 - retval == -ERESTARTNOINTR) { 476 + switch (retval) { 477 + case -ERESTARTNOHAND: 478 + case -ERESTARTSYS: 479 + case -ERESTARTNOINTR: 453 480 regs->gprs[2] = regs->orig_gpr2; 454 481 regs->psw.addr = restart_addr; 455 - } else if (retval == -ERESTART_RESTARTBLOCK) { 482 + break; 483 + case -ERESTART_RESTARTBLOCK: 456 484 regs->gprs[2] = -EINTR; 457 485 } 458 486 } ··· 479 503 /* Whee! Actually deliver the signal. */ 480 504 #ifdef CONFIG_COMPAT 481 505 if (test_thread_flag(TIF_31BIT)) { 482 - extern void handle_signal32(unsigned long sig, 483 - struct k_sigaction *ka, 484 - siginfo_t *info, 485 - sigset_t *oldset, 486 - struct pt_regs *regs); 487 - handle_signal32(signr, &ka, &info, oldset, regs); 488 - return 1; 506 + extern int handle_signal32(unsigned long sig, 507 + struct k_sigaction *ka, 508 + siginfo_t *info, 509 + sigset_t *oldset, 510 + struct pt_regs *regs); 511 + if (handle_signal32( 512 + signr, &ka, &info, oldset, regs) == 0) { 513 + if (test_thread_flag(TIF_RESTORE_SIGMASK)) 514 + clear_thread_flag(TIF_RESTORE_SIGMASK); 515 + } 516 + return; 489 517 } 490 518 #endif 491 - handle_signal(signr, &ka, &info, oldset, regs); 492 - return 1; 519 + if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { 520 + /* 521 + * A signal was successfully delivered; the saved 522 + * sigmask will have been stored in the signal frame, 523 + * and will be restored by sigreturn, so we can simply 524 + * clear the TIF_RESTORE_SIGMASK flag. 525 + */ 526 + if (test_thread_flag(TIF_RESTORE_SIGMASK)) 527 + clear_thread_flag(TIF_RESTORE_SIGMASK); 528 + } 529 + return; 530 + } 531 + 532 + /* 533 + * If there's no signal to deliver, we just put the saved sigmask back. 534 + */ 535 + if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 536 + clear_thread_flag(TIF_RESTORE_SIGMASK); 537 + sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 493 538 } 494 539 495 540 /* Restart a different system call. */ ··· 519 522 regs->gprs[2] = __NR_restart_syscall; 520 523 set_thread_flag(TIF_RESTART_SVC); 521 524 } 522 - return 0; 523 525 }
+19 -3
arch/s390/kernel/syscalls.S
··· 80 80 NI_SYSCALL /* old ssetmask syscall*/ 81 81 SYSCALL(sys_setreuid16,sys_ni_syscall,sys32_setreuid16_wrapper) /* old setreuid16 syscall */ 82 82 SYSCALL(sys_setregid16,sys_ni_syscall,sys32_setregid16_wrapper) /* old setregid16 syscall */ 83 - SYSCALL(sys_sigsuspend_glue,sys_sigsuspend_glue,sys32_sigsuspend_glue) 83 + SYSCALL(sys_sigsuspend,sys_sigsuspend,sys_sigsuspend_wrapper) 84 84 SYSCALL(sys_sigpending,sys_sigpending,compat_sys_sigpending_wrapper) 85 85 SYSCALL(sys_sethostname,sys_sethostname,sys32_sethostname_wrapper) 86 86 SYSCALL(sys_setrlimit,sys_setrlimit,compat_sys_setrlimit_wrapper) /* 75 */ ··· 187 187 SYSCALL(sys_rt_sigpending,sys_rt_sigpending,sys32_rt_sigpending_wrapper) 188 188 SYSCALL(sys_rt_sigtimedwait,sys_rt_sigtimedwait,compat_sys_rt_sigtimedwait_wrapper) 189 189 SYSCALL(sys_rt_sigqueueinfo,sys_rt_sigqueueinfo,sys32_rt_sigqueueinfo_wrapper) 190 - SYSCALL(sys_rt_sigsuspend_glue,sys_rt_sigsuspend_glue,sys32_rt_sigsuspend_glue) 190 + SYSCALL(sys_rt_sigsuspend,sys_rt_sigsuspend,compat_sys_rt_sigsuspend_wrapper) 191 191 SYSCALL(sys_pread64,sys_pread64,sys32_pread64_wrapper) /* 180 */ 192 192 SYSCALL(sys_pwrite64,sys_pwrite64,sys32_pwrite64_wrapper) 193 193 SYSCALL(sys_chown16,sys_ni_syscall,sys32_chown16_wrapper) /* old chown16 syscall */ ··· 293 293 SYSCALL(sys_ioprio_set,sys_ioprio_set,sys_ioprio_set_wrapper) 294 294 SYSCALL(sys_ioprio_get,sys_ioprio_get,sys_ioprio_get_wrapper) 295 295 SYSCALL(sys_inotify_init,sys_inotify_init,sys_inotify_init) 296 - SYSCALL(sys_inotify_add_watch,sys_inotify_add_watch,sys_inotify_add_watch_wrapper) 296 + SYSCALL(sys_inotify_add_watch,sys_inotify_add_watch,sys_inotify_add_watch_wrapper) /* 285 */ 297 297 SYSCALL(sys_inotify_rm_watch,sys_inotify_rm_watch,sys_inotify_rm_watch_wrapper) 298 + NI_SYSCALL /* 287 sys_migrate_pages */ 299 + SYSCALL(sys_openat,sys_openat,compat_sys_openat_wrapper) 300 + SYSCALL(sys_mkdirat,sys_mkdirat,sys_mkdirat_wrapper) 301 + SYSCALL(sys_mknodat,sys_mknodat,sys_mknodat_wrapper) /* 290 */ 302 + SYSCALL(sys_fchownat,sys_fchownat,sys_fchownat_wrapper) 303 + SYSCALL(sys_futimesat,sys_futimesat,compat_sys_futimesat_wrapper) 304 + SYSCALL(sys_newfstatat,sys_newfstatat,compat_sys_newfstatat_wrapper) 305 + SYSCALL(sys_unlinkat,sys_unlinkat,sys_unlinkat_wrapper) 306 + SYSCALL(sys_renameat,sys_renameat,sys_renameat_wrapper) /* 295 */ 307 + SYSCALL(sys_linkat,sys_linkat,sys_linkat_wrapper) 308 + SYSCALL(sys_symlinkat,sys_symlinkat,sys_symlinkat_wrapper) 309 + SYSCALL(sys_readlinkat,sys_readlinkat,sys_readlinkat_wrapper) 310 + SYSCALL(sys_fchmodat,sys_fchmodat,sys_fchmodat_wrapper) 311 + SYSCALL(sys_faccessat,sys_faccessat,sys_faccessat_wrapper) /* 300 */ 312 + SYSCALL(sys_pselect6,sys_pselect6,compat_sys_pselect6_wrapper) 313 + SYSCALL(sys_ppoll,sys_ppoll,compat_sys_ppoll_wrapper)
+3 -3
include/asm-s390/thread_info.h
··· 2 2 * include/asm-s390/thread_info.h 3 3 * 4 4 * S390 version 5 - * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 + * Copyright (C) IBM Corp. 2002,2006 6 6 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) 7 7 */ 8 8 ··· 88 88 * thread information flags bit numbers 89 89 */ 90 90 #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ 91 - #define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ 91 + #define TIF_RESTORE_SIGMASK 1 /* restore signal mask in do_signal() */ 92 92 #define TIF_SIGPENDING 2 /* signal pending */ 93 93 #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ 94 94 #define TIF_RESTART_SVC 4 /* restart svc with new svc number */ ··· 102 102 #define TIF_MEMDIE 19 103 103 104 104 #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) 105 - #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) 105 + #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) 106 106 #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) 107 107 #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) 108 108 #define _TIF_RESTART_SVC (1<<TIF_RESTART_SVC)
+22 -2
include/asm-s390/unistd.h
··· 279 279 #define __NR_inotify_init 284 280 280 #define __NR_inotify_add_watch 285 281 281 #define __NR_inotify_rm_watch 286 282 + /* Number 287 is reserved for new sys_migrate_pages */ 283 + #define __NR_openat 288 284 + #define __NR_mkdirat 289 285 + #define __NR_mknodat 290 286 + #define __NR_fchownat 291 287 + #define __NR_futimesat 292 288 + #define __NR_newfstatat 293 289 + #define __NR_unlinkat 294 290 + #define __NR_renameat 295 291 + #define __NR_linkat 296 292 + #define __NR_symlinkat 297 293 + #define __NR_readlinkat 298 294 + #define __NR_fchmodat 299 295 + #define __NR_faccessat 300 296 + #define __NR_pselect6 301 297 + #define __NR_ppoll 302 282 298 283 - #define NR_syscalls 287 299 + #define NR_syscalls 303 284 300 285 301 /* 286 302 * There are some system calls that are not present on 64 bit, some ··· 555 539 #define __ARCH_WANT_SYS_SIGPENDING 556 540 #define __ARCH_WANT_SYS_SIGPROCMASK 557 541 #define __ARCH_WANT_SYS_RT_SIGACTION 542 + #define __ARCH_WANT_SYS_RT_SIGSUSPEND 558 543 # ifndef CONFIG_64BIT 559 544 # define __ARCH_WANT_STAT64 560 545 # define __ARCH_WANT_SYS_TIME 561 546 # endif 562 - # define __ARCH_WANT_COMPAT_SYS_TIME 547 + # ifdef CONFIG_COMPAT 548 + # define __ARCH_WANT_COMPAT_SYS_TIME 549 + # define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND 550 + # endif 563 551 #endif 564 552 565 553 #ifdef __KERNEL_SYSCALLS__