Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F164797163
D43302.id132249.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D43302.id132249.diff
View Options
diff --git a/sys/arm64/arm64/exec_machdep.c b/sys/arm64/arm64/exec_machdep.c
--- a/sys/arm64/arm64/exec_machdep.c
+++ b/sys/arm64/arm64/exec_machdep.c
@@ -569,12 +569,36 @@
int
sys_sigreturn(struct thread *td, struct sigreturn_args *uap)
{
+ struct arm64_reg_context ctx;
ucontext_t uc;
+ vm_offset_t addr;
int error;
+ bool done;
if (copyin(uap->sigcntxp, &uc, sizeof(uc)))
return (EFAULT);
+ /* Read any register contexts we find */
+ if (uc.uc_mcontext.mc_ptr != 0) {
+ addr = uc.uc_mcontext.mc_ptr;
+
+ done = false;
+ do {
+ if (copyin((const void *)addr, &ctx, sizeof(ctx)))
+ return (EFAULT);
+
+ switch(ctx.ctx_id) {
+ case ARM64_CTX_END:
+ done = true;
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ addr += ctx.ctx_size;
+ } while (!done);
+ }
+
error = set_mcontext(td, &uc.uc_mcontext);
if (error != 0)
return (error);
@@ -585,6 +609,31 @@
return (EJUSTRETURN);
}
+static bool
+sendsig_ctx_end(struct thread *td, vm_offset_t *addrp)
+{
+ struct arm64_reg_context end_ctx;
+ vm_offset_t ctx_addr;
+
+ *addrp -= sizeof(end_ctx);
+ ctx_addr = *addrp;
+
+ memset(&end_ctx, 0, sizeof(end_ctx));
+ end_ctx.ctx_id = ARM64_CTX_END;
+ end_ctx.ctx_size = sizeof(end_ctx);
+
+ if (copyout(&end_ctx, (void *)ctx_addr, sizeof(end_ctx)) != 0)
+ return (false);
+
+ return (true);
+}
+
+typedef bool(*ctx_func)(struct thread *, vm_offset_t *);
+static const ctx_func ctx_funcs[] = {
+ sendsig_ctx_end, /* Must be first to end the linked list */
+ NULL,
+};
+
void
sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
@@ -593,6 +642,7 @@
struct trapframe *tf;
struct sigframe *fp, frame;
struct sigacts *psp;
+ vm_offset_t addr;
int onstack, sig;
td = curthread;
@@ -612,19 +662,15 @@
/* Allocate and validate space for the signal handler context. */
if ((td->td_pflags & TDP_ALTSTACK) != 0 && !onstack &&
SIGISMEMBER(psp->ps_sigonstack, sig)) {
- fp = (struct sigframe *)((uintptr_t)td->td_sigstk.ss_sp +
+ addr = ((uintptr_t)td->td_sigstk.ss_sp +
td->td_sigstk.ss_size);
#if defined(COMPAT_43)
td->td_sigstk.ss_flags |= SS_ONSTACK;
#endif
} else {
- fp = (struct sigframe *)td->td_frame->tf_sp;
+ addr = td->td_frame->tf_sp;
}
- /* Make room, keeping the stack aligned */
- fp--;
- fp = (struct sigframe *)STACKALIGN(fp);
-
/* Fill in the frame to copy out */
bzero(&frame, sizeof(frame));
get_mcontext(td, &frame.sf_uc.uc_mcontext, 0);
@@ -636,6 +682,26 @@
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(td->td_proc);
+ for (int i = 0; ctx_funcs[i] != NULL; i++) {
+ if (!ctx_funcs[i](td, &addr)) {
+ /* Process has trashed its stack. Kill it. */
+ CTR4(KTR_SIG,
+ "sendsig: frame sigexit td=%p fp=%#lx func[%d]=%p",
+ td, addr, i, ctx_funcs[i]);
+ PROC_LOCK(p);
+ sigexit(td, SIGILL);
+ /* NOTREACHED */
+ }
+ }
+
+ /* Point at the first context */
+ frame.sf_uc.uc_mcontext.mc_ptr = addr;
+
+ /* Make room, keeping the stack aligned */
+ fp = (struct sigframe *)addr;
+ fp--;
+ fp = (struct sigframe *)STACKALIGN(fp);
+
/* Copy the sigframe out to the user's stack. */
if (copyout(&frame, fp, sizeof(*fp)) != 0) {
/* Process has trashed its stack. Kill it. */
diff --git a/sys/arm64/include/ucontext.h b/sys/arm64/include/ucontext.h
--- a/sys/arm64/include/ucontext.h
+++ b/sys/arm64/include/ucontext.h
@@ -51,15 +51,29 @@
int fp_pad;
};
+/*
+ * Support for registers that don't fit into gpregs or fpregs, e.g. SVE.
+ * There are some registers that have been added so are optional. To support
+ * these create an array of headers that point at the register data.
+ */
+struct arm64_reg_context {
+ __uint32_t ctx_id;
+ __uint32_t ctx_size;
+};
+
+#define ARM64_CTX_END 0xa5a5a5a5
+
struct __mcontext {
struct gpregs mc_gpregs;
struct fpregs mc_fpregs;
int mc_flags;
#define _MC_FP_VALID 0x1 /* Set when mc_fpregs has valid data */
int mc_pad; /* Padding */
- __uint64_t mc_spare[8]; /* Space for expansion, set to zero */
+ __uint64_t mc_ptr; /* Address of extra_regs struct */
+ __uint64_t mc_spare[7]; /* Space for expansion, set to zero */
};
+
typedef struct __mcontext mcontext_t;
#ifdef COMPAT_FREEBSD32
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Aug 5, 2:33 AM (20 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35984263
Default Alt Text
D43302.id132249.diff (4 KB)
Attached To
Mode
D43302: arm64: Support passing more registers to signals
Attached
Detach File
Event Timeline
Log In to Comment