Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/compat/linux/arch/i386/linux_machdep.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/compat/linux/arch/i386/linux_machdep.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.123 retrieving revision 1.123.2.2 diff -u -p -r1.123 -r1.123.2.2 --- src/sys/compat/linux/arch/i386/linux_machdep.c 2007/03/04 06:01:19 1.123 +++ src/sys/compat/linux/arch/i386/linux_machdep.c 2007/07/15 13:27:07 1.123.2.2 @@ -1,4 +1,4 @@ -/* $NetBSD: linux_machdep.c,v 1.123 2007/03/04 06:01:19 christos Exp $ */ +/* $NetBSD: linux_machdep.c,v 1.123.2.2 2007/07/15 13:27:07 ad Exp $ */ /*- * Copyright (c) 1995, 2000 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.123 2007/03/04 06:01:19 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.123.2.2 2007/07/15 13:27:07 ad Exp $"); #if defined(_KERNEL_OPT) #include "opt_vm86.h" @@ -107,13 +107,6 @@ __KERNEL_RCSID(0, "$NetBSD: linux_machde #endif #endif -#ifdef USER_LDT -int linux_read_ldt __P((struct lwp *, struct linux_sys_modify_ldt_args *, - register_t *)); -int linux_write_ldt __P((struct lwp *, struct linux_sys_modify_ldt_args *, - register_t *)); -#endif - #ifdef DEBUG_LINUX #define DPRINTF(a) uprintf a #else @@ -338,7 +331,7 @@ linux_rt_sendsig(const ksiginfo_t *ksi, lsi->lsi_pid = ksi->ksi_pid; if (lsi->lsi_signo == LINUX_SIGALRM || lsi->lsi_signo >= LINUX_SIGRTMIN) - lsi->lsi_value.sival_ptr = ksi->ksi_sigval.sival_ptr; + lsi->lsi_value.sival_ptr = ksi->ksi_value.sival_ptr; break; } @@ -582,39 +575,46 @@ linux_restore_sigcontext(struct lwp *l, #ifdef USER_LDT -int -linux_read_ldt(l, uap, retval) - struct lwp *l; - struct linux_sys_modify_ldt_args /* { - syscallarg(int) func; - syscallarg(void *) ptr; - syscallarg(size_t) bytecount; - } */ *uap; - register_t *retval; +static int +linux_read_ldt(struct lwp *l, struct linux_sys_modify_ldt_args *uap, + register_t *retval) { - struct proc *p = l->l_proc; - struct i386_get_ldt_args gl; + struct x86_get_ldt_args gl; int error; - void *sg; - char *parms; + int num_ldt; + union descriptor *ldt_buf; + + /* + * I've checked the linux code - this function is asymetric with + * linux_write_ldt, and returns raw ldt entries. + * NB, the code I saw zerod the spare parts of the user buffer. + */ DPRINTF(("linux_read_ldt!")); - sg = stackgap_init(p, 0); + + num_ldt = x86_get_ldt_len(l); + if (num_ldt <= 0) + return EINVAL; gl.start = 0; - gl.desc = SCARG(uap, ptr); + gl.desc = NULL; gl.num = SCARG(uap, bytecount) / sizeof(union descriptor); - parms = stackgap_alloc(p, &sg, sizeof(gl)); + if (gl.num > num_ldt) + gl.num = num_ldt; - if ((error = copyout(&gl, parms, sizeof(gl))) != 0) - return (error); + ldt_buf = malloc(gl.num * sizeof *ldt, M_TEMP, M_WAITOK); - if ((error = i386_get_ldt(l, parms, retval)) != 0) - return (error); + error = x86_get_ldt1(l, &gl, ldt_buf); + /* NB gl.num might have changed */ + if (error == 0) { + *retval = gl.num * sizeof *ldt; + error = copyout(ldt_buf, SCARG(uap, ptr), + gl.num * sizeof *ldt_buf); + } + free(ldt, M_TEMP); - *retval *= sizeof(union descriptor); - return (0); + return error; } struct linux_ldt_info { @@ -629,24 +629,14 @@ struct linux_ldt_info { u_int useable:1; }; -int -linux_write_ldt(l, uap, retval) - struct lwp *l; - struct linux_sys_modify_ldt_args /* { - syscallarg(int) func; - syscallarg(void *) ptr; - syscallarg(size_t) bytecount; - } */ *uap; - register_t *retval; +static int +linux_write_ldt(struct lwp *l, struct linux_sys_modify_ldt_args *uap, + int oldmode) { - struct proc *p = l->l_proc; struct linux_ldt_info ldt_info; - struct segment_descriptor sd; - struct i386_set_ldt_args sl; + union descriptor d; + struct x86_set_ldt_args sl; int error; - void *sg; - char *parms; - int oldmode = (int)retval[0]; DPRINTF(("linux_write_ldt %d\n", oldmode)); if (SCARG(uap, bytecount) != sizeof(ldt_info)) @@ -668,43 +658,31 @@ linux_write_ldt(l, uap, retval) ldt_info.limit_in_pages == 0 && ldt_info.seg_not_present == 1 && ldt_info.useable == 0))) { /* this means you should zero the ldt */ - (void)memset(&sd, 0, sizeof(sd)); + (void)memset(&d, 0, sizeof(d)); } else { - sd.sd_lobase = ldt_info.base_addr & 0xffffff; - sd.sd_hibase = (ldt_info.base_addr >> 24) & 0xff; - sd.sd_lolimit = ldt_info.limit & 0xffff; - sd.sd_hilimit = (ldt_info.limit >> 16) & 0xf; - sd.sd_type = 16 | (ldt_info.contents << 2) | + d.sd.sd_lobase = ldt_info.base_addr & 0xffffff; + d.sd.sd_hibase = (ldt_info.base_addr >> 24) & 0xff; + d.sd.sd_lolimit = ldt_info.limit & 0xffff; + d.sd.sd_hilimit = (ldt_info.limit >> 16) & 0xf; + d.sd.sd_type = 16 | (ldt_info.contents << 2) | (!ldt_info.read_exec_only << 1); - sd.sd_dpl = SEL_UPL; - sd.sd_p = !ldt_info.seg_not_present; - sd.sd_def32 = ldt_info.seg_32bit; - sd.sd_gran = ldt_info.limit_in_pages; + d.sd.sd_dpl = SEL_UPL; + d.sd.sd_p = !ldt_info.seg_not_present; + d.sd.sd_def32 = ldt_info.seg_32bit; + d.sd.sd_gran = ldt_info.limit_in_pages; if (!oldmode) - sd.sd_xx = ldt_info.useable; + d.sd.sd_xx = ldt_info.useable; else - sd.sd_xx = 0; + d.sd.sd_xx = 0; } - sg = stackgap_init(p, 0); sl.start = ldt_info.entry_number; - sl.desc = stackgap_alloc(p, &sg, sizeof(sd)); + sl.desc = NULL;; sl.num = 1; DPRINTF(("linux_write_ldt: idx=%d, base=0x%lx, limit=0x%x\n", ldt_info.entry_number, ldt_info.base_addr, ldt_info.limit)); - parms = stackgap_alloc(p, &sg, sizeof(sl)); - - if ((error = copyout(&sd, sl.desc, sizeof(sd))) != 0) - return (error); - if ((error = copyout(&sl, parms, sizeof(sl))) != 0) - return (error); - - if ((error = i386_set_ldt(l, parms, retval)) != 0) - return (error); - - *retval = 0; - return (0); + return x86_set_ldt1(l, &sl, &d); } #endif /* USER_LDT */ @@ -724,8 +702,7 @@ linux_sys_modify_ldt(struct lwp *l, void case 0: return linux_read_ldt(l, uap, retval); case 1: - retval[0] = 1; - return linux_write_ldt(l, uap, retval); + return linux_write_ldt(l, uap, 1); case 2: #ifdef notyet return (linux_read_default_ldt(l, uap, retval); @@ -733,8 +710,7 @@ linux_sys_modify_ldt(struct lwp *l, void return (ENOSYS); #endif case 0x11: - retval[0] = 0; - return linux_write_ldt(l, uap, retval); + return linux_write_ldt(l, uap, 0); #endif /* USER_LDT */ default: @@ -904,7 +880,6 @@ linux_machdepioctl(l, v, retval) int error, error1; #if (NWSDISPLAY > 0) struct vt_mode lvt; - void *bvtp, *sg; struct kbentry kbe; #endif struct linux_hd_geometry hdg; @@ -974,33 +949,23 @@ linux_machdepioctl(l, v, retval) com = VT_OPENQRY; break; case LINUX_VT_GETMODE: - SCARG(&bia, com) = VT_GETMODE; - /* XXX NJWLWP */ - if ((error = sys_ioctl(curlwp, &bia, retval))) - goto out; - if ((error = copyin(SCARG(uap, data), (void *)&lvt, - sizeof (struct vt_mode)))) + error = fp->f_ops->fo_ioctl(fp, VT_GETMODE, &lvt, l); + if (error != 0) goto out; lvt.relsig = native_to_linux_signo[lvt.relsig]; lvt.acqsig = native_to_linux_signo[lvt.acqsig]; lvt.frsig = native_to_linux_signo[lvt.frsig]; - error = copyout((void *)&lvt, SCARG(uap, data), - sizeof (struct vt_mode)); + error = copyout(&lvt, SCARG(uap, data), sizeof (lvt)); goto out; case LINUX_VT_SETMODE: - com = VT_SETMODE; - if ((error = copyin(SCARG(uap, data), (void *)&lvt, - sizeof (struct vt_mode)))) + error = copyin(SCARG(uap, data), &lvt, sizeof (lvt)); + if (error != 0) goto out; lvt.relsig = linux_to_native_signo[lvt.relsig]; lvt.acqsig = linux_to_native_signo[lvt.acqsig]; lvt.frsig = linux_to_native_signo[lvt.frsig]; - sg = stackgap_init(p, 0); - bvtp = stackgap_alloc(p, &sg, sizeof (struct vt_mode)); - if ((error = copyout(&lvt, bvtp, sizeof (struct vt_mode)))) - goto out; - SCARG(&bia, data) = bvtp; - break; + error = fp->f_ops->fo_ioctl(fp, VT_SETMODE, &lvt, l); + goto out; case LINUX_VT_DISALLOCATE: /* XXX should use WSDISPLAYIO_DELSCREEN */ error = 0; @@ -1183,3 +1148,34 @@ linux_usertrap(struct lwp *l, vaddr_t tr { return 0; } + +const char * +linux_get_uname_arch(void) +{ + static char uname_arch[5] = "i386"; + + if (uname_arch[1] == '3') + uname_arch[1] += cpu_class; + return uname_arch; +} + +#ifdef LINUX_NPTL +void * +linux_get_newtls(l) + struct lwp *l; +{ + struct trapframe *tf = l->l_md.md_regs; + + /* XXX: Implement me */ + return NULL; +} + +int +linux_set_newtls(l, tls) + struct lwp *l; + void *tls; +{ + /* XXX: Implement me */ + return 0; +} +#endif