Lines Matching +full:current +full:- +full:limit
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 1995-2009 Russell King
25 #include <asm/debug-monitors.h>
37 * Do a signal return; undo the signal stack. These are aligned to 128-bit.
54 unsigned long limit; /* largest allowed size */ member
70 sizeof(user->sigframe->uc.uc_mcontext.__reserved); in init_user_layout()
73 user->size = offsetof(struct rt_sigframe, uc.uc_mcontext.__reserved); in init_user_layout()
75 user->limit = user->size + reserved_size; in init_user_layout()
77 user->limit -= TERMINATOR_SIZE; in init_user_layout()
78 user->limit -= EXTRA_CONTEXT_SIZE; in init_user_layout()
84 return round_up(max(user->size, sizeof(struct rt_sigframe)), 16); in sigframe_size()
88 * Sanity limit on the approximate maximum size of signal frame we'll
90 * not taken into account. This limit is not a guarantee and is
100 if (padded_size > user->limit - user->size && in __sigframe_alloc()
101 !user->extra_offset && in __sigframe_alloc()
105 user->limit += EXTRA_CONTEXT_SIZE; in __sigframe_alloc()
106 ret = __sigframe_alloc(user, &user->extra_offset, in __sigframe_alloc()
109 user->limit -= EXTRA_CONTEXT_SIZE; in __sigframe_alloc()
114 user->size += TERMINATOR_SIZE; in __sigframe_alloc()
120 user->limit = SIGFRAME_MAXSZ - TERMINATOR_SIZE; in __sigframe_alloc()
124 if (padded_size > user->limit - user->size) in __sigframe_alloc()
125 return -ENOMEM; in __sigframe_alloc()
127 *offset = user->size; in __sigframe_alloc()
128 user->size += padded_size; in __sigframe_alloc()
149 /* Un-reserve the space reserved for the terminator: */ in sigframe_alloc_end()
150 user->limit += TERMINATOR_SIZE; in sigframe_alloc_end()
152 ret = sigframe_alloc(user, &user->end_offset, in sigframe_alloc_end()
158 user->limit = user->size; in sigframe_alloc_end()
165 char __user *base = (char __user *)user->sigframe; in apply_user_offset()
173 ¤t->thread.uw.fpsimd_state; in preserve_fpsimd_context()
177 err = __copy_to_user(ctx->vregs, fpsimd->vregs, sizeof(fpsimd->vregs)); in preserve_fpsimd_context()
178 __put_user_error(fpsimd->fpsr, &ctx->fpsr, err); in preserve_fpsimd_context()
179 __put_user_error(fpsimd->fpcr, &ctx->fpcr, err); in preserve_fpsimd_context()
182 __put_user_error(FPSIMD_MAGIC, &ctx->head.magic, err); in preserve_fpsimd_context()
183 __put_user_error(sizeof(struct fpsimd_context), &ctx->head.size, err); in preserve_fpsimd_context()
185 return err ? -EFAULT : 0; in preserve_fpsimd_context()
195 __get_user_error(magic, &ctx->head.magic, err); in restore_fpsimd_context()
196 __get_user_error(size, &ctx->head.size, err); in restore_fpsimd_context()
198 return -EFAULT; in restore_fpsimd_context()
200 return -EINVAL; in restore_fpsimd_context()
203 err = __copy_from_user(fpsimd.vregs, ctx->vregs, in restore_fpsimd_context()
205 __get_user_error(fpsimd.fpsr, &ctx->fpsr, err); in restore_fpsimd_context()
206 __get_user_error(fpsimd.fpcr, &ctx->fpcr, err); in restore_fpsimd_context()
214 return err ? -EFAULT : 0; in restore_fpsimd_context()
228 u16 reserved[ARRAY_SIZE(ctx->__reserved)]; in preserve_sve_context()
229 unsigned int vl = current->thread.sve_vl; in preserve_sve_context()
237 __put_user_error(SVE_MAGIC, &ctx->head.magic, err); in preserve_sve_context()
239 &ctx->head.size, err); in preserve_sve_context()
240 __put_user_error(vl, &ctx->vl, err); in preserve_sve_context()
241 BUILD_BUG_ON(sizeof(ctx->__reserved) != sizeof(reserved)); in preserve_sve_context()
242 err |= __copy_to_user(&ctx->__reserved, reserved, sizeof(reserved)); in preserve_sve_context()
251 current->thread.sve_state, in preserve_sve_context()
255 return err ? -EFAULT : 0; in preserve_sve_context()
265 if (__copy_from_user(&sve, user->sve, sizeof(sve))) in restore_sve_fpsimd_context()
266 return -EFAULT; in restore_sve_fpsimd_context()
268 if (sve.vl != current->thread.sve_vl) in restore_sve_fpsimd_context()
269 return -EINVAL; in restore_sve_fpsimd_context()
271 if (sve.head.size <= sizeof(*user->sve)) { in restore_sve_fpsimd_context()
279 return -EINVAL; in restore_sve_fpsimd_context()
288 fpsimd_flush_task_state(current); in restore_sve_fpsimd_context()
291 sve_alloc(current); in restore_sve_fpsimd_context()
292 err = __copy_from_user(current->thread.sve_state, in restore_sve_fpsimd_context()
293 (char __user const *)user->sve + in restore_sve_fpsimd_context()
297 return -EFAULT; in restore_sve_fpsimd_context()
303 /* restore_sigframe() already checked that user->fpsimd != NULL. */ in restore_sve_fpsimd_context()
304 err = __copy_from_user(fpsimd.vregs, user->fpsimd->vregs, in restore_sve_fpsimd_context()
306 __get_user_error(fpsimd.fpsr, &user->fpsimd->fpsr, err); in restore_sve_fpsimd_context()
307 __get_user_error(fpsimd.fpcr, &user->fpsimd->fpcr, err); in restore_sve_fpsimd_context()
313 return err ? -EFAULT : 0; in restore_sve_fpsimd_context()
318 /* Turn any non-optimised out attempts to use these into a link error: */
328 struct sigcontext __user *const sc = &sf->uc.uc_mcontext; in parse_user_sigframe()
330 char __user *base = (char __user *)&sc->__reserved; in parse_user_sigframe()
332 size_t limit = sizeof(sc->__reserved); in parse_user_sigframe() local
336 user->fpsimd = NULL; in parse_user_sigframe()
337 user->sve = NULL; in parse_user_sigframe()
352 if (limit - offset < sizeof(*head)) in parse_user_sigframe()
359 __get_user_error(magic, &head->magic, err); in parse_user_sigframe()
360 __get_user_error(size, &head->size, err); in parse_user_sigframe()
364 if (limit - offset < size) in parse_user_sigframe()
377 if (user->fpsimd) in parse_user_sigframe()
380 if (size < sizeof(*user->fpsimd)) in parse_user_sigframe()
383 user->fpsimd = (struct fpsimd_context __user *)head; in parse_user_sigframe()
394 if (user->sve) in parse_user_sigframe()
397 if (size < sizeof(*user->sve)) in parse_user_sigframe()
400 user->sve = (struct sve_context __user *)head; in parse_user_sigframe()
415 __get_user_error(extra_datap, &extra->datap, err); in parse_user_sigframe()
416 __get_user_error(extra_size, &extra->size, err); in parse_user_sigframe()
422 if (limit - offset - size < TERMINATOR_SIZE) in parse_user_sigframe()
428 __get_user_error(end_magic, &end->magic, err); in parse_user_sigframe()
429 __get_user_error(end_size, &end->size, err); in parse_user_sigframe()
450 if (extra_size > sfp + SIGFRAME_MAXSZ - userp) in parse_user_sigframe()
458 limit = extra_size; in parse_user_sigframe()
460 if (!access_ok(base, limit)) in parse_user_sigframe()
472 if (limit - offset < size) in parse_user_sigframe()
482 return -EINVAL; in parse_user_sigframe()
492 err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); in restore_sigframe()
497 __get_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], in restore_sigframe()
499 __get_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); in restore_sigframe()
500 __get_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); in restore_sigframe()
501 __get_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); in restore_sigframe()
508 err |= !valid_user_regs(®s->user_regs, current); in restore_sigframe()
514 return -EINVAL; in restore_sigframe()
518 return -EINVAL; in restore_sigframe()
534 /* Always make any pending restarted system calls return -EINTR */ in SYSCALL_DEFINE0()
535 current->restart_block.fn = do_no_restart_syscall; in SYSCALL_DEFINE0()
538 * Since we stacked the signal on a 128-bit boundary, then 'sp' should in SYSCALL_DEFINE0()
541 if (regs->sp & 15) in SYSCALL_DEFINE0()
544 frame = (struct rt_sigframe __user *)regs->sp; in SYSCALL_DEFINE0()
552 if (restore_altstack(&frame->uc.uc_stack)) in SYSCALL_DEFINE0()
555 return regs->regs[0]; in SYSCALL_DEFINE0()
558 arm64_notify_segfault(regs->sp); in SYSCALL_DEFINE0()
566 * this task; otherwise, generates a layout for the current state
574 err = sigframe_alloc(user, &user->fpsimd_offset, in setup_sigframe_layout()
580 if (add_all || current->thread.fault_code) { in setup_sigframe_layout()
581 err = sigframe_alloc(user, &user->esr_offset, in setup_sigframe_layout()
594 vl = current->thread.sve_vl; in setup_sigframe_layout()
599 err = sigframe_alloc(user, &user->sve_offset, in setup_sigframe_layout()
612 struct rt_sigframe __user *sf = user->sigframe; in setup_sigframe()
615 __put_user_error(regs->regs[29], &user->next_frame->fp, err); in setup_sigframe()
616 __put_user_error(regs->regs[30], &user->next_frame->lr, err); in setup_sigframe()
619 __put_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], in setup_sigframe()
621 __put_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); in setup_sigframe()
622 __put_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); in setup_sigframe()
623 __put_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); in setup_sigframe()
625 __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err); in setup_sigframe()
627 err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); in setup_sigframe()
631 apply_user_offset(user, user->fpsimd_offset); in setup_sigframe()
636 if (err == 0 && user->esr_offset) { in setup_sigframe()
638 apply_user_offset(user, user->esr_offset); in setup_sigframe()
640 __put_user_error(ESR_MAGIC, &esr_ctx->head.magic, err); in setup_sigframe()
641 __put_user_error(sizeof(*esr_ctx), &esr_ctx->head.size, err); in setup_sigframe()
642 __put_user_error(current->thread.fault_code, &esr_ctx->esr, err); in setup_sigframe()
646 if (system_supports_sve() && err == 0 && user->sve_offset) { in setup_sigframe()
648 apply_user_offset(user, user->sve_offset); in setup_sigframe()
652 if (err == 0 && user->extra_offset) { in setup_sigframe()
653 char __user *sfp = (char __user *)user->sigframe; in setup_sigframe()
655 apply_user_offset(user, user->extra_offset); in setup_sigframe()
674 extra_size = sfp + round_up(user->size, 16) - userp; in setup_sigframe()
676 __put_user_error(EXTRA_MAGIC, &extra->head.magic, err); in setup_sigframe()
677 __put_user_error(EXTRA_CONTEXT_SIZE, &extra->head.size, err); in setup_sigframe()
678 __put_user_error(extra_datap, &extra->datap, err); in setup_sigframe()
679 __put_user_error(extra_size, &extra->size, err); in setup_sigframe()
682 __put_user_error(0, &end->magic, err); in setup_sigframe()
683 __put_user_error(0, &end->size, err); in setup_sigframe()
689 apply_user_offset(user, user->end_offset); in setup_sigframe()
691 __put_user_error(0, &end->magic, err); in setup_sigframe()
692 __put_user_error(0, &end->size, err); in setup_sigframe()
709 sp = sp_top = sigsp(regs->sp, ksig); in get_sigframe()
711 sp = round_down(sp - sizeof(struct frame_record), 16); in get_sigframe()
712 user->next_frame = (struct frame_record __user *)sp; in get_sigframe()
714 sp = round_down(sp, 16) - sigframe_size(user); in get_sigframe()
715 user->sigframe = (struct rt_sigframe __user *)sp; in get_sigframe()
720 if (!access_ok(user->sigframe, sp_top - sp)) in get_sigframe()
721 return -EFAULT; in get_sigframe()
731 regs->regs[0] = usig; in setup_return()
732 regs->sp = (unsigned long)user->sigframe; in setup_return()
733 regs->regs[29] = (unsigned long)&user->next_frame->fp; in setup_return()
734 regs->pc = (unsigned long)ka->sa.sa_handler; in setup_return()
748 regs->pstate &= ~PSR_BTYPE_MASK; in setup_return()
749 regs->pstate |= PSR_BTYPE_C; in setup_return()
753 regs->pstate &= ~PSR_TCO_BIT; in setup_return()
755 if (ka->sa.sa_flags & SA_RESTORER) in setup_return()
756 sigtramp = ka->sa.sa_restorer; in setup_return()
758 sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp); in setup_return()
760 regs->regs[30] = (unsigned long)sigtramp; in setup_return()
777 __put_user_error(0, &frame->uc.uc_flags, err); in setup_rt_frame()
778 __put_user_error(NULL, &frame->uc.uc_link, err); in setup_rt_frame()
780 err |= __save_altstack(&frame->uc.uc_stack, regs->sp); in setup_rt_frame()
783 setup_return(regs, &ksig->ka, &user, usig); in setup_rt_frame()
784 if (ksig->ka.sa.sa_flags & SA_SIGINFO) { in setup_rt_frame()
785 err |= copy_siginfo_to_user(&frame->info, &ksig->info); in setup_rt_frame()
786 regs->regs[1] = (unsigned long)&frame->info; in setup_rt_frame()
787 regs->regs[2] = (unsigned long)&frame->uc; in setup_rt_frame()
799 regs->regs[8] = __NR_restart_syscall; in setup_restart_syscall()
808 int usig = ksig->sig; in handle_signal()
817 if (ksig->ka.sa.sa_flags & SA_SIGINFO) in handle_signal()
828 ret |= !valid_user_regs(®s->user_regs, current); in handle_signal()
840 * the kernel can handle, and then we build all the user-level signal handling
841 * stack-frames in one go after that.
854 continue_addr = regs->pc; in do_signal()
855 restart_addr = continue_addr - (compat_thumb_mode(regs) ? 2 : 4); in do_signal()
856 retval = regs->regs[0]; in do_signal()
868 case -ERESTARTNOHAND: in do_signal()
869 case -ERESTARTSYS: in do_signal()
870 case -ERESTARTNOINTR: in do_signal()
871 case -ERESTART_RESTARTBLOCK: in do_signal()
872 regs->regs[0] = regs->orig_x0; in do_signal()
873 regs->pc = restart_addr; in do_signal()
888 if (regs->pc == restart_addr && in do_signal()
889 (retval == -ERESTARTNOHAND || in do_signal()
890 retval == -ERESTART_RESTARTBLOCK || in do_signal()
891 (retval == -ERESTARTSYS && in do_signal()
893 regs->regs[0] = -EINTR; in do_signal()
894 regs->pc = continue_addr; in do_signal()
905 if (syscall && regs->pc == restart_addr) { in do_signal()
906 if (retval == -ERESTART_RESTARTBLOCK) in do_signal()
908 user_rewind_single_step(current); in do_signal()
920 * Update the trace code with the current status. in do_notify_resume()
942 (void __user *)NULL, current); in do_notify_resume()
958 thread_flags = READ_ONCE(current_thread_info()->flags); in do_notify_resume()