Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F95548384
D43302.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.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
@@ -461,8 +461,12 @@
set_mcontext(struct thread *td, mcontext_t *mcp)
{
#define PSR_13_MASK 0xfffffffful
+ struct arm64_reg_context ctx;
struct trapframe *tf = td->td_frame;
uint64_t spsr;
+ vm_offset_t addr;
+ int error;
+ bool done;
spsr = mcp->mc_gpregs.gp_spsr;
#ifdef COMPAT_FREEBSD13
@@ -501,8 +505,35 @@
READ_SPECIALREG(mdscr_el1) | MDSCR_SS);
isb();
}
+
set_fpcontext(td, mcp);
+ /* Read any register contexts we find */
+ if (mcp->mc_ptr != 0) {
+ addr = mcp->mc_ptr;
+
+ done = false;
+ do {
+ if (!__is_aligned(addr,
+ _Alignof(struct arm64_reg_context)))
+ return (EINVAL);
+
+ error = copyin((const void *)addr, &ctx, sizeof(ctx));
+ if (error != 0)
+ return (error);
+
+ switch (ctx.ctx_id) {
+ case ARM64_CTX_END:
+ done = true;
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ addr += ctx.ctx_size;
+ } while (!done);
+ }
+
return (0);
#undef PSR_13_MASK
}
@@ -585,6 +616,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 +649,7 @@
struct trapframe *tf;
struct sigframe *fp, frame;
struct sigacts *psp;
+ vm_offset_t addr;
int onstack, sig;
td = curthread;
@@ -612,19 +669,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 +689,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
Sun, Sep 22, 11:40 AM (21 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12384896
Default Alt Text
D43302.diff (4 KB)
Attached To
Mode
D43302: arm64: Support passing more registers to signals
Attached
Detach File
Event Timeline
Log In to Comment