Module Name: src
Committed By: ad
Date: Sun Mar 29 09:24:53 UTC 2009
Modified Files:
src/sys/arch/amd64/include: types.h
src/sys/arch/i386/include: types.h
src/sys/arch/x86/x86: sys_machdep.c
src/sys/kern: sys_lwp.c
src/sys/sys: cpu.h
Log Message:
_lwp_setprivate: provide the value to MD code if a hook is present.
This will be used to support TLS. The MD method must match the ELF TLS spec
for that CPU architecture (if there is a spec).
At this time it is only implemented for i386, where it means setting the
per-thread base address for %gs. Please implement this for your platform!
To generate a diff of this commit:
cvs rdiff -u -r1.27 -r1.28 src/sys/arch/amd64/include/types.h
cvs rdiff -u -r1.60 -r1.61 src/sys/arch/i386/include/types.h
cvs rdiff -u -r1.17 -r1.18 src/sys/arch/x86/x86/sys_machdep.c
cvs rdiff -u -r1.44 -r1.45 src/sys/kern/sys_lwp.c
cvs rdiff -u -r1.27 -r1.28 src/sys/sys/cpu.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/amd64/include/types.h
diff -u src/sys/arch/amd64/include/types.h:1.27 src/sys/arch/amd64/include/types.h:1.28
--- src/sys/arch/amd64/include/types.h:1.27 Sun Oct 26 00:08:15 2008
+++ src/sys/arch/amd64/include/types.h Sun Mar 29 09:24:52 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: types.h,v 1.27 2008/10/26 00:08:15 mrg Exp $ */
+/* $NetBSD: types.h,v 1.28 2009/03/29 09:24:52 ad Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@@ -75,6 +75,7 @@
#define __HAVE_MINIMAL_EMUL
#define __HAVE_ATOMIC64_OPS
#define __HAVE_ATOMIC_AS_MEMBAR
+#define __HAVE_CPU_LWP_SETPRIVATE
#ifdef _KERNEL_OPT
#include "opt_xen.h"
Index: src/sys/arch/i386/include/types.h
diff -u src/sys/arch/i386/include/types.h:1.60 src/sys/arch/i386/include/types.h:1.61
--- src/sys/arch/i386/include/types.h:1.60 Sun Oct 26 06:57:30 2008
+++ src/sys/arch/i386/include/types.h Sun Mar 29 09:24:52 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: types.h,v 1.60 2008/10/26 06:57:30 mrg Exp $ */
+/* $NetBSD: types.h,v 1.61 2009/03/29 09:24:52 ad Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@@ -83,6 +83,7 @@
#define __HAVE_OLD_DISKLABEL
#define __HAVE_ATOMIC64_OPS
#define __HAVE_ATOMIC_AS_MEMBAR
+#define __HAVE_CPU_LWP_SETPRIVATE
#if defined(_KERNEL)
#define __HAVE_RAS
Index: src/sys/arch/x86/x86/sys_machdep.c
diff -u src/sys/arch/x86/x86/sys_machdep.c:1.17 src/sys/arch/x86/x86/sys_machdep.c:1.18
--- src/sys/arch/x86/x86/sys_machdep.c:1.17 Sat Mar 21 14:41:30 2009
+++ src/sys/arch/x86/x86/sys_machdep.c Sun Mar 29 09:24:52 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: sys_machdep.c,v 1.17 2009/03/21 14:41:30 ad Exp $ */
+/* $NetBSD: sys_machdep.c,v 1.18 2009/03/29 09:24:52 ad Exp $ */
/*-
* Copyright (c) 1998, 2007, 2009 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.17 2009/03/21 14:41:30 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.18 2009/03/29 09:24:52 ad Exp $");
#include "opt_mtrr.h"
#include "opt_perfctrs.h"
@@ -93,8 +93,8 @@
int x86_set_ioperm(struct lwp *, void *, register_t *);
int x86_get_mtrr(struct lwp *, void *, register_t *);
int x86_set_mtrr(struct lwp *, void *, register_t *);
-int x86_set_sdbase(void *arg, char which);
-int x86_get_sdbase(void *arg, char which);
+int x86_set_sdbase(void *, char, lwp_t *, bool);
+int x86_get_sdbase(void *, char);
#ifdef LDT_DEBUG
static void x86_print_ldt(int, const struct segment_descriptor *);
@@ -588,16 +588,21 @@
}
int
-x86_set_sdbase(void *arg, char which)
+x86_set_sdbase(void *arg, char which, lwp_t *l, bool direct)
{
#ifdef i386
struct segment_descriptor sd;
+ struct pcb *pcb;
vaddr_t base;
int error;
- error = copyin(arg, &base, sizeof(base));
- if (error != 0)
- return error;
+ if (direct) {
+ base = (vaddr_t)arg;
+ } else {
+ error = copyin(arg, &base, sizeof(base));
+ if (error != 0)
+ return error;
+ }
sd.sd_lobase = base & 0xffffff;
sd.sd_hibase = (base >> 24) & 0xff;
@@ -611,12 +616,17 @@
sd.sd_gran = 1;
kpreempt_disable();
+ pcb = &l->l_addr->u_pcb;
if (which == 'f') {
- memcpy(&curpcb->pcb_fsd, &sd, sizeof(sd));
- memcpy(&curcpu()->ci_gdt[GUFS_SEL], &sd, sizeof(sd));
+ memcpy(&pcb->pcb_fsd, &sd, sizeof(sd));
+ if (l == curlwp) {
+ memcpy(&curcpu()->ci_gdt[GUFS_SEL], &sd, sizeof(sd));
+ }
} else /* which == 'g' */ {
- memcpy(&curpcb->pcb_gsd, &sd, sizeof(sd));
- memcpy(&curcpu()->ci_gdt[GUGS_SEL], &sd, sizeof(sd));
+ memcpy(&pcb->pcb_gsd, &sd, sizeof(sd));
+ if (l == curlwp) {
+ memcpy(&curcpu()->ci_gdt[GUGS_SEL], &sd, sizeof(sd));
+ }
}
kpreempt_enable();
@@ -718,11 +728,11 @@
#endif
case X86_SET_FSBASE:
- error = x86_set_sdbase(SCARG(uap, parms), 'f');
+ error = x86_set_sdbase(SCARG(uap, parms), 'f', curlwp, false);
break;
case X86_SET_GSBASE:
- error = x86_set_sdbase(SCARG(uap, parms), 'g');
+ error = x86_set_sdbase(SCARG(uap, parms), 'g', curlwp, false);
break;
case X86_GET_FSBASE:
@@ -739,3 +749,10 @@
}
return (error);
}
+
+int
+cpu_lwp_setprivate(lwp_t *l, void *addr)
+{
+
+ return x86_set_sdbase(addr, 'g', l, true);
+}
Index: src/sys/kern/sys_lwp.c
diff -u src/sys/kern/sys_lwp.c:1.44 src/sys/kern/sys_lwp.c:1.45
--- src/sys/kern/sys_lwp.c:1.44 Sun Jan 11 02:45:52 2009
+++ src/sys/kern/sys_lwp.c Sun Mar 29 09:24:52 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: sys_lwp.c,v 1.44 2009/01/11 02:45:52 christos Exp $ */
+/* $NetBSD: sys_lwp.c,v 1.45 2009/03/29 09:24:52 ad Exp $ */
/*-
* Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_lwp.c,v 1.44 2009/01/11 02:45:52 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_lwp.c,v 1.45 2009/03/29 09:24:52 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -47,6 +47,7 @@
#include <sys/kmem.h>
#include <sys/sleepq.h>
#include <sys/lwpctl.h>
+#include <sys/cpu.h>
#include <uvm/uvm_extern.h>
@@ -186,6 +187,10 @@
} */
l->l_private = SCARG(uap, ptr);
+#ifdef __HAVE_CPU_LWP_SETPRIVATE
+ cpu_lwp_setprivate(l, SCARG(uap, ptr));
+#endif
+
return 0;
}
Index: src/sys/sys/cpu.h
diff -u src/sys/sys/cpu.h:1.27 src/sys/sys/cpu.h:1.28
--- src/sys/sys/cpu.h:1.27 Sun Dec 7 11:40:53 2008
+++ src/sys/sys/cpu.h Sun Mar 29 09:24:52 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.27 2008/12/07 11:40:53 ad Exp $ */
+/* $NetBSD: cpu.h,v 1.28 2009/03/29 09:24:52 ad Exp $ */
/*-
* Copyright (c) 2007 YAMAMOTO Takashi,
@@ -76,6 +76,7 @@
bool cpu_kpreempt_enter(uintptr_t, int);
void cpu_kpreempt_exit(uintptr_t);
bool cpu_kpreempt_disabled(void);
+int cpu_lwp_setprivate(lwp_t *, void *);
CIRCLEQ_HEAD(cpuqueue, cpu_info);