|
| 1 | +diff --git a/linux-user/mmap.c b/linux-user/mmap.c |
| 2 | +index 4c5fe832ad..e1ed9085c7 100644 |
| 3 | +--- a/linux-user/mmap.c |
| 4 | ++++ b/linux-user/mmap.c |
| 5 | +@@ -1014,59 +1014,38 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot, |
| 6 | + static int mmap_reserve_or_unmap(abi_ulong start, abi_ulong len) |
| 7 | + { |
| 8 | + int host_page_size = qemu_real_host_page_size(); |
| 9 | ++ abi_ulong end; |
| 10 | + abi_ulong real_start; |
| 11 | +- abi_ulong real_last; |
| 12 | +- abi_ulong real_len; |
| 13 | +- abi_ulong last; |
| 14 | +- abi_ulong a; |
| 15 | ++ abi_ulong real_end; |
| 16 | ++ abi_ulong off; |
| 17 | + void *host_start; |
| 18 | + int prot; |
| 19 | + |
| 20 | +- last = start + len - 1; |
| 21 | ++ end = ROUND_UP(start + len, TARGET_PAGE_SIZE); |
| 22 | ++ |
| 23 | + real_start = start & -host_page_size; |
| 24 | +- real_last = ROUND_UP(last, host_page_size) - 1; |
| 25 | ++ real_end = ROUND_UP(end, host_page_size); |
| 26 | + |
| 27 | +- /* |
| 28 | +- * If guest pages remain on the first or last host pages, |
| 29 | +- * adjust the deallocation to retain those guest pages. |
| 30 | +- * The single page special case is required for the last page, |
| 31 | +- * lest real_start overflow to zero. |
| 32 | +- */ |
| 33 | +- if (real_last - real_start < host_page_size) { |
| 34 | +- prot = 0; |
| 35 | +- for (a = real_start; a < start; a += TARGET_PAGE_SIZE) { |
| 36 | +- prot |= page_get_flags(a); |
| 37 | +- } |
| 38 | +- for (a = last; a < real_last; a += TARGET_PAGE_SIZE) { |
| 39 | +- prot |= page_get_flags(a + 1); |
| 40 | +- } |
| 41 | +- if (prot != 0) { |
| 42 | +- return 0; |
| 43 | +- } |
| 44 | +- } else { |
| 45 | +- for (prot = 0, a = real_start; a < start; a += TARGET_PAGE_SIZE) { |
| 46 | +- prot |= page_get_flags(a); |
| 47 | +- } |
| 48 | +- if (prot != 0) { |
| 49 | +- real_start += host_page_size; |
| 50 | +- } |
| 51 | ++ /* end or real_end may have overflowed to 0, but that's okay. */ |
| 52 | + |
| 53 | +- for (prot = 0, a = last; a < real_last; a += TARGET_PAGE_SIZE) { |
| 54 | +- prot |= page_get_flags(a + 1); |
| 55 | +- } |
| 56 | +- if (prot != 0) { |
| 57 | +- real_last -= host_page_size; |
| 58 | +- } |
| 59 | ++ /* If [real_start,start) contains a mapped guest page, retain the first page. */ |
| 60 | ++ for (prot = 0, off = 0; off < start - real_start; off += TARGET_PAGE_SIZE) { |
| 61 | ++ prot |= page_get_flags(real_start + off); |
| 62 | ++ } |
| 63 | ++ if (prot != 0) { |
| 64 | ++ real_start += host_page_size; |
| 65 | ++ } |
| 66 | + |
| 67 | +- if (real_last < real_start) { |
| 68 | +- return 0; |
| 69 | +- } |
| 70 | ++ /* If [end,real_end) contains a mapped guest page, retain the last page. */ |
| 71 | ++ for (prot = 0, off = 0; off < real_end - end; off += TARGET_PAGE_SIZE) { |
| 72 | ++ prot |= page_get_flags(end + off); |
| 73 | ++ } |
| 74 | ++ if (prot != 0) { |
| 75 | ++ real_end -= host_page_size; |
| 76 | + } |
| 77 | + |
| 78 | +- real_len = real_last - real_start + 1; |
| 79 | + host_start = g2h_untagged(real_start); |
| 80 | +- |
| 81 | +- return do_munmap(host_start, real_len); |
| 82 | ++ return do_munmap(host_start, real_end - real_start); |
| 83 | + } |
| 84 | + |
| 85 | + int target_munmap(abi_ulong start, abi_ulong len) |
0 commit comments