1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 21da177e4SLinus Torvalds /* 3df24e178SHelge Deller * PA-RISC architecture-specific signal handling support. 41da177e4SLinus Torvalds * 51da177e4SLinus Torvalds * Copyright (C) 2000 David Huggins-Daines <dhd@debian.org> 61da177e4SLinus Torvalds * Copyright (C) 2000 Linuxcare, Inc. 7df24e178SHelge Deller * Copyright (C) 2000-2022 Helge Deller <deller@gmx.de> 8df24e178SHelge Deller * Copyright (C) 2022 John David Anglin <dave.anglin@bell.net> 91da177e4SLinus Torvalds * 101da177e4SLinus Torvalds * Based on the ia64, i386, and alpha versions. 111da177e4SLinus Torvalds */ 121da177e4SLinus Torvalds 131da177e4SLinus Torvalds #include <linux/sched.h> 14b17b0153SIngo Molnar #include <linux/sched/debug.h> 151da177e4SLinus Torvalds #include <linux/mm.h> 161da177e4SLinus Torvalds #include <linux/smp.h> 171da177e4SLinus Torvalds #include <linux/kernel.h> 181da177e4SLinus Torvalds #include <linux/signal.h> 191da177e4SLinus Torvalds #include <linux/errno.h> 201da177e4SLinus Torvalds #include <linux/wait.h> 211da177e4SLinus Torvalds #include <linux/ptrace.h> 2203248addSEric W. Biederman #include <linux/resume_user_mode.h> 231da177e4SLinus Torvalds #include <linux/unistd.h> 241da177e4SLinus Torvalds #include <linux/stddef.h> 251da177e4SLinus Torvalds #include <linux/compat.h> 261da177e4SLinus Torvalds #include <linux/elf.h> 271da177e4SLinus Torvalds #include <asm/ucontext.h> 281da177e4SLinus Torvalds #include <asm/rt_sigframe.h> 297c0f6ba6SLinus Torvalds #include <linux/uaccess.h> 301da177e4SLinus Torvalds #include <asm/cacheflush.h> 310013a854SSam Ravnborg #include <asm/asm-offsets.h> 32df24e178SHelge Deller #include <asm/vdso.h> 331da177e4SLinus Torvalds 341da177e4SLinus Torvalds #ifdef CONFIG_COMPAT 351da177e4SLinus Torvalds #include "signal32.h" 361da177e4SLinus Torvalds #endif 371da177e4SLinus Torvalds 381da177e4SLinus Torvalds #define DEBUG_SIG 0 391da177e4SLinus Torvalds #define DEBUG_SIG_LEVEL 2 401da177e4SLinus Torvalds 411da177e4SLinus Torvalds #if DEBUG_SIG 421da177e4SLinus Torvalds #define DBG(LEVEL, ...) \ 431da177e4SLinus Torvalds ((DEBUG_SIG_LEVEL >= LEVEL) \ 441da177e4SLinus Torvalds ? printk(__VA_ARGS__) : (void) 0) 451da177e4SLinus Torvalds #else 461da177e4SLinus Torvalds #define DBG(LEVEL, ...) 471da177e4SLinus Torvalds #endif 481da177e4SLinus Torvalds 491da177e4SLinus Torvalds /* gcc will complain if a pointer is cast to an integer of different 501da177e4SLinus Torvalds * size. If you really need to do this (and we do for an ELF32 user 511da177e4SLinus Torvalds * application in an ELF64 kernel) then you have to do a cast to an 521da177e4SLinus Torvalds * integer of the same size first. The A() macro accomplishes 531da177e4SLinus Torvalds * this. */ 541da177e4SLinus Torvalds #define A(__x) ((unsigned long)(__x)) 551da177e4SLinus Torvalds 561da177e4SLinus Torvalds /* 571da177e4SLinus Torvalds * Do a signal return - restore sigcontext. 581da177e4SLinus Torvalds */ 591da177e4SLinus Torvalds 601da177e4SLinus Torvalds static long 611da177e4SLinus Torvalds restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs) 621da177e4SLinus Torvalds { 631da177e4SLinus Torvalds long err = 0; 641da177e4SLinus Torvalds 651da177e4SLinus Torvalds err |= __copy_from_user(regs->gr, sc->sc_gr, sizeof(regs->gr)); 661da177e4SLinus Torvalds err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr)); 671da177e4SLinus Torvalds err |= __copy_from_user(regs->iaoq, sc->sc_iaoq, sizeof(regs->iaoq)); 681da177e4SLinus Torvalds err |= __copy_from_user(regs->iasq, sc->sc_iasq, sizeof(regs->iasq)); 691da177e4SLinus Torvalds err |= __get_user(regs->sar, &sc->sc_sar); 70df24e178SHelge Deller DBG(2, "%s: iaoq is %#lx / %#lx\n", 71df24e178SHelge Deller __func__, regs->iaoq[0], regs->iaoq[1]); 72df24e178SHelge Deller DBG(2, "%s: r28 is %ld\n", __func__, regs->gr[28]); 731da177e4SLinus Torvalds return err; 741da177e4SLinus Torvalds } 751da177e4SLinus Torvalds 76cfb25b82SHelge Deller asmlinkage void 771da177e4SLinus Torvalds sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) 781da177e4SLinus Torvalds { 791da177e4SLinus Torvalds struct rt_sigframe __user *frame; 801da177e4SLinus Torvalds sigset_t set; 811da177e4SLinus Torvalds unsigned long usp = (regs->gr[30] & ~(0x01UL)); 821da177e4SLinus Torvalds unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE; 83a8f44e38SHelge Deller #ifdef CONFIG_64BIT 841da177e4SLinus Torvalds struct compat_rt_sigframe __user * compat_frame; 851da177e4SLinus Torvalds 86a3ea84faSKyle McMartin if (is_compat_task()) 871da177e4SLinus Torvalds sigframe_size = PARISC_RT_SIGFRAME_SIZE32; 881da177e4SLinus Torvalds #endif 891da177e4SLinus Torvalds 90f56141e3SAndy Lutomirski current->restart_block.fn = do_no_restart_syscall; 911da177e4SLinus Torvalds 921da177e4SLinus Torvalds /* Unwind the user stack to get the rt_sigframe structure. */ 931da177e4SLinus Torvalds frame = (struct rt_sigframe __user *) 941da177e4SLinus Torvalds (usp - sigframe_size); 95df24e178SHelge Deller DBG(2, "%s: frame is %p pid %d\n", __func__, frame, task_pid_nr(current)); 961da177e4SLinus Torvalds 9700df111eSAl Viro regs->orig_r28 = 1; /* no restarts for sigreturn */ 9800df111eSAl Viro 99a8f44e38SHelge Deller #ifdef CONFIG_64BIT 1001da177e4SLinus Torvalds compat_frame = (struct compat_rt_sigframe __user *)frame; 1011da177e4SLinus Torvalds 102a3ea84faSKyle McMartin if (is_compat_task()) { 103d74f0f47SAl Viro if (get_compat_sigset(&set, &compat_frame->uc.uc_sigmask)) 1041da177e4SLinus Torvalds goto give_sigsegv; 1051da177e4SLinus Torvalds } else 1061da177e4SLinus Torvalds #endif 1071da177e4SLinus Torvalds { 1081da177e4SLinus Torvalds if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 1091da177e4SLinus Torvalds goto give_sigsegv; 1101da177e4SLinus Torvalds } 1111da177e4SLinus Torvalds 112ade7728bSMatt Fleming set_current_blocked(&set); 1131da177e4SLinus Torvalds 1141da177e4SLinus Torvalds /* Good thing we saved the old gr[30], eh? */ 115a8f44e38SHelge Deller #ifdef CONFIG_64BIT 116a3ea84faSKyle McMartin if (is_compat_task()) { 117df24e178SHelge Deller DBG(1, "%s: compat_frame->uc.uc_mcontext 0x%p\n", 118df24e178SHelge Deller __func__, &compat_frame->uc.uc_mcontext); 1191da177e4SLinus Torvalds // FIXME: Load upper half from register file 1201da177e4SLinus Torvalds if (restore_sigcontext32(&compat_frame->uc.uc_mcontext, 1211da177e4SLinus Torvalds &compat_frame->regs, regs)) 1221da177e4SLinus Torvalds goto give_sigsegv; 123df24e178SHelge Deller DBG(1, "%s: usp %#08lx stack 0x%p\n", 124df24e178SHelge Deller __func__, usp, &compat_frame->uc.uc_stack); 1256e26aab9SAl Viro if (compat_restore_altstack(&compat_frame->uc.uc_stack)) 1261da177e4SLinus Torvalds goto give_sigsegv; 1271da177e4SLinus Torvalds } else 1281da177e4SLinus Torvalds #endif 1291da177e4SLinus Torvalds { 130df24e178SHelge Deller DBG(1, "%s: frame->uc.uc_mcontext 0x%p\n", 131df24e178SHelge Deller __func__, &frame->uc.uc_mcontext); 1321da177e4SLinus Torvalds if (restore_sigcontext(&frame->uc.uc_mcontext, regs)) 1331da177e4SLinus Torvalds goto give_sigsegv; 134df24e178SHelge Deller DBG(1, "%s: usp %#08lx stack 0x%p\n", 135df24e178SHelge Deller __func__, usp, &frame->uc.uc_stack); 1366e26aab9SAl Viro if (restore_altstack(&frame->uc.uc_stack)) 1371da177e4SLinus Torvalds goto give_sigsegv; 1381da177e4SLinus Torvalds } 1391da177e4SLinus Torvalds 1401da177e4SLinus Torvalds 1411da177e4SLinus Torvalds 1421da177e4SLinus Torvalds /* If we are on the syscall path IAOQ will not be restored, and 1431da177e4SLinus Torvalds * if we are on the interrupt path we must not corrupt gr31. 1441da177e4SLinus Torvalds */ 1451da177e4SLinus Torvalds if (in_syscall) 1461da177e4SLinus Torvalds regs->gr[31] = regs->iaoq[0]; 147df24e178SHelge Deller 1481da177e4SLinus Torvalds return; 1491da177e4SLinus Torvalds 1501da177e4SLinus Torvalds give_sigsegv: 151df24e178SHelge Deller DBG(1, "%s: Sending SIGSEGV\n", __func__); 1523cf5d076SEric W. Biederman force_sig(SIGSEGV); 1531da177e4SLinus Torvalds return; 1541da177e4SLinus Torvalds } 1551da177e4SLinus Torvalds 1561da177e4SLinus Torvalds /* 1571da177e4SLinus Torvalds * Set up a signal frame. 1581da177e4SLinus Torvalds */ 1591da177e4SLinus Torvalds 1601da177e4SLinus Torvalds static inline void __user * 1611da177e4SLinus Torvalds get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) 1621da177e4SLinus Torvalds { 1631da177e4SLinus Torvalds /*FIXME: ELF32 vs. ELF64 has different frame_size, but since we 1641da177e4SLinus Torvalds don't use the parameter it doesn't matter */ 1651da177e4SLinus Torvalds 166df24e178SHelge Deller DBG(1, "%s: ka = %#lx, sp = %#lx, frame_size = %zu\n", 167df24e178SHelge Deller __func__, (unsigned long)ka, sp, frame_size); 1681da177e4SLinus Torvalds 169ad30f3ffSJohn David Anglin /* Align alternate stack and reserve 64 bytes for the signal 170ad30f3ffSJohn David Anglin handler's frame marker. */ 171d09042daSLaurent MEYER if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp)) 172ad30f3ffSJohn David Anglin sp = (current->sas_ss_sp + 0x7f) & ~0x3f; /* Stacks grow up! */ 1731da177e4SLinus Torvalds 174df24e178SHelge Deller DBG(1, "%s: Returning sp = %#lx\n", __func__, (unsigned long)sp); 1751da177e4SLinus Torvalds return (void __user *) sp; /* Stacks grow up. Fun. */ 1761da177e4SLinus Torvalds } 1771da177e4SLinus Torvalds 1781da177e4SLinus Torvalds static long 179cfb25b82SHelge Deller setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, long in_syscall) 1801da177e4SLinus Torvalds 1811da177e4SLinus Torvalds { 1821da177e4SLinus Torvalds unsigned long flags = 0; 1831da177e4SLinus Torvalds long err = 0; 1841da177e4SLinus Torvalds 1851da177e4SLinus Torvalds if (on_sig_stack((unsigned long) sc)) 1861da177e4SLinus Torvalds flags |= PARISC_SC_FLAG_ONSTACK; 1871da177e4SLinus Torvalds if (in_syscall) { 1881da177e4SLinus Torvalds flags |= PARISC_SC_FLAG_IN_SYSCALL; 1891da177e4SLinus Torvalds /* regs->iaoq is undefined in the syscall return path */ 1901da177e4SLinus Torvalds err |= __put_user(regs->gr[31], &sc->sc_iaoq[0]); 1911da177e4SLinus Torvalds err |= __put_user(regs->gr[31]+4, &sc->sc_iaoq[1]); 1921da177e4SLinus Torvalds err |= __put_user(regs->sr[3], &sc->sc_iasq[0]); 1931da177e4SLinus Torvalds err |= __put_user(regs->sr[3], &sc->sc_iasq[1]); 194df24e178SHelge Deller DBG(1, "%s: iaoq %#lx / %#lx (in syscall)\n", 195df24e178SHelge Deller __func__, regs->gr[31], regs->gr[31]+4); 1961da177e4SLinus Torvalds } else { 1971da177e4SLinus Torvalds err |= __copy_to_user(sc->sc_iaoq, regs->iaoq, sizeof(regs->iaoq)); 1981da177e4SLinus Torvalds err |= __copy_to_user(sc->sc_iasq, regs->iasq, sizeof(regs->iasq)); 199df24e178SHelge Deller DBG(1, "%s: iaoq %#lx / %#lx (not in syscall)\n", 200df24e178SHelge Deller __func__, regs->iaoq[0], regs->iaoq[1]); 2011da177e4SLinus Torvalds } 2021da177e4SLinus Torvalds 2031da177e4SLinus Torvalds err |= __put_user(flags, &sc->sc_flags); 2041da177e4SLinus Torvalds err |= __copy_to_user(sc->sc_gr, regs->gr, sizeof(regs->gr)); 2051da177e4SLinus Torvalds err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr)); 2061da177e4SLinus Torvalds err |= __put_user(regs->sar, &sc->sc_sar); 207df24e178SHelge Deller DBG(1, "%s: r28 is %ld\n", __func__, regs->gr[28]); 2081da177e4SLinus Torvalds 2091da177e4SLinus Torvalds return err; 2101da177e4SLinus Torvalds } 2111da177e4SLinus Torvalds 2121da177e4SLinus Torvalds static long 213e4dc894bSRichard Weinberger setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs, 214cfb25b82SHelge Deller long in_syscall) 2151da177e4SLinus Torvalds { 2161da177e4SLinus Torvalds struct rt_sigframe __user *frame; 2171da177e4SLinus Torvalds unsigned long rp, usp; 2181da177e4SLinus Torvalds unsigned long haddr, sigframe_size; 219df24e178SHelge Deller unsigned long start; 2201da177e4SLinus Torvalds int err = 0; 221a8f44e38SHelge Deller #ifdef CONFIG_64BIT 2221da177e4SLinus Torvalds struct compat_rt_sigframe __user * compat_frame; 2231da177e4SLinus Torvalds #endif 2241da177e4SLinus Torvalds 2251da177e4SLinus Torvalds usp = (regs->gr[30] & ~(0x01UL)); 2263e4a1affSHelge Deller sigframe_size = PARISC_RT_SIGFRAME_SIZE; 227030f6530SMikulas Patocka #ifdef CONFIG_64BIT 228030f6530SMikulas Patocka if (is_compat_task()) { 229030f6530SMikulas Patocka /* The gcc alloca implementation leaves garbage in the upper 32 bits of sp */ 230030f6530SMikulas Patocka usp = (compat_uint_t)usp; 2313e4a1affSHelge Deller sigframe_size = PARISC_RT_SIGFRAME_SIZE32; 232030f6530SMikulas Patocka } 233030f6530SMikulas Patocka #endif 2343e4a1affSHelge Deller frame = get_sigframe(&ksig->ka, usp, sigframe_size); 2351da177e4SLinus Torvalds 236df24e178SHelge Deller DBG(1, "%s: frame %p info %p\n", __func__, frame, &ksig->info); 2371da177e4SLinus Torvalds 2383e4a1affSHelge Deller start = (unsigned long) frame; 239967747bbSArnd Bergmann if (start >= TASK_SIZE_MAX - sigframe_size) 2403e4a1affSHelge Deller return -EFAULT; 2411da177e4SLinus Torvalds 242a8f44e38SHelge Deller #ifdef CONFIG_64BIT 2431da177e4SLinus Torvalds 2441da177e4SLinus Torvalds compat_frame = (struct compat_rt_sigframe __user *)frame; 2451da177e4SLinus Torvalds 246a3ea84faSKyle McMartin if (is_compat_task()) { 247df24e178SHelge Deller DBG(1, "%s: frame->info = 0x%p\n", __func__, &compat_frame->info); 248e4dc894bSRichard Weinberger err |= copy_siginfo_to_user32(&compat_frame->info, &ksig->info); 2496e26aab9SAl Viro err |= __compat_save_altstack( &compat_frame->uc.uc_stack, regs->gr[30]); 250df24e178SHelge Deller DBG(1, "%s: frame->uc = 0x%p\n", __func__, &compat_frame->uc); 251df24e178SHelge Deller DBG(1, "%s: frame->uc.uc_mcontext = 0x%p\n", 252df24e178SHelge Deller __func__, &compat_frame->uc.uc_mcontext); 2531da177e4SLinus Torvalds err |= setup_sigcontext32(&compat_frame->uc.uc_mcontext, 2541da177e4SLinus Torvalds &compat_frame->regs, regs, in_syscall); 255d74f0f47SAl Viro err |= put_compat_sigset(&compat_frame->uc.uc_sigmask, set, 256d74f0f47SAl Viro sizeof(compat_sigset_t)); 2571da177e4SLinus Torvalds } else 2581da177e4SLinus Torvalds #endif 2591da177e4SLinus Torvalds { 260df24e178SHelge Deller DBG(1, "%s: frame->info = 0x%p\n", __func__, &frame->info); 261e4dc894bSRichard Weinberger err |= copy_siginfo_to_user(&frame->info, &ksig->info); 2626e26aab9SAl Viro err |= __save_altstack(&frame->uc.uc_stack, regs->gr[30]); 263df24e178SHelge Deller DBG(1, "%s: frame->uc = 0x%p\n", __func__, &frame->uc); 264df24e178SHelge Deller DBG(1, "%s: frame->uc.uc_mcontext = 0x%p\n", 265df24e178SHelge Deller __func__, &frame->uc.uc_mcontext); 2661da177e4SLinus Torvalds err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, in_syscall); 2671da177e4SLinus Torvalds /* FIXME: Should probably be converted as well for the compat case */ 2681da177e4SLinus Torvalds err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 2691da177e4SLinus Torvalds } 2701da177e4SLinus Torvalds 2711da177e4SLinus Torvalds if (err) 272e4dc894bSRichard Weinberger return -EFAULT; 2731da177e4SLinus Torvalds 274df24e178SHelge Deller #ifdef CONFIG_64BIT 275df24e178SHelge Deller if (!is_compat_task()) 276df24e178SHelge Deller rp = VDSO64_SYMBOL(current, sigtramp_rt); 277df24e178SHelge Deller else 278df24e178SHelge Deller #endif 279df24e178SHelge Deller rp = VDSO32_SYMBOL(current, sigtramp_rt); 2801da177e4SLinus Torvalds 281df24e178SHelge Deller if (in_syscall) 282df24e178SHelge Deller rp += 4*4; /* skip 4 instructions and start at ldi 1,%r25 */ 2831da177e4SLinus Torvalds 284e4dc894bSRichard Weinberger haddr = A(ksig->ka.sa.sa_handler); 2851da177e4SLinus Torvalds /* The sa_handler may be a pointer to a function descriptor */ 286a8f44e38SHelge Deller #ifdef CONFIG_64BIT 287a3ea84faSKyle McMartin if (is_compat_task()) { 2881da177e4SLinus Torvalds #endif 2891da177e4SLinus Torvalds if (haddr & PA_PLABEL_FDESC) { 2901da177e4SLinus Torvalds Elf32_Fdesc fdesc; 2911da177e4SLinus Torvalds Elf32_Fdesc __user *ufdesc = (Elf32_Fdesc __user *)A(haddr & ~3); 2921da177e4SLinus Torvalds 2931da177e4SLinus Torvalds err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc)); 2941da177e4SLinus Torvalds 2951da177e4SLinus Torvalds if (err) 296e4dc894bSRichard Weinberger return -EFAULT; 2971da177e4SLinus Torvalds 2981da177e4SLinus Torvalds haddr = fdesc.addr; 2991da177e4SLinus Torvalds regs->gr[19] = fdesc.gp; 3001da177e4SLinus Torvalds } 301a8f44e38SHelge Deller #ifdef CONFIG_64BIT 3021da177e4SLinus Torvalds } else { 3031da177e4SLinus Torvalds Elf64_Fdesc fdesc; 3041da177e4SLinus Torvalds Elf64_Fdesc __user *ufdesc = (Elf64_Fdesc __user *)A(haddr & ~3); 3051da177e4SLinus Torvalds 3061da177e4SLinus Torvalds err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc)); 3071da177e4SLinus Torvalds 3081da177e4SLinus Torvalds if (err) 309e4dc894bSRichard Weinberger return -EFAULT; 3101da177e4SLinus Torvalds 3111da177e4SLinus Torvalds haddr = fdesc.addr; 3121da177e4SLinus Torvalds regs->gr[19] = fdesc.gp; 313df24e178SHelge Deller DBG(1, "%s: 64 bit signal, exe=%#lx, r19=%#lx, in_syscall=%d\n", 314df24e178SHelge Deller __func__, haddr, regs->gr[19], in_syscall); 3151da177e4SLinus Torvalds } 3161da177e4SLinus Torvalds #endif 3171da177e4SLinus Torvalds 3181da177e4SLinus Torvalds /* The syscall return path will create IAOQ values from r31. 3191da177e4SLinus Torvalds */ 3201da177e4SLinus Torvalds if (in_syscall) { 3211da177e4SLinus Torvalds regs->gr[31] = haddr; 322a8f44e38SHelge Deller #ifdef CONFIG_64BIT 323df570b9cSKyle McMartin if (!test_thread_flag(TIF_32BIT)) 324df24e178SHelge Deller sigframe_size |= 1; /* XXX ???? */ 3251da177e4SLinus Torvalds #endif 3261da177e4SLinus Torvalds } else { 3271da177e4SLinus Torvalds unsigned long psw = USER_PSW; 328a8f44e38SHelge Deller #ifdef CONFIG_64BIT 329df570b9cSKyle McMartin if (!test_thread_flag(TIF_32BIT)) 3301da177e4SLinus Torvalds psw |= PSW_W; 3311da177e4SLinus Torvalds #endif 3321da177e4SLinus Torvalds 3331da177e4SLinus Torvalds /* If we are singlestepping, arrange a trap to be delivered 3341da177e4SLinus Torvalds when we return to userspace. Note the semantics -- we 3351da177e4SLinus Torvalds should trap before the first insn in the handler is 3361da177e4SLinus Torvalds executed. Ref: 3371da177e4SLinus Torvalds http://sources.redhat.com/ml/gdb/2004-11/msg00245.html 3381da177e4SLinus Torvalds */ 3391da177e4SLinus Torvalds if (pa_psw(current)->r) { 3401da177e4SLinus Torvalds pa_psw(current)->r = 0; 3411da177e4SLinus Torvalds psw |= PSW_R; 3421da177e4SLinus Torvalds mtctl(-1, 0); 3431da177e4SLinus Torvalds } 3441da177e4SLinus Torvalds 3451da177e4SLinus Torvalds regs->gr[0] = psw; 346df24e178SHelge Deller regs->iaoq[0] = haddr | PRIV_USER; 3471da177e4SLinus Torvalds regs->iaoq[1] = regs->iaoq[0] + 4; 3481da177e4SLinus Torvalds } 3491da177e4SLinus Torvalds 3501da177e4SLinus Torvalds regs->gr[2] = rp; /* userland return pointer */ 351e4dc894bSRichard Weinberger regs->gr[26] = ksig->sig; /* signal number */ 3521da177e4SLinus Torvalds 353a8f44e38SHelge Deller #ifdef CONFIG_64BIT 354a3ea84faSKyle McMartin if (is_compat_task()) { 3551da177e4SLinus Torvalds regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */ 3561da177e4SLinus Torvalds regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */ 3571da177e4SLinus Torvalds } else 3581da177e4SLinus Torvalds #endif 3591da177e4SLinus Torvalds { 3601da177e4SLinus Torvalds regs->gr[25] = A(&frame->info); /* siginfo pointer */ 3611da177e4SLinus Torvalds regs->gr[24] = A(&frame->uc); /* ucontext pointer */ 3621da177e4SLinus Torvalds } 3631da177e4SLinus Torvalds 364df24e178SHelge Deller DBG(1, "%s: making sigreturn frame: %#lx + %#lx = %#lx\n", __func__, 3651da177e4SLinus Torvalds regs->gr[30], sigframe_size, 3661da177e4SLinus Torvalds regs->gr[30] + sigframe_size); 3671da177e4SLinus Torvalds /* Raise the user stack pointer to make a proper call frame. */ 3681da177e4SLinus Torvalds regs->gr[30] = (A(frame) + sigframe_size); 3691da177e4SLinus Torvalds 3701da177e4SLinus Torvalds 371df24e178SHelge Deller DBG(1, "%s: sig deliver (%s,%d) frame=0x%p sp=%#lx iaoq=%#lx/%#lx rp=%#lx\n", 372df24e178SHelge Deller __func__, current->comm, current->pid, frame, regs->gr[30], 3731da177e4SLinus Torvalds regs->iaoq[0], regs->iaoq[1], rp); 3741da177e4SLinus Torvalds 3751da177e4SLinus Torvalds return 0; 3761da177e4SLinus Torvalds } 3771da177e4SLinus Torvalds 3781da177e4SLinus Torvalds /* 3791da177e4SLinus Torvalds * OK, we're invoking a handler. 3801da177e4SLinus Torvalds */ 3811da177e4SLinus Torvalds 382e3b880c6SAl Viro static void 383cfb25b82SHelge Deller handle_signal(struct ksignal *ksig, struct pt_regs *regs, long in_syscall) 3841da177e4SLinus Torvalds { 385e4dc894bSRichard Weinberger int ret; 386b7f9a11aSAl Viro sigset_t *oldset = sigmask_to_save(); 387e4dc894bSRichard Weinberger 388df24e178SHelge Deller DBG(1, "%s: sig=%d, ka=%p, info=%p, oldset=%p, regs=%p\n", 389df24e178SHelge Deller __func__, ksig->sig, &ksig->ka, &ksig->info, oldset, regs); 3901da177e4SLinus Torvalds 3911da177e4SLinus Torvalds /* Set up the stack frame */ 392e4dc894bSRichard Weinberger ret = setup_rt_frame(ksig, oldset, regs, in_syscall); 3931da177e4SLinus Torvalds 394e4dc894bSRichard Weinberger signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP) || 39522a8cdd6SKyle McMartin test_thread_flag(TIF_BLOCKSTEP)); 396ecf02de5SKyle McMartin 397df24e178SHelge Deller DBG(1, "%s: Exit (success), regs->gr[28] = %ld\n", 398df24e178SHelge Deller __func__, regs->gr[28]); 3991da177e4SLinus Torvalds } 4001da177e4SLinus Torvalds 40171a71fb5SHelge Deller /* 40271a71fb5SHelge Deller * Check how the syscall number gets loaded into %r20 within 40371a71fb5SHelge Deller * the delay branch in userspace and adjust as needed. 40471a71fb5SHelge Deller */ 40571a71fb5SHelge Deller 40671a71fb5SHelge Deller static void check_syscallno_in_delay_branch(struct pt_regs *regs) 40771a71fb5SHelge Deller { 40871a71fb5SHelge Deller u32 opcode, source_reg; 40971a71fb5SHelge Deller u32 __user *uaddr; 41071a71fb5SHelge Deller int err; 41171a71fb5SHelge Deller 41271a71fb5SHelge Deller /* Usually we don't have to restore %r20 (the system call number) 41371a71fb5SHelge Deller * because it gets loaded in the delay slot of the branch external 41471a71fb5SHelge Deller * instruction via the ldi instruction. 41571a71fb5SHelge Deller * In some cases a register-to-register copy instruction might have 41671a71fb5SHelge Deller * been used instead, in which case we need to copy the syscall 41771a71fb5SHelge Deller * number into the source register before returning to userspace. 41871a71fb5SHelge Deller */ 41971a71fb5SHelge Deller 42071a71fb5SHelge Deller /* A syscall is just a branch, so all we have to do is fiddle the 42171a71fb5SHelge Deller * return pointer so that the ble instruction gets executed again. 42271a71fb5SHelge Deller */ 42371a71fb5SHelge Deller regs->gr[31] -= 8; /* delayed branching */ 42471a71fb5SHelge Deller 42571a71fb5SHelge Deller /* Get assembler opcode of code in delay branch */ 426*dc54a52aSHelge Deller uaddr = (u32 __user *) ((regs->gr[31] & ~3) + 4); 42771a71fb5SHelge Deller err = get_user(opcode, uaddr); 42871a71fb5SHelge Deller if (err) 42971a71fb5SHelge Deller return; 43071a71fb5SHelge Deller 43171a71fb5SHelge Deller /* Check if delay branch uses "ldi int,%r20" */ 43271a71fb5SHelge Deller if ((opcode & 0xffff0000) == 0x34140000) 43371a71fb5SHelge Deller return; /* everything ok, just return */ 43471a71fb5SHelge Deller 43571a71fb5SHelge Deller /* Check if delay branch uses "nop" */ 43671a71fb5SHelge Deller if (opcode == INSN_NOP) 43771a71fb5SHelge Deller return; 43871a71fb5SHelge Deller 43971a71fb5SHelge Deller /* Check if delay branch uses "copy %rX,%r20" */ 44071a71fb5SHelge Deller if ((opcode & 0xffe0ffff) == 0x08000254) { 44171a71fb5SHelge Deller source_reg = (opcode >> 16) & 31; 44271a71fb5SHelge Deller regs->gr[source_reg] = regs->gr[20]; 44371a71fb5SHelge Deller return; 44471a71fb5SHelge Deller } 44571a71fb5SHelge Deller 44671a71fb5SHelge Deller pr_warn("syscall restart: %s (pid %d): unexpected opcode 0x%08x\n", 44771a71fb5SHelge Deller current->comm, task_pid_nr(current), opcode); 44871a71fb5SHelge Deller } 44971a71fb5SHelge Deller 4502b163b71SKyle McMartin static inline void 4512b163b71SKyle McMartin syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) 4522b163b71SKyle McMartin { 45300df111eSAl Viro if (regs->orig_r28) 45400df111eSAl Viro return; 45500df111eSAl Viro regs->orig_r28 = 1; /* no more restarts */ 456df24e178SHelge Deller 457df24e178SHelge Deller DBG(1, "%s: orig_r28 = %ld pid %d r20 %ld\n", 458df24e178SHelge Deller __func__, regs->orig_r28, task_pid_nr(current), regs->gr[20]); 459df24e178SHelge Deller 4602b163b71SKyle McMartin /* Check the return code */ 4612b163b71SKyle McMartin switch (regs->gr[28]) { 4622b163b71SKyle McMartin case -ERESTART_RESTARTBLOCK: 4632b163b71SKyle McMartin case -ERESTARTNOHAND: 464df24e178SHelge Deller DBG(1, "%s: ERESTARTNOHAND: returning -EINTR\n", __func__); 4652b163b71SKyle McMartin regs->gr[28] = -EINTR; 4662b163b71SKyle McMartin break; 4672b163b71SKyle McMartin case -ERESTARTSYS: 4682b163b71SKyle McMartin if (!(ka->sa.sa_flags & SA_RESTART)) { 469df24e178SHelge Deller DBG(1, "%s: ERESTARTSYS: putting -EINTR pid %d\n", 470df24e178SHelge Deller __func__, task_pid_nr(current)); 4712b163b71SKyle McMartin regs->gr[28] = -EINTR; 4722b163b71SKyle McMartin break; 4732b163b71SKyle McMartin } 474df561f66SGustavo A. R. Silva fallthrough; 4752b163b71SKyle McMartin case -ERESTARTNOINTR: 476df24e178SHelge Deller DBG(1, "%s: %ld\n", __func__, regs->gr[28]); 47771a71fb5SHelge Deller check_syscallno_in_delay_branch(regs); 4782b163b71SKyle McMartin break; 4792b163b71SKyle McMartin } 4802b163b71SKyle McMartin } 4812b163b71SKyle McMartin 4822b163b71SKyle McMartin static inline void 4832b163b71SKyle McMartin insert_restart_trampoline(struct pt_regs *regs) 4842b163b71SKyle McMartin { 48500df111eSAl Viro if (regs->orig_r28) 48600df111eSAl Viro return; 48700df111eSAl Viro regs->orig_r28 = 1; /* no more restarts */ 488df24e178SHelge Deller 489df24e178SHelge Deller DBG(2, "%s: gr28 = %ld pid %d\n", 490df24e178SHelge Deller __func__, regs->gr[28], task_pid_nr(current)); 491df24e178SHelge Deller 4922b163b71SKyle McMartin switch (regs->gr[28]) { 4932b163b71SKyle McMartin case -ERESTART_RESTARTBLOCK: { 4942b163b71SKyle McMartin /* Restart the system call - no handlers present */ 4952b163b71SKyle McMartin unsigned int *usp = (unsigned int *)regs->gr[30]; 496df24e178SHelge Deller unsigned long rp; 4970bd1e94bSHelge Deller long err = 0; 4982b163b71SKyle McMartin 4993e4a1affSHelge Deller /* check that we don't exceed the stack */ 500967747bbSArnd Bergmann if (A(&usp[0]) >= TASK_SIZE_MAX - 5 * sizeof(int)) 5013e4a1affSHelge Deller return; 5023e4a1affSHelge Deller 503df24e178SHelge Deller /* Call trampoline in vdso to restart the syscall 504df24e178SHelge Deller * with __NR_restart_syscall. 505df24e178SHelge Deller * Original return addresses are on stack like this: 5062b163b71SKyle McMartin * 5072b163b71SKyle McMartin * 0: <return address (orig r31)> 5082b163b71SKyle McMartin * 4: <2nd half for 64-bit> 5092b163b71SKyle McMartin */ 5102b163b71SKyle McMartin #ifdef CONFIG_64BIT 511df24e178SHelge Deller if (!is_compat_task()) { 5120bd1e94bSHelge Deller err |= put_user(regs->gr[31] >> 32, &usp[0]); 5130bd1e94bSHelge Deller err |= put_user(regs->gr[31] & 0xffffffff, &usp[1]); 514df24e178SHelge Deller rp = VDSO64_SYMBOL(current, restart_syscall); 515df24e178SHelge Deller } else 5162b163b71SKyle McMartin #endif 517df24e178SHelge Deller { 518df24e178SHelge Deller err |= put_user(regs->gr[31], &usp[0]); 519df24e178SHelge Deller rp = VDSO32_SYMBOL(current, restart_syscall); 520df24e178SHelge Deller } 5210bd1e94bSHelge Deller WARN_ON(err); 5220bd1e94bSHelge Deller 523df24e178SHelge Deller regs->gr[31] = rp; 524df24e178SHelge Deller DBG(1, "%s: ERESTART_RESTARTBLOCK\n", __func__); 5252b163b71SKyle McMartin return; 5262b163b71SKyle McMartin } 527df24e178SHelge Deller case -EINTR: 528df24e178SHelge Deller /* ok, was handled before and should be returned. */ 529df24e178SHelge Deller break; 5302b163b71SKyle McMartin case -ERESTARTNOHAND: 5312b163b71SKyle McMartin case -ERESTARTSYS: 53271a71fb5SHelge Deller case -ERESTARTNOINTR: 533df24e178SHelge Deller DBG(1, "%s: Type %ld\n", __func__, regs->gr[28]); 53471a71fb5SHelge Deller check_syscallno_in_delay_branch(regs); 5352b163b71SKyle McMartin return; 5362b163b71SKyle McMartin default: 5372b163b71SKyle McMartin break; 5382b163b71SKyle McMartin } 5392b163b71SKyle McMartin } 5402b163b71SKyle McMartin 5411da177e4SLinus Torvalds /* 5421da177e4SLinus Torvalds * We need to be able to restore the syscall arguments (r21-r26) to 5431da177e4SLinus Torvalds * restart syscalls. Thus, the syscall path should save them in the 5441da177e4SLinus Torvalds * pt_regs structure (it's okay to do so since they are caller-save 5451da177e4SLinus Torvalds * registers). As noted below, the syscall number gets restored for 5461da177e4SLinus Torvalds * us due to the magic of delayed branching. 5471da177e4SLinus Torvalds */ 548df24e178SHelge Deller static void do_signal(struct pt_regs *regs, long in_syscall) 5491da177e4SLinus Torvalds { 550e4dc894bSRichard Weinberger struct ksignal ksig; 551df24e178SHelge Deller int restart_syscall; 552df24e178SHelge Deller bool has_handler; 5531da177e4SLinus Torvalds 554df24e178SHelge Deller has_handler = get_signal(&ksig); 5551da177e4SLinus Torvalds 556df24e178SHelge Deller restart_syscall = 0; 5572b163b71SKyle McMartin if (in_syscall) 558df24e178SHelge Deller restart_syscall = 1; 559df24e178SHelge Deller 560df24e178SHelge Deller if (has_handler) { 561df24e178SHelge Deller /* Restart a system call if necessary. */ 562df24e178SHelge Deller if (restart_syscall) 563e4dc894bSRichard Weinberger syscall_restart(regs, &ksig.ka); 5641da177e4SLinus Torvalds 565e4dc894bSRichard Weinberger handle_signal(&ksig, regs, in_syscall); 566df24e178SHelge Deller DBG(1, "%s: Handled signal pid %d\n", 567df24e178SHelge Deller __func__, task_pid_nr(current)); 5684650f0a5SKyle McMartin return; 5691da177e4SLinus Torvalds } 5701da177e4SLinus Torvalds 571df24e178SHelge Deller /* Do we need to restart the system call? */ 572df24e178SHelge Deller if (restart_syscall) 5732b163b71SKyle McMartin insert_restart_trampoline(regs); 5741da177e4SLinus Torvalds 575df24e178SHelge Deller DBG(1, "%s: Exit (not delivered), regs->gr[28] = %ld orig_r28 = %ld pid %d\n", 576df24e178SHelge Deller __func__, regs->gr[28], regs->orig_r28, task_pid_nr(current)); 5771da177e4SLinus Torvalds 57851a7b448SAl Viro restore_saved_sigmask(); 5794650f0a5SKyle McMartin } 5804650f0a5SKyle McMartin 581cfb25b82SHelge Deller asmlinkage void do_notify_resume(struct pt_regs *regs, long in_syscall) 5824650f0a5SKyle McMartin { 58318cb3281SJens Axboe if (test_thread_flag(TIF_SIGPENDING) || 58418cb3281SJens Axboe test_thread_flag(TIF_NOTIFY_SIGNAL)) 5854650f0a5SKyle McMartin do_signal(regs, in_syscall); 586d0420c83SDavid Howells 5873c532798SJens Axboe if (test_thread_flag(TIF_NOTIFY_RESUME)) 58803248addSEric W. Biederman resume_user_mode_work(regs); 589d0420c83SDavid Howells } 590