[prev in list] [next in list] [prev in thread] [next in thread]
List: qemu-devel
Subject: [Qemu-devel] [PATCH 07/17] shmat(): use mmap_find_vma to find free
From: riku.voipio () iki ! fi
Date: 2009-03-31 20:40:39
Message-ID: 86d08b42c01686f7c71d679170a17ab0e90f1f32.1238531009.git.riku.voipio () iki ! fi
[Download RAW message or body]
From: Kirill A. Shutemov <kirill@shutemov.name>
This patch depends on new implementation of mmap_find_vma().
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
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
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic