summaryrefslogtreecommitdiffstats
path: root/sys/i386/linux/linux_sysvec.c
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2005-02-06 17:29:20 +0000
committerdas <das@FreeBSD.org>2005-02-06 17:29:20 +0000
commit89cc41ef8f5b4277ced60a71929d3c688e460c6b (patch)
tree6a53d6aaa2c5e606210b667b4254eb0b6ca38db2 /sys/i386/linux/linux_sysvec.c
parent552b43ee4475faf2c3ca9b4bce75dfa87d3d7507 (diff)
downloadFreeBSD-src-89cc41ef8f5b4277ced60a71929d3c688e460c6b.zip
FreeBSD-src-89cc41ef8f5b4277ced60a71929d3c688e460c6b.tar.gz
When running Linux binaries, set up the initial FPU state as Linux
would. PR: 28966
Diffstat (limited to 'sys/i386/linux/linux_sysvec.c')
-rw-r--r--sys/i386/linux/linux_sysvec.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index 8592701..34b4c49 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -94,6 +94,9 @@ MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
#define LINUX_SYS_linux_rt_sendsig 0
#define LINUX_SYS_linux_sendsig 0
+#define fldcw(addr) __asm("fldcw %0" : : "m" (*(addr)))
+#define __LINUX_NPXCW__ 0x37f
+
extern char linux_sigcode[];
extern int linux_szsigcode;
@@ -775,12 +778,16 @@ static void
exec_linux_setregs(struct thread *td, u_long entry,
u_long stack, u_long ps_strings)
{
+ static const u_short control = __LINUX_NPXCW__;
struct pcb *pcb = td->td_pcb;
exec_setregs(td, entry, stack, ps_strings);
/* Linux sets %gs to 0, we default to _udatasel */
pcb->pcb_gs = 0; load_gs(0);
+
+ /* Linux sets the i387 to extended precision. */
+ fldcw(&control);
}
struct sysentvec linux_sysvec = {
OpenPOWER on IntegriCloud