Commit c8a706fe6242a553960ccc3071a4e75ceba6f3d2
1 parent
30813cea
Multithreaded locking for mmap().
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4654 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
98 additions
and
28 deletions
exec.c
@@ -234,6 +234,7 @@ static void page_init(void) | @@ -234,6 +234,7 @@ static void page_init(void) | ||
234 | FILE *f; | 234 | FILE *f; |
235 | int n; | 235 | int n; |
236 | 236 | ||
237 | + mmap_lock(); | ||
237 | last_brk = (unsigned long)sbrk(0); | 238 | last_brk = (unsigned long)sbrk(0); |
238 | f = fopen("/proc/self/maps", "r"); | 239 | f = fopen("/proc/self/maps", "r"); |
239 | if (f) { | 240 | if (f) { |
@@ -251,6 +252,7 @@ static void page_init(void) | @@ -251,6 +252,7 @@ static void page_init(void) | ||
251 | } while (!feof(f)); | 252 | } while (!feof(f)); |
252 | fclose(f); | 253 | fclose(f); |
253 | } | 254 | } |
255 | + mmap_unlock(); | ||
254 | } | 256 | } |
255 | #endif | 257 | #endif |
256 | } | 258 | } |
@@ -326,6 +328,8 @@ static inline PhysPageDesc *phys_page_find(target_phys_addr_t index) | @@ -326,6 +328,8 @@ static inline PhysPageDesc *phys_page_find(target_phys_addr_t index) | ||
326 | static void tlb_protect_code(ram_addr_t ram_addr); | 328 | static void tlb_protect_code(ram_addr_t ram_addr); |
327 | static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr, | 329 | static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr, |
328 | target_ulong vaddr); | 330 | target_ulong vaddr); |
331 | +#define mmap_lock() do { } while(0) | ||
332 | +#define mmap_unlock() do { } while(0) | ||
329 | #endif | 333 | #endif |
330 | 334 | ||
331 | #define DEFAULT_CODE_GEN_BUFFER_SIZE (32 * 1024 * 1024) | 335 | #define DEFAULT_CODE_GEN_BUFFER_SIZE (32 * 1024 * 1024) |
@@ -1049,6 +1053,9 @@ void tb_link_phys(TranslationBlock *tb, | @@ -1049,6 +1053,9 @@ void tb_link_phys(TranslationBlock *tb, | ||
1049 | unsigned int h; | 1053 | unsigned int h; |
1050 | TranslationBlock **ptb; | 1054 | TranslationBlock **ptb; |
1051 | 1055 | ||
1056 | + /* Grab the mmap lock to stop another thread invalidating this TB | ||
1057 | + before we are done. */ | ||
1058 | + mmap_lock(); | ||
1052 | /* add in the physical hash table */ | 1059 | /* add in the physical hash table */ |
1053 | h = tb_phys_hash_func(phys_pc); | 1060 | h = tb_phys_hash_func(phys_pc); |
1054 | ptb = &tb_phys_hash[h]; | 1061 | ptb = &tb_phys_hash[h]; |
@@ -1075,6 +1082,7 @@ void tb_link_phys(TranslationBlock *tb, | @@ -1075,6 +1082,7 @@ void tb_link_phys(TranslationBlock *tb, | ||
1075 | #ifdef DEBUG_TB_CHECK | 1082 | #ifdef DEBUG_TB_CHECK |
1076 | tb_page_check(); | 1083 | tb_page_check(); |
1077 | #endif | 1084 | #endif |
1085 | + mmap_unlock(); | ||
1078 | } | 1086 | } |
1079 | 1087 | ||
1080 | /* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr < | 1088 | /* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr < |
@@ -2002,6 +2010,7 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) | @@ -2002,6 +2010,7 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) | ||
2002 | PageDesc *p; | 2010 | PageDesc *p; |
2003 | target_ulong addr; | 2011 | target_ulong addr; |
2004 | 2012 | ||
2013 | + /* mmap_lock should already be held. */ | ||
2005 | start = start & TARGET_PAGE_MASK; | 2014 | start = start & TARGET_PAGE_MASK; |
2006 | end = TARGET_PAGE_ALIGN(end); | 2015 | end = TARGET_PAGE_ALIGN(end); |
2007 | if (flags & PAGE_WRITE) | 2016 | if (flags & PAGE_WRITE) |
@@ -2065,11 +2074,18 @@ int page_unprotect(target_ulong address, unsigned long pc, void *puc) | @@ -2065,11 +2074,18 @@ int page_unprotect(target_ulong address, unsigned long pc, void *puc) | ||
2065 | PageDesc *p, *p1; | 2074 | PageDesc *p, *p1; |
2066 | target_ulong host_start, host_end, addr; | 2075 | target_ulong host_start, host_end, addr; |
2067 | 2076 | ||
2077 | + /* Technically this isn't safe inside a signal handler. However we | ||
2078 | + know this only ever happens in a synchronous SEGV handler, so in | ||
2079 | + practice it seems to be ok. */ | ||
2080 | + mmap_lock(); | ||
2081 | + | ||
2068 | host_start = address & qemu_host_page_mask; | 2082 | host_start = address & qemu_host_page_mask; |
2069 | page_index = host_start >> TARGET_PAGE_BITS; | 2083 | page_index = host_start >> TARGET_PAGE_BITS; |
2070 | p1 = page_find(page_index); | 2084 | p1 = page_find(page_index); |
2071 | - if (!p1) | 2085 | + if (!p1) { |
2086 | + mmap_unlock(); | ||
2072 | return 0; | 2087 | return 0; |
2088 | + } | ||
2073 | host_end = host_start + qemu_host_page_size; | 2089 | host_end = host_start + qemu_host_page_size; |
2074 | p = p1; | 2090 | p = p1; |
2075 | prot = 0; | 2091 | prot = 0; |
@@ -2091,9 +2107,11 @@ int page_unprotect(target_ulong address, unsigned long pc, void *puc) | @@ -2091,9 +2107,11 @@ int page_unprotect(target_ulong address, unsigned long pc, void *puc) | ||
2091 | #ifdef DEBUG_TB_CHECK | 2107 | #ifdef DEBUG_TB_CHECK |
2092 | tb_invalidate_check(address); | 2108 | tb_invalidate_check(address); |
2093 | #endif | 2109 | #endif |
2110 | + mmap_unlock(); | ||
2094 | return 1; | 2111 | return 1; |
2095 | } | 2112 | } |
2096 | } | 2113 | } |
2114 | + mmap_unlock(); | ||
2097 | return 0; | 2115 | return 0; |
2098 | } | 2116 | } |
2099 | 2117 |
linux-user/mmap.c
@@ -29,6 +29,34 @@ | @@ -29,6 +29,34 @@ | ||
29 | 29 | ||
30 | //#define DEBUG_MMAP | 30 | //#define DEBUG_MMAP |
31 | 31 | ||
32 | +#if defined(USE_NPTL) | ||
33 | +pthread_mutex_t mmap_mutex; | ||
34 | +static int __thread mmap_lock_count; | ||
35 | + | ||
36 | +void mmap_lock(void) | ||
37 | +{ | ||
38 | + if (mmap_lock_count++ == 0) { | ||
39 | + pthread_mutex_lock(&mmap_mutex); | ||
40 | + } | ||
41 | +} | ||
42 | + | ||
43 | +void mmap_unlock(void) | ||
44 | +{ | ||
45 | + if (--mmap_lock_count == 0) { | ||
46 | + pthread_mutex_unlock(&mmap_mutex); | ||
47 | + } | ||
48 | +} | ||
49 | +#else | ||
50 | +/* We aren't threadsafe to start with, so no need to worry about locking. */ | ||
51 | +void mmap_lock(void) | ||
52 | +{ | ||
53 | +} | ||
54 | + | ||
55 | +void mmap_unlock(void) | ||
56 | +{ | ||
57 | +} | ||
58 | +#endif | ||
59 | + | ||
32 | /* NOTE: all the constants are the HOST ones, but addresses are target. */ | 60 | /* NOTE: all the constants are the HOST ones, but addresses are target. */ |
33 | int target_mprotect(abi_ulong start, abi_ulong len, int prot) | 61 | int target_mprotect(abi_ulong start, abi_ulong len, int prot) |
34 | { | 62 | { |
@@ -53,6 +81,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot) | @@ -53,6 +81,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot) | ||
53 | if (len == 0) | 81 | if (len == 0) |
54 | return 0; | 82 | return 0; |
55 | 83 | ||
84 | + mmap_lock(); | ||
56 | host_start = start & qemu_host_page_mask; | 85 | host_start = start & qemu_host_page_mask; |
57 | host_end = HOST_PAGE_ALIGN(end); | 86 | host_end = HOST_PAGE_ALIGN(end); |
58 | if (start > host_start) { | 87 | if (start > host_start) { |
@@ -69,7 +98,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot) | @@ -69,7 +98,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot) | ||
69 | } | 98 | } |
70 | ret = mprotect(g2h(host_start), qemu_host_page_size, prot1 & PAGE_BITS); | 99 | ret = mprotect(g2h(host_start), qemu_host_page_size, prot1 & PAGE_BITS); |
71 | if (ret != 0) | 100 | if (ret != 0) |
72 | - return ret; | 101 | + goto error; |
73 | host_start += qemu_host_page_size; | 102 | host_start += qemu_host_page_size; |
74 | } | 103 | } |
75 | if (end < host_end) { | 104 | if (end < host_end) { |
@@ -80,7 +109,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot) | @@ -80,7 +109,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot) | ||
80 | ret = mprotect(g2h(host_end - qemu_host_page_size), qemu_host_page_size, | 109 | ret = mprotect(g2h(host_end - qemu_host_page_size), qemu_host_page_size, |
81 | prot1 & PAGE_BITS); | 110 | prot1 & PAGE_BITS); |
82 | if (ret != 0) | 111 | if (ret != 0) |
83 | - return ret; | 112 | + goto error; |
84 | host_end -= qemu_host_page_size; | 113 | host_end -= qemu_host_page_size; |
85 | } | 114 | } |
86 | 115 | ||
@@ -88,10 +117,14 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot) | @@ -88,10 +117,14 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot) | ||
88 | if (host_start < host_end) { | 117 | if (host_start < host_end) { |
89 | ret = mprotect(g2h(host_start), host_end - host_start, prot); | 118 | ret = mprotect(g2h(host_start), host_end - host_start, prot); |
90 | if (ret != 0) | 119 | if (ret != 0) |
91 | - return ret; | 120 | + goto error; |
92 | } | 121 | } |
93 | page_set_flags(start, start + len, prot | PAGE_VALID); | 122 | page_set_flags(start, start + len, prot | PAGE_VALID); |
123 | + mmap_unlock(); | ||
94 | return 0; | 124 | return 0; |
125 | +error: | ||
126 | + mmap_unlock(); | ||
127 | + return ret; | ||
95 | } | 128 | } |
96 | 129 | ||
97 | /* map an incomplete host page */ | 130 | /* map an incomplete host page */ |
@@ -214,6 +247,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | @@ -214,6 +247,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | ||
214 | abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len; | 247 | abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len; |
215 | unsigned long host_start; | 248 | unsigned long host_start; |
216 | 249 | ||
250 | + mmap_lock(); | ||
217 | #ifdef DEBUG_MMAP | 251 | #ifdef DEBUG_MMAP |
218 | { | 252 | { |
219 | printf("mmap: start=0x" TARGET_FMT_lx | 253 | printf("mmap: start=0x" TARGET_FMT_lx |
@@ -243,12 +277,12 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | @@ -243,12 +277,12 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | ||
243 | 277 | ||
244 | if (offset & ~TARGET_PAGE_MASK) { | 278 | if (offset & ~TARGET_PAGE_MASK) { |
245 | errno = EINVAL; | 279 | errno = EINVAL; |
246 | - return -1; | 280 | + goto fail; |
247 | } | 281 | } |
248 | 282 | ||
249 | len = TARGET_PAGE_ALIGN(len); | 283 | len = TARGET_PAGE_ALIGN(len); |
250 | if (len == 0) | 284 | if (len == 0) |
251 | - return start; | 285 | + goto the_end; |
252 | real_start = start & qemu_host_page_mask; | 286 | real_start = start & qemu_host_page_mask; |
253 | 287 | ||
254 | if (!(flags & MAP_FIXED)) { | 288 | if (!(flags & MAP_FIXED)) { |
@@ -260,7 +294,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | @@ -260,7 +294,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | ||
260 | mmap_start = mmap_find_vma(real_start, host_len); | 294 | mmap_start = mmap_find_vma(real_start, host_len); |
261 | if (mmap_start == (abi_ulong)-1) { | 295 | if (mmap_start == (abi_ulong)-1) { |
262 | errno = ENOMEM; | 296 | errno = ENOMEM; |
263 | - return -1; | 297 | + goto fail; |
264 | } | 298 | } |
265 | /* Note: we prefer to control the mapping address. It is | 299 | /* Note: we prefer to control the mapping address. It is |
266 | especially important if qemu_host_page_size > | 300 | especially important if qemu_host_page_size > |
@@ -268,7 +302,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | @@ -268,7 +302,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | ||
268 | p = mmap(g2h(mmap_start), | 302 | p = mmap(g2h(mmap_start), |
269 | host_len, prot, flags | MAP_FIXED, fd, host_offset); | 303 | host_len, prot, flags | MAP_FIXED, fd, host_offset); |
270 | if (p == MAP_FAILED) | 304 | if (p == MAP_FAILED) |
271 | - return -1; | 305 | + goto fail; |
272 | /* update start so that it points to the file position at 'offset' */ | 306 | /* update start so that it points to the file position at 'offset' */ |
273 | host_start = (unsigned long)p; | 307 | host_start = (unsigned long)p; |
274 | if (!(flags & MAP_ANONYMOUS)) | 308 | if (!(flags & MAP_ANONYMOUS)) |
@@ -280,7 +314,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | @@ -280,7 +314,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | ||
280 | 314 | ||
281 | if (start & ~TARGET_PAGE_MASK) { | 315 | if (start & ~TARGET_PAGE_MASK) { |
282 | errno = EINVAL; | 316 | errno = EINVAL; |
283 | - return -1; | 317 | + goto fail; |
284 | } | 318 | } |
285 | end = start + len; | 319 | end = start + len; |
286 | real_end = HOST_PAGE_ALIGN(end); | 320 | real_end = HOST_PAGE_ALIGN(end); |
@@ -289,7 +323,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | @@ -289,7 +323,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | ||
289 | flg = page_get_flags(addr); | 323 | flg = page_get_flags(addr); |
290 | if (flg & PAGE_RESERVED) { | 324 | if (flg & PAGE_RESERVED) { |
291 | errno = ENXIO; | 325 | errno = ENXIO; |
292 | - return -1; | 326 | + goto fail; |
293 | } | 327 | } |
294 | } | 328 | } |
295 | 329 | ||
@@ -302,18 +336,20 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | @@ -302,18 +336,20 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | ||
302 | if ((flags & MAP_TYPE) == MAP_SHARED && | 336 | if ((flags & MAP_TYPE) == MAP_SHARED && |
303 | (prot & PROT_WRITE)) { | 337 | (prot & PROT_WRITE)) { |
304 | errno = EINVAL; | 338 | errno = EINVAL; |
305 | - return -1; | 339 | + goto fail; |
306 | } | 340 | } |
307 | retaddr = target_mmap(start, len, prot | PROT_WRITE, | 341 | retaddr = target_mmap(start, len, prot | PROT_WRITE, |
308 | MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, | 342 | MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, |
309 | -1, 0); | 343 | -1, 0); |
310 | if (retaddr == -1) | 344 | if (retaddr == -1) |
311 | - return -1; | 345 | + goto fail; |
312 | pread(fd, g2h(start), len, offset); | 346 | pread(fd, g2h(start), len, offset); |
313 | if (!(prot & PROT_WRITE)) { | 347 | if (!(prot & PROT_WRITE)) { |
314 | ret = target_mprotect(start, len, prot); | 348 | ret = target_mprotect(start, len, prot); |
315 | - if (ret != 0) | ||
316 | - return ret; | 349 | + if (ret != 0) { |
350 | + start = ret; | ||
351 | + goto the_end; | ||
352 | + } | ||
317 | } | 353 | } |
318 | goto the_end; | 354 | goto the_end; |
319 | } | 355 | } |
@@ -325,13 +361,13 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | @@ -325,13 +361,13 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | ||
325 | ret = mmap_frag(real_start, start, end, | 361 | ret = mmap_frag(real_start, start, end, |
326 | prot, flags, fd, offset); | 362 | prot, flags, fd, offset); |
327 | if (ret == -1) | 363 | if (ret == -1) |
328 | - return ret; | 364 | + goto fail; |
329 | goto the_end1; | 365 | goto the_end1; |
330 | } | 366 | } |
331 | ret = mmap_frag(real_start, start, real_start + qemu_host_page_size, | 367 | ret = mmap_frag(real_start, start, real_start + qemu_host_page_size, |
332 | prot, flags, fd, offset); | 368 | prot, flags, fd, offset); |
333 | if (ret == -1) | 369 | if (ret == -1) |
334 | - return ret; | 370 | + goto fail; |
335 | real_start += qemu_host_page_size; | 371 | real_start += qemu_host_page_size; |
336 | } | 372 | } |
337 | /* handle the end of the mapping */ | 373 | /* handle the end of the mapping */ |
@@ -341,7 +377,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | @@ -341,7 +377,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | ||
341 | prot, flags, fd, | 377 | prot, flags, fd, |
342 | offset + real_end - qemu_host_page_size - start); | 378 | offset + real_end - qemu_host_page_size - start); |
343 | if (ret == -1) | 379 | if (ret == -1) |
344 | - return -1; | 380 | + goto fail; |
345 | real_end -= qemu_host_page_size; | 381 | real_end -= qemu_host_page_size; |
346 | } | 382 | } |
347 | 383 | ||
@@ -356,7 +392,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | @@ -356,7 +392,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | ||
356 | p = mmap(g2h(real_start), real_end - real_start, | 392 | p = mmap(g2h(real_start), real_end - real_start, |
357 | prot, flags, fd, offset1); | 393 | prot, flags, fd, offset1); |
358 | if (p == MAP_FAILED) | 394 | if (p == MAP_FAILED) |
359 | - return -1; | 395 | + goto fail; |
360 | } | 396 | } |
361 | } | 397 | } |
362 | the_end1: | 398 | the_end1: |
@@ -367,7 +403,11 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | @@ -367,7 +403,11 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, | ||
367 | page_dump(stdout); | 403 | page_dump(stdout); |
368 | printf("\n"); | 404 | printf("\n"); |
369 | #endif | 405 | #endif |
406 | + mmap_unlock(); | ||
370 | return start; | 407 | return start; |
408 | +fail: | ||
409 | + mmap_unlock(); | ||
410 | + return -1; | ||
371 | } | 411 | } |
372 | 412 | ||
373 | int target_munmap(abi_ulong start, abi_ulong len) | 413 | int target_munmap(abi_ulong start, abi_ulong len) |
@@ -383,6 +423,7 @@ int target_munmap(abi_ulong start, abi_ulong len) | @@ -383,6 +423,7 @@ int target_munmap(abi_ulong start, abi_ulong len) | ||
383 | len = TARGET_PAGE_ALIGN(len); | 423 | len = TARGET_PAGE_ALIGN(len); |
384 | if (len == 0) | 424 | if (len == 0) |
385 | return -EINVAL; | 425 | return -EINVAL; |
426 | + mmap_lock(); | ||
386 | end = start + len; | 427 | end = start + len; |
387 | real_start = start & qemu_host_page_mask; | 428 | real_start = start & qemu_host_page_mask; |
388 | real_end = HOST_PAGE_ALIGN(end); | 429 | real_end = HOST_PAGE_ALIGN(end); |
@@ -411,15 +452,16 @@ int target_munmap(abi_ulong start, abi_ulong len) | @@ -411,15 +452,16 @@ int target_munmap(abi_ulong start, abi_ulong len) | ||
411 | real_end -= qemu_host_page_size; | 452 | real_end -= qemu_host_page_size; |
412 | } | 453 | } |
413 | 454 | ||
455 | + ret = 0; | ||
414 | /* unmap what we can */ | 456 | /* unmap what we can */ |
415 | if (real_start < real_end) { | 457 | if (real_start < real_end) { |
416 | ret = munmap(g2h(real_start), real_end - real_start); | 458 | ret = munmap(g2h(real_start), real_end - real_start); |
417 | - if (ret != 0) | ||
418 | - return ret; | ||
419 | } | 459 | } |
420 | 460 | ||
421 | - page_set_flags(start, start + len, 0); | ||
422 | - return 0; | 461 | + if (ret == 0) |
462 | + page_set_flags(start, start + len, 0); | ||
463 | + mmap_unlock(); | ||
464 | + return ret; | ||
423 | } | 465 | } |
424 | 466 | ||
425 | /* XXX: currently, we only handle MAP_ANONYMOUS and not MAP_FIXED | 467 | /* XXX: currently, we only handle MAP_ANONYMOUS and not MAP_FIXED |
@@ -431,14 +473,18 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, | @@ -431,14 +473,18 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, | ||
431 | int prot; | 473 | int prot; |
432 | unsigned long host_addr; | 474 | unsigned long host_addr; |
433 | 475 | ||
476 | + mmap_lock(); | ||
434 | /* XXX: use 5 args syscall */ | 477 | /* XXX: use 5 args syscall */ |
435 | host_addr = (long)mremap(g2h(old_addr), old_size, new_size, flags); | 478 | host_addr = (long)mremap(g2h(old_addr), old_size, new_size, flags); |
436 | - if (host_addr == -1) | ||
437 | - return -1; | ||
438 | - new_addr = h2g(host_addr); | ||
439 | - prot = page_get_flags(old_addr); | ||
440 | - page_set_flags(old_addr, old_addr + old_size, 0); | ||
441 | - page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID); | 479 | + if (host_addr == -1) { |
480 | + new_addr = -1; | ||
481 | + } else { | ||
482 | + new_addr = h2g(host_addr); | ||
483 | + prot = page_get_flags(old_addr); | ||
484 | + page_set_flags(old_addr, old_addr + old_size, 0); | ||
485 | + page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID); | ||
486 | + } | ||
487 | + mmap_unlock(); | ||
442 | return new_addr; | 488 | return new_addr; |
443 | } | 489 | } |
444 | 490 |
linux-user/qemu.h
@@ -233,6 +233,8 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, | @@ -233,6 +233,8 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, | ||
233 | abi_ulong new_addr); | 233 | abi_ulong new_addr); |
234 | int target_msync(abi_ulong start, abi_ulong len, int flags); | 234 | int target_msync(abi_ulong start, abi_ulong len, int flags); |
235 | extern unsigned long last_brk; | 235 | extern unsigned long last_brk; |
236 | +void mmap_lock(void); | ||
237 | +void mmap_unlock(void); | ||
236 | 238 | ||
237 | /* user access */ | 239 | /* user access */ |
238 | 240 | ||
@@ -423,4 +425,8 @@ static inline void *lock_user_string(abi_ulong guest_addr) | @@ -423,4 +425,8 @@ static inline void *lock_user_string(abi_ulong guest_addr) | ||
423 | #define unlock_user_struct(host_ptr, guest_addr, copy) \ | 425 | #define unlock_user_struct(host_ptr, guest_addr, copy) \ |
424 | unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0) | 426 | unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0) |
425 | 427 | ||
428 | +#if defined(USE_NPTL) | ||
429 | +#include <pthread.h> | ||
430 | +#endif | ||
431 | + | ||
426 | #endif /* QEMU_H */ | 432 | #endif /* QEMU_H */ |