summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authordeischen <deischen@FreeBSD.org>2002-12-02 19:58:55 +0000
committerdeischen <deischen@FreeBSD.org>2002-12-02 19:58:55 +0000
commit88d7b8f56badfe1166bf9c4ca3fe30a8e9e4b306 (patch)
treec46b44c418609ede008e86880bbd07544a9f2fa9 /sys/i386
parent09074e808047049fdcb245eb25886bc976452efa (diff)
downloadFreeBSD-src-88d7b8f56badfe1166bf9c4ca3fe30a8e9e4b306.zip
FreeBSD-src-88d7b8f56badfe1166bf9c4ca3fe30a8e9e4b306.tar.gz
Align the FPU state in the ucontext and sigcontext to 16 bytes
to accomodate the new SSE/XMM floating point save/restore instructions. This commit is mostly from bde and includes some style nits. Approved by: re (jhb)
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/genassym.c3
-rw-r--r--sys/i386/i386/locore.s24
-rw-r--r--sys/i386/i386/machdep.c9
-rw-r--r--sys/i386/include/signal.h4
-rw-r--r--sys/i386/include/ucontext.h10
5 files changed, 31 insertions, 19 deletions
diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c
index 4785645..92915b6 100644
--- a/sys/i386/i386/genassym.c
+++ b/sys/i386/i386/genassym.c
@@ -157,6 +157,9 @@ ASSYM(SIGF_HANDLER, offsetof(struct sigframe, sf_ahu.sf_handler));
ASSYM(SIGF_SC, offsetof(struct osigframe, sf_siginfo.si_sc));
#endif
ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc));
+#ifdef COMPAT_FREEBSD4
+ASSYM(SIGF_UC4, offsetof(struct sigframe4, sf_uc));
+#endif
#ifdef COMPAT_43
ASSYM(SC_PS, offsetof(struct osigcontext, sc_ps));
ASSYM(SC_FS, offsetof(struct osigcontext, sc_fs));
diff --git a/sys/i386/i386/locore.s b/sys/i386/i386/locore.s
index 8f1d801..19a6ac7 100644
--- a/sys/i386/i386/locore.s
+++ b/sys/i386/i386/locore.s
@@ -394,32 +394,36 @@ begin:
* Signal trampoline, copied to top of user stack
*/
NON_GPROF_ENTRY(sigcode)
- call *SIGF_HANDLER(%esp) /* call signal handler */
- lea SIGF_UC(%esp),%eax /* get ucontext_t */
+ calll *SIGF_HANDLER(%esp)
+ leal SIGF_UC(%esp),%eax /* get ucontext */
pushl %eax
testl $PSL_VM,UC_EFLAGS(%eax)
- jne 9f
+ jne 1f
movl UC_GS(%eax),%gs /* restore %gs */
-9:
+1:
movl $SYS_sigreturn,%eax
pushl %eax /* junk to fake return addr. */
int $0x80 /* enter kernel with args */
-0: jmp 0b
+ /* on stack */
+1:
+ jmp 1b
#ifdef COMPAT_FREEBSD4
ALIGN_TEXT
freebsd4_sigcode:
- call *SIGF_HANDLER(%esp) /* call signal handler */
- lea SIGF_UC(%esp),%eax /* get ucontext_t */
+ calll *SIGF_HANDLER(%esp)
+ leal SIGF_UC4(%esp),%eax /* get ucontext */
pushl %eax
testl $PSL_VM,UC4_EFLAGS(%eax)
- jne 9f
+ jne 1f
movl UC4_GS(%eax),%gs /* restore %gs */
-9:
+1:
movl $344,%eax /* 4.x SYS_sigreturn */
pushl %eax /* junk to fake return addr. */
int $0x80 /* enter kernel with args */
-0: jmp 0b
+ /* on stack */
+1:
+ jmp 1b
#endif
#ifdef COMPAT_43
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 1aedc3d..27b3bca 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -506,6 +506,7 @@ sendsig(catcher, sig, mask, code)
struct proc *p;
struct thread *td;
struct sigacts *psp;
+ char *sp;
struct trapframe *regs;
int oonstack;
@@ -544,13 +545,15 @@ sendsig(catcher, sig, mask, code)
/* Allocate space for the signal handler context. */
if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack &&
SIGISMEMBER(psp->ps_sigonstack, sig)) {
- sfp = (struct sigframe *)(p->p_sigstk.ss_sp +
- p->p_sigstk.ss_size - sizeof(struct sigframe));
+ sp = p->p_sigstk.ss_sp +
+ p->p_sigstk.ss_size - sizeof(struct sigframe);
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
p->p_sigstk.ss_flags |= SS_ONSTACK;
#endif
} else
- sfp = (struct sigframe *)regs->tf_esp - 1;
+ sp = (char *)regs->tf_esp - sizeof(struct sigframe);
+ /* Align to 16 bytes. */
+ sfp = (struct sigframe *)((unsigned int)sp & ~0xF);
PROC_UNLOCK(p);
/* Translate the signal if appropriate. */
diff --git a/sys/i386/include/signal.h b/sys/i386/include/signal.h
index efc7ef0..fb2d82c 100644
--- a/sys/i386/include/signal.h
+++ b/sys/i386/include/signal.h
@@ -100,7 +100,7 @@ struct osigcontext {
struct sigcontext {
struct __sigset sc_mask; /* signal mask to restore */
int sc_onstack; /* sigstack state to restore */
- int sc_gs; /* machine state (struct trapframe): */
+ int sc_gs; /* machine state (struct trapframe) */
int sc_fs;
int sc_es;
int sc_ds;
@@ -127,7 +127,7 @@ struct sigcontext {
int sc_fpformat;
int sc_ownedfp;
int sc_spare1[1];
- int sc_fpstate[128];
+ int sc_fpstate[128] __aligned(16);
int sc_spare2[8];
};
diff --git a/sys/i386/include/ucontext.h b/sys/i386/include/ucontext.h
index ea6f0b6..ec3e0ee 100644
--- a/sys/i386/include/ucontext.h
+++ b/sys/i386/include/ucontext.h
@@ -38,7 +38,7 @@ typedef struct __mcontext {
* and ucontext_t at the same time.
*/
int mc_onstack; /* XXX - sigcontext compat. */
- int mc_gs; /* machine state (trapframe) */
+ int mc_gs; /* machine state (struct trapframe) */
int mc_fs;
int mc_es;
int mc_ds;
@@ -68,15 +68,17 @@ typedef struct __mcontext {
#define _MC_FPOWNED_PCB 0x20002 /* FP state came from PCB */
int mc_ownedfp;
int mc_spare1[1]; /* align next field to 16 bytes */
- int mc_fpstate[128]; /* must be multiple of 16 bytes */
+ /*
+ * See <machine/npx.h> for the internals of mc_fpstate[].
+ */
+ int mc_fpstate[128] __aligned(16);
int mc_spare2[8];
} mcontext_t;
#if defined(_KERNEL) && defined(COMPAT_FREEBSD4)
-/* For 4.x binaries */
struct mcontext4 {
int mc_onstack; /* XXX - sigcontext compat. */
- int mc_gs;
+ int mc_gs; /* machine state (struct trapframe) */
int mc_fs;
int mc_es;
int mc_ds;
OpenPOWER on IntegriCloud