Print this page
XXX AVX procfs
@@ -131,17 +131,19 @@
label_t ljb;
volatile caddr_t sp;
caddr_t fp;
volatile struct regs *rp;
volatile greg_t upc;
- volatile proc_t *p = ttoproc(curthread);
+ proc_t *volatile p = ttoproc(curthread);
struct as *as = p->p_as;
klwp_t *lwp = ttolwp(curthread);
ucontext_t *volatile tuc = NULL;
ucontext_t *uc;
siginfo_t *sip_addr;
volatile int watched;
+ char *volatile xregs = NULL;
+ volatile size_t xregs_size = 0;
/*
* This routine is utterly dependent upon STACK_ALIGN being
* 16 and STACK_ENTRY_ALIGN being 8. Let's just acknowledge
* that and require it.
@@ -173,10 +175,18 @@
ASSERT((sizeof (struct sigframe) % 16) == 8);
minstacksz = sizeof (struct sigframe) + SA(sizeof (*uc));
if (sip != NULL)
minstacksz += SA(sizeof (siginfo_t));
+
+ /*
+ * Extra registers, if supported by this platform, may be of arbitrary
+ * length. Size them now so we know how big the signal frame has to be.
+ */
+ xregs_size = xregs_getsize(p);
+ minstacksz += SA(xregs_size);
+
ASSERT((minstacksz & (STACK_ENTRY_ALIGN - 1ul)) == 0);
/*
* Figure out whether we will be handling this signal on
* an alternate stack specified by the user. Then allocate
@@ -287,10 +297,24 @@
* 16-byte alignment for ucontext_t and its %xmm registers.
*/
uc = (ucontext_t *)(sp + sizeof (struct sigframe));
tuc = kmem_alloc(sizeof (*tuc), KM_SLEEP);
savecontext(tuc, &lwp->lwp_sigoldmask);
+
+ /*
+ * Save extra register state if it exists.
+ */
+ if (xregs_size != 0) {
+ xregs_setptr(lwp, tuc, sp);
+ xregs = kmem_alloc(xregs_size, KM_SLEEP);
+ xregs_get(lwp, xregs);
+ copyout_noerr(xregs, sp, xregs_size);
+ kmem_free(xregs, xregs_size);
+ xregs = NULL;
+ sp += SA(xregs_size);
+ }
+
copyout_noerr(tuc, uc, sizeof (*tuc));
kmem_free(tuc, sizeof (*tuc));
tuc = NULL;
lwp->lwp_oldcontext = (uintptr_t)uc;
@@ -352,10 +376,12 @@
no_fault();
if (watched)
watch_enable_addr((caddr_t)sp, minstacksz, S_WRITE);
if (tuc)
kmem_free(tuc, sizeof (*tuc));
+ if (xregs)
+ kmem_free(xregs, xregs_size);
#ifdef DEBUG
printf("sendsig: bad signal stack cmd=%s, pid=%d, sig=%d\n",
PTOU(p)->u_comm, p->p_pid, sig);
printf("on fault, sigsp = 0x%p, action = 0x%p, upc = 0x%lx\n",
(void *)sp, (void *)hdlr, (uintptr_t)upc);
@@ -391,23 +417,33 @@
label_t ljb;
volatile caddr_t sp;
caddr_t fp;
volatile struct regs *rp;
volatile greg_t upc;
- volatile proc_t *p = ttoproc(curthread);
+ proc_t *volatile p = ttoproc(curthread);
klwp_t *lwp = ttolwp(curthread);
ucontext32_t *volatile tuc = NULL;
ucontext32_t *uc;
siginfo32_t *sip_addr;
volatile int watched;
+ char *volatile xregs = NULL;
+ volatile size_t xregs_size = 0;
rp = lwptoregs(lwp);
upc = rp->r_pc;
minstacksz = SA32(sizeof (struct sigframe32)) + SA32(sizeof (*uc));
if (sip != NULL)
minstacksz += SA32(sizeof (siginfo32_t));
+
+ /*
+ * Extra registers, if supported by this platform, may be of arbitrary
+ * length. Size them now so we know how big the signal frame has to be.
+ */
+ xregs_size = xregs_getsize(p);
+ minstacksz += SA32(xregs_size);
+
ASSERT((minstacksz & (STACK_ALIGN32 - 1)) == 0);
/*
* Figure out whether we will be handling this signal on
* an alternate stack specified by the user. Then allocate
@@ -505,10 +541,24 @@
/* save the current context on the user stack */
fp -= SA32(sizeof (*tuc));
uc = (ucontext32_t *)fp;
tuc = kmem_alloc(sizeof (*tuc), KM_SLEEP);
savecontext32(tuc, &lwp->lwp_sigoldmask);
+
+ /*
+ * Save extra register state if it exists.
+ */
+ if (xregs_size != 0) {
+ xregs_setptr32(lwp, tuc, (caddr32_t)(uintptr_t)sp);
+ xregs = kmem_alloc(xregs_size, KM_SLEEP);
+ xregs_get(lwp, xregs);
+ copyout_noerr(xregs, sp, xregs_size);
+ kmem_free(xregs, xregs_size);
+ xregs = NULL;
+ sp += SA32(xregs_size);
+ }
+
copyout_noerr(tuc, uc, sizeof (*tuc));
kmem_free(tuc, sizeof (*tuc));
tuc = NULL;
lwp->lwp_oldcontext = (uintptr_t)uc;
@@ -570,10 +620,12 @@
no_fault();
if (watched)
watch_enable_addr((caddr_t)sp, minstacksz, S_WRITE);
if (tuc)
kmem_free(tuc, sizeof (*tuc));
+ if (xregs_size)
+ kmem_free(xregs, xregs_size);
#ifdef DEBUG
printf("sendsig32: bad signal stack cmd=%s pid=%d, sig=%d\n",
PTOU(p)->u_comm, p->p_pid, sig);
printf("on fault, sigsp = 0x%p, action = 0x%p, upc = 0x%lx\n",
(void *)sp, (void *)hdlr, (uintptr_t)upc);