Date: Wed, 4 Nov 2009 20:53:35 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org Subject: svn commit: r198926 - in stable/7/sys: amd64/linux32 i386/linux Message-ID: <200911042053.nA4KrZh8046264@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Wed Nov 4 20:53:35 2009 New Revision: 198926 URL: http://svn.freebsd.org/changeset/base/198926 Log: MFC 198554: Fix some problems with effective mmap() offsets > 32 bits. This was partially fixed on amd64 earlier. Rather than forcing linux_mmap_common() to use a 32-bit offset, have it accept a 64-bit file offset. This offset is then passed to the real mmap() call. Rather than inventing a structure to hold the normal linux_mmap args that has a 64-bit offset, just pass each of the arguments individually to linux_mmap_common() since that more closes matches the existing style of various kern_foo() functions. Modified: stable/7/sys/amd64/linux32/linux32_machdep.c stable/7/sys/i386/linux/linux_machdep.c Directory Properties: stable/7/sys/ (props changed) stable/7/sys/contrib/pf/ (props changed) Modified: stable/7/sys/amd64/linux32/linux32_machdep.c ============================================================================== --- stable/7/sys/amd64/linux32/linux32_machdep.c Wed Nov 4 20:49:14 2009 (r198925) +++ stable/7/sys/amd64/linux32/linux32_machdep.c Wed Nov 4 20:53:35 2009 (r198926) @@ -91,6 +91,10 @@ linux_to_bsd_sigaltstack(int lsa) return (bsa); } +static int linux_mmap_common(struct thread *td, l_uintptr_t addr, + l_size_t len, l_int prot, l_int flags, l_int fd, + l_loff_t pos); + int bsd_to_linux_sigaltstack(int bsa) { @@ -759,12 +763,9 @@ linux_clone(struct thread *td, struct li #define STACK_SIZE (2 * 1024 * 1024) #define GUARD_SIZE (4 * PAGE_SIZE) -static int linux_mmap_common(struct thread *, struct l_mmap_argv *); - int linux_mmap2(struct thread *td, struct linux_mmap2_args *args) { - struct l_mmap_argv linux_args; #ifdef DEBUG if (ldebug(mmap2)) @@ -773,14 +774,9 @@ linux_mmap2(struct thread *td, struct li args->flags, args->fd, args->pgoff); #endif - linux_args.addr = PTROUT(args->addr); - linux_args.len = args->len; - linux_args.prot = args->prot; - linux_args.flags = args->flags; - linux_args.fd = args->fd; - linux_args.pgoff = args->pgoff; - - return (linux_mmap_common(td, &linux_args)); + return (linux_mmap_common(td, PTROUT(args->addr), args->len, args->prot, + args->flags, args->fd, (uint64_t)(uint32_t)args->pgoff * + PAGE_SIZE)); } int @@ -799,15 +795,15 @@ linux_mmap(struct thread *td, struct lin linux_args.addr, linux_args.len, linux_args.prot, linux_args.flags, linux_args.fd, linux_args.pgoff); #endif - if ((linux_args.pgoff % PAGE_SIZE) != 0) - return (EINVAL); - linux_args.pgoff /= PAGE_SIZE; - return (linux_mmap_common(td, &linux_args)); + return (linux_mmap_common(td, linux_args.addr, linux_args.len, + linux_args.prot, linux_args.flags, linux_args.fd, + (uint32_t)linux_args.pgoff)); } static int -linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args) +linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot, + l_int flags, l_int fd, l_loff_t pos) { struct proc *p = td->td_proc; struct mmap_args /* { @@ -830,21 +826,20 @@ linux_mmap_common(struct thread *td, str * Linux mmap(2): * You must specify exactly one of MAP_SHARED and MAP_PRIVATE */ - if (! ((linux_args->flags & LINUX_MAP_SHARED) ^ - (linux_args->flags & LINUX_MAP_PRIVATE))) + if (!((flags & LINUX_MAP_SHARED) ^ (flags & LINUX_MAP_PRIVATE))) return (EINVAL); - if (linux_args->flags & LINUX_MAP_SHARED) + if (flags & LINUX_MAP_SHARED) bsd_args.flags |= MAP_SHARED; - if (linux_args->flags & LINUX_MAP_PRIVATE) + if (flags & LINUX_MAP_PRIVATE) bsd_args.flags |= MAP_PRIVATE; - if (linux_args->flags & LINUX_MAP_FIXED) + if (flags & LINUX_MAP_FIXED) bsd_args.flags |= MAP_FIXED; - if (linux_args->flags & LINUX_MAP_ANON) + if (flags & LINUX_MAP_ANON) bsd_args.flags |= MAP_ANON; else bsd_args.flags |= MAP_NOSYNC; - if (linux_args->flags & LINUX_MAP_GROWSDOWN) + if (flags & LINUX_MAP_GROWSDOWN) bsd_args.flags |= MAP_STACK; /* @@ -852,12 +847,12 @@ linux_mmap_common(struct thread *td, str * on Linux/i386. We do this to ensure maximum compatibility. * Linux/ia64 does the same in i386 emulation mode. */ - bsd_args.prot = linux_args->prot; + bsd_args.prot = prot; if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) bsd_args.prot |= PROT_READ | PROT_EXEC; /* Linux does not check file descriptor when MAP_ANONYMOUS is set. */ - bsd_args.fd = (bsd_args.flags & MAP_ANON) ? -1 : linux_args->fd; + bsd_args.fd = (bsd_args.flags & MAP_ANON) ? -1 : fd; if (bsd_args.fd != -1) { /* * Linux follows Solaris mmap(2) description: @@ -882,7 +877,7 @@ linux_mmap_common(struct thread *td, str fdrop(fp, td); } - if (linux_args->flags & LINUX_MAP_GROWSDOWN) { + if (flags & LINUX_MAP_GROWSDOWN) { /* * The Linux MAP_GROWSDOWN option does not limit auto * growth of the region. Linux mmap with this option @@ -905,8 +900,7 @@ linux_mmap_common(struct thread *td, str * fixed size of (STACK_SIZE - GUARD_SIZE). */ - if ((caddr_t)PTRIN(linux_args->addr) + linux_args->len > - p->p_vmspace->vm_maxsaddr) { + if ((caddr_t)PTRIN(addr) + len > p->p_vmspace->vm_maxsaddr) { /* * Some Linux apps will attempt to mmap * thread stacks near the top of their @@ -937,19 +931,19 @@ linux_mmap_common(struct thread *td, str * we map the full stack, since we don't have a way * to autogrow it. */ - if (linux_args->len > STACK_SIZE - GUARD_SIZE) { - bsd_args.addr = (caddr_t)PTRIN(linux_args->addr); - bsd_args.len = linux_args->len; + if (len > STACK_SIZE - GUARD_SIZE) { + bsd_args.addr = (caddr_t)PTRIN(addr); + bsd_args.len = len; } else { - bsd_args.addr = (caddr_t)PTRIN(linux_args->addr) - - (STACK_SIZE - GUARD_SIZE - linux_args->len); + bsd_args.addr = (caddr_t)PTRIN(addr) - + (STACK_SIZE - GUARD_SIZE - len); bsd_args.len = STACK_SIZE - GUARD_SIZE; } } else { - bsd_args.addr = (caddr_t)PTRIN(linux_args->addr); - bsd_args.len = linux_args->len; + bsd_args.addr = (caddr_t)PTRIN(addr); + bsd_args.len = len; } - bsd_args.pos = (off_t)linux_args->pgoff * PAGE_SIZE; + bsd_args.pos = pos; #ifdef DEBUG if (ldebug(mmap)) Modified: stable/7/sys/i386/linux/linux_machdep.c ============================================================================== --- stable/7/sys/i386/linux/linux_machdep.c Wed Nov 4 20:49:14 2009 (r198925) +++ stable/7/sys/i386/linux/linux_machdep.c Wed Nov 4 20:53:35 2009 (r198926) @@ -93,6 +93,10 @@ struct l_old_select_argv { struct l_timeval *timeout; }; +static int linux_mmap_common(struct thread *td, l_uintptr_t addr, + l_size_t len, l_int prot, l_int flags, l_int fd, + l_loff_t pos); + int linux_to_bsd_sigaltstack(int lsa) { @@ -591,12 +595,9 @@ linux_clone(struct thread *td, struct li #define STACK_SIZE (2 * 1024 * 1024) #define GUARD_SIZE (4 * PAGE_SIZE) -static int linux_mmap_common(struct thread *, struct l_mmap_argv *); - int linux_mmap2(struct thread *td, struct linux_mmap2_args *args) { - struct l_mmap_argv linux_args; #ifdef DEBUG if (ldebug(mmap2)) @@ -605,14 +606,9 @@ linux_mmap2(struct thread *td, struct li args->flags, args->fd, args->pgoff); #endif - linux_args.addr = args->addr; - linux_args.len = args->len; - linux_args.prot = args->prot; - linux_args.flags = args->flags; - linux_args.fd = args->fd; - linux_args.pgoff = args->pgoff * PAGE_SIZE; - - return (linux_mmap_common(td, &linux_args)); + return (linux_mmap_common(td, args->addr, args->len, args->prot, + args->flags, args->fd, (uint64_t)(uint32_t)args->pgoff * + PAGE_SIZE)); } int @@ -632,11 +628,14 @@ linux_mmap(struct thread *td, struct lin linux_args.flags, linux_args.fd, linux_args.pgoff); #endif - return (linux_mmap_common(td, &linux_args)); + return (linux_mmap_common(td, linux_args.addr, linux_args.len, + linux_args.prot, linux_args.flags, linux_args.fd, + (uint32_t)linux_args.pgoff)); } static int -linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args) +linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot, + l_int flags, l_int fd, l_loff_t pos) { struct proc *p = td->td_proc; struct mmap_args /* { @@ -659,21 +658,20 @@ linux_mmap_common(struct thread *td, str * Linux mmap(2): * You must specify exactly one of MAP_SHARED and MAP_PRIVATE */ - if (! ((linux_args->flags & LINUX_MAP_SHARED) ^ - (linux_args->flags & LINUX_MAP_PRIVATE))) + if (!((flags & LINUX_MAP_SHARED) ^ (flags & LINUX_MAP_PRIVATE))) return (EINVAL); - if (linux_args->flags & LINUX_MAP_SHARED) + if (flags & LINUX_MAP_SHARED) bsd_args.flags |= MAP_SHARED; - if (linux_args->flags & LINUX_MAP_PRIVATE) + if (flags & LINUX_MAP_PRIVATE) bsd_args.flags |= MAP_PRIVATE; - if (linux_args->flags & LINUX_MAP_FIXED) + if (flags & LINUX_MAP_FIXED) bsd_args.flags |= MAP_FIXED; - if (linux_args->flags & LINUX_MAP_ANON) + if (flags & LINUX_MAP_ANON) bsd_args.flags |= MAP_ANON; else bsd_args.flags |= MAP_NOSYNC; - if (linux_args->flags & LINUX_MAP_GROWSDOWN) + if (flags & LINUX_MAP_GROWSDOWN) bsd_args.flags |= MAP_STACK; /* @@ -681,12 +679,12 @@ linux_mmap_common(struct thread *td, str * on Linux/i386. We do this to ensure maximum compatibility. * Linux/ia64 does the same in i386 emulation mode. */ - bsd_args.prot = linux_args->prot; + bsd_args.prot = prot; if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) bsd_args.prot |= PROT_READ | PROT_EXEC; /* Linux does not check file descriptor when MAP_ANONYMOUS is set. */ - bsd_args.fd = (bsd_args.flags & MAP_ANON) ? -1 : linux_args->fd; + bsd_args.fd = (bsd_args.flags & MAP_ANON) ? -1 : fd; if (bsd_args.fd != -1) { /* * Linux follows Solaris mmap(2) description: @@ -711,9 +709,9 @@ linux_mmap_common(struct thread *td, str fdrop(fp, td); } - if (linux_args->flags & LINUX_MAP_GROWSDOWN) { + if (flags & LINUX_MAP_GROWSDOWN) { /* - * The linux MAP_GROWSDOWN option does not limit auto + * The Linux MAP_GROWSDOWN option does not limit auto * growth of the region. Linux mmap with this option * takes as addr the inital BOS, and as len, the initial * region size. It can then grow down from addr without @@ -734,8 +732,7 @@ linux_mmap_common(struct thread *td, str * fixed size of (STACK_SIZE - GUARD_SIZE). */ - if ((caddr_t)PTRIN(linux_args->addr) + linux_args->len > - p->p_vmspace->vm_maxsaddr) { + if ((caddr_t)PTRIN(addr) + len > p->p_vmspace->vm_maxsaddr) { /* * Some linux apps will attempt to mmap * thread stacks near the top of their @@ -766,19 +763,19 @@ linux_mmap_common(struct thread *td, str * we map the full stack, since we don't have a way * to autogrow it. */ - if (linux_args->len > STACK_SIZE - GUARD_SIZE) { - bsd_args.addr = (caddr_t)PTRIN(linux_args->addr); - bsd_args.len = linux_args->len; + if (len > STACK_SIZE - GUARD_SIZE) { + bsd_args.addr = (caddr_t)PTRIN(addr); + bsd_args.len = len; } else { - bsd_args.addr = (caddr_t)PTRIN(linux_args->addr) - - (STACK_SIZE - GUARD_SIZE - linux_args->len); + bsd_args.addr = (caddr_t)PTRIN(addr) - + (STACK_SIZE - GUARD_SIZE - len); bsd_args.len = STACK_SIZE - GUARD_SIZE; } } else { - bsd_args.addr = (caddr_t)PTRIN(linux_args->addr); - bsd_args.len = linux_args->len; + bsd_args.addr = (caddr_t)PTRIN(addr); + bsd_args.len = len; } - bsd_args.pos = linux_args->pgoff; + bsd_args.pos = pos; #ifdef DEBUG if (ldebug(mmap))
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911042053.nA4KrZh8046264>