Module Name:    src
Committed By:   chs
Date:           Wed Jul  7 01:20:50 UTC 2010

Modified Files:
        src/sys/arch/alpha/alpha: sys_machdep.c
        src/sys/arch/alpha/include: types.h
        src/sys/arch/arm/arm32: sys_machdep.c
        src/sys/arch/arm/include/arm32: types.h
        src/sys/arch/powerpc/include: types.h
        src/sys/arch/powerpc/powerpc: sys_machdep.c
        src/sys/arch/x86/x86: sys_machdep.c vm_machdep.c

Log Message:
implement cpu_lwp_setprivate() on several platforms.


To generate a diff of this commit:
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/alpha/alpha/sys_machdep.c
cvs rdiff -u -r1.42 -r1.43 src/sys/arch/alpha/include/types.h
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/arm/arm32/sys_machdep.c
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/arm/include/arm32/types.h
cvs rdiff -u -r1.34 -r1.35 src/sys/arch/powerpc/include/types.h
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/powerpc/powerpc/sys_machdep.c
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/x86/x86/sys_machdep.c
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/x86/x86/vm_machdep.c

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/alpha/alpha/sys_machdep.c
diff -u src/sys/arch/alpha/alpha/sys_machdep.c:1.18 src/sys/arch/alpha/alpha/sys_machdep.c:1.19
--- src/sys/arch/alpha/alpha/sys_machdep.c:1.18	Mon Apr 28 20:23:10 2008
+++ src/sys/arch/alpha/alpha/sys_machdep.c	Wed Jul  7 01:20:49 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: sys_machdep.c,v 1.18 2008/04/28 20:23:10 martin Exp $ */
+/* $NetBSD: sys_machdep.c,v 1.19 2010/07/07 01:20:49 chs Exp $ */
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -58,12 +58,13 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.18 2008/04/28 20:23:10 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.19 2010/07/07 01:20:49 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/device.h>
 #include <sys/proc.h>
+#include <sys/cpu.h>
 
 #include <sys/mount.h>
 #include <sys/syscallargs.h>
@@ -229,3 +230,13 @@
 
 	return (error);
 }
+
+int
+cpu_lwp_setprivate(lwp_t *l, void *addr)
+{
+	struct pcb *pcb;
+
+	pcb = lwp_getpcb(l);
+	pcb->pcb_hw.apcb_unique = (unsigned long)addr;
+	return 0;
+}

Index: src/sys/arch/alpha/include/types.h
diff -u src/sys/arch/alpha/include/types.h:1.42 src/sys/arch/alpha/include/types.h:1.43
--- src/sys/arch/alpha/include/types.h:1.42	Fri Dec 11 05:52:03 2009
+++ src/sys/arch/alpha/include/types.h	Wed Jul  7 01:20:49 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: types.h,v 1.42 2009/12/11 05:52:03 matt Exp $ */
+/* $NetBSD: types.h,v 1.43 2010/07/07 01:20:49 chs Exp $ */
 
 /*-
  * Copyright (c) 1990, 1993
@@ -75,6 +75,7 @@
 #define	__HAVE_MINIMAL_EMUL
 #define	__HAVE_AST_PERPROC
 #define	__HAVE_ATOMIC64_OPS
+#define	__HAVE_CPU_LWP_SETPRIVATE
 
 #if defined(_KERNEL)
 #define	__HAVE_RAS

Index: src/sys/arch/arm/arm32/sys_machdep.c
diff -u src/sys/arch/arm/arm32/sys_machdep.c:1.10 src/sys/arch/arm/arm32/sys_machdep.c:1.11
--- src/sys/arch/arm/arm32/sys_machdep.c:1.10	Sun Apr 27 18:58:44 2008
+++ src/sys/arch/arm/arm32/sys_machdep.c	Wed Jul  7 01:20:49 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_machdep.c,v 1.10 2008/04/27 18:58:44 matt Exp $	*/
+/*	$NetBSD: sys_machdep.c,v 1.11 2010/07/07 01:20:49 chs Exp $	*/
 
 /*
  * Copyright (c) 1995-1997 Mark Brinicombe.
@@ -41,13 +41,14 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.10 2008/04/27 18:58:44 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.11 2010/07/07 01:20:49 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/proc.h>
 #include <sys/mbuf.h>
 #include <sys/mount.h>
+#include <sys/cpu.h>
 #include <uvm/uvm_extern.h>
 #include <sys/sysctl.h>
 #include <sys/syscallargs.h>
@@ -110,4 +111,20 @@
 	return (error);
 }
   
-/* End of sys_machdep.c */
+int
+cpu_lwp_setprivate(lwp_t *l, void *addr)
+{
+#ifdef _ARM_ARCH_6
+	struct pcb *pcb;
+
+	pcb = lwp_getpcb(l);
+	kpreempt_disable();
+	pcb->pcb_un.un_32.pcb32_user_pid_ro = (u_int)addr;
+	if (l == curlwp)
+		__asm("mcr p15, 0, %0, c13, c0, 3" : : "r" (addr));
+	kpreempt_enable();
+	return 0;
+#else
+	return ENOSYS;
+#endif
+}

Index: src/sys/arch/arm/include/arm32/types.h
diff -u src/sys/arch/arm/include/arm32/types.h:1.8 src/sys/arch/arm/include/arm32/types.h:1.9
--- src/sys/arch/arm/include/arm32/types.h:1.8	Wed May 21 18:04:43 2003
+++ src/sys/arch/arm/include/arm32/types.h	Wed Jul  7 01:20:50 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: types.h,v 1.8 2003/05/21 18:04:43 thorpej Exp $	*/
+/*	$NetBSD: types.h,v 1.9 2010/07/07 01:20:50 chs Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -48,4 +48,6 @@
 
 #include <arm/types.h>		/* pull in generic ARM definitions */
 
+#define	__HAVE_CPU_LWP_SETPRIVATE
+
 #endif /* _ARM_ARM32_TYPES_H_ */

Index: src/sys/arch/powerpc/include/types.h
diff -u src/sys/arch/powerpc/include/types.h:1.34 src/sys/arch/powerpc/include/types.h:1.35
--- src/sys/arch/powerpc/include/types.h:1.34	Fri Dec 11 05:52:03 2009
+++ src/sys/arch/powerpc/include/types.h	Wed Jul  7 01:20:50 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: types.h,v 1.34 2009/12/11 05:52:03 matt Exp $	*/
+/*	$NetBSD: types.h,v 1.35 2010/07/07 01:20:50 chs Exp $	*/
 
 /*-
  * Copyright (C) 1995 Wolfgang Solfrank.
@@ -73,6 +73,7 @@
 
 #define	__HAVE_CPU_COUNTER
 #define	__HAVE_SYSCALL_INTERN
+#define	__HAVE_CPU_LWP_SETPRIVATE
 
 #ifdef _LP64
 #define	__HAVE_ATOMIC64_OPS

Index: src/sys/arch/powerpc/powerpc/sys_machdep.c
diff -u src/sys/arch/powerpc/powerpc/sys_machdep.c:1.9 src/sys/arch/powerpc/powerpc/sys_machdep.c:1.10
--- src/sys/arch/powerpc/powerpc/sys_machdep.c:1.9	Sat Dec 22 08:59:02 2007
+++ src/sys/arch/powerpc/powerpc/sys_machdep.c	Wed Jul  7 01:20:50 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_machdep.c,v 1.9 2007/12/22 08:59:02 dsl Exp $	*/
+/*	$NetBSD: sys_machdep.c,v 1.10 2010/07/07 01:20:50 chs Exp $	*/
 
 /*
  * Copyright (C) 1996 Wolfgang Solfrank.
@@ -32,12 +32,15 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.9 2007/12/22 08:59:02 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.10 2010/07/07 01:20:50 chs Exp $");
 
 #include <sys/param.h>
 
 #include <sys/mount.h>
 #include <sys/syscallargs.h>
+#include <sys/cpu.h>
+
+#include <uvm/uvm_extern.h>
 
 int
 sys_sysarch(struct lwp *l, const struct sys_sysarch_args *uap, register_t *retval)
@@ -47,3 +50,13 @@
 	 */
 	return (ENOSYS);
 }
+
+int
+cpu_lwp_setprivate(lwp_t *l, void *addr)
+{
+	struct trapframe *tf;
+
+	tf = trapframe(l);
+	tf->fixreg[2] = (register_t)addr;
+	return 0;
+}

Index: src/sys/arch/x86/x86/sys_machdep.c
diff -u src/sys/arch/x86/x86/sys_machdep.c:1.23 src/sys/arch/x86/x86/sys_machdep.c:1.24
--- src/sys/arch/x86/x86/sys_machdep.c:1.23	Fri Apr 23 16:07:33 2010
+++ src/sys/arch/x86/x86/sys_machdep.c	Wed Jul  7 01:20:50 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_machdep.c,v 1.23 2010/04/23 16:07:33 joerg Exp $	*/
+/*	$NetBSD: sys_machdep.c,v 1.24 2010/07/07 01:20:50 chs 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.23 2010/04/23 16:07:33 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.24 2010/07/07 01:20:50 chs Exp $");
 
 #include "opt_mtrr.h"
 #include "opt_perfctrs.h"
@@ -92,7 +92,9 @@
 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_sdbase32(void *, char, lwp_t *, bool);
 int x86_set_sdbase(void *, char, lwp_t *, bool);
+int x86_get_sdbase32(void *, char);
 int x86_get_sdbase(void *, char);
 
 #ifdef LDT_DEBUG
@@ -581,13 +583,19 @@
 #endif
 }
 
+#ifdef __x86_64__
+#define pcb_fsd pcb_fs
+#define pcb_gsd pcb_gs
+#define segment_descriptor mem_segment_descriptor
+#endif
+
 int
-x86_set_sdbase(void *arg, char which, lwp_t *l, bool direct)
+x86_set_sdbase32(void *arg, char which, lwp_t *l, bool direct)
 {
-#ifdef i386
-	union  descriptor usd;
+	struct trapframe *tf = l->l_md.md_regs;
+	union descriptor usd;
 	struct pcb *pcb;
-	vaddr_t base;
+	uint32_t base;
 	int error;
 
 	if (direct) {
@@ -598,6 +606,7 @@
 			return error;
 	}
 
+	memset(&usd, 0, sizeof(usd));
 	usd.sd.sd_lobase = base & 0xffffff;
 	usd.sd.sd_hibase = (base >> 24) & 0xff;
 	usd.sd.sd_lolimit = 0xffff;
@@ -605,46 +614,105 @@
 	usd.sd.sd_type = SDT_MEMRWA;
 	usd.sd.sd_dpl = SEL_UPL;
 	usd.sd.sd_p = 1;
-	usd.sd.sd_xx = 0;
 	usd.sd.sd_def32 = 1;
 	usd.sd.sd_gran = 1;
 
-	kpreempt_disable();
 	pcb = lwp_getpcb(l);
+	kpreempt_disable();
 	if (which == 'f') {
 		memcpy(&pcb->pcb_fsd, &usd.sd,
 		    sizeof(struct segment_descriptor));
 		if (l == curlwp) {
 			update_descriptor(&curcpu()->ci_gdt[GUFS_SEL], &usd);
+#ifdef __x86_64__
+			setfs(GSEL(GUFS_SEL, SEL_UPL));
+#endif
 		}
+		tf->tf_fs = GSEL(GUFS_SEL, SEL_UPL);
 	} else /* which == 'g' */ {
 		memcpy(&pcb->pcb_gsd, &usd.sd,
 		    sizeof(struct segment_descriptor));
 		if (l == curlwp) {
 			update_descriptor(&curcpu()->ci_gdt[GUGS_SEL], &usd);
+#ifdef __x86_64__
+#ifndef XEN
+			setusergs(GSEL(GUGS_SEL, SEL_UPL));
+#else
+			HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL,
+						    GSEL(GUGS_SEL, SEL_UPL));
+#endif
+#endif
 		}
+		tf->tf_gs = GSEL(GUGS_SEL, SEL_UPL);
 	}
 	kpreempt_enable();
-
 	return 0;
+}
+
+int
+x86_set_sdbase(void *arg, char which, lwp_t *l, bool direct)
+{
+#ifdef i386
+	return x86_set_sdbase32(arg, which, l, direct);
 #else
-	return EINVAL;
+	struct pcb *pcb;
+	vaddr_t base;
+	int error;
+
+	if (l->l_proc->p_flag & PK_32) {
+		return x86_set_sdbase32(arg, which, l, direct);
+	}
+
+	if (direct) {
+		base = (vaddr_t)arg;
+	} else {
+		error = copyin(arg, &base, sizeof(base));
+		if (error != 0)
+			return error;
+	}
+
+	if (base >= VM_MAXUSER_ADDRESS)
+		return EINVAL;
+
+	if (error) {
+		return error;
+	}
+
+	pcb = lwp_getpcb(l);
+
+	kpreempt_disable();
+	switch(which) {
+	case 'f':
+		pcb->pcb_fs = base;
+		if (l == curlwp)
+			wrmsr(MSR_FSBASE, pcb->pcb_fs);
+		break;
+	case 'g':
+		pcb->pcb_gs = base;
+		if (l == curlwp)
+			wrmsr(MSR_KERNELGSBASE, pcb->pcb_gs);
+		break;
+	default:
+		panic("x86_get_sdbase");
+	}
+	kpreempt_enable();
+
+	return error;
 #endif
 }
 
 int
-x86_get_sdbase(void *arg, char which)
+x86_get_sdbase32(void *arg, char which)
 {
-#ifdef i386
 	struct segment_descriptor *sd;
-	vaddr_t base;
+	uint32_t base;
 
 	switch (which) {
 	case 'f':
-		sd = &curpcb->pcb_fsd;
+		sd = (void *)&curpcb->pcb_fsd;
 		break;
 	case 'g':
-		sd = &curpcb->pcb_gsd;
+		sd = (void *)&curpcb->pcb_gsd;
 		break;
 	default:
 		panic("x86_get_sdbase");
@@ -652,8 +720,35 @@
 
 	base = sd->sd_hibase << 24 | sd->sd_lobase;
 	return copyout(&base, arg, sizeof(base));
+}
+
+int
+x86_get_sdbase(void *arg, char which)
+{
+#ifdef i386
+	return x86_get_sdbase32(arg, which);
 #else
-	return EINVAL;
+	vaddr_t base;
+	struct pcb *pcb;
+
+	if (curproc->p_flag & PK_32) {
+		return x86_get_sdbase32(arg, which);
+	}
+
+	pcb = lwp_getpcb(curlwp);
+
+	switch(which) {
+	case 'f':
+		base = pcb->pcb_fs;
+		break;
+	case 'g':
+		base = pcb->pcb_gs;
+		break;
+	default:
+		panic("x86_get_sdbase");
+	}
+
+	return copyout(&base, arg, sizeof(base));
 #endif
 }
 
@@ -750,5 +845,10 @@
 cpu_lwp_setprivate(lwp_t *l, void *addr)
 {
 
+#ifdef __x86_64__
+	if ((l->l_proc->p_flag & PK_32) == 0) {
+		return x86_set_sdbase(addr, 'f', l, true);
+	}
+#endif	
 	return x86_set_sdbase(addr, 'g', l, true);
 }

Index: src/sys/arch/x86/x86/vm_machdep.c
diff -u src/sys/arch/x86/x86/vm_machdep.c:1.9 src/sys/arch/x86/x86/vm_machdep.c:1.10
--- src/sys/arch/x86/x86/vm_machdep.c:1.9	Fri Apr 23 16:07:33 2010
+++ src/sys/arch/x86/x86/vm_machdep.c	Wed Jul  7 01:20:50 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: vm_machdep.c,v 1.9 2010/04/23 16:07:33 joerg Exp $	*/
+/*	$NetBSD: vm_machdep.c,v 1.10 2010/07/07 01:20:50 chs Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986 The Regents of the University of California.
@@ -80,7 +80,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.9 2010/04/23 16:07:33 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.10 2010/07/07 01:20:50 chs Exp $");
 
 #include "opt_mtrr.h"
 
@@ -179,23 +179,16 @@
 	 * newly-created child process to go directly to user level with a
 	 * parent return value of 0 from fork(), while the parent process
 	 * returns normally.
-	 * 
-	 * Also, copy PCB %fs/%gs base from parent.
 	 */
 	uv = uvm_lwp_getuarea(l2);
 
 #ifdef __x86_64__
 	pcb2->pcb_rsp0 = (uv + KSTACK_SIZE - 16) & ~0xf;
 	tf = (struct trapframe *)pcb2->pcb_rsp0 - 1;
-
-	pcb2->pcb_fs = pcb1->pcb_fs;
-	pcb2->pcb_gs = pcb1->pcb_gs;
 #else
 	pcb2->pcb_esp0 = (uv + KSTACK_SIZE - 16);
 	tf = (struct trapframe *)pcb2->pcb_esp0 - 1;
 
-	memcpy(&pcb2->pcb_fsd, &pcb1->pcb_fsd, sizeof(pcb2->pcb_fsd));
-	memcpy(&pcb2->pcb_gsd, &pcb1->pcb_gsd, sizeof(pcb2->pcb_gsd));
 	pcb2->pcb_iomap = NULL;
 #endif
 	l2->l_md.md_regs = tf;

Reply via email to