1/*- 2 * Copyright (c) 2000 Marcel Moolenaar 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 13 unchanged lines hidden (view full) --- 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/sys/i386/linux/linux_machdep.c 166727 2007-02-15 00:54:40Z jkim $"); |
31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/file.h> 35#include <sys/fcntl.h> 36#include <sys/imgact.h> 37#include <sys/lock.h> 38#include <sys/malloc.h> --- 540 unchanged lines hidden (view full) --- 579 while (p2->p_flag & P_PPWAIT) 580 msleep(td->td_proc, &p2->p_mtx, PWAIT, "ppwait", 0); 581 PROC_UNLOCK(p2); 582 } 583 584 return (0); 585} 586 |
587#define STACK_SIZE (2 * 1024 * 1024) 588#define GUARD_SIZE (4 * PAGE_SIZE) 589 590static int linux_mmap_common(struct thread *, struct l_mmap_argv *); 591 592int 593linux_mmap2(struct thread *td, struct linux_mmap2_args *args) 594{ 595 struct l_mmap_argv linux_args; 596 597#ifdef DEBUG 598 if (ldebug(mmap2)) 599 printf(ARGS(mmap2, "%p, %d, %d, 0x%08x, %d, %d"), 600 (void *)args->addr, args->len, args->prot, 601 args->flags, args->fd, args->pgoff); 602#endif 603 |
604 linux_args.addr = args->addr; |
605 linux_args.len = args->len; 606 linux_args.prot = args->prot; 607 linux_args.flags = args->flags; 608 linux_args.fd = args->fd; |
609 linux_args.pgoff = args->pgoff * PAGE_SIZE; |
610 611 return (linux_mmap_common(td, &linux_args)); 612} 613 614int 615linux_mmap(struct thread *td, struct linux_mmap_args *args) 616{ 617 int error; 618 struct l_mmap_argv linux_args; 619 620 error = copyin(args->ptr, &linux_args, sizeof(linux_args)); 621 if (error) 622 return (error); 623 624#ifdef DEBUG 625 if (ldebug(mmap)) 626 printf(ARGS(mmap, "%p, %d, %d, 0x%08x, %d, %d"), 627 (void *)linux_args.addr, linux_args.len, linux_args.prot, |
628 linux_args.flags, linux_args.fd, linux_args.pgoff); |
629#endif 630 631 return (linux_mmap_common(td, &linux_args)); 632} 633 634static int 635linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args) 636{ --- 27 unchanged lines hidden (view full) --- 664 if (linux_args->flags & LINUX_MAP_PRIVATE) 665 bsd_args.flags |= MAP_PRIVATE; 666 if (linux_args->flags & LINUX_MAP_FIXED) 667 bsd_args.flags |= MAP_FIXED; 668 if (linux_args->flags & LINUX_MAP_ANON) 669 bsd_args.flags |= MAP_ANON; 670 else 671 bsd_args.flags |= MAP_NOSYNC; |
672 if (linux_args->flags & LINUX_MAP_GROWSDOWN) |
673 bsd_args.flags |= MAP_STACK; 674 |
675 /* 676 * PROT_READ, PROT_WRITE, or PROT_EXEC implies PROT_READ and PROT_EXEC 677 * on Linux/i386. We do this to ensure maximum compatibility. 678 * Linux/ia64 does the same in i386 emulation mode. 679 */ 680 bsd_args.prot = linux_args->prot; 681 if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) 682 bsd_args.prot |= PROT_READ | PROT_EXEC; 683 684 if (linux_args->fd != -1) { 685 /* 686 * Linux follows Solaris mmap(2) description: 687 * The file descriptor fildes is opened with 688 * read permission, regardless of the 689 * protection options specified. 690 */ 691 692 if ((error = fget(td, linux_args->fd, &fp)) != 0) 693 return (error); 694 if (fp->f_type != DTYPE_VNODE) { 695 fdrop(fp, td); 696 return (EINVAL); 697 } 698 699 /* Linux mmap() just fails for O_WRONLY files */ 700 if (!(fp->f_flag & FREAD)) { 701 fdrop(fp, td); 702 return (EACCES); 703 } 704 705 fdrop(fp, td); 706 } 707 bsd_args.fd = linux_args->fd; 708 709 if (linux_args->flags & LINUX_MAP_GROWSDOWN) { |
710 /* 711 * The linux MAP_GROWSDOWN option does not limit auto 712 * growth of the region. Linux mmap with this option 713 * takes as addr the inital BOS, and as len, the initial 714 * region size. It can then grow down from addr without 715 * limit. However, linux threads has an implicit internal 716 * limit to stack size of STACK_SIZE. Its just not 717 * enforced explicitly in linux. But, here we impose --- 6 unchanged lines hidden (view full) --- 724 * and autgrows the region down, up to the limit 725 * in addr. 726 * 727 * If we don't use the MAP_STACK option, the effect 728 * of this code is to allocate a stack region of a 729 * fixed size of (STACK_SIZE - GUARD_SIZE). 730 */ 731 |
732 if ((caddr_t)PTRIN(linux_args->addr) + linux_args->len > 733 p->p_vmspace->vm_maxsaddr) { |
734 /* 735 * Some linux apps will attempt to mmap 736 * thread stacks near the top of their 737 * address space. If their TOS is greater 738 * than vm_maxsaddr, vm_map_growstack() 739 * will confuse the thread stack with the 740 * process stack and deliver a SEGV if they 741 * attempt to grow the thread stack past their --- 19 unchanged lines hidden (view full) --- 761 762 /* 763 * This gives us a new BOS. If we're using VM_STACK, then 764 * mmap will just map the top SGROWSIZ bytes, and let 765 * the stack grow down to the limit at BOS. If we're 766 * not using VM_STACK we map the full stack, since we 767 * don't have a way to autogrow it. 768 */ |
769 bsd_args.addr = (caddr_t)PTRIN(linux_args->addr) - 770 bsd_args.len; |
771 } else { |
772 bsd_args.addr = (caddr_t)PTRIN(linux_args->addr); |
773 bsd_args.len = linux_args->len; 774 } |
775 bsd_args.pos = linux_args->pgoff; |
776 bsd_args.pad = 0; 777 778#ifdef DEBUG 779 if (ldebug(mmap)) 780 printf("-> %s(%p, %d, %d, 0x%08x, %d, 0x%x)\n", 781 __func__, 782 (void *)bsd_args.addr, bsd_args.len, bsd_args.prot, 783 bsd_args.flags, bsd_args.fd, (int)bsd_args.pos); 784#endif 785 error = mmap(td, &bsd_args); 786#ifdef DEBUG 787 if (ldebug(mmap)) 788 printf("-> %s() return: 0x%x (0x%08x)\n", 789 __func__, error, (u_int)td->td_retval[0]); 790#endif 791 return (error); 792} 793 794int |
795linux_mprotect(struct thread *td, struct linux_mprotect_args *uap) 796{ 797 struct mprotect_args bsd_args; 798 799 bsd_args.addr = uap->addr; 800 bsd_args.len = uap->len; 801 bsd_args.prot = uap->prot; 802 if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) 803 bsd_args.prot |= PROT_READ | PROT_EXEC; 804 return (mprotect(td, &bsd_args)); 805} 806 807int |
808linux_pipe(struct thread *td, struct linux_pipe_args *args) 809{ 810 int error; 811 int reg_edx; 812 813#ifdef DEBUG 814 if (ldebug(pipe)) 815 printf(ARGS(pipe, "*")); --- 500 unchanged lines hidden --- |