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,13 +61,18 @@ int target_mprotect(unsigned long start, unsigned long len, int prot) | ||
| 61 | for(addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) { | 61 | for(addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) { |
| 62 | prot1 |= page_get_flags(addr); | 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 | ret = mprotect((void *)host_start, host_page_size, prot1 & PAGE_BITS); | 70 | ret = mprotect((void *)host_start, host_page_size, prot1 & PAGE_BITS); |
| 65 | if (ret != 0) | 71 | if (ret != 0) |
| 66 | return ret; | 72 | return ret; |
| 67 | host_start += host_page_size; | 73 | host_start += host_page_size; |
| 68 | } | 74 | } |
| 69 | if (end < host_end) { | 75 | if (end < host_end) { |
| 70 | - /* handle host page containing end (can be the same as first page) */ | ||
| 71 | prot1 = prot; | 76 | prot1 = prot; |
| 72 | for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) { | 77 | for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) { |
| 73 | prot1 |= page_get_flags(addr); | 78 | prot1 |= page_get_flags(addr); |
| @@ -85,7 +90,6 @@ int target_mprotect(unsigned long start, unsigned long len, int prot) | @@ -85,7 +90,6 @@ int target_mprotect(unsigned long start, unsigned long len, int prot) | ||
| 85 | if (ret != 0) | 90 | if (ret != 0) |
| 86 | return ret; | 91 | return ret; |
| 87 | } | 92 | } |
| 88 | - | ||
| 89 | page_set_flags(start, start + len, prot | PAGE_VALID); | 93 | page_set_flags(start, start + len, prot | PAGE_VALID); |
| 90 | return 0; | 94 | return 0; |
| 91 | } | 95 | } |
| @@ -311,11 +315,16 @@ int target_munmap(unsigned long start, unsigned long len) | @@ -311,11 +315,16 @@ int target_munmap(unsigned long start, unsigned long len) | ||
| 311 | for(addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) { | 315 | for(addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) { |
| 312 | prot |= page_get_flags(addr); | 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 | if (prot != 0) | 324 | if (prot != 0) |
| 315 | host_start += host_page_size; | 325 | host_start += host_page_size; |
| 316 | } | 326 | } |
| 317 | if (end < host_end) { | 327 | if (end < host_end) { |
| 318 | - /* handle host page containing end (can be the same as first page) */ | ||
| 319 | prot = 0; | 328 | prot = 0; |
| 320 | for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) { | 329 | for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) { |
| 321 | prot |= page_get_flags(addr); | 330 | prot |= page_get_flags(addr); |
| @@ -360,11 +369,13 @@ int target_msync(unsigned long start, unsigned long len, int flags) | @@ -360,11 +369,13 @@ int target_msync(unsigned long start, unsigned long len, int flags) | ||
| 360 | if (start & ~TARGET_PAGE_MASK) | 369 | if (start & ~TARGET_PAGE_MASK) |
| 361 | return -EINVAL; | 370 | return -EINVAL; |
| 362 | len = TARGET_PAGE_ALIGN(len); | 371 | len = TARGET_PAGE_ALIGN(len); |
| 363 | - if (len == 0) | ||
| 364 | - return 0; | ||
| 365 | end = start + len; | 372 | end = start + len; |
| 373 | + if (end < start) | ||
| 374 | + return -EINVAL; | ||
| 375 | + if (end == start) | ||
| 376 | + return 0; | ||
| 366 | 377 | ||
| 367 | start &= host_page_mask; | 378 | start &= host_page_mask; |
| 368 | - return msync((void *)start, len, flags); | 379 | + return msync((void *)start, end - start, flags); |
| 369 | } | 380 | } |
| 370 | 381 |