Deleted Added
full compact
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 ---