* [PATCH v2] linux-user: Undo incomplete mmap
@ 2023-09-03 5:39 Akihiko Odaki
2023-09-21 7:09 ` Akihiko Odaki
0 siblings, 1 reply; 4+ messages in thread
From: Akihiko Odaki @ 2023-09-03 5:39 UTC (permalink / raw)
Cc: Richard Henderson, qemu-devel, joel, laurent, deller,
Akihiko Odaki
When the host page size is greater than the target page size and
MAP_FIXED or MAP_FIXED_NOREPLACE is requested, mmap will be done for
three parts: start, middle, and end. If a later part of mmap fail,
mmap done in the earlier parts must be reverted.
Fixes: 54936004fd ("mmap emulation")
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
V1 -> V2: Rebased.
linux-user/mmap.c | 65 +++++++++++++++++++++++++++++------------------
1 file changed, 40 insertions(+), 25 deletions(-)
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 9aab48d4a3..72521f8d27 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -224,13 +224,15 @@ int target_mprotect(abi_ulong start, abi_ulong len, int target_prot)
/* map an incomplete host page */
static bool mmap_frag(abi_ulong real_start, abi_ulong start, abi_ulong last,
- int prot, int flags, int fd, off_t offset)
+ int prot, int flags, int fd, off_t offset, bool *mapped)
{
abi_ulong real_last;
void *host_start;
int prot_old, prot_new;
int host_prot_old, host_prot_new;
+ *mapped = false;
+
if (!(flags & MAP_ANONYMOUS)
&& (flags & MAP_TYPE) == MAP_SHARED
&& (prot & PROT_WRITE)) {
@@ -271,6 +273,7 @@ static bool mmap_frag(abi_ulong real_start, abi_ulong start, abi_ulong last,
return false;
}
prot_old = prot;
+ *mapped = true;
}
prot_new = prot | prot_old;
@@ -448,7 +451,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong align)
abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
int flags, int fd, off_t offset)
{
- abi_ulong ret, last, real_start, real_last, retaddr, host_len;
+ abi_ulong ret, last, real_start, retaddr, host_len;
abi_ulong passthrough_start = -1, passthrough_last = 0;
int page_flags;
off_t host_offset;
@@ -577,12 +580,16 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
passthrough_start = start;
passthrough_last = last;
} else {
+ abi_ulong middle_start = HOST_PAGE_ALIGN(start);
+ abi_ulong middle_last = ((start + len) & qemu_host_page_mask) - 1;
+ abi_ulong mapped_len = 0;
+ bool mapped;
+
if (start & ~TARGET_PAGE_MASK) {
errno = EINVAL;
goto fail;
}
last = start + len - 1;
- real_last = HOST_PAGE_ALIGN(last) - 1;
/*
* Test if requested memory area fits target address space
@@ -649,35 +656,26 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
}
/* handle the start of the mapping */
- if (start > real_start) {
- if (real_last == real_start + qemu_host_page_size - 1) {
+ if (start < middle_start) {
+ if (last < middle_start) {
/* one single host page */
if (!mmap_frag(real_start, start, last,
- target_prot, flags, fd, offset)) {
+ target_prot, flags, fd, offset, &mapped)) {
goto fail;
}
goto the_end1;
}
- if (!mmap_frag(real_start, start,
- real_start + qemu_host_page_size - 1,
- target_prot, flags, fd, offset)) {
+ if (!mmap_frag(real_start, start, middle_start - 1,
+ target_prot, flags, fd, offset, &mapped)) {
goto fail;
}
- real_start += qemu_host_page_size;
- }
- /* handle the end of the mapping */
- if (last < real_last) {
- abi_ulong real_page = real_last - qemu_host_page_size + 1;
- if (!mmap_frag(real_page, real_page, last,
- target_prot, flags, fd,
- offset + real_page - start)) {
- goto fail;
+ if (mapped) {
+ mapped_len = qemu_host_page_size;
}
- real_last -= qemu_host_page_size;
}
/* map the middle (easier) */
- if (real_start < real_last) {
+ if (middle_start < middle_last) {
void *p, *want_p;
off_t offset1;
size_t len1;
@@ -685,10 +683,10 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
if (flags & MAP_ANONYMOUS) {
offset1 = 0;
} else {
- offset1 = offset + real_start - start;
+ offset1 = offset + middle_start - start;
}
- len1 = real_last - real_start + 1;
- want_p = g2h_untagged(real_start);
+ len1 = middle_last - middle_start + 1;
+ want_p = g2h_untagged(middle_start);
p = mmap(want_p, len1, target_to_host_prot(target_prot),
flags, fd, offset1);
@@ -697,10 +695,27 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
munmap(p, len1);
errno = EEXIST;
}
+ if (mapped_len) {
+ munmap(g2h_untagged(middle_start - mapped_len), mapped_len);
+ }
+ goto fail;
+ }
+ mapped_len += len1;
+ passthrough_start = middle_start;
+ passthrough_last = middle_last;
+ }
+
+ /* handle the end of the mapping */
+ if (last > middle_last) {
+ abi_ulong real_page = middle_last + 1;
+ if (!mmap_frag(real_page, real_page, last,
+ target_prot, flags, fd,
+ offset + real_page - start, &mapped)) {
+ if (mapped_len) {
+ munmap(g2h_untagged(real_page - mapped_len), mapped_len);
+ }
goto fail;
}
- passthrough_start = real_start;
- passthrough_last = real_last;
}
}
the_end1:
--
2.42.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v2] linux-user: Undo incomplete mmap
2023-09-03 5:39 [PATCH v2] linux-user: Undo incomplete mmap Akihiko Odaki
@ 2023-09-21 7:09 ` Akihiko Odaki
2023-10-03 20:42 ` Richard Henderson
0 siblings, 1 reply; 4+ messages in thread
From: Akihiko Odaki @ 2023-09-21 7:09 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel, joel, laurent, deller
On 2023/09/03 14:39, Akihiko Odaki wrote:
> When the host page size is greater than the target page size and
> MAP_FIXED or MAP_FIXED_NOREPLACE is requested, mmap will be done for
> three parts: start, middle, and end. If a later part of mmap fail,
> mmap done in the earlier parts must be reverted.
>
> Fixes: 54936004fd ("mmap emulation")
> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
> ---
> V1 -> V2: Rebased.
>
> linux-user/mmap.c | 65 +++++++++++++++++++++++++++++------------------
> 1 file changed, 40 insertions(+), 25 deletions(-)
>
> diff --git a/linux-user/mmap.c b/linux-user/mmap.c
> index 9aab48d4a3..72521f8d27 100644
> --- a/linux-user/mmap.c
> +++ b/linux-user/mmap.c
> @@ -224,13 +224,15 @@ int target_mprotect(abi_ulong start, abi_ulong len, int target_prot)
>
> /* map an incomplete host page */
> static bool mmap_frag(abi_ulong real_start, abi_ulong start, abi_ulong last,
> - int prot, int flags, int fd, off_t offset)
> + int prot, int flags, int fd, off_t offset, bool *mapped)
> {
> abi_ulong real_last;
> void *host_start;
> int prot_old, prot_new;
> int host_prot_old, host_prot_new;
>
> + *mapped = false;
> +
> if (!(flags & MAP_ANONYMOUS)
> && (flags & MAP_TYPE) == MAP_SHARED
> && (prot & PROT_WRITE)) {
> @@ -271,6 +273,7 @@ static bool mmap_frag(abi_ulong real_start, abi_ulong start, abi_ulong last,
> return false;
> }
> prot_old = prot;
> + *mapped = true;
> }
> prot_new = prot | prot_old;
>
> @@ -448,7 +451,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong align)
> abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
> int flags, int fd, off_t offset)
> {
> - abi_ulong ret, last, real_start, real_last, retaddr, host_len;
> + abi_ulong ret, last, real_start, retaddr, host_len;
> abi_ulong passthrough_start = -1, passthrough_last = 0;
> int page_flags;
> off_t host_offset;
> @@ -577,12 +580,16 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
> passthrough_start = start;
> passthrough_last = last;
> } else {
> + abi_ulong middle_start = HOST_PAGE_ALIGN(start);
> + abi_ulong middle_last = ((start + len) & qemu_host_page_mask) - 1;
> + abi_ulong mapped_len = 0;
> + bool mapped;
> +
> if (start & ~TARGET_PAGE_MASK) {
> errno = EINVAL;
> goto fail;
> }
> last = start + len - 1;
> - real_last = HOST_PAGE_ALIGN(last) - 1;
>
> /*
> * Test if requested memory area fits target address space
> @@ -649,35 +656,26 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
> }
>
> /* handle the start of the mapping */
> - if (start > real_start) {
> - if (real_last == real_start + qemu_host_page_size - 1) {
> + if (start < middle_start) {
> + if (last < middle_start) {
> /* one single host page */
> if (!mmap_frag(real_start, start, last,
> - target_prot, flags, fd, offset)) {
> + target_prot, flags, fd, offset, &mapped)) {
> goto fail;
> }
> goto the_end1;
> }
> - if (!mmap_frag(real_start, start,
> - real_start + qemu_host_page_size - 1,
> - target_prot, flags, fd, offset)) {
> + if (!mmap_frag(real_start, start, middle_start - 1,
> + target_prot, flags, fd, offset, &mapped)) {
> goto fail;
> }
> - real_start += qemu_host_page_size;
> - }
> - /* handle the end of the mapping */
> - if (last < real_last) {
> - abi_ulong real_page = real_last - qemu_host_page_size + 1;
> - if (!mmap_frag(real_page, real_page, last,
> - target_prot, flags, fd,
> - offset + real_page - start)) {
> - goto fail;
> + if (mapped) {
> + mapped_len = qemu_host_page_size;
> }
> - real_last -= qemu_host_page_size;
> }
>
> /* map the middle (easier) */
> - if (real_start < real_last) {
> + if (middle_start < middle_last) {
> void *p, *want_p;
> off_t offset1;
> size_t len1;
> @@ -685,10 +683,10 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
> if (flags & MAP_ANONYMOUS) {
> offset1 = 0;
> } else {
> - offset1 = offset + real_start - start;
> + offset1 = offset + middle_start - start;
> }
> - len1 = real_last - real_start + 1;
> - want_p = g2h_untagged(real_start);
> + len1 = middle_last - middle_start + 1;
> + want_p = g2h_untagged(middle_start);
>
> p = mmap(want_p, len1, target_to_host_prot(target_prot),
> flags, fd, offset1);
> @@ -697,10 +695,27 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
> munmap(p, len1);
> errno = EEXIST;
> }
> + if (mapped_len) {
> + munmap(g2h_untagged(middle_start - mapped_len), mapped_len);
> + }
> + goto fail;
> + }
> + mapped_len += len1;
> + passthrough_start = middle_start;
> + passthrough_last = middle_last;
> + }
> +
> + /* handle the end of the mapping */
> + if (last > middle_last) {
> + abi_ulong real_page = middle_last + 1;
> + if (!mmap_frag(real_page, real_page, last,
> + target_prot, flags, fd,
> + offset + real_page - start, &mapped)) {
> + if (mapped_len) {
> + munmap(g2h_untagged(real_page - mapped_len), mapped_len);
> + }
> goto fail;
> }
> - passthrough_start = real_start;
> - passthrough_last = real_last;
> }
> }
> the_end1:
Hi Richard,
Can you have a look at this patch?
Regards,
Akihiko Odaki
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2] linux-user: Undo incomplete mmap
2023-09-21 7:09 ` Akihiko Odaki
@ 2023-10-03 20:42 ` Richard Henderson
2023-10-05 5:17 ` Akihiko Odaki
0 siblings, 1 reply; 4+ messages in thread
From: Richard Henderson @ 2023-10-03 20:42 UTC (permalink / raw)
To: Akihiko Odaki; +Cc: qemu-devel, joel, laurent, deller
On 9/21/23 00:09, Akihiko Odaki wrote:
> On 2023/09/03 14:39, Akihiko Odaki wrote:
>> When the host page size is greater than the target page size and
>> MAP_FIXED or MAP_FIXED_NOREPLACE is requested, mmap will be done for
>> three parts: start, middle, and end. If a later part of mmap fail,
>> mmap done in the earlier parts must be reverted.
>>
>> Fixes: 54936004fd ("mmap emulation")
>> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
>> ---
>> V1 -> V2: Rebased.
>>
>> linux-user/mmap.c | 65 +++++++++++++++++++++++++++++------------------
>> 1 file changed, 40 insertions(+), 25 deletions(-)
>>
>> diff --git a/linux-user/mmap.c b/linux-user/mmap.c
>> index 9aab48d4a3..72521f8d27 100644
>> --- a/linux-user/mmap.c
>> +++ b/linux-user/mmap.c
>> @@ -224,13 +224,15 @@ int target_mprotect(abi_ulong start, abi_ulong len, int target_prot)
>> /* map an incomplete host page */
>> static bool mmap_frag(abi_ulong real_start, abi_ulong start, abi_ulong last,
>> - int prot, int flags, int fd, off_t offset)
>> + int prot, int flags, int fd, off_t offset, bool *mapped)
>> {
>> abi_ulong real_last;
>> void *host_start;
>> int prot_old, prot_new;
>> int host_prot_old, host_prot_new;
>> + *mapped = false;
>> +
>> if (!(flags & MAP_ANONYMOUS)
>> && (flags & MAP_TYPE) == MAP_SHARED
>> && (prot & PROT_WRITE)) {
>> @@ -271,6 +273,7 @@ static bool mmap_frag(abi_ulong real_start, abi_ulong start,
>> abi_ulong last,
>> return false;
>> }
>> prot_old = prot;
>> + *mapped = true;
>> }
>> prot_new = prot | prot_old;
>> @@ -448,7 +451,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong
>> align)
>> abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
>> int flags, int fd, off_t offset)
>> {
>> - abi_ulong ret, last, real_start, real_last, retaddr, host_len;
>> + abi_ulong ret, last, real_start, retaddr, host_len;
>> abi_ulong passthrough_start = -1, passthrough_last = 0;
>> int page_flags;
>> off_t host_offset;
>> @@ -577,12 +580,16 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
>> passthrough_start = start;
>> passthrough_last = last;
>> } else {
>> + abi_ulong middle_start = HOST_PAGE_ALIGN(start);
>> + abi_ulong middle_last = ((start + len) & qemu_host_page_mask) - 1;
>> + abi_ulong mapped_len = 0;
>> + bool mapped;
>> +
>> if (start & ~TARGET_PAGE_MASK) {
>> errno = EINVAL;
>> goto fail;
>> }
>> last = start + len - 1;
>> - real_last = HOST_PAGE_ALIGN(last) - 1;
>> /*
>> * Test if requested memory area fits target address space
>> @@ -649,35 +656,26 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
>> }
>> /* handle the start of the mapping */
>> - if (start > real_start) {
>> - if (real_last == real_start + qemu_host_page_size - 1) {
>> + if (start < middle_start) {
>> + if (last < middle_start) {
>> /* one single host page */
>> if (!mmap_frag(real_start, start, last,
>> - target_prot, flags, fd, offset)) {
>> + target_prot, flags, fd, offset, &mapped)) {
>> goto fail;
>> }
>> goto the_end1;
>> }
>> - if (!mmap_frag(real_start, start,
>> - real_start + qemu_host_page_size - 1,
>> - target_prot, flags, fd, offset)) {
>> + if (!mmap_frag(real_start, start, middle_start - 1,
>> + target_prot, flags, fd, offset, &mapped)) {
>> goto fail;
>> }
>> - real_start += qemu_host_page_size;
>> - }
>> - /* handle the end of the mapping */
>> - if (last < real_last) {
>> - abi_ulong real_page = real_last - qemu_host_page_size + 1;
>> - if (!mmap_frag(real_page, real_page, last,
>> - target_prot, flags, fd,
>> - offset + real_page - start)) {
>> - goto fail;
>> + if (mapped) {
>> + mapped_len = qemu_host_page_size;
>> }
>> - real_last -= qemu_host_page_size;
>> }
>> /* map the middle (easier) */
>> - if (real_start < real_last) {
>> + if (middle_start < middle_last) {
>> void *p, *want_p;
>> off_t offset1;
>> size_t len1;
>> @@ -685,10 +683,10 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
>> if (flags & MAP_ANONYMOUS) {
>> offset1 = 0;
>> } else {
>> - offset1 = offset + real_start - start;
>> + offset1 = offset + middle_start - start;
>> }
>> - len1 = real_last - real_start + 1;
>> - want_p = g2h_untagged(real_start);
>> + len1 = middle_last - middle_start + 1;
>> + want_p = g2h_untagged(middle_start);
>> p = mmap(want_p, len1, target_to_host_prot(target_prot),
>> flags, fd, offset1);
>> @@ -697,10 +695,27 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
>> munmap(p, len1);
>> errno = EEXIST;
>> }
>> + if (mapped_len) {
>> + munmap(g2h_untagged(middle_start - mapped_len), mapped_len);
>> + }
>> + goto fail;
>> + }
>> + mapped_len += len1;
>> + passthrough_start = middle_start;
>> + passthrough_last = middle_last;
>> + }
>> +
>> + /* handle the end of the mapping */
>> + if (last > middle_last) {
>> + abi_ulong real_page = middle_last + 1;
>> + if (!mmap_frag(real_page, real_page, last,
>> + target_prot, flags, fd,
>> + offset + real_page - start, &mapped)) {
>> + if (mapped_len) {
>> + munmap(g2h_untagged(real_page - mapped_len), mapped_len);
>> + }
>> goto fail;
>> }
>> - passthrough_start = real_start;
>> - passthrough_last = real_last;
>> }
>> }
>> the_end1:
>
> Hi Richard,
>
> Can you have a look at this patch?
munmap isn't always correct -- one has to keep the virtual address space allocated for
reserved_va. So mmap_reserve_or_unmap.
That said, I've got one reorg of mmap.c outstanding already, and I'm planning another to
allow use of softmmu in user-only mode. The latter would eliminate mmap_frag entirely.
r~
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2] linux-user: Undo incomplete mmap
2023-10-03 20:42 ` Richard Henderson
@ 2023-10-05 5:17 ` Akihiko Odaki
0 siblings, 0 replies; 4+ messages in thread
From: Akihiko Odaki @ 2023-10-05 5:17 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel, joel, laurent, deller
On 2023/10/04 5:42, Richard Henderson wrote:
> On 9/21/23 00:09, Akihiko Odaki wrote:
>> On 2023/09/03 14:39, Akihiko Odaki wrote:
>>> When the host page size is greater than the target page size and
>>> MAP_FIXED or MAP_FIXED_NOREPLACE is requested, mmap will be done for
>>> three parts: start, middle, and end. If a later part of mmap fail,
>>> mmap done in the earlier parts must be reverted.
>>>
>>> Fixes: 54936004fd ("mmap emulation")
>>> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
>>> ---
>>> V1 -> V2: Rebased.
>>>
>>> linux-user/mmap.c | 65 +++++++++++++++++++++++++++++------------------
>>> 1 file changed, 40 insertions(+), 25 deletions(-)
>>>
>>> diff --git a/linux-user/mmap.c b/linux-user/mmap.c
>>> index 9aab48d4a3..72521f8d27 100644
>>> --- a/linux-user/mmap.c
>>> +++ b/linux-user/mmap.c
>>> @@ -224,13 +224,15 @@ int target_mprotect(abi_ulong start, abi_ulong
>>> len, int target_prot)
>>> /* map an incomplete host page */
>>> static bool mmap_frag(abi_ulong real_start, abi_ulong start,
>>> abi_ulong last,
>>> - int prot, int flags, int fd, off_t offset)
>>> + int prot, int flags, int fd, off_t offset,
>>> bool *mapped)
>>> {
>>> abi_ulong real_last;
>>> void *host_start;
>>> int prot_old, prot_new;
>>> int host_prot_old, host_prot_new;
>>> + *mapped = false;
>>> +
>>> if (!(flags & MAP_ANONYMOUS)
>>> && (flags & MAP_TYPE) == MAP_SHARED
>>> && (prot & PROT_WRITE)) {
>>> @@ -271,6 +273,7 @@ static bool mmap_frag(abi_ulong real_start,
>>> abi_ulong start, abi_ulong last,
>>> return false;
>>> }
>>> prot_old = prot;
>>> + *mapped = true;
>>> }
>>> prot_new = prot | prot_old;
>>> @@ -448,7 +451,7 @@ abi_ulong mmap_find_vma(abi_ulong start,
>>> abi_ulong size, abi_ulong align)
>>> abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
>>> int flags, int fd, off_t offset)
>>> {
>>> - abi_ulong ret, last, real_start, real_last, retaddr, host_len;
>>> + abi_ulong ret, last, real_start, retaddr, host_len;
>>> abi_ulong passthrough_start = -1, passthrough_last = 0;
>>> int page_flags;
>>> off_t host_offset;
>>> @@ -577,12 +580,16 @@ abi_long target_mmap(abi_ulong start, abi_ulong
>>> len, int target_prot,
>>> passthrough_start = start;
>>> passthrough_last = last;
>>> } else {
>>> + abi_ulong middle_start = HOST_PAGE_ALIGN(start);
>>> + abi_ulong middle_last = ((start + len) &
>>> qemu_host_page_mask) - 1;
>>> + abi_ulong mapped_len = 0;
>>> + bool mapped;
>>> +
>>> if (start & ~TARGET_PAGE_MASK) {
>>> errno = EINVAL;
>>> goto fail;
>>> }
>>> last = start + len - 1;
>>> - real_last = HOST_PAGE_ALIGN(last) - 1;
>>> /*
>>> * Test if requested memory area fits target address space
>>> @@ -649,35 +656,26 @@ abi_long target_mmap(abi_ulong start, abi_ulong
>>> len, int target_prot,
>>> }
>>> /* handle the start of the mapping */
>>> - if (start > real_start) {
>>> - if (real_last == real_start + qemu_host_page_size - 1) {
>>> + if (start < middle_start) {
>>> + if (last < middle_start) {
>>> /* one single host page */
>>> if (!mmap_frag(real_start, start, last,
>>> - target_prot, flags, fd, offset)) {
>>> + target_prot, flags, fd, offset,
>>> &mapped)) {
>>> goto fail;
>>> }
>>> goto the_end1;
>>> }
>>> - if (!mmap_frag(real_start, start,
>>> - real_start + qemu_host_page_size - 1,
>>> - target_prot, flags, fd, offset)) {
>>> + if (!mmap_frag(real_start, start, middle_start - 1,
>>> + target_prot, flags, fd, offset, &mapped)) {
>>> goto fail;
>>> }
>>> - real_start += qemu_host_page_size;
>>> - }
>>> - /* handle the end of the mapping */
>>> - if (last < real_last) {
>>> - abi_ulong real_page = real_last - qemu_host_page_size + 1;
>>> - if (!mmap_frag(real_page, real_page, last,
>>> - target_prot, flags, fd,
>>> - offset + real_page - start)) {
>>> - goto fail;
>>> + if (mapped) {
>>> + mapped_len = qemu_host_page_size;
>>> }
>>> - real_last -= qemu_host_page_size;
>>> }
>>> /* map the middle (easier) */
>>> - if (real_start < real_last) {
>>> + if (middle_start < middle_last) {
>>> void *p, *want_p;
>>> off_t offset1;
>>> size_t len1;
>>> @@ -685,10 +683,10 @@ abi_long target_mmap(abi_ulong start, abi_ulong
>>> len, int target_prot,
>>> if (flags & MAP_ANONYMOUS) {
>>> offset1 = 0;
>>> } else {
>>> - offset1 = offset + real_start - start;
>>> + offset1 = offset + middle_start - start;
>>> }
>>> - len1 = real_last - real_start + 1;
>>> - want_p = g2h_untagged(real_start);
>>> + len1 = middle_last - middle_start + 1;
>>> + want_p = g2h_untagged(middle_start);
>>> p = mmap(want_p, len1, target_to_host_prot(target_prot),
>>> flags, fd, offset1);
>>> @@ -697,10 +695,27 @@ abi_long target_mmap(abi_ulong start, abi_ulong
>>> len, int target_prot,
>>> munmap(p, len1);
>>> errno = EEXIST;
>>> }
>>> + if (mapped_len) {
>>> + munmap(g2h_untagged(middle_start - mapped_len),
>>> mapped_len);
>>> + }
>>> + goto fail;
>>> + }
>>> + mapped_len += len1;
>>> + passthrough_start = middle_start;
>>> + passthrough_last = middle_last;
>>> + }
>>> +
>>> + /* handle the end of the mapping */
>>> + if (last > middle_last) {
>>> + abi_ulong real_page = middle_last + 1;
>>> + if (!mmap_frag(real_page, real_page, last,
>>> + target_prot, flags, fd,
>>> + offset + real_page - start, &mapped)) {
>>> + if (mapped_len) {
>>> + munmap(g2h_untagged(real_page - mapped_len),
>>> mapped_len);
>>> + }
>>> goto fail;
>>> }
>>> - passthrough_start = real_start;
>>> - passthrough_last = real_last;
>>> }
>>> }
>>> the_end1:
>>
>> Hi Richard,
>>
>> Can you have a look at this patch?
>
> munmap isn't always correct -- one has to keep the virtual address space
> allocated for reserved_va. So mmap_reserve_or_unmap.
>
> That said, I've got one reorg of mmap.c outstanding already, and I'm
> planning another to allow use of softmmu in user-only mode. The latter
> would eliminate mmap_frag entirely.
That sounds great. I'll wait for the changes instead of pushing this
forward.
Regards,
Akihiko Odaki
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2023-10-05 5:17 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-09-03 5:39 [PATCH v2] linux-user: Undo incomplete mmap Akihiko Odaki
2023-09-21 7:09 ` Akihiko Odaki
2023-10-03 20:42 ` Richard Henderson
2023-10-05 5:17 ` Akihiko Odaki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).