qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 07/17] shmat(): use mmap_find_vma to find free memor


From: riku . voipio
Subject: [Qemu-devel] [PATCH 07/17] shmat(): use mmap_find_vma to find free memory area
Date: Tue, 31 Mar 2009 23:40:39 +0300

From: Kirill A. Shutemov <address@hidden>

This patch depends on new implementation of mmap_find_vma().

Signed-off-by: Kirill A. Shutemov <address@hidden>
Signed-off-by: Riku Voipio <address@hidden>
---
 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 7ebb36d..b2ffe3a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2304,25 +2304,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));
@@ -2335,6 +2350,7 @@ static inline abi_long do_shmat(int shmid, abi_ulong 
shmaddr, int shmflg,
         }
     }
 
+    mmap_unlock();
     return 0;
 }
 
-- 
1.6.2.1





reply via email to

[Prev in Thread] Current Thread [Next in Thread]