--- old/usr/src/cmd/mdb/common/mdb/mdb_proc.c	2013-01-23 13:19:01.266124636 +0000
+++ new/usr/src/cmd/mdb/common/mdb/mdb_proc.c	2013-01-23 13:19:01.317775276 +0000
@@ -4720,8 +4720,6 @@
 	return (set_errno(EMDB_NOPROC));
 }
 
-#ifdef	__sparc
-
 /*ARGSUSED*/
 static int
 pt_lwp_getxregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, prxregset_t *xregs)
@@ -4745,8 +4743,6 @@
 	return (set_errno(EMDB_NOPROC));
 }
 
-#endif	/* __sparc */
-
 /*ARGSUSED*/
 static int
 pt_lwp_getfpregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid,
@@ -4778,10 +4774,8 @@
 	pt_lwp_iter,
 	pt_lwp_getregs,
 	pt_lwp_setregs,
-#ifdef __sparc
 	pt_lwp_getxregs,
 	pt_lwp_setxregs,
-#endif
 	pt_lwp_getfpregs,
 	pt_lwp_setfpregs
 };
--- old/usr/src/cmd/mdb/common/mdb/mdb_proc.h	2013-01-23 13:19:01.967435522 +0000
+++ new/usr/src/cmd/mdb/common/mdb/mdb_proc.h	2013-01-23 13:19:01.978815224 +0000
@@ -27,8 +27,6 @@
 #ifndef	_MDB_PROC_H
 #define	_MDB_PROC_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <mdb/mdb_target_impl.h>
 #include <mdb/mdb_io_impl.h>
 #include <mdb/mdb_addrvec.h>
@@ -65,12 +63,10 @@
 	int (*ptl_iter)(mdb_tgt_t *, void *, mdb_addrvec_t *);
 	int (*ptl_getregs)(mdb_tgt_t *, void *, mdb_tgt_tid_t, prgregset_t);
 	int (*ptl_setregs)(mdb_tgt_t *, void *, mdb_tgt_tid_t, prgregset_t);
-#ifdef	__sparc
 	int (*ptl_getxregs)(mdb_tgt_t *, void *, mdb_tgt_tid_t,
 	    prxregset_t *);
 	int (*ptl_setxregs)(mdb_tgt_t *, void *, mdb_tgt_tid_t,
 	    const prxregset_t *);
-#endif
 	int (*ptl_getfpregs)(mdb_tgt_t *, void *, mdb_tgt_tid_t,
 	    prfpregset_t *);
 	int (*ptl_setfpregs)(mdb_tgt_t *, void *, mdb_tgt_tid_t,
@@ -100,8 +96,6 @@
 	(((pt_data_t *)((t)->t_data))->p_ptl_ops->ptl_setregs((t), \
 	((pt_data_t *)((t)->t_data))->p_ptl_hdl, (tid), (gregs)))
 
-#ifdef	__sparc
-
 #define	PTL_GETXREGS(t, tid, xregs) \
 	(((pt_data_t *)((t)->t_data))->p_ptl_ops->ptl_getxregs((t), \
 	((pt_data_t *)((t)->t_data))->p_ptl_hdl, (tid), (xregs)))
@@ -110,8 +104,6 @@
 	(((pt_data_t *)((t)->t_data))->p_ptl_ops->ptl_setxregs((t), \
 	((pt_data_t *)((t)->t_data))->p_ptl_hdl, (tid), (xregs)))
 
-#endif	/* __sparc */
-
 #define	PTL_GETFPREGS(t, tid, fpregs) \
 	(((pt_data_t *)((t)->t_data))->p_ptl_ops->ptl_getfpregs((t), \
 	((pt_data_t *)((t)->t_data))->p_ptl_hdl, (tid), (fpregs)))
--- old/usr/src/cmd/mdb/intel/mdb/proc_amd64dep.c	2013-01-23 13:19:02.400353789 +0000
+++ new/usr/src/cmd/mdb/intel/mdb/proc_amd64dep.c	2013-01-23 13:19:02.410730614 +0000
@@ -24,8 +24,6 @@
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * User Process Target Intel 32-bit component
  *
@@ -187,7 +185,7 @@
 	mdb_printf("%%trapno = 0x%x\n", grs[REG_TRAPNO]);
 	mdb_printf("   %%err = 0x%x\n", grs[REG_ERR]);
 
-	return (set_errno(ENOTSUP));
+	return (DCMD_OK);
 }
 
 static const char *
--- old/usr/src/lib/libc_db/common/thread_db.c	2013-01-23 13:19:02.851707300 +0000
+++ new/usr/src/lib/libc_db/common/thread_db.c	2013-01-23 13:19:02.868529320 +0000
@@ -1963,7 +1963,6 @@
 td_err_e
 __td_thr_getxregsize(td_thrhandle_t *th_p, int *xregsize)
 {
-#if defined(__sparc)
 	struct ps_prochandle *ph_p;
 	td_err_e return_val;
 
@@ -1980,9 +1979,6 @@
 	(void) ps_pcontinue(ph_p);
 	ph_unlock(th_p->th_ta_p);
 	return (return_val);
-#else	/* __sparc */
-	return (TD_NOXREGS);
-#endif	/* __sparc */
 }
 
 /*
@@ -1993,7 +1989,6 @@
 td_err_e
 __td_thr_getxregs(td_thrhandle_t *th_p, void *xregset)
 {
-#if defined(__sparc)
 	struct ps_prochandle *ph_p;
 	td_err_e return_val;
 
@@ -2010,9 +2005,6 @@
 	(void) ps_pcontinue(ph_p);
 	ph_unlock(th_p->th_ta_p);
 	return (return_val);
-#else	/* __sparc */
-	return (TD_NOXREGS);
-#endif	/* __sparc */
 }
 
 /*
@@ -2023,7 +2015,6 @@
 td_err_e
 __td_thr_setxregs(td_thrhandle_t *th_p, const void *xregset)
 {
-#if defined(__sparc)
 	struct ps_prochandle *ph_p;
 	td_err_e return_val;
 
@@ -2040,9 +2031,6 @@
 	(void) ps_pcontinue(ph_p);
 	ph_unlock(th_p->th_ta_p);
 	return (return_val);
-#else	/* __sparc */
-	return (TD_NOXREGS);
-#endif	/* __sparc */
 }
 
 struct searcher {
--- old/usr/src/lib/libproc/common/Pcontrol.h	2013-01-23 13:19:03.337518701 +0000
+++ new/usr/src/lib/libproc/common/Pcontrol.h	2013-01-23 13:19:03.347258987 +0000
@@ -132,9 +132,9 @@
 	lwpid_t	lwp_id;		/* lwp identifier */
 	lwpsinfo_t lwp_psinfo;	/* /proc/<pid>/lwp/<lwpid>/lwpsinfo data */
 	lwpstatus_t lwp_status;	/* /proc/<pid>/lwp/<lwpid>/lwpstatus data */
+	prxregset_t *lwp_xregs;	/* /proc/<pid>/lwp/<lwpid>/xregs data */
 #if defined(sparc) || defined(__sparc)
 	gwindows_t *lwp_gwins;	/* /proc/<pid>/lwp/<lwpid>/gwindows data */
-	prxregset_t *lwp_xregs;	/* /proc/<pid>/lwp/<lwpid>/xregs data */
 	int64_t *lwp_asrs;	/* /proc/<pid>/lwp/<lwpid>/asrs data */
 #endif
 } lwp_info_t;
--- old/usr/src/lib/libproc/common/Pcore.c	2013-01-23 13:19:03.801165384 +0000
+++ new/usr/src/lib/libproc/common/Pcore.c	2013-01-23 13:19:03.818907094 +0000
@@ -587,7 +587,6 @@
 	return (0);
 }
 
-#ifdef __sparc
 static int
 note_xreg(struct ps_prochandle *P, size_t nbytes)
 {
@@ -600,17 +599,20 @@
 
 	if ((xregs = malloc(xbytes)) == NULL)
 		return (-1);
-
+#ifdef __sparc
 	if (read(P->asfd, xregs, xbytes) != xbytes) {
+#else
+	panic("port me");
+#endif
 		dprintf("Pgrab_core: failed to read NT_PRXREG\n");
 		free(xregs);
 		return (-1);
 	}
-
 	lwp->lwp_xregs = xregs;
 	return (0);
 }
 
+#ifdef __sparc
 static int
 note_gwindows(struct ps_prochandle *P, size_t nbytes)
 {
@@ -689,11 +691,7 @@
 	note_notsup,		/*  1	NT_PRSTATUS (old)	*/
 	note_notsup,		/*  2	NT_PRFPREG (old)	*/
 	note_notsup,		/*  3	NT_PRPSINFO (old)	*/
-#ifdef __sparc
 	note_xreg,		/*  4	NT_PRXREG		*/
-#else
-	note_notsup,		/*  4	NT_PRXREG		*/
-#endif
 	note_platform,		/*  5	NT_PLATFORM		*/
 	note_auxv,		/*  6	NT_AUXV			*/
 #ifdef __sparc
--- old/usr/src/lib/libproc/common/Plwpregs.c	2013-01-23 13:19:04.262530235 +0000
+++ new/usr/src/lib/libproc/common/Plwpregs.c	2013-01-23 13:19:04.279592538 +0000
@@ -23,8 +23,6 @@
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <sys/types.h>
 #include <sys/uio.h>
 #include <string.h>
@@ -219,7 +217,6 @@
 	return (setlwpregs(P, lwpid, PCSFPREG, fpregs, sizeof (prfpregset_t)));
 }
 
-#if defined(sparc) || defined(__sparc)
 int
 Plwp_getxregs(struct ps_prochandle *P, lwpid_t lwpid, prxregset_t *xregs)
 {
@@ -256,6 +253,7 @@
 	return (setlwpregs(P, lwpid, PCSXREG, xregs, sizeof (prxregset_t)));
 }
 
+#if defined(sparc) || defined(__sparc)
 int
 Plwp_getgwindows(struct ps_prochandle *P, lwpid_t lwpid, gwindows_t *gwins)
 {
--- old/usr/src/lib/libproc/common/Pservice.c	2013-01-23 13:19:04.659681830 +0000
+++ new/usr/src/lib/libproc/common/Pservice.c	2013-01-23 13:19:04.673537249 +0000
@@ -23,8 +23,6 @@
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <stdarg.h>
 #include <string.h>
 #include "Pcontrol.h"
@@ -166,8 +164,6 @@
 	return (PS_BADLID);
 }
 
-#if defined(sparc) || defined(__sparc)
-
 ps_err_e
 ps_lgetxregsize(struct ps_prochandle *P, lwpid_t lwpid, int *xrsize)
 {
@@ -227,8 +223,6 @@
 	return (PS_BADLID);
 }
 
-#endif	/* sparc */
-
 #if defined(__i386) || defined(__amd64)
 
 ps_err_e
--- old/usr/src/lib/libproc/common/libproc.h	2013-01-23 13:19:05.053686145 +0000
+++ new/usr/src/lib/libproc/common/libproc.h	2013-01-23 13:19:05.062306837 +0000
@@ -369,11 +369,11 @@
 extern int Plwp_setfpregs(struct ps_prochandle *, lwpid_t,
     const prfpregset_t *);
 
-#if defined(__sparc)
-
 extern int Plwp_getxregs(struct ps_prochandle *, lwpid_t, prxregset_t *);
 extern int Plwp_setxregs(struct ps_prochandle *, lwpid_t, const prxregset_t *);
 
+#if defined(__sparc)
+
 extern int Plwp_getgwindows(struct ps_prochandle *, lwpid_t, gwindows_t *);
 
 #if defined(__sparcv9)
--- old/usr/src/lib/libproc/common/llib-lproc	2013-01-23 13:19:05.414633942 +0000
+++ new/usr/src/lib/libproc/common/llib-lproc	2013-01-23 13:19:05.422520205 +0000
@@ -112,14 +112,12 @@
 int Plwp_setregs(struct ps_prochandle *Pr, lwpid_t i, const prgregset_t gr);
 int Plwp_getfpregs(struct ps_prochandle *Pr, lwpid_t i, prfpregset_t *fp);
 int Plwp_setfpregs(struct ps_prochandle *Pr, lwpid_t i, const prfpregset_t *fp);
-#if defined(sparc) || defined(__sparc)
 int Plwp_getxregs(struct ps_prochandle *Pr, lwpid_t i, prxregset_t *xr);
 int Plwp_setxregs(struct ps_prochandle *Pr, lwpid_t i, const prxregset_t *xr);
 #if defined(__sparcv9)
 int Plwp_getasrs(struct ps_prochandle *Pr, lwpid_t i, asrset_t asrs);
 int Plwp_setasrs(struct ps_prochandle *Pr, lwpid_t i, const asrset_t asrs);
 #endif  /* __sparcv9 */
-#endif  /* __sparc */
 int Plwp_getpsinfo(struct ps_prochandle *Pr, lwpid_t i, lwpsinfo_t *lps);
 
 /* Pcore.c */
--- old/usr/src/uts/common/fs/proc/prcontrol.c	2013-01-23 13:19:05.866395524 +0000
+++ new/usr/src/uts/common/fs/proc/prcontrol.c	2013-01-23 13:19:05.887894057 +0000
@@ -59,8 +59,8 @@
 
 static	void	pr_settrace(proc_t *, sigset_t *);
 static	int	pr_setfpregs(prnode_t *, prfpregset_t *);
-#if defined(__sparc)
 static	int	pr_setxregs(prnode_t *, prxregset_t *);
+#if defined(__sparc)
 static	int	pr_setasrs(prnode_t *, asrset_t);
 #endif
 static	int	pr_setvaddr(prnode_t *, caddr_t);
@@ -87,8 +87,8 @@
 	sysset_t	sysset;		/* PCSENTRY, PCSEXIT */
 	prgregset_t	prgregset;	/* PCSREG, PCAGENT */
 	prfpregset_t	prfpregset;	/* PCSFPREG */
-#if defined(__sparc)
 	prxregset_t	prxregset;	/* PCSXREG */
+#if defined(__sparc)
 	asrset_t	asrset;		/* PCSASRS */
 #endif
 	prwatch_t	prwatch;	/* PCWATCH */
@@ -152,10 +152,10 @@
 	case PCSFPREG:
 		size += sizeof (prfpregset_t);
 		break;
-#if defined(__sparc)
 	case PCSXREG:
 		size += sizeof (prxregset_t);
 		break;
+#if defined(__sparc)
 	case PCSASRS:
 		size += sizeof (asrset_t);
 		break;
@@ -418,11 +418,7 @@
 		break;
 
 	case PCSXREG:	/* set extra registers */
-#if defined(__sparc)
 		error = pr_setxregs(pnp, &argp->prxregset);
-#else
-		error = EINVAL;
-#endif
 		break;
 
 #if defined(__sparc)
@@ -503,9 +499,7 @@
 	sysset_t	sysset;		/* PCSENTRY, PCSEXIT */
 	prgregset32_t	prgregset;	/* PCSREG, PCAGENT */
 	prfpregset32_t	prfpregset;	/* PCSFPREG */
-#if defined(__sparc)
 	prxregset_t	prxregset;	/* PCSXREG */
-#endif
 	prwatch32_t	prwatch;	/* PCWATCH */
 	priovec32_t	priovec;	/* PCREAD, PCWRITE */
 	prcred32_t	prcred;		/* PCSCRED */
@@ -573,11 +567,9 @@
 	case PCSFPREG:
 		size += sizeof (prfpregset32_t);
 		break;
-#if defined(__sparc)
 	case PCSXREG:
 		size += sizeof (prxregset_t);
 		break;
-#endif
 	case PCWATCH:
 		size += sizeof (prwatch32_t);
 		break;
@@ -866,14 +858,10 @@
 		break;
 
 	case PCSXREG:	/* set extra registers */
-#if defined(__sparc)
 		if (PROCESS_NOT_32BIT(p))
 			error = EOVERFLOW;
 		else
 			error = pr_setxregs(pnp, &argp->prxregset);
-#else
-		error = EINVAL;
-#endif
 		break;
 
 	case PCSVADDR:	/* set virtual address at which to resume */
@@ -1706,7 +1694,6 @@
 }
 #endif	/* _SYSCALL32_IMPL */
 
-#if defined(__sparc)
 /* ARGSUSED */
 static int
 pr_setxregs(prnode_t *pnp, prxregset_t *prxregset)
@@ -1731,6 +1718,7 @@
 	return (0);
 }
 
+#if defined(__sparc)
 static int
 pr_setasrs(prnode_t *pnp, asrset_t asrset)
 {
--- old/usr/src/uts/common/fs/proc/prioctl.c	2013-01-23 13:19:06.334276824 +0000
+++ new/usr/src/uts/common/fs/proc/prioctl.c	2013-01-23 13:19:06.342957416 +0000
@@ -256,11 +256,7 @@
 		break;
 	case PIOCSXREG:		/* set extra registers */
 	case PIOCGXREG:		/* get extra registers */
-#if defined(__sparc)
 		thingsize = sizeof (prxregset_t);
-#else
-		thingsize = 0;
-#endif
 		break;
 	case PIOCACTION:
 		thingsize = (nsig-1) * sizeof (struct sigaction);
--- old/usr/src/uts/common/fs/proc/prvnops.c	2013-01-23 13:19:06.911163473 +0000
+++ new/usr/src/uts/common/fs/proc/prvnops.c	2013-01-23 13:19:06.931925013 +0000
@@ -1524,7 +1524,6 @@
 static int
 pr_read_xregs(prnode_t *pnp, uio_t *uiop)
 {
-#if defined(__sparc)
 	proc_t *p;
 	kthread_t *t;
 	int error;
@@ -1557,9 +1556,6 @@
 out:
 	kmem_free(xreg, sizeof (prxregset_t));
 	return (error);
-#else
-	return (0);
-#endif
 }
 
 #if defined(__sparc)
--- old/usr/src/uts/intel/Makefile.files	2013-01-23 13:19:07.462518149 +0000
+++ new/usr/src/uts/intel/Makefile.files	2013-01-23 13:19:07.474782207 +0000
@@ -76,7 +76,8 @@
 	prom_exit.o	\
 	prom_panic.o	\
 	sendsig.o	\
-	syscall.o
+	syscall.o	\
+	xregs.o
 
 
 #
--- old/usr/src/uts/intel/amd64/sys/privregs.h	2013-01-23 13:19:07.798507592 +0000
+++ new/usr/src/uts/intel/amd64/sys/privregs.h	2013-01-23 13:19:07.809627262 +0000
@@ -110,6 +110,7 @@
 
 #ifdef _KERNEL
 #define	lwptoregs(lwp)	((struct regs *)((lwp)->lwp_regs))
+#define	lwptofpu(lwp)	((kfpu_t *)((lwp)->lwp_fpu))
 #endif /* _KERNEL */
 
 #else	/* !_ASM */
--- old/usr/src/uts/intel/fs/proc/prmachdep.c	2013-01-23 13:19:08.491087105 +0000
+++ new/usr/src/uts/intel/fs/proc/prmachdep.c	2013-01-23 13:19:08.503347817 +0000
@@ -238,41 +238,42 @@
 /*
  * Does the system support extra register state?
  */
-/* ARGSUSED */
 int
 prhasx(proc_t *p)
 {
-	return (0);
+	/* XXX */
+	return (1);
 }
 
 /*
  * Get the size of the extra registers.
  */
-/* ARGSUSED */
 int
 prgetprxregsize(proc_t *p)
 {
-	return (0);
+	return (xregs_getsize(p));
 }
 
 /*
  * Get extra registers.
  */
-/*ARGSUSED*/
 void
 prgetprxregs(klwp_t *lwp, caddr_t prx)
 {
-	/* no extra registers */
+	extern void xregs_get(struct _klwp *, caddr_t);
+
+	xregs_get(lwp, prx);
 }
 
 /*
  * Set extra registers.
  */
-/*ARGSUSED*/
 void
 prsetprxregs(klwp_t *lwp, caddr_t prx)
 {
-	/* no extra registers */
+	extern void xregs_set(struct _klwp *, caddr_t);
+
+	xregs_set(lwp, prx);
 }
 
 /*
--- old/usr/src/uts/intel/ia32/os/sendsig.c	2013-01-23 13:19:08.913729112 +0000
+++ new/usr/src/uts/intel/ia32/os/sendsig.c	2013-01-23 13:19:08.922717765 +0000
@@ -133,13 +133,15 @@
 	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
@@ -175,6 +177,14 @@
 	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);
 
 	/*
@@ -289,6 +299,20 @@
 	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;
@@ -354,6 +378,8 @@
 		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);
@@ -393,12 +419,14 @@
 	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;
@@ -406,6 +434,14 @@
 	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);
 
 	/*
@@ -507,6 +543,20 @@
 	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;
@@ -572,6 +622,8 @@
 		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);
--- /dev/null	2013-01-23 13:19:09.000000000 +0000
+++ new/usr/src/uts/intel/ia32/os/xregs.c	2013-01-23 13:19:09.297431276 +0000
@@ -0,0 +1,232 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1994-1998,2003 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright 2013 David Hoeppner.  All rights reserved.
+ */
+
+#include <sys/types.h>
+#include <sys/t_lock.h>
+#include <sys/klwp.h>
+#include <sys/proc.h>
+#include <sys/ucontext.h>
+#include <sys/procfs.h>
+#include <sys/privregs.h>
+#include <sys/fp.h>
+#include <sys/cpuvar.h>
+#include <sys/cmn_err.h>
+#include <sys/disp.h>
+#include <sys/systm.h>
+#include <sys/archsystm.h>
+#include <sys/note.h>
+
+/*
+ * Clear the struct ucontext extra register state pointer.
+ */
+void
+xregs_clrptr(klwp_id_t lwp, ucontext_t *uc)
+{
+	uc->uc_xrs.xrs_id = 0;
+	uc->uc_xrs.xrs_ptr = NULL;
+}
+
+/*
+ * Indicate whether or not an extra register state
+ * pointer is associated with a struct ucontext.
+ */
+int
+xregs_hasptr(klwp_id_t lwp, ucontext_t *uc)
+{
+	_NOTE(ARGUNUSED(lwp));
+
+	return (uc->uc_xrs.xrs_id == XRS_ID);
+}
+
+/*
+ * Get the struct ucontext extra register state pointer field.
+ */
+caddr_t
+xregs_getptr(klwp_id_t lwp, ucontext_t *uc)
+{
+	_NOTE(ARGUNUSED(lwp));
+
+	if (uc->uc_xrs.xrs_id == XRS_ID)
+		return (uc->uc_xrs.xrs_ptr);
+
+	return (NULL);
+}
+
+/*
+ * Set the struct ucontext extra register state pointer field.
+ */
+void
+xregs_setptr(klwp_id_t lwp, ucontext_t *uc, caddr_t xrp)
+{
+	_NOTE(ARGUNUSED(lwp));
+
+	uc->uc_xrs.xrs_id = XRS_ID;
+	uc->uc_xrs.xrs_ptr = xrp;
+}
+
+#if defined(_SYSCALL32_IMPL)
+
+void
+xregs_clrptr32(klwp_id_t lwp, ucontext32_t *uc)
+{
+	_NOTE(ARGUNUSED(lwp));
+
+	uc->uc_xrs.xrs_id = 0;
+	uc->uc_xrs.xrs_ptr = NULL;
+}
+
+int
+xregs_hasptr32(klwp_id_t lwp, ucontext32_t *uc)
+{
+	_NOTE(ARGUNUSED(lwp));
+
+	return (uc->uc_xrs.xrs_id == XRS_ID);
+}
+
+caddr32_t
+xregs_getptr32(klwp_id_t lwp, ucontext32_t *uc)
+{
+	_NOTE(ARGUNUSED(lwp));
+
+	if (uc->uc_xrs.xrs_id == XRS_ID)
+		return (uc->uc_xrs.xrs_ptr);
+
+	return (0);
+}
+
+void
+xregs_setptr32(klwp_id_t lwp, ucontext32_t *uc, caddr32_t xrp)
+{
+	_NOTE(ARGUNUSED(lwp));
+
+	uc->uc_xrs.xrs_id = XRS_ID;
+	uc->uc_xrs.xrs_ptr = xrp;
+}
+
+#endif	/* _SYSCALL32_IMPL */
+
+/*
+ * Fill in the extra register state area specified with the
+ * specified lwp's floating point extra register state information.
+ */
+void
+xregs_getfpregs(klwp_id_t lwp, caddr_t xrp)
+{
+	prxregset_t *xregs = (prxregset_t *)xrp;
+	kfpu_t *fp = lwptofpu(lwp);
+
+	if (xregs == NULL)
+		return;
+
+	kpreempt_disable();
+
+	xregs->pr_type = XR_TYPE_XSAVE;
+
+	kpreempt_enable();
+}
+
+/*
+ * Fill in the extra register state area specified with
+ * the specified kwp's extra register state information.
+ */
+void
+xregs_get(klwp_id_t lwp, caddr_t xrp)
+{
+
+	if (xrp != NULL) {
+		bzero(xrp, sizeof (prxregset_t));
+		xregs_getfpregs(lwp, xrp);
+	}
+}
+
+/*
+ * Set the specified lwp's floating-point extra
+ * register state based on the specified input.
+ */
+void
+xregs_setfpregs(klwp_id_t lwp, caddr_t xrp)
+{
+	prxregset_t *xregs = (prxregset_t *)xrp;
+	kfpu_t *fp = lwptofpu(lwp);
+	fpu_ctx_t *fpu = &lwp->lwp_pcb.pcb_fpu;
+
+	if (xregs == NULL)
+		return;
+
+#if defined(DEBUG)
+	if (xregs->pr_type != XR_TYPE_XSAVE) {
+		cmn_err(CE_WARN,
+		    "xregs_setfpregs: pr_type is %d and should be %d",
+		    xregs->pr_type, XR_TYPE_XSAVE);
+	}
+#endif	/* DEBUG */
+
+	if (fpu->fpu_flags & FPU_EN) {
+		kpreempt_disable();
+		(void) kcopy(&xregs->pr_un.pr_xsave.pr_ymm,
+		    &fp->kfpu_u.kfpu_xs.xs_ymm,
+		    sizeof (&xregs->pr_un.pr_xsave.pr_ymm));
+
+		/*
+		 * If not the current lwp then resume() will handle it.
+		 */
+		if (lwp != ttolwp(curthread)) {
+			/* Force resume to reload fp regs */
+			kpreempt_enable();
+			return;
+		}
+
+		if (fpu_exists) {
+		}
+
+		kpreempt_enable();
+	}
+}
+
+/*
+ * Set the specified lwp's extra register
+ * state based on the specified input.
+ */
+void
+xregs_set(klwp_id_t lwp, caddr_t xrp)
+{
+	if (xrp != NULL) {
+		xregs_setfpregs(lwp, xrp);
+	}
+}
+
+/*
+ * Return the size of the extra register state.
+ */
+int
+xregs_getsize(proc_t *p)
+{
+	return (sizeof (prxregset_t));
+}
--- old/usr/src/uts/intel/ia32/sys/privregs.h	2013-01-23 13:19:09.503509057 +0000
+++ new/usr/src/uts/intel/ia32/sys/privregs.h	2013-01-23 13:19:09.515639102 +0000
@@ -27,8 +27,6 @@
 #ifndef	_IA32_SYS_PRIVREGS_H
 #define	_IA32_SYS_PRIVREGS_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -90,6 +88,7 @@
 
 #ifdef _KERNEL
 #define	lwptoregs(lwp)	((struct regs *)((lwp)->lwp_regs))
+#define	lwptofpu(lwp)	((kfpu_t *)((lwp)->lwp_fpu))
 #endif /* _KERNEL */
 
 #else	/* !_ASM */
--- old/usr/src/uts/intel/ia32/syscall/getcontext.c	2013-01-23 13:19:09.905031364 +0000
+++ new/usr/src/uts/intel/ia32/syscall/getcontext.c	2013-01-23 13:19:09.914480403 +0000
@@ -184,6 +184,8 @@
 	ucontext_t *ucp;
 	klwp_t *lwp = ttolwp(curthread);
 	stack_t dummy_stk;
+	caddr_t xregs = NULL;
+	int xregs_size = 0;
 
 	/*
 	 * In future releases, when the ucontext structure grows,
@@ -228,11 +230,23 @@
 			return (set_errno(EFAULT));
 		}
 
+		/*
+		 * Get extra register state.
+		 */
+		xregs_clrptr(lwp, &uc);
+
 		restorecontext(&uc);
 
 		if ((uc.uc_flags & UC_STACK) && (lwp->lwp_ustack != 0))
 			(void) copyout(&uc.uc_stack, (stack_t *)lwp->lwp_ustack,
 			    sizeof (uc.uc_stack));
+
+		/*
+		 * Free extra register state.
+		 */
+		if (xregs_size)
+			kmem_free(xregs, xregs_size);
+
 		return (0);
 
 	case GETUSTACK:
--- old/usr/src/uts/intel/sys/archsystm.h	2013-01-23 13:19:10.347478897 +0000
+++ new/usr/src/uts/intel/sys/archsystm.h	2013-01-23 13:19:10.368461577 +0000
@@ -121,6 +121,24 @@
 extern void getfpregs32(klwp_t *, fpregset32_t *);
 #endif
 
+struct ucontext;
+extern void xregs_clrptr(struct _klwp *, struct ucontext *);
+extern int xregs_hasptr(struct _klwp *, struct ucontext *);
+extern caddr_t xregs_getptr(struct _klwp *, struct ucontext *);
+extern void xregs_setptr(struct _klwp *, struct ucontext *, caddr_t);
+
+#if defined(_SYSCALL32_IMPL)
+struct ucontext32;
+extern void xregs_clrptr32(struct _klwp *, struct ucontext32 *);
+extern int xregs_hasptr32(struct _klwp *, struct ucontext32 *);
+extern caddr32_t xregs_getptr32(struct _klwp *, struct ucontext32 *);
+extern void xregs_setptr32(struct _klwp *, struct ucontext32 *, caddr32_t);
+#endif /* _SYSCALL32_IMPL */
+
+extern void xregs_get(struct _klwp *, caddr_t);
+extern void xregs_set(struct _klwp *, caddr_t);
+extern int xregs_getsize(struct proc *);
+
 struct fpu_ctx;
 
 extern void fp_free(struct fpu_ctx *, int);
--- old/usr/src/uts/intel/sys/procfs_isa.h	2013-01-23 13:19:10.785033058 +0000
+++ new/usr/src/uts/intel/sys/procfs_isa.h	2013-01-23 13:19:10.796295795 +0000
@@ -27,8 +27,6 @@
 #ifndef _SYS_PROCFS_ISA_H
 #define	_SYS_PROCFS_ISA_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * Instruction Set Architecture specific component of <sys/procfs.h>
  * i386 version
@@ -114,6 +112,64 @@
 #define	R_R1	EDX
 #endif
 
+#define	XR_TYPE_XSAVE	0x101
+
+typedef struct prxregset {
+	uint32_t	pr_type;
+	uint32_t	pr_align;
+	uint32_t	pr_xsize;
+	uint32_t	pr_pad;
+	union {
+		struct pr_xsave {
+			uint16_t	pr_fcw;
+			uint16_t	pr_fsw;
+			uint16_t	pr_fctw;
+			uint16_t	pr_fop;
+#if defined(__amd64)
+			uint64_t	pr_rip;
+			uint64_t	pr_rdp;
+#else
+			uint32_t	pr_eip;
+			uint16_t	pr_cs;
+			uint16_t	__pr_ign0;
+			uint32_t	pr_dp;
+			uint16_t	pr_ds;
+			uint16_t	__pr_ign1;
+#endif
+			uint32_t	pr_mxcsr;
+			uint32_t	pr_mxcsr_mask;
+			union {
+				uint16_t	pr_fpr_16[5];
+				u_longlong_t	pr_fpr_mmx;
+				uint32_t	__pr_fpr_pad[4];
+			} pr_st[8];
+#if defined(__amd64)
+			upad128_t	pr_xmm[16];
+			upad128_t	__pr_ign2[3];
+#else
+			upad128_t	pr_xmm[8];
+			upad128_t	__pr_ign2[11];
+#endif
+			union {
+				struct {
+					uint64_t	pr_xcr0;
+					uint64_t	pr_mbz[2];
+				} pr_xsave_info;
+				upad128_t	__pr_pad[3];
+			} pr_sw_avail;
+			uint64_t	pr_xstate_bv;
+			uint64_t	pr_rsv_mbz[2];
+			uint64_t	pr_reserved[5];
+#if defined(__amd64)
+			upad128_t	pr_ymm[16];
+#else
+			upad128_t	pr_ymm[8];
+			upad128_t	__pr_ign3[8];
+#endif
+		} pr_xsave;
+	} pr_un;
+} prxregset_t;
+
 #ifdef	__cplusplus
 }
 #endif
--- old/usr/src/uts/intel/sys/ucontext.h	2013-01-23 13:19:11.183802662 +0000
+++ new/usr/src/uts/intel/sys/ucontext.h	2013-01-23 13:19:11.192402678 +0000
@@ -72,6 +72,13 @@
 typedef	struct __ucontext ucontext_t;
 #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */
 
+#define	XRS_ID	0x00737278	/* the string "xrs" */
+
+typedef struct {
+	unsigned long	xrs_id;
+	caddr_t		xrs_ptr;
+} xrs_t;
+
 #if !defined(_XPG4_2) || defined(__EXTENSIONS__)
 struct	ucontext {
 #else
@@ -82,11 +89,17 @@
 	sigset_t   	uc_sigmask;
 	stack_t 	uc_stack;
 	mcontext_t 	uc_mcontext;
-	long		uc_filler[5];	/* see ABI spec for Intel386 */
+	xrs_t		uc_xrs;
+	long		uc_filler[3];	/* see ABI spec for Intel386 */
 };
 
 #if defined(_SYSCALL32)
 
+typedef struct {
+	uint32_t	xrs_id;
+	caddr32_t	xrs_ptr;
+} xrs32_t;
+
 /* Kernel view of user ILP32 ucontext structure */
 
 typedef struct ucontext32 {
@@ -95,7 +108,8 @@
 	sigset_t	uc_sigmask;
 	stack32_t	uc_stack;
 	mcontext32_t	uc_mcontext;
-	int32_t		uc_filler[5];
+	xrs32_t		uc_xrs;
+	int32_t		uc_filler[3];
 } ucontext32_t;
 
 #if defined(_KERNEL)
@@ -122,6 +136,7 @@
 #define	UC_STACK	0x02
 #define	UC_CPU		0x04
 #define	UC_MAU		0x08
+#define	UC_XREGS	0x10
 #define	UC_FPU		UC_MAU
 
 #define	UC_MCONTEXT	(UC_CPU|UC_FPU)
