hdr = *sc_vec; /* Place state to the user's signal context space after the hdr */
state = (struct __sc_riscv_v_state __user *)(hdr + 1); /* Point datap right after the end of __sc_riscv_v_state */
datap = state + 1;
/* datap is designed to be 16 byte aligned for better performance */
WARN_ON(!IS_ALIGNED((unsignedlong)datap, 16));
/* Copy everything of vstate but datap. */
err = __copy_to_user(&state->v_state, ¤t->thread.vstate,
offsetof(struct __riscv_v_ext_state, datap)); /* Copy the pointer datap itself. */
err |= __put_user((__force void *)datap, &state->v_state.datap); /* Copy the whole vector content to user space datap. */
err |= __copy_to_user(datap, current->thread.vstate.datap, riscv_v_vsize); /* Copy magic to the user space after saving all vector conetext */
err |= __put_user(RISCV_V_MAGIC, &hdr->magic);
err |= __put_user(riscv_v_sc_size, &hdr->size); if (unlikely(err)) return err;
/* Only progress the sv_vec if everything has done successfully */
*sc_vec += riscv_v_sc_size; return0;
}
staticlong restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
{ void __user *sc_ext_ptr = &sc->sc_extdesc.hdr;
__u32 rsvd; long err; /* sc_regs is structured the same as the start of pt_regs */
err = __copy_from_user(regs, &sc->sc_regs, sizeof(sc->sc_regs)); if (unlikely(err)) return err;
/* Restore the floating-point state. */ if (has_fpu()) {
err = restore_fp_state(regs, &sc->sc_fpregs); if (unlikely(err)) return err;
}
/* Check the reserved word before extensions parsing */
err = __get_user(rsvd, &sc->sc_extdesc.reserved); if (unlikely(err)) return err; if (unlikely(rsvd)) return -EINVAL;
/* sc_regs is structured the same as the start of pt_regs */
err = __copy_to_user(&sc->sc_regs, regs, sizeof(sc->sc_regs)); /* Save the floating-point state. */ if (has_fpu())
err |= save_fp_state(regs, &sc->sc_fpregs); /* Save the vector state. */ if ((has_vector() || has_xtheadvector()) && riscv_v_vstate_query(regs))
err |= save_v_state(regs, (void __user **)&sc_ext_ptr); /* Write zero to fp-reserved space and check it on restore_sigcontext */
err |= __put_user(0, &sc->sc_extdesc.reserved); /* And put END __riscv_ctx_hdr at the end. */
err |= __put_user(END_MAGIC, &sc_ext_ptr->magic);
err |= __put_user(END_HDR_SIZE, &sc_ext_ptr->size);
return err;
}
staticinlinevoid __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t framesize)
{ unsignedlong sp; /* Default to using normal stack */
sp = regs->sp;
/* Set up to return from userspace. */ #ifdef CONFIG_MMU
regs->ra = (unsignedlong)VDSO_SYMBOL(
current->mm->context.vdso, rt_sigreturn); #else /* *Forthenommucasewedon'thaveaVDSO.Insteadwepushtwo *instructionstocallthert_sigreturnsyscallontotheuserstack.
*/ if (copy_to_user(&frame->sigreturn_code, __user_rt_sigreturn, sizeof(frame->sigreturn_code))) return -EFAULT;
addr = (unsignedlong)&frame->sigreturn_code; /* Make sure the two instructions are pushed to icache. */
flush_icache_range(addr, addr + sizeof(frame->sigreturn_code));
/* If we were from a system call, check for system call restarting */ if (syscall) {
continue_addr = regs->epc;
restart_addr = continue_addr - 4;
retval = regs->a0;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.