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} |