linux_machdep.c (166395) | linux_machdep.c (166727) |
---|---|
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> | 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 166395 2007-02-01 13:27:52Z kib $"); | 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 | 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/* XXX move */ 588struct l_mmap_argv { 589 l_caddr_t addr; 590 l_int len; 591 l_int prot; 592 l_int flags; 593 l_int fd; 594 l_int pos; 595}; 596 | |
597#define STACK_SIZE (2 * 1024 * 1024) 598#define GUARD_SIZE (4 * PAGE_SIZE) 599 600static int linux_mmap_common(struct thread *, struct l_mmap_argv *); 601 602int 603linux_mmap2(struct thread *td, struct linux_mmap2_args *args) 604{ 605 struct l_mmap_argv linux_args; 606 607#ifdef DEBUG 608 if (ldebug(mmap2)) 609 printf(ARGS(mmap2, "%p, %d, %d, 0x%08x, %d, %d"), 610 (void *)args->addr, args->len, args->prot, 611 args->flags, args->fd, args->pgoff); 612#endif 613 | 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 |
614 linux_args.addr = (l_caddr_t)args->addr; | 604 linux_args.addr = args->addr; |
615 linux_args.len = args->len; 616 linux_args.prot = args->prot; 617 linux_args.flags = args->flags; 618 linux_args.fd = args->fd; | 605 linux_args.len = args->len; 606 linux_args.prot = args->prot; 607 linux_args.flags = args->flags; 608 linux_args.fd = args->fd; |
619 linux_args.pos = args->pgoff * PAGE_SIZE; | 609 linux_args.pgoff = args->pgoff * PAGE_SIZE; |
620 621 return (linux_mmap_common(td, &linux_args)); 622} 623 624int 625linux_mmap(struct thread *td, struct linux_mmap_args *args) 626{ 627 int error; 628 struct l_mmap_argv linux_args; 629 630 error = copyin(args->ptr, &linux_args, sizeof(linux_args)); 631 if (error) 632 return (error); 633 634#ifdef DEBUG 635 if (ldebug(mmap)) 636 printf(ARGS(mmap, "%p, %d, %d, 0x%08x, %d, %d"), 637 (void *)linux_args.addr, linux_args.len, linux_args.prot, | 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, |
638 linux_args.flags, linux_args.fd, linux_args.pos); | 628 linux_args.flags, linux_args.fd, linux_args.pgoff); |
639#endif 640 641 return (linux_mmap_common(td, &linux_args)); 642} 643 644static int 645linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args) 646{ --- 27 unchanged lines hidden (view full) --- 674 if (linux_args->flags & LINUX_MAP_PRIVATE) 675 bsd_args.flags |= MAP_PRIVATE; 676 if (linux_args->flags & LINUX_MAP_FIXED) 677 bsd_args.flags |= MAP_FIXED; 678 if (linux_args->flags & LINUX_MAP_ANON) 679 bsd_args.flags |= MAP_ANON; 680 else 681 bsd_args.flags |= MAP_NOSYNC; | 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; |
682 if (linux_args->flags & LINUX_MAP_GROWSDOWN) { | 672 if (linux_args->flags & LINUX_MAP_GROWSDOWN) |
683 bsd_args.flags |= MAP_STACK; 684 | 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) { |
|
685 /* 686 * The linux MAP_GROWSDOWN option does not limit auto 687 * growth of the region. Linux mmap with this option 688 * takes as addr the inital BOS, and as len, the initial 689 * region size. It can then grow down from addr without 690 * limit. However, linux threads has an implicit internal 691 * limit to stack size of STACK_SIZE. Its just not 692 * enforced explicitly in linux. But, here we impose --- 6 unchanged lines hidden (view full) --- 699 * and autgrows the region down, up to the limit 700 * in addr. 701 * 702 * If we don't use the MAP_STACK option, the effect 703 * of this code is to allocate a stack region of a 704 * fixed size of (STACK_SIZE - GUARD_SIZE). 705 */ 706 | 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 |
707 /* This gives us TOS */ 708 bsd_args.addr = linux_args->addr + linux_args->len; 709 710 if (bsd_args.addr > p->p_vmspace->vm_maxsaddr) { | 732 if ((caddr_t)PTRIN(linux_args->addr) + linux_args->len > 733 p->p_vmspace->vm_maxsaddr) { |
711 /* 712 * Some linux apps will attempt to mmap 713 * thread stacks near the top of their 714 * address space. If their TOS is greater 715 * than vm_maxsaddr, vm_map_growstack() 716 * will confuse the thread stack with the 717 * process stack and deliver a SEGV if they 718 * attempt to grow the thread stack past their --- 19 unchanged lines hidden (view full) --- 738 739 /* 740 * This gives us a new BOS. If we're using VM_STACK, then 741 * mmap will just map the top SGROWSIZ bytes, and let 742 * the stack grow down to the limit at BOS. If we're 743 * not using VM_STACK we map the full stack, since we 744 * don't have a way to autogrow it. 745 */ | 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 */ |
746 bsd_args.addr -= bsd_args.len; | 769 bsd_args.addr = (caddr_t)PTRIN(linux_args->addr) - 770 bsd_args.len; |
747 } else { | 771 } else { |
748 bsd_args.addr = linux_args->addr; | 772 bsd_args.addr = (caddr_t)PTRIN(linux_args->addr); |
749 bsd_args.len = linux_args->len; 750 } | 773 bsd_args.len = linux_args->len; 774 } |
751 752 bsd_args.prot = linux_args->prot; 753 if (linux_args->flags & LINUX_MAP_ANON) 754 bsd_args.fd = -1; 755 else { 756 /* 757 * Linux follows Solaris mmap(2) description: 758 * The file descriptor fildes is opened with 759 * read permission, regardless of the 760 * protection options specified. 761 * If PROT_WRITE is specified, the application 762 * must have opened the file descriptor 763 * fildes with write permission unless 764 * MAP_PRIVATE is specified in the flag 765 * argument as described below. 766 */ 767 768 if ((error = fget(td, linux_args->fd, &fp)) != 0) 769 return (error); 770 if (fp->f_type != DTYPE_VNODE) { 771 fdrop(fp, td); 772 return (EINVAL); 773 } 774 775 /* Linux mmap() just fails for O_WRONLY files */ 776 if (! (fp->f_flag & FREAD)) { 777 fdrop(fp, td); 778 return (EACCES); 779 } 780 781 bsd_args.fd = linux_args->fd; 782 fdrop(fp, td); 783 } 784 bsd_args.pos = linux_args->pos; | 775 bsd_args.pos = linux_args->pgoff; |
785 bsd_args.pad = 0; 786 787#ifdef DEBUG 788 if (ldebug(mmap)) 789 printf("-> %s(%p, %d, %d, 0x%08x, %d, 0x%x)\n", 790 __func__, 791 (void *)bsd_args.addr, bsd_args.len, bsd_args.prot, 792 bsd_args.flags, bsd_args.fd, (int)bsd_args.pos); 793#endif 794 error = mmap(td, &bsd_args); 795#ifdef DEBUG 796 if (ldebug(mmap)) 797 printf("-> %s() return: 0x%x (0x%08x)\n", 798 __func__, error, (u_int)td->td_retval[0]); 799#endif 800 return (error); 801} 802 803int | 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 |
|
804linux_pipe(struct thread *td, struct linux_pipe_args *args) 805{ 806 int error; 807 int reg_edx; 808 809#ifdef DEBUG 810 if (ldebug(pipe)) 811 printf(ARGS(pipe, "*")); --- 500 unchanged lines hidden --- | 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 --- |