Loading arch/powerpc/kernel/signal.c +2 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,7 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs) ti->local_flags &= ~_TLF_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } regs->trap = 0; return 0; /* no signals delivered */ } Loading @@ -164,6 +165,7 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs) ret = handle_rt_signal64(signr, &ka, &info, oldset, regs); } regs->trap = 0; if (ret) { spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked, ¤t->blocked, Loading arch/powerpc/kernel/signal_32.c +1 −2 Original line number Diff line number Diff line Loading @@ -511,6 +511,7 @@ static long restore_user_regs(struct pt_regs *regs, if (!sig) save_r2 = (unsigned int)regs->gpr[2]; err = restore_general_regs(regs, sr); regs->trap = 0; err |= __get_user(msr, &sr->mc_gregs[PT_MSR]); if (!sig) regs->gpr[2] = (unsigned long) save_r2; Loading Loading @@ -884,7 +885,6 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, regs->nip = (unsigned long) ka->sa.sa_handler; /* enter the signal handler in big-endian mode */ regs->msr &= ~MSR_LE; regs->trap = 0; return 1; badframe: Loading Loading @@ -1228,7 +1228,6 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka, regs->nip = (unsigned long) ka->sa.sa_handler; /* enter the signal handler in big-endian mode */ regs->msr &= ~MSR_LE; regs->trap = 0; return 1; Loading arch/powerpc/kernel/signal_64.c +1 −1 Original line number Diff line number Diff line Loading @@ -178,7 +178,7 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, err |= __get_user(regs->xer, &sc->gp_regs[PT_XER]); err |= __get_user(regs->ccr, &sc->gp_regs[PT_CCR]); /* skip SOFTE */ err |= __get_user(regs->trap, &sc->gp_regs[PT_TRAP]); regs->trap = 0; err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]); err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]); err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]); Loading arch/sparc/kernel/perf_event.c +12 −3 Original line number Diff line number Diff line Loading @@ -1076,13 +1076,24 @@ static int sparc_pmu_event_init(struct perf_event *event) break; case PERF_TYPE_RAW: return -EOPNOTSUPP; pmap = NULL; break; default: return -ENOENT; } if (pmap) { hwc->event_base = perf_event_encode(pmap); } else { /* * User gives us "(encoding << 16) | pic_mask" for * PERF_TYPE_RAW events. */ hwc->event_base = attr->config; } /* We save the enable bits in the config_base. */ hwc->config_base = sparc_pmu->irq_bit; if (!attr->exclude_user) Loading @@ -1092,8 +1103,6 @@ static int sparc_pmu_event_init(struct perf_event *event) if (!attr->exclude_hv) hwc->config_base |= sparc_pmu->hv_bit; hwc->event_base = perf_event_encode(pmap); n = 0; if (event->group_leader != event) { n = collect_events(event->group_leader, Loading arch/sparc/kernel/signal32.c +97 −64 Original line number Diff line number Diff line Loading @@ -453,7 +453,65 @@ static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) return err; } static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, /* The I-cache flush instruction only works in the primary ASI, which * right now is the nucleus, aka. kernel space. * * Therefore we have to kick the instructions out using the kernel * side linear mapping of the physical address backing the user * instructions. */ static void flush_signal_insns(unsigned long address) { unsigned long pstate, paddr; pte_t *ptep, pte; pgd_t *pgdp; pud_t *pudp; pmd_t *pmdp; /* Commit all stores of the instructions we are about to flush. */ wmb(); /* Disable cross-call reception. In this way even a very wide * munmap() on another cpu can't tear down the page table * hierarchy from underneath us, since that can't complete * until the IPI tlb flush returns. */ __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); __asm__ __volatile__("wrpr %0, %1, %%pstate" : : "r" (pstate), "i" (PSTATE_IE)); pgdp = pgd_offset(current->mm, address); if (pgd_none(*pgdp)) goto out_irqs_on; pudp = pud_offset(pgdp, address); if (pud_none(*pudp)) goto out_irqs_on; pmdp = pmd_offset(pudp, address); if (pmd_none(*pmdp)) goto out_irqs_on; ptep = pte_offset_map(pmdp, address); pte = *ptep; if (!pte_present(pte)) goto out_unmap; paddr = (unsigned long) page_address(pte_page(pte)); __asm__ __volatile__("flush %0 + %1" : /* no outputs */ : "r" (paddr), "r" (address & (PAGE_SIZE - 1)) : "memory"); out_unmap: pte_unmap(ptep); out_irqs_on: __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); } static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset) { struct signal_frame32 __user *sf; Loading Loading @@ -547,13 +605,7 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (ka->ka_restorer) { regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; } else { /* Flush instruction space. */ unsigned long address = ((unsigned long)&(sf->insns[0])); pgd_t *pgdp = pgd_offset(current->mm, address); pud_t *pudp = pud_offset(pgdp, address); pmd_t *pmdp = pmd_offset(pudp, address); pte_t *ptep; pte_t pte; regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); Loading @@ -562,32 +614,20 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (err) goto sigsegv; preempt_disable(); ptep = pte_offset_map(pmdp, address); pte = *ptep; if (pte_present(pte)) { unsigned long page = (unsigned long) page_address(pte_page(pte)); wmb(); __asm__ __volatile__("flush %0 + %1" : /* no outputs */ : "r" (page), "r" (address & (PAGE_SIZE - 1)) : "memory"); flush_signal_insns(address); } pte_unmap(ptep); preempt_enable(); } return; return 0; sigill: do_exit(SIGILL); return -EINVAL; sigsegv: force_sigsegv(signo, current); return -EFAULT; } static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, unsigned long signr, sigset_t *oldset, siginfo_t *info) { Loading Loading @@ -687,12 +727,7 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (ka->ka_restorer) regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; else { /* Flush instruction space. */ unsigned long address = ((unsigned long)&(sf->insns[0])); pgd_t *pgdp = pgd_offset(current->mm, address); pud_t *pudp = pud_offset(pgdp, address); pmd_t *pmdp = pmd_offset(pudp, address); pte_t *ptep; regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); Loading @@ -704,38 +739,32 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (err) goto sigsegv; preempt_disable(); ptep = pte_offset_map(pmdp, address); if (pte_present(*ptep)) { unsigned long page = (unsigned long) page_address(pte_page(*ptep)); wmb(); __asm__ __volatile__("flush %0 + %1" : /* no outputs */ : "r" (page), "r" (address & (PAGE_SIZE - 1)) : "memory"); flush_signal_insns(address); } pte_unmap(ptep); preempt_enable(); } return; return 0; sigill: do_exit(SIGILL); return -EINVAL; sigsegv: force_sigsegv(signr, current); return -EFAULT; } static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { int err; if (ka->sa.sa_flags & SA_SIGINFO) setup_rt_frame32(ka, regs, signr, oldset, info); err = setup_rt_frame32(ka, regs, signr, oldset, info); else setup_frame32(ka, regs, signr, oldset); err = setup_frame32(ka, regs, signr, oldset); if (err) return err; spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); Loading @@ -743,6 +772,10 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, sigaddset(¤t->blocked,signr); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); tracehook_signal_handler(signr, info, ka, regs, 0); return 0; } static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, Loading Loading @@ -789,16 +822,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, if (signr > 0) { if (restart_syscall) syscall_restart32(orig_i0, regs, &ka.sa); handle_signal32(signr, &ka, &info, oldset, regs); if (handle_signal32(signr, &ka, &info, oldset, regs) == 0) { /* A signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply * clear the TS_RESTORE_SIGMASK flag. */ current_thread_info()->status &= ~TS_RESTORE_SIGMASK; tracehook_signal_handler(signr, &info, &ka, regs, 0); } return; } if (restart_syscall && Loading @@ -809,12 +840,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; pt_regs_clear_syscall(regs); } if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; regs->tnpc -= 4; pt_regs_clear_syscall(regs); } /* If there's no signal to deliver, we just put the saved sigmask Loading Loading
arch/powerpc/kernel/signal.c +2 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,7 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs) ti->local_flags &= ~_TLF_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } regs->trap = 0; return 0; /* no signals delivered */ } Loading @@ -164,6 +165,7 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs) ret = handle_rt_signal64(signr, &ka, &info, oldset, regs); } regs->trap = 0; if (ret) { spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked, ¤t->blocked, Loading
arch/powerpc/kernel/signal_32.c +1 −2 Original line number Diff line number Diff line Loading @@ -511,6 +511,7 @@ static long restore_user_regs(struct pt_regs *regs, if (!sig) save_r2 = (unsigned int)regs->gpr[2]; err = restore_general_regs(regs, sr); regs->trap = 0; err |= __get_user(msr, &sr->mc_gregs[PT_MSR]); if (!sig) regs->gpr[2] = (unsigned long) save_r2; Loading Loading @@ -884,7 +885,6 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, regs->nip = (unsigned long) ka->sa.sa_handler; /* enter the signal handler in big-endian mode */ regs->msr &= ~MSR_LE; regs->trap = 0; return 1; badframe: Loading Loading @@ -1228,7 +1228,6 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka, regs->nip = (unsigned long) ka->sa.sa_handler; /* enter the signal handler in big-endian mode */ regs->msr &= ~MSR_LE; regs->trap = 0; return 1; Loading
arch/powerpc/kernel/signal_64.c +1 −1 Original line number Diff line number Diff line Loading @@ -178,7 +178,7 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, err |= __get_user(regs->xer, &sc->gp_regs[PT_XER]); err |= __get_user(regs->ccr, &sc->gp_regs[PT_CCR]); /* skip SOFTE */ err |= __get_user(regs->trap, &sc->gp_regs[PT_TRAP]); regs->trap = 0; err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]); err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]); err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]); Loading
arch/sparc/kernel/perf_event.c +12 −3 Original line number Diff line number Diff line Loading @@ -1076,13 +1076,24 @@ static int sparc_pmu_event_init(struct perf_event *event) break; case PERF_TYPE_RAW: return -EOPNOTSUPP; pmap = NULL; break; default: return -ENOENT; } if (pmap) { hwc->event_base = perf_event_encode(pmap); } else { /* * User gives us "(encoding << 16) | pic_mask" for * PERF_TYPE_RAW events. */ hwc->event_base = attr->config; } /* We save the enable bits in the config_base. */ hwc->config_base = sparc_pmu->irq_bit; if (!attr->exclude_user) Loading @@ -1092,8 +1103,6 @@ static int sparc_pmu_event_init(struct perf_event *event) if (!attr->exclude_hv) hwc->config_base |= sparc_pmu->hv_bit; hwc->event_base = perf_event_encode(pmap); n = 0; if (event->group_leader != event) { n = collect_events(event->group_leader, Loading
arch/sparc/kernel/signal32.c +97 −64 Original line number Diff line number Diff line Loading @@ -453,7 +453,65 @@ static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) return err; } static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, /* The I-cache flush instruction only works in the primary ASI, which * right now is the nucleus, aka. kernel space. * * Therefore we have to kick the instructions out using the kernel * side linear mapping of the physical address backing the user * instructions. */ static void flush_signal_insns(unsigned long address) { unsigned long pstate, paddr; pte_t *ptep, pte; pgd_t *pgdp; pud_t *pudp; pmd_t *pmdp; /* Commit all stores of the instructions we are about to flush. */ wmb(); /* Disable cross-call reception. In this way even a very wide * munmap() on another cpu can't tear down the page table * hierarchy from underneath us, since that can't complete * until the IPI tlb flush returns. */ __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); __asm__ __volatile__("wrpr %0, %1, %%pstate" : : "r" (pstate), "i" (PSTATE_IE)); pgdp = pgd_offset(current->mm, address); if (pgd_none(*pgdp)) goto out_irqs_on; pudp = pud_offset(pgdp, address); if (pud_none(*pudp)) goto out_irqs_on; pmdp = pmd_offset(pudp, address); if (pmd_none(*pmdp)) goto out_irqs_on; ptep = pte_offset_map(pmdp, address); pte = *ptep; if (!pte_present(pte)) goto out_unmap; paddr = (unsigned long) page_address(pte_page(pte)); __asm__ __volatile__("flush %0 + %1" : /* no outputs */ : "r" (paddr), "r" (address & (PAGE_SIZE - 1)) : "memory"); out_unmap: pte_unmap(ptep); out_irqs_on: __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); } static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset) { struct signal_frame32 __user *sf; Loading Loading @@ -547,13 +605,7 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (ka->ka_restorer) { regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; } else { /* Flush instruction space. */ unsigned long address = ((unsigned long)&(sf->insns[0])); pgd_t *pgdp = pgd_offset(current->mm, address); pud_t *pudp = pud_offset(pgdp, address); pmd_t *pmdp = pmd_offset(pudp, address); pte_t *ptep; pte_t pte; regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); Loading @@ -562,32 +614,20 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (err) goto sigsegv; preempt_disable(); ptep = pte_offset_map(pmdp, address); pte = *ptep; if (pte_present(pte)) { unsigned long page = (unsigned long) page_address(pte_page(pte)); wmb(); __asm__ __volatile__("flush %0 + %1" : /* no outputs */ : "r" (page), "r" (address & (PAGE_SIZE - 1)) : "memory"); flush_signal_insns(address); } pte_unmap(ptep); preempt_enable(); } return; return 0; sigill: do_exit(SIGILL); return -EINVAL; sigsegv: force_sigsegv(signo, current); return -EFAULT; } static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, unsigned long signr, sigset_t *oldset, siginfo_t *info) { Loading Loading @@ -687,12 +727,7 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (ka->ka_restorer) regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; else { /* Flush instruction space. */ unsigned long address = ((unsigned long)&(sf->insns[0])); pgd_t *pgdp = pgd_offset(current->mm, address); pud_t *pudp = pud_offset(pgdp, address); pmd_t *pmdp = pmd_offset(pudp, address); pte_t *ptep; regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); Loading @@ -704,38 +739,32 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (err) goto sigsegv; preempt_disable(); ptep = pte_offset_map(pmdp, address); if (pte_present(*ptep)) { unsigned long page = (unsigned long) page_address(pte_page(*ptep)); wmb(); __asm__ __volatile__("flush %0 + %1" : /* no outputs */ : "r" (page), "r" (address & (PAGE_SIZE - 1)) : "memory"); flush_signal_insns(address); } pte_unmap(ptep); preempt_enable(); } return; return 0; sigill: do_exit(SIGILL); return -EINVAL; sigsegv: force_sigsegv(signr, current); return -EFAULT; } static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { int err; if (ka->sa.sa_flags & SA_SIGINFO) setup_rt_frame32(ka, regs, signr, oldset, info); err = setup_rt_frame32(ka, regs, signr, oldset, info); else setup_frame32(ka, regs, signr, oldset); err = setup_frame32(ka, regs, signr, oldset); if (err) return err; spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); Loading @@ -743,6 +772,10 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, sigaddset(¤t->blocked,signr); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); tracehook_signal_handler(signr, info, ka, regs, 0); return 0; } static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, Loading Loading @@ -789,16 +822,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, if (signr > 0) { if (restart_syscall) syscall_restart32(orig_i0, regs, &ka.sa); handle_signal32(signr, &ka, &info, oldset, regs); if (handle_signal32(signr, &ka, &info, oldset, regs) == 0) { /* A signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply * clear the TS_RESTORE_SIGMASK flag. */ current_thread_info()->status &= ~TS_RESTORE_SIGMASK; tracehook_signal_handler(signr, &info, &ka, regs, 0); } return; } if (restart_syscall && Loading @@ -809,12 +840,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; pt_regs_clear_syscall(regs); } if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; regs->tnpc -= 4; pt_regs_clear_syscall(regs); } /* If there's no signal to deliver, we just put the saved sigmask Loading