diff options
| author | christos <christos@NetBSD.org> | 2008-10-26 03:43:42 +0000 |
|---|---|---|
| committer | christos <christos@NetBSD.org> | 2008-10-26 03:43:42 +0000 |
| commit | 86f314b4bf30917ebc60772648e2a36675e69d4d (patch) | |
| tree | f3fded95c56b6f7034fc2028adb05ee0081529e5 /sys/compat/linux | |
| parent | 4adcca090c3a61bf0c77f7649ff5dec079b55f0b (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.c | 23 |
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; } |
