Deleted Added
full compact
linux32_machdep.c (166395) linux32_machdep.c (166727)
1/*-
2 * Copyright (c) 2004 Tim J. Robbins
3 * Copyright (c) 2002 Doug Rabson
4 * Copyright (c) 2000 Marcel Moolenaar
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 15 unchanged lines hidden (view full) ---

24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2004 Tim J. Robbins
3 * Copyright (c) 2002 Doug Rabson
4 * Copyright (c) 2000 Marcel Moolenaar
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 15 unchanged lines hidden (view full) ---

24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: head/sys/amd64/linux32/linux32_machdep.c 166395 2007-02-01 13:27:52Z kib $");
32__FBSDID("$FreeBSD: head/sys/amd64/linux32/linux32_machdep.c 166727 2007-02-15 00:54:40Z jkim $");
33
34#include <sys/param.h>
35#include <sys/kernel.h>
36#include <sys/systm.h>
37#include <sys/file.h>
38#include <sys/fcntl.h>
39#include <sys/clock.h>
40#include <sys/imgact.h>

--- 644 unchanged lines hidden (view full) ---

685 while (p2->p_flag & P_PPWAIT)
686 msleep(td->td_proc, &p2->p_mtx, PWAIT, "ppwait", 0);
687 PROC_UNLOCK(p2);
688 }
689
690 return (0);
691}
692
33
34#include <sys/param.h>
35#include <sys/kernel.h>
36#include <sys/systm.h>
37#include <sys/file.h>
38#include <sys/fcntl.h>
39#include <sys/clock.h>
40#include <sys/imgact.h>

--- 644 unchanged lines hidden (view full) ---

685 while (p2->p_flag & P_PPWAIT)
686 msleep(td->td_proc, &p2->p_mtx, PWAIT, "ppwait", 0);
687 PROC_UNLOCK(p2);
688 }
689
690 return (0);
691}
692
693/* XXX move */
694struct l_mmap_argv {
695 l_ulong addr;
696 l_ulong len;
697 l_ulong prot;
698 l_ulong flags;
699 l_ulong fd;
700 l_ulong pgoff;
701};
702
703#define STACK_SIZE (2 * 1024 * 1024)
704#define GUARD_SIZE (4 * PAGE_SIZE)
705
706static int linux_mmap_common(struct thread *, struct l_mmap_argv *);
707
708int
709linux_mmap2(struct thread *td, struct linux_mmap2_args *args)
710{

--- 73 unchanged lines hidden (view full) ---

784 if (linux_args->flags & LINUX_MAP_PRIVATE)
785 bsd_args.flags |= MAP_PRIVATE;
786 if (linux_args->flags & LINUX_MAP_FIXED)
787 bsd_args.flags |= MAP_FIXED;
788 if (linux_args->flags & LINUX_MAP_ANON)
789 bsd_args.flags |= MAP_ANON;
790 else
791 bsd_args.flags |= MAP_NOSYNC;
693#define STACK_SIZE (2 * 1024 * 1024)
694#define GUARD_SIZE (4 * PAGE_SIZE)
695
696static int linux_mmap_common(struct thread *, struct l_mmap_argv *);
697
698int
699linux_mmap2(struct thread *td, struct linux_mmap2_args *args)
700{

--- 73 unchanged lines hidden (view full) ---

774 if (linux_args->flags & LINUX_MAP_PRIVATE)
775 bsd_args.flags |= MAP_PRIVATE;
776 if (linux_args->flags & LINUX_MAP_FIXED)
777 bsd_args.flags |= MAP_FIXED;
778 if (linux_args->flags & LINUX_MAP_ANON)
779 bsd_args.flags |= MAP_ANON;
780 else
781 bsd_args.flags |= MAP_NOSYNC;
792 if (linux_args->flags & LINUX_MAP_GROWSDOWN) {
782 if (linux_args->flags & LINUX_MAP_GROWSDOWN)
793 bsd_args.flags |= MAP_STACK;
794
783 bsd_args.flags |= MAP_STACK;
784
785 /*
786 * PROT_READ, PROT_WRITE, or PROT_EXEC implies PROT_READ and PROT_EXEC
787 * on Linux/i386. We do this to ensure maximum compatibility.
788 * Linux/ia64 does the same in i386 emulation mode.
789 */
790 bsd_args.prot = linux_args->prot;
791 if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC))
792 bsd_args.prot |= PROT_READ | PROT_EXEC;
793
794 if (linux_args->fd != -1) {
795 /*
796 * Linux follows Solaris mmap(2) description:
797 * The file descriptor fildes is opened with
798 * read permission, regardless of the
799 * protection options specified.
800 */
801
802 if ((error = fget(td, linux_args->fd, &fp)) != 0)
803 return (error);
804 if (fp->f_type != DTYPE_VNODE) {
805 fdrop(fp, td);
806 return (EINVAL);
807 }
808
809 /* Linux mmap() just fails for O_WRONLY files */
810 if (!(fp->f_flag & FREAD)) {
811 fdrop(fp, td);
812 return (EACCES);
813 }
814
815 fdrop(fp, td);
816 }
817 bsd_args.fd = linux_args->fd;
818
819 if (linux_args->flags & LINUX_MAP_GROWSDOWN) {
795 /*
796 * The linux MAP_GROWSDOWN option does not limit auto
797 * growth of the region. Linux mmap with this option
798 * takes as addr the inital BOS, and as len, the initial
799 * region size. It can then grow down from addr without
800 * limit. However, linux threads has an implicit internal
801 * limit to stack size of STACK_SIZE. Its just not
802 * enforced explicitly in linux. But, here we impose

--- 6 unchanged lines hidden (view full) ---

809 * and autgrows the region down, up to the limit
810 * in addr.
811 *
812 * If we don't use the MAP_STACK option, the effect
813 * of this code is to allocate a stack region of a
814 * fixed size of (STACK_SIZE - GUARD_SIZE).
815 */
816
820 /*
821 * The linux MAP_GROWSDOWN option does not limit auto
822 * growth of the region. Linux mmap with this option
823 * takes as addr the inital BOS, and as len, the initial
824 * region size. It can then grow down from addr without
825 * limit. However, linux threads has an implicit internal
826 * limit to stack size of STACK_SIZE. Its just not
827 * enforced explicitly in linux. But, here we impose

--- 6 unchanged lines hidden (view full) ---

834 * and autgrows the region down, up to the limit
835 * in addr.
836 *
837 * If we don't use the MAP_STACK option, the effect
838 * of this code is to allocate a stack region of a
839 * fixed size of (STACK_SIZE - GUARD_SIZE).
840 */
841
817 /* This gives us TOS */
818 bsd_args.addr = (caddr_t)PTRIN(linux_args->addr) +
819 linux_args->len;
820
821 if ((caddr_t)PTRIN(bsd_args.addr) >
842 if ((caddr_t)PTRIN(linux_args->addr) + linux_args->len >
822 p->p_vmspace->vm_maxsaddr) {
823 /*
824 * Some linux apps will attempt to mmap
825 * thread stacks near the top of their
826 * address space. If their TOS is greater
827 * than vm_maxsaddr, vm_map_growstack()
828 * will confuse the thread stack with the
829 * process stack and deliver a SEGV if they
830 * attempt to grow the thread stack past their
831 * current stacksize rlimit. To avoid this,
832 * adjust vm_maxsaddr upwards to reflect
833 * the current stacksize rlimit rather
834 * than the maximum possible stacksize.
835 * It would be better to adjust the
836 * mmap'ed region, but some apps do not check
837 * mmap's return value.
838 */
839 PROC_LOCK(p);
843 p->p_vmspace->vm_maxsaddr) {
844 /*
845 * Some linux apps will attempt to mmap
846 * thread stacks near the top of their
847 * address space. If their TOS is greater
848 * than vm_maxsaddr, vm_map_growstack()
849 * will confuse the thread stack with the
850 * process stack and deliver a SEGV if they
851 * attempt to grow the thread stack past their
852 * current stacksize rlimit. To avoid this,
853 * adjust vm_maxsaddr upwards to reflect
854 * the current stacksize rlimit rather
855 * than the maximum possible stacksize.
856 * It would be better to adjust the
857 * mmap'ed region, but some apps do not check
858 * mmap's return value.
859 */
860 PROC_LOCK(p);
840 p->p_vmspace->vm_maxsaddr =
841 (char *)LINUX32_USRSTACK -
861 p->p_vmspace->vm_maxsaddr = (char *)LINUX32_USRSTACK -
842 lim_cur(p, RLIMIT_STACK);
843 PROC_UNLOCK(p);
844 }
845
846 /* This gives us our maximum stack size */
847 if (linux_args->len > STACK_SIZE - GUARD_SIZE)
848 bsd_args.len = linux_args->len;
849 else
850 bsd_args.len = STACK_SIZE - GUARD_SIZE;
851
852 /*
853 * This gives us a new BOS. If we're using VM_STACK, then
854 * mmap will just map the top SGROWSIZ bytes, and let
855 * the stack grow down to the limit at BOS. If we're
856 * not using VM_STACK we map the full stack, since we
857 * don't have a way to autogrow it.
858 */
862 lim_cur(p, RLIMIT_STACK);
863 PROC_UNLOCK(p);
864 }
865
866 /* This gives us our maximum stack size */
867 if (linux_args->len > STACK_SIZE - GUARD_SIZE)
868 bsd_args.len = linux_args->len;
869 else
870 bsd_args.len = STACK_SIZE - GUARD_SIZE;
871
872 /*
873 * This gives us a new BOS. If we're using VM_STACK, then
874 * mmap will just map the top SGROWSIZ bytes, and let
875 * the stack grow down to the limit at BOS. If we're
876 * not using VM_STACK we map the full stack, since we
877 * don't have a way to autogrow it.
878 */
859 bsd_args.addr -= bsd_args.len;
879 bsd_args.addr = (caddr_t)PTRIN(linux_args->addr) -
880 bsd_args.len;
860 } else {
861 bsd_args.addr = (caddr_t)PTRIN(linux_args->addr);
862 bsd_args.len = linux_args->len;
863 }
881 } else {
882 bsd_args.addr = (caddr_t)PTRIN(linux_args->addr);
883 bsd_args.len = linux_args->len;
884 }
864
865 /*
866 * We add PROT_EXEC to work around buggy applications (e.g. Java)
867 * that take advantage of the fact that execute permissions are not
868 * enforced by x86 CPUs.
869 */
870 bsd_args.prot = linux_args->prot | PROT_EXEC;
871 if (linux_args->flags & LINUX_MAP_ANON)
872 bsd_args.fd = -1;
873 else {
874 /*
875 * Linux follows Solaris mmap(2) description:
876 * The file descriptor fildes is opened with
877 * read permission, regardless of the
878 * protection options specified.
879 * If PROT_WRITE is specified, the application
880 * must have opened the file descriptor
881 * fildes with write permission unless
882 * MAP_PRIVATE is specified in the flag
883 * argument as described below.
884 */
885
886 if ((error = fget(td, linux_args->fd, &fp)) != 0)
887 return (error);
888 if (fp->f_type != DTYPE_VNODE) {
889 fdrop(fp, td);
890 return (EINVAL);
891 }
892
893 /* Linux mmap() just fails for O_WRONLY files */
894 if (! (fp->f_flag & FREAD)) {
895 fdrop(fp, td);
896 return (EACCES);
897 }
898
899 bsd_args.fd = linux_args->fd;
900 fdrop(fp, td);
901 }
902 bsd_args.pos = (off_t)linux_args->pgoff * PAGE_SIZE;
903 bsd_args.pad = 0;
904
905#ifdef DEBUG
906 if (ldebug(mmap))
907 printf("-> %s(%p, %d, %d, 0x%08x, %d, 0x%x)\n",
908 __func__,
909 (void *)bsd_args.addr, (int)bsd_args.len, bsd_args.prot,

--- 266 unchanged lines hidden (view full) ---

1176int
1177linux_mprotect(struct thread *td, struct linux_mprotect_args *uap)
1178{
1179 struct mprotect_args bsd_args;
1180
1181 bsd_args.addr = uap->addr;
1182 bsd_args.len = uap->len;
1183 bsd_args.prot = uap->prot;
885 bsd_args.pos = (off_t)linux_args->pgoff * PAGE_SIZE;
886 bsd_args.pad = 0;
887
888#ifdef DEBUG
889 if (ldebug(mmap))
890 printf("-> %s(%p, %d, %d, 0x%08x, %d, 0x%x)\n",
891 __func__,
892 (void *)bsd_args.addr, (int)bsd_args.len, bsd_args.prot,

--- 266 unchanged lines hidden (view full) ---

1159int
1160linux_mprotect(struct thread *td, struct linux_mprotect_args *uap)
1161{
1162 struct mprotect_args bsd_args;
1163
1164 bsd_args.addr = uap->addr;
1165 bsd_args.len = uap->len;
1166 bsd_args.prot = uap->prot;
1184 /* XXX PROT_READ implies PROT_EXEC; see linux_mmap_common(). */
1185 if ((bsd_args.prot & PROT_READ) != 0)
1186 bsd_args.prot |= PROT_EXEC;
1167 if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC))
1168 bsd_args.prot |= PROT_READ | PROT_EXEC;
1187 return (mprotect(td, &bsd_args));
1188}
1169 return (mprotect(td, &bsd_args));
1170}