From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KzQsJ-0003eu-K2 for qemu-devel@nongnu.org; Mon, 10 Nov 2008 02:07:51 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KzQsJ-0003ei-2Y for qemu-devel@nongnu.org; Mon, 10 Nov 2008 02:07:51 -0500 Received: from [199.232.76.173] (port=41572 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KzQsI-0003ef-VD for qemu-devel@nongnu.org; Mon, 10 Nov 2008 02:07:50 -0500 Received: from ey-out-1920.google.com ([74.125.78.150]:10556) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KzQsI-0003SM-An for qemu-devel@nongnu.org; Mon, 10 Nov 2008 02:07:50 -0500 Received: by ey-out-1920.google.com with SMTP id 4so881169eyk.4 for ; Sun, 09 Nov 2008 23:07:49 -0800 (PST) From: "Kirill A. Shutemov" Date: Mon, 10 Nov 2008 09:09:41 +0200 Message-Id: <1226300981-4147-1-git-send-email-kirill@shutemov.name> In-Reply-To: <1223892640-15545-13-git-send-email-kirill@shutemov.name> References: <1223892640-15545-13-git-send-email-kirill@shutemov.name> Subject: [Qemu-devel] [PATCH, v3] shmat(): use mmap_find_vma to find free memory area Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: "Kirill A. Shutemov" Signed-off-by: Kirill A. Shutemov --- linux-user/syscall.c | 32 ++++++++++++++++++++++++-------- 1 files changed, 24 insertions(+), 8 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 7142606..ebf7375 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2271,25 +2271,40 @@ static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf) static inline abi_long do_shmat(int shmid, abi_ulong shmaddr, int shmflg, unsigned long *raddr) { + abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size); abi_long ret; struct shmid_ds shm_info; int i; - /* SHM_* flags are the same on all linux platforms */ - *raddr = (unsigned long) shmat(shmid, g2h(shmaddr), shmflg); - - if (*raddr == -1) { - return get_errno(*raddr); - } - /* find out the length of the shared memory segment */ ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info)); if (is_error(ret)) { /* can't get length, bail out */ - shmdt((void *) *raddr); return get_errno(ret); } + mmap_lock(); + + if (shmaddr) + *raddr = (unsigned long) shmat(shmid, g2h(shmaddr), shmflg); + else { + abi_ulong mmap_start; + + mmap_start = mmap_find_vma(0, shm_info.shm_segsz); + + if (mmap_start == -1) { + errno = ENOMEM; + *raddr = -1; + } else + *raddr = (unsigned long) shmat(shmid, g2h(mmap_start), + shmflg | SHM_REMAP); + } + + if (*raddr == -1) { + mmap_unlock(); + return get_errno(*raddr); + } + page_set_flags(h2g(*raddr), h2g(*raddr) + shm_info.shm_segsz, PAGE_VALID | PAGE_READ | ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE)); @@ -2302,6 +2317,7 @@ static inline abi_long do_shmat(int shmid, abi_ulong shmaddr, int shmflg, } } + mmap_unlock(); return 0; } -- 1.6.0.2.GIT