--- amd64/linux32/linux32_proto.h.orig +++ amd64/linux32/linux32_proto.h @@ -2,7 +2,7 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/amd64/linux32/linux32_proto.h,v 1.21 2006/08/15 17:36:58 jhb Exp $ + * $FreeBSD$ * created from FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.19 2006/08/15 12:28:14 netchild Exp */ @@ -724,6 +724,9 @@ char uaddr2_l_[PADL_(void *)]; void * uaddr2; char uaddr2_r_[PADR_(void *)]; char val3_l_[PADL_(int)]; int val3; char val3_r_[PADR_(int)]; }; +struct linux_set_thread_area_args { + char desc_l_[PADL_(struct l_user_desc *)]; struct l_user_desc * desc; char desc_r_[PADR_(struct l_user_desc *)]; +}; struct linux_fadvise64_args { register_t dummy; }; @@ -1080,6 +1083,7 @@ int linux_fremovexattr(struct thread *, struct linux_fremovexattr_args *); int linux_tkill(struct thread *, struct linux_tkill_args *); int linux_sys_futex(struct thread *, struct linux_sys_futex_args *); +int linux_set_thread_area(struct thread *, struct linux_set_thread_area_args *); int linux_fadvise64(struct thread *, struct linux_fadvise64_args *); int linux_exit_group(struct thread *, struct linux_exit_group_args *); int linux_lookup_dcookie(struct thread *, struct linux_lookup_dcookie_args *); @@ -1325,6 +1329,7 @@ #define LINUX_SYS_AUE_linux_fremovexattr AUE_NULL #define LINUX_SYS_AUE_linux_tkill AUE_NULL #define LINUX_SYS_AUE_linux_sys_futex AUE_NULL +#define LINUX_SYS_AUE_linux_set_thread_area AUE_NULL #define LINUX_SYS_AUE_linux_fadvise64 AUE_NULL #define LINUX_SYS_AUE_linux_exit_group AUE_EXIT #define LINUX_SYS_AUE_linux_lookup_dcookie AUE_NULL --- amd64/linux32/linux32_syscall.h.orig +++ amd64/linux32/linux32_syscall.h @@ -2,7 +2,7 @@ * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/amd64/linux32/linux32_syscall.h,v 1.21 2006/08/15 17:36:58 jhb Exp $ + * $FreeBSD$ * created from FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.19 2006/08/15 12:28:14 netchild Exp */ @@ -221,6 +221,7 @@ #define LINUX_SYS_linux_fremovexattr 237 #define LINUX_SYS_linux_tkill 238 #define LINUX_SYS_linux_sys_futex 240 +#define LINUX_SYS_linux_set_thread_area 243 #define LINUX_SYS_linux_fadvise64 250 #define LINUX_SYS_linux_exit_group 252 #define LINUX_SYS_linux_lookup_dcookie 253 --- amd64/linux32/linux32_sysent.c.orig +++ amd64/linux32/linux32_sysent.c @@ -2,7 +2,7 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/amd64/linux32/linux32_sysent.c,v 1.21 2006/08/15 17:36:58 jhb Exp $ + * $FreeBSD$ * created from FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.19 2006/08/15 12:28:14 netchild Exp */ @@ -263,7 +263,7 @@ { AS(linux_sys_futex_args), (sy_call_t *)linux_sys_futex, AUE_NULL, NULL, 0, 0 }, /* 240 = linux_sys_futex */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 241 = linux_sched_setaffinity */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 242 = linux_sched_getaffinity */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 243 = linux_set_thread_area */ + { AS(linux_set_thread_area_args), (sy_call_t *)linux_set_thread_area, AUE_NULL, NULL, 0, 0 }, /* 243 = linux_set_thread_area */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 244 = linux_get_thread_area */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 245 = linux_io_setup */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 246 = linux_io_destroy */ --- amd64/linux32/linux32_sysvec.c.orig +++ amd64/linux32/linux32_sysvec.c @@ -124,7 +124,7 @@ static void linux32_fixlimits(struct proc *p); extern LIST_HEAD(futex_list, futex) futex_list; -extern struct mtx futex_mtx; +extern struct sx futex_sx; static eventhandler_tag linux_exit_tag; static eventhandler_tag linux_schedtail_tag; @@ -1080,7 +1080,7 @@ sx_init(&emul_lock, "emuldata lock"); sx_init(&emul_shared_lock, "emuldata->shared lock"); LIST_INIT(&futex_list); - mtx_init(&futex_mtx, "futex protection lock", NULL, MTX_DEF); + sx_init(&futex_sx, "futex protection lock"); linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, linux_proc_exit, NULL, 1000); linux_schedtail_tag = EVENTHANDLER_REGISTER(schedtail, linux_schedtail, @@ -1110,7 +1110,7 @@ linux_device_unregister_handler(*ldhp); sx_destroy(&emul_lock); sx_destroy(&emul_shared_lock); - mtx_destroy(&futex_mtx); + sx_destroy(&futex_sx); EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag); EVENTHANDLER_DEREGISTER(schedtail, linux_schedtail_tag); EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag); --- amd64/linux32/syscalls.master.orig +++ amd64/linux32/syscalls.master @@ -404,7 +404,7 @@ struct l_timespec *timeout, void *uaddr2, int val3); } 241 AUE_NULL UNIMPL linux_sched_setaffinity 242 AUE_NULL UNIMPL linux_sched_getaffinity -243 AUE_NULL UNIMPL linux_set_thread_area +243 AUE_NULL STD { int linux_set_thread_area(struct l_user_desc *desc); } 244 AUE_NULL UNIMPL linux_get_thread_area 245 AUE_NULL UNIMPL linux_io_setup 246 AUE_NULL UNIMPL linux_io_destroy --- compat/linux/linux_emul.c.orig +++ compat/linux/linux_emul.c @@ -27,7 +27,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/compat/linux/linux_emul.c,v 1.4 2006/08/19 11:54:19 ssouhlal Exp $"); +__FBSDID("$FreeBSD$"); #include "opt_compat.h" @@ -82,14 +82,14 @@ if (child != 0) { /* non-exec call */ - em = malloc(sizeof *em, M_LINUX, M_WAITOK | M_ZERO); + em = malloc(sizeof *em, M_LINUX, M_WAITOK | M_ZERO); em->pid = child; if (flags & CLONE_VM) { /* handled later in the code */ } else { struct linux_emuldata_shared *s; - s = malloc(sizeof *s, M_LINUX, M_WAITOK | M_ZERO); + s = malloc(sizeof *s, M_LINUX, M_WAITOK | M_ZERO); em->shared = s; s->refs = 1; s->group_pid = child; @@ -101,6 +101,7 @@ panic("process not found in proc_init\n"); p->p_emuldata = em; PROC_UNLOCK(p); + EMUL_LOCK(&emul_lock); } else { /* lookup the old one */ em = em_find(td->td_proc, EMUL_UNLOCKED); @@ -129,14 +130,15 @@ if (child != 0) { + EMUL_UNLOCK(&emul_lock); EMUL_SHARED_WLOCK(&emul_shared_lock); LIST_INSERT_HEAD(&em->shared->threads, em, threads); EMUL_SHARED_WUNLOCK(&emul_shared_lock); p = pfind(child); - PROC_UNLOCK(p); /* we might have a sleeping linux_schedtail */ wakeup(&p->p_emuldata); + PROC_UNLOCK(p); } else EMUL_UNLOCK(&emul_lock); @@ -232,10 +234,10 @@ em->shared->refs--; if (em->shared->refs == 0) - FREE(em->shared, M_LINUX); + free(em->shared, M_LINUX); EMUL_SHARED_WUNLOCK(&emul_shared_lock); - FREE(em, M_LINUX); + free(em, M_LINUX); } } --- compat/linux/linux_emul.h.orig +++ compat/linux/linux_emul.h @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/compat/linux/linux_emul.h,v 1.3 2006/08/17 21:06:48 netchild Exp $ + * $FreeBSD$ */ #ifndef _LINUX_EMUL_H_ --- compat/linux/linux_futex.c.orig +++ compat/linux/linux_futex.c @@ -32,7 +32,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/compat/linux/linux_futex.c,v 1.3 2006/08/19 11:07:22 ssouhlal Exp $"); +__FBSDID("$FreeBSD$"); #if 0 __KERNEL_RCSID(1, "$NetBSD: linux_futex.c,v 1.5 2005/11/23 16:14:57 manu Exp $"); #endif @@ -47,6 +47,7 @@ #include #include #include +#include #include #ifdef COMPAT_LINUX32 @@ -73,10 +74,10 @@ }; LIST_HEAD(futex_list, futex) futex_list; -struct mtx futex_mtx; /* this protects the LIST of futexes */ +struct sx futex_sx; /* this protects the LIST of futexes */ -#define FUTEX_LOCK mtx_lock(&futex_mtx) -#define FUTEX_UNLOCK mtx_unlock(&futex_mtx) +#define FUTEX_LOCK sx_xlock(&futex_sx) +#define FUTEX_UNLOCK sx_xunlock(&futex_sx) #define FUTEX_LOCKED 1 #define FUTEX_UNLOCKED 0 @@ -306,8 +307,8 @@ printf("second wakeup\n"); #endif op_ret = 0; - /* Linux always puts there 0 retries */ - op_ret += futex_wake(f2, 0, NULL); + /* Linux always puts there struct timespec *utime :) */ + op_ret += futex_wake(f2, 0x7fffffff, NULL); ret += op_ret; } futex_put(f2); @@ -342,16 +343,11 @@ return f; } } - if (locked == FUTEX_UNLOCKED) - FUTEX_UNLOCK; - /* Not found, create it */ f = malloc(sizeof(*f), M_LINUX, M_WAITOK); f->f_uaddr = uaddr; f->f_refcount = 1; TAILQ_INIT(&f->f_waiting_proc); - if (locked == FUTEX_UNLOCKED) - FUTEX_LOCK; LIST_INSERT_HEAD(&futex_list, f, f_list); if (locked == FUTEX_UNLOCKED) FUTEX_UNLOCK; @@ -451,8 +447,6 @@ #endif /* XXX: linux verifies access here and returns EFAULT */ - critical_enter(); - switch (op) { case FUTEX_OP_SET: ret = futex_xchgl(oparg, uaddr, &oldval); @@ -473,8 +467,6 @@ ret = -ENOSYS; } - critical_exit(); - if (!ret) switch (cmp) { case FUTEX_OP_CMP_EQ: --- compat/linux/linux_futex.h.orig +++ compat/linux/linux_futex.h @@ -30,7 +30,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/compat/linux/linux_futex.h,v 1.1 2006/08/15 12:20:59 netchild Exp $ + * $FreeBSD$ */ #ifndef _LINUX_FUTEX_H --- compat/linux/linux_mib.c.orig +++ compat/linux/linux_mib.c @@ -81,7 +81,7 @@ 0, 0, linux_sysctl_osname, "A", "Linux kernel OS name"); -static char linux_osrelease[LINUX_MAX_UTSNAME] = "2.4.2"; +static char linux_osrelease[LINUX_MAX_UTSNAME] = "2.6.16"; static int linux_sysctl_osrelease(SYSCTL_HANDLER_ARGS) --- compat/linux/linux_stats.c.orig +++ compat/linux/linux_stats.c @@ -312,6 +312,19 @@ l_int f_spare[6]; }; +struct l_statfs64 { + l_int f_type; + l_int f_bsize; + uint64_t f_blocks; + uint64_t f_bfree; + uint64_t f_bavail; + uint64_t f_files; + uint64_t f_ffree; + l_fsid_t f_fsid; + l_int f_namelen; + l_int f_spare[6]; +}; + #define LINUX_CODA_SUPER_MAGIC 0x73757245L #define LINUX_EXT2_SUPER_MAGIC 0xEF53L #define LINUX_HPFS_SUPER_MAGIC 0xf995e849L @@ -387,6 +400,44 @@ return copyout(&linux_statfs, args->buf, sizeof(linux_statfs)); } +static void +bsd_to_linux_statfs64(struct statfs *bsd_statfs, struct l_statfs64 *linux_statfs) +{ + + linux_statfs->f_type = bsd_to_linux_ftype(bsd_statfs->f_fstypename); + linux_statfs->f_bsize = bsd_statfs->f_bsize; + linux_statfs->f_blocks = bsd_statfs->f_blocks; + linux_statfs->f_bfree = bsd_statfs->f_bfree; + linux_statfs->f_bavail = bsd_statfs->f_bavail; + linux_statfs->f_ffree = bsd_statfs->f_ffree; + linux_statfs->f_files = bsd_statfs->f_files; + linux_statfs->f_fsid.val[0] = bsd_statfs->f_fsid.val[0]; + linux_statfs->f_fsid.val[1] = bsd_statfs->f_fsid.val[1]; + linux_statfs->f_namelen = MAXNAMLEN; +} + +int +linux_statfs64(struct thread *td, struct linux_statfs64_args *args) +{ + struct l_statfs64 linux_statfs; + struct statfs bsd_statfs; + char *path; + int error; + + LCONVPATHEXIST(td, args->path, &path); + +#ifdef DEBUG + if (ldebug(statfs)) + printf(ARGS(statfs, "%s, *"), path); +#endif + error = kern_statfs(td, path, UIO_SYSSPACE, &bsd_statfs); + LFREEPATH(path); + if (error) + return (error); + bsd_to_linux_statfs64(&bsd_statfs, &linux_statfs); + return copyout(&linux_statfs, args->buf, sizeof(linux_statfs)); +} + int linux_fstatfs(struct thread *td, struct linux_fstatfs_args *args) { --- compat/linux/linux_time.c.orig +++ compat/linux/linux_time.c @@ -37,7 +37,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/compat/linux/linux_time.c,v 1.1 2006/08/15 12:20:59 netchild Exp $"); +__FBSDID("$FreeBSD$"); #if 0 __KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp $"); #endif --- i386/linux/linux_dummy.c.orig +++ i386/linux/linux_dummy.c @@ -73,7 +73,6 @@ DUMMY(epoll_ctl); DUMMY(epoll_wait); DUMMY(remap_file_pages); -DUMMY(statfs64); DUMMY(fstatfs64); DUMMY(utimes); DUMMY(fadvise64_64); --- i386/linux/linux_proto.h.orig +++ i386/linux/linux_proto.h @@ -2,7 +2,7 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/i386/linux/linux_proto.h,v 1.80 2006/08/15 17:37:00 jhb Exp $ + * $FreeBSD$ * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.77 2006/08/15 12:28:14 netchild Exp */ @@ -784,7 +784,8 @@ char rmtp_l_[PADL_(struct l_timespec *)]; struct l_timespec * rmtp; char rmtp_r_[PADR_(struct l_timespec *)]; }; struct linux_statfs64_args { - register_t dummy; + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char buf_l_[PADL_(struct l_statfs64_buf *)]; struct l_statfs64_buf * buf; char buf_r_[PADR_(struct l_statfs64_buf *)]; }; struct linux_fstatfs64_args { register_t dummy; --- i386/linux/linux_syscall.h.orig +++ i386/linux/linux_syscall.h @@ -2,7 +2,7 @@ * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/i386/linux/linux_syscall.h,v 1.74 2006/08/15 17:37:00 jhb Exp $ + * $FreeBSD$ * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.77 2006/08/15 12:28:14 netchild Exp */ --- i386/linux/linux_sysent.c.orig +++ i386/linux/linux_sysent.c @@ -2,7 +2,7 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/i386/linux/linux_sysent.c,v 1.81 2006/08/15 17:37:00 jhb Exp $ + * $FreeBSD$ * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.77 2006/08/15 12:28:14 netchild Exp */ @@ -287,7 +287,7 @@ { AS(linux_clock_gettime_args), (sy_call_t *)linux_clock_gettime, AUE_NULL, NULL, 0, 0 }, /* 265 = linux_clock_gettime */ { AS(linux_clock_getres_args), (sy_call_t *)linux_clock_getres, AUE_NULL, NULL, 0, 0 }, /* 266 = linux_clock_getres */ { AS(linux_clock_nanosleep_args), (sy_call_t *)linux_clock_nanosleep, AUE_NULL, NULL, 0, 0 }, /* 267 = linux_clock_nanosleep */ - { 0, (sy_call_t *)linux_statfs64, AUE_NULL, NULL, 0, 0 }, /* 268 = linux_statfs64 */ + { AS(linux_statfs64_args), (sy_call_t *)linux_statfs64, AUE_NULL, NULL, 0, 0 }, /* 268 = linux_statfs64 */ { 0, (sy_call_t *)linux_fstatfs64, AUE_NULL, NULL, 0, 0 }, /* 269 = linux_fstatfs64 */ { AS(linux_tgkill_args), (sy_call_t *)linux_tgkill, AUE_NULL, NULL, 0, 0 }, /* 270 = linux_tgkill */ { 0, (sy_call_t *)linux_utimes, AUE_NULL, NULL, 0, 0 }, /* 271 = linux_utimes */ --- i386/linux/linux_sysvec.c.orig +++ i386/linux/linux_sysvec.c @@ -108,7 +108,7 @@ u_long stack, u_long ps_strings); extern LIST_HEAD(futex_list, futex) futex_list; -extern struct mtx futex_mtx; +extern struct sx futex_sx; static eventhandler_tag linux_exit_tag; static eventhandler_tag linux_schedtail_tag; @@ -920,7 +920,7 @@ sx_init(&emul_lock, "emuldata lock"); sx_init(&emul_shared_lock, "emuldata->shared lock"); LIST_INIT(&futex_list); - mtx_init(&futex_mtx, "futex protection lock", NULL, MTX_DEF); + sx_init(&futex_sx, "futex protection lock"); linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, linux_proc_exit, NULL, 1000); linux_schedtail_tag = EVENTHANDLER_REGISTER(schedtail, linux_schedtail, @@ -950,7 +950,7 @@ linux_device_unregister_handler(*ldhp); sx_destroy(&emul_lock); sx_destroy(&emul_shared_lock); - mtx_destroy(&futex_mtx); + sx_destroy(&futex_sx); EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag); EVENTHANDLER_DEREGISTER(schedtail, linux_schedtail_tag); EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag); --- i386/linux/syscalls.master.orig +++ i386/linux/syscalls.master @@ -434,7 +434,7 @@ 266 AUE_NULL STD { int linux_clock_getres(clockid_t which, struct l_timespec *tp); } 267 AUE_NULL STD { int linux_clock_nanosleep(clockid_t which, int flags, \ struct l_timespec *rqtp, struct l_timespec *rmtp); } -268 AUE_NULL STD { int linux_statfs64(void); } +268 AUE_NULL STD { int linux_statfs64(char *path, struct l_statfs64_buf *buf); } 269 AUE_NULL STD { int linux_fstatfs64(void); } 270 AUE_NULL STD { int linux_tgkill(int tgid, int pid, int sig); } 271 AUE_NULL STD { int linux_utimes(void); } --- kern/link_elf_obj.c.orig +++ kern/link_elf_obj.c @@ -1114,6 +1114,51 @@ } static void +link_elf_fix_link_set(elf_file_t ef) +{ + static const char startn[] = "__start_"; + static const char stopn[] = "__stop_"; + Elf_Sym *sym; + const char *sym_name, *linkset_name; + Elf_Addr startp, stopp; + Elf_Size symidx; + int start, i; + + startp = stopp = 0; + for (symidx = 1 /* zero entry is special */; + symidx < ef->ddbsymcnt; symidx++) { + sym = ef->ddbsymtab + symidx; + if (sym->st_shndx != SHN_UNDEF) + continue; + + sym_name = ef->ddbstrtab + sym->st_name; + if (strncmp(sym_name, startn, sizeof(startn) - 1) == 0) { + start = 1; + linkset_name = sym_name + sizeof(startn) - 1; + } + else if (strncmp(sym_name, stopn, sizeof(stopn) - 1) == 0) { + start = 0; + linkset_name = sym_name + sizeof(stopn) - 1; + } + else + continue; + + for (i = 0; i < ef->nprogtab; i++) { + if (strcmp(ef->progtab[i].name, linkset_name) == 0) { + startp = (Elf_Addr)ef->progtab[i].addr; + stopp = (Elf_Addr)(startp + ef->progtab[i].size); + break; + } + } + if (i == ef->nprogtab) + continue; + + sym->st_value = start ? startp : stopp; + sym->st_shndx = i; + } +} + +static void link_elf_reloc_local(linker_file_t lf) { elf_file_t ef = (elf_file_t)lf; @@ -1126,6 +1171,8 @@ int i; Elf_Size symidx; + link_elf_fix_link_set(ef); + /* Perform relocations without addend if there are any: */ for (i = 0; i < ef->nrel; i++) { rel = ef->reltab[i].rel; --- modules/Makefile.orig +++ modules/Makefile @@ -468,6 +468,9 @@ _ipw= ipw _iwi= iwi _ixgb= ixgb +_linprocfs= linprocfs +_linsysfs= linsysfs +_linux= linux _mly= mly _mxge= mxge _ndis= ndis