summaryrefslogtreecommitdiff
path: root/sys/compat/linux
diff options
context:
space:
mode:
authorchristos <christos@NetBSD.org>2008-10-26 03:43:42 +0000
committerchristos <christos@NetBSD.org>2008-10-26 03:43:42 +0000
commit86f314b4bf30917ebc60772648e2a36675e69d4d (patch)
treef3fded95c56b6f7034fc2028adb05ee0081529e5 /sys/compat/linux
parent4adcca090c3a61bf0c77f7649ff5dec079b55f0b (diff)
don't forget the percpu stuff and load gs immediately.
Diffstat (limited to 'sys/compat/linux')
-rw-r--r--sys/compat/linux/arch/i386/linux_exec_machdep.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/sys/compat/linux/arch/i386/linux_exec_machdep.c b/sys/compat/linux/arch/i386/linux_exec_machdep.c
index 3ed1d57848c..c7c0c8d719e 100644
--- a/sys/compat/linux/arch/i386/linux_exec_machdep.c
+++ b/sys/compat/linux/arch/i386/linux_exec_machdep.c
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_exec_machdep.c,v 1.6 2008/10/25 23:38:28 christos Exp $ */
+/* $NetBSD: linux_exec_machdep.c,v 1.7 2008/10/26 03:43:42 christos Exp $ */
/*-
* Copyright (c) 2004 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_exec_machdep.c,v 1.6 2008/10/25 23:38:28 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_exec_machdep.c,v 1.7 2008/10/26 03:43:42 christos Exp $");
#if defined(_KERNEL_OPT)
#include "opt_vm86.h"
@@ -70,6 +70,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux_exec_machdep.c,v 1.6 2008/10/25 23:38:28 chris
#include <compat/linux/common/linux_errno.h>
#include <compat/linux//linux_syscallargs.h>
+
int
linux_exec_setup_stack(struct lwp *l, struct exec_package *epp)
{
@@ -132,6 +133,12 @@ linux_exec_setup_stack(struct lwp *l, struct exec_package *epp)
#ifdef LINUX_NPTL
+static __inline void
+load_gs(u_int sel)
+{
+ __asm __volatile("movl %0,%%gs" : : "rm" (sel));
+}
+
int
linux_init_thread_area(struct lwp *l, struct lwp *l2)
@@ -175,8 +182,12 @@ linux_init_thread_area(struct lwp *l, struct lwp *l2)
sd.sd_hibase, sd.sd_lolimit, sd.sd_hilimit, sd.sd_type, sd.sd_dpl,
sd.sd_p, sd.sd_xx, sd.sd_def32, sd.sd_gran));
- (void)memcpy(pcb2->pcb_gsd, &sd, sizeof(pcb2->pcb_gsd));
+ kpreempt_disable();
+ (void)memcpy(&pcb2->pcb_gsd, &sd, sizeof(sd));
+ (void)memcpy(&curcpu()->ci_gdt[GUGS_SEL], &sd, sizeof(sd));
tf2->tf_gs = GSEL(GUGS_SEL, SEL_UPL);
+ load_gs(tf2->tf_gs);
+ kpreempt_enable();
return 0;
}
@@ -255,8 +266,12 @@ linux_sys_set_thread_area(struct lwp *l,
sd.sd_hilimit, sd.sd_type, sd.sd_dpl, sd.sd_p, sd.sd_xx,
sd.sd_def32, sd.sd_gran));
- (void)memcpy(pcb->pcb_gsd, &sd, sizeof(pcb->pcb_gsd));
+ kpreempt_disable();
+ (void)memcpy(&pcb->pcb_gsd, &sd, sizeof(sd));
+ (void)memcpy(&curcpu()->ci_gdt[GUGS_SEL], &sd, sizeof(sd));
tf->tf_gs = GSEL(GUGS_SEL, SEL_UPL);
+ load_gs(tf->tf_gs);
+ kpreempt_enable();
return 0;
}