Commit d418c81eff3ca1b7cdb3c6d09b9b7ecc9becdd41
1 parent
2a29ca73
fixed small page handling
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@160 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
17 additions
and
6 deletions
linux-user/mmap.c
| ... | ... | @@ -61,13 +61,18 @@ int target_mprotect(unsigned long start, unsigned long len, int prot) |
| 61 | 61 | for(addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) { |
| 62 | 62 | prot1 |= page_get_flags(addr); |
| 63 | 63 | } |
| 64 | + if (host_end == host_start + host_page_size) { | |
| 65 | + for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) { | |
| 66 | + prot1 |= page_get_flags(addr); | |
| 67 | + } | |
| 68 | + end = host_end; | |
| 69 | + } | |
| 64 | 70 | ret = mprotect((void *)host_start, host_page_size, prot1 & PAGE_BITS); |
| 65 | 71 | if (ret != 0) |
| 66 | 72 | return ret; |
| 67 | 73 | host_start += host_page_size; |
| 68 | 74 | } |
| 69 | 75 | if (end < host_end) { |
| 70 | - /* handle host page containing end (can be the same as first page) */ | |
| 71 | 76 | prot1 = prot; |
| 72 | 77 | for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) { |
| 73 | 78 | prot1 |= page_get_flags(addr); |
| ... | ... | @@ -85,7 +90,6 @@ int target_mprotect(unsigned long start, unsigned long len, int prot) |
| 85 | 90 | if (ret != 0) |
| 86 | 91 | return ret; |
| 87 | 92 | } |
| 88 | - | |
| 89 | 93 | page_set_flags(start, start + len, prot | PAGE_VALID); |
| 90 | 94 | return 0; |
| 91 | 95 | } |
| ... | ... | @@ -311,11 +315,16 @@ int target_munmap(unsigned long start, unsigned long len) |
| 311 | 315 | for(addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) { |
| 312 | 316 | prot |= page_get_flags(addr); |
| 313 | 317 | } |
| 318 | + if (host_end == host_start + host_page_size) { | |
| 319 | + for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) { | |
| 320 | + prot |= page_get_flags(addr); | |
| 321 | + } | |
| 322 | + end = host_end; | |
| 323 | + } | |
| 314 | 324 | if (prot != 0) |
| 315 | 325 | host_start += host_page_size; |
| 316 | 326 | } |
| 317 | 327 | if (end < host_end) { |
| 318 | - /* handle host page containing end (can be the same as first page) */ | |
| 319 | 328 | prot = 0; |
| 320 | 329 | for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) { |
| 321 | 330 | prot |= page_get_flags(addr); |
| ... | ... | @@ -360,11 +369,13 @@ int target_msync(unsigned long start, unsigned long len, int flags) |
| 360 | 369 | if (start & ~TARGET_PAGE_MASK) |
| 361 | 370 | return -EINVAL; |
| 362 | 371 | len = TARGET_PAGE_ALIGN(len); |
| 363 | - if (len == 0) | |
| 364 | - return 0; | |
| 365 | 372 | end = start + len; |
| 373 | + if (end < start) | |
| 374 | + return -EINVAL; | |
| 375 | + if (end == start) | |
| 376 | + return 0; | |
| 366 | 377 | |
| 367 | 378 | start &= host_page_mask; |
| 368 | - return msync((void *)start, len, flags); | |
| 379 | + return msync((void *)start, end - start, flags); | |
| 369 | 380 | } |
| 370 | 381 | ... | ... |