diff options
author | Philip Guenthe <guenther@cvs.openbsd.org> | 2011-11-07 15:41:34 +0000 |
---|---|---|
committer | Philip Guenthe <guenther@cvs.openbsd.org> | 2011-11-07 15:41:34 +0000 |
commit | 4286555c95c718904f5039bb91dbc4d4539853fa (patch) | |
tree | d41020946a62758e47641dfd29c915908320b08e /sys/arch | |
parent | 361e3cf9abc3f9abe09c72570cc51d6e92e61c83 (diff) |
Lift the copyout() from i386_get_threadbase() to sys_sysarch(), so that
it can be used correctly from linux_sys_get_thread_area() and tcb.h.
linux_sys_set_thread_area() should use the copied in value instead of
deferencing SCARG() again. i386_set_threadbase() should only update
curcpu's GDT if it's being called for curproc.
ok pirofti@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/i386/i386/linux_machdep.c | 17 | ||||
-rw-r--r-- | sys/arch/i386/i386/sys_machdep.c | 28 | ||||
-rw-r--r-- | sys/arch/i386/include/sysarch.h | 4 |
3 files changed, 25 insertions, 24 deletions
diff --git a/sys/arch/i386/i386/linux_machdep.c b/sys/arch/i386/i386/linux_machdep.c index c9c8a5c5b00..024e7c664b2 100644 --- a/sys/arch/i386/i386/linux_machdep.c +++ b/sys/arch/i386/i386/linux_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_machdep.c,v 1.41 2011/08/03 16:11:31 guenther Exp $ */ +/* $OpenBSD: linux_machdep.c,v 1.42 2011/11/07 15:41:33 guenther Exp $ */ /* $NetBSD: linux_machdep.c,v 1.29 1996/05/03 19:42:11 christos Exp $ */ /* @@ -653,7 +653,7 @@ linux_sys_set_thread_area(struct proc *p, void *v, register_t *retval) } else if (ldesc.entry_number != GUGS_SEL) return EINVAL; - return i386_set_threadbase(p, SCARG(uap, desc)->base_addr, TSEG_GS); + return i386_set_threadbase(p, ldesc.base_addr, TSEG_GS); } int @@ -663,7 +663,6 @@ linux_sys_get_thread_area(struct proc *p, void *v, register_t *retval) struct l_segment_descriptor info; int error; int idx; - void *base; error = copyin(SCARG(uap, desc), &info, sizeof(info)); if (error) @@ -673,11 +672,7 @@ linux_sys_get_thread_area(struct proc *p, void *v, register_t *retval) if (idx != GUGS_SEL) return (EINVAL); - error = i386_get_threadbase(p, &base, TSEG_GS); - if (error) - return error; - - info.base_addr = (int)base; + info.base_addr = i386_get_threadbase(p, TSEG_GS); info.limit = atop(VM_MAXUSER_ADDRESS) - 1; info.seg_32bit = 1; info.contents = 0; @@ -686,9 +681,5 @@ linux_sys_get_thread_area(struct proc *p, void *v, register_t *retval) info.seg_not_present = 0; info.useable = 1; - error = copyout(&info, SCARG(uap, desc), sizeof(SCARG(uap, desc))); - if (error) - return error; - - return 0; + return (copyout(&info, SCARG(uap, desc), sizeof(SCARG(uap, desc)))); } diff --git a/sys/arch/i386/i386/sys_machdep.c b/sys/arch/i386/i386/sys_machdep.c index 0289edbaf0b..eae9c71c6c6 100644 --- a/sys/arch/i386/i386/sys_machdep.c +++ b/sys/arch/i386/i386/sys_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_machdep.c,v 1.30 2011/08/03 16:11:31 guenther Exp $ */ +/* $OpenBSD: sys_machdep.c,v 1.31 2011/11/07 15:41:33 guenther Exp $ */ /* $NetBSD: sys_machdep.c,v 1.28 1996/05/03 19:42:29 christos Exp $ */ /*- @@ -392,14 +392,12 @@ i386_set_ioperm(struct proc *p, void *args, register_t *retval) return copyin(ua.iomap, pcb->pcb_iomap, sizeof(pcb->pcb_iomap)); } -int -i386_get_threadbase(struct proc *p, void *args, int which) +uint32_t +i386_get_threadbase(struct proc *p, int which) { struct segment_descriptor *sdp = &p->p_addr->u_pcb.pcb_threadsegs[which]; - uint32_t base = sdp->sd_hibase << 24 | sdp->sd_lobase; - - return copyout(&base, args, sizeof(base)); + return sdp->sd_hibase << 24 | sdp->sd_lobase; } int @@ -418,7 +416,11 @@ i386_set_threadbase(struct proc *p, uint32_t base, int which) */ sdp = &p->p_addr->u_pcb.pcb_threadsegs[which]; setsegment(sdp, (void *)base, 0xfffff, SDT_MEMRWA, SEL_UPL, 1, 1); - curcpu()->ci_gdt[which == TSEG_FS ? GUFS_SEL : GUGS_SEL].sd = *sdp; + + if (p == curproc) { + curcpu()->ci_gdt[which == TSEG_FS ? GUFS_SEL : GUGS_SEL].sd + = *sdp; + } return 0; } @@ -461,8 +463,12 @@ sys_sysarch(struct proc *p, void *v, register_t *retval) #endif case I386_GET_FSBASE: - error = i386_get_threadbase(p, SCARG(uap, parms), TSEG_FS); + { + uint32_t base = i386_get_threadbase(p, TSEG_FS); + + error = copyout(&base, SCARG(uap, parms), sizeof(base)); break; + } case I386_SET_FSBASE: { @@ -475,8 +481,12 @@ sys_sysarch(struct proc *p, void *v, register_t *retval) } case I386_GET_GSBASE: - error = i386_get_threadbase(p, SCARG(uap, parms), TSEG_GS); + { + uint32_t base = i386_get_threadbase(p, TSEG_GS); + + error = copyout(&base, SCARG(uap, parms), sizeof(base)); break; + } case I386_SET_GSBASE: { diff --git a/sys/arch/i386/include/sysarch.h b/sys/arch/i386/include/sysarch.h index 116325310cd..e870866f464 100644 --- a/sys/arch/i386/include/sysarch.h +++ b/sys/arch/i386/include/sysarch.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sysarch.h,v 1.9 2011/08/03 16:11:31 guenther Exp $ */ +/* $OpenBSD: sysarch.h,v 1.10 2011/11/07 15:41:33 guenther Exp $ */ /* $NetBSD: sysarch.h,v 1.8 1996/01/08 13:51:44 mycroft Exp $ */ #ifndef _MACHINE_SYSARCH_H_ @@ -54,7 +54,7 @@ int i386_get_gsbase(void **); int i386_set_gsbase(void *); int sysarch(int, void *); #else -int i386_get_threadbase(struct proc *, void *, int); +uint32_t i386_get_threadbase(struct proc *, int); int i386_set_threadbase(struct proc *, uint32_t, int); #endif |