Hello Razvan,

On 3/3/26 20:01, razvan ghiorghe wrote:
Hi,
I'd like to kindly ping this patch. It has been a few weeks since submission 
and I haven't received any feedback yet.
I'm working on getting familiar with the contribution flux. Any review, even 
brief comments on the approach would be very helpful!

First of all, I could not find the "v2" version of your patch.
It's not in the qemu mail archives, only in your mail below.
Did you sent a v2 version at all?

More importantly, I can confirm with the testcase from 
https://gitlab.com/qemu-project/qemu/-/issues/3105,
that the problem exists.
Testcase works on a physical hppa box, but fails in qemu-linux-user.

The patch seems ok, but it did not work for me.

Without your patch:
(hppa-chroot)root@p100:/# ./a.out
mremap with old_size=0 failed: Bad address
-> problem exists as you described.

With your patch:
(hppa-chroot)root@p100:/# ./a.out
qemu-hppa-static: ../../qemu/linux-user/mmap.c:1142: target_mremap: Assertion 
`h2g_valid(host_addr)' failed.
Aborted  (core dumped) ./a.out

More info:
(hppa-chroot)root@p100:/# QEMU_LOG=strace ./a.out
...
7087 mmap2(NULL,4096,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0) = 
0x45214000
7087 mremap(1159806976,0,8192,1,0,1159087572)
qemu-hppa-static: ../../qemu/linux-user/mmap.c:1142: target_mremap: Assertion 
`h2g_valid(host_addr)' failed.
Aborted                    (core dumped) QEMU_LOG=strace ./a.out

Helge


Thanks in advance,
Razvan

În dum., 1 feb. 2026 la 03:08, Razvan Ghiorghe <[email protected] 
<mailto:[email protected]>> a scris:

    When old_size is zero and old_address refers to a shareable mapping,
    mremap() should create a new mapping of the same pages according to the
    mremap(2) man page. The MREMAP_MAYMOVE flag must be specified in this case.
    Previously, QEMU's target_mremap() rejected this valid case with EFAULT 
during
    the initial validation, before checking for the special old_size == 0 
behaviour.

    This patch adds proper handling for old_size == 0:
    - Validates that MREMAP_MAYMOVE flag is set (required by man spec)
    - Passes the call through to the host mremap()
    - Creates a new mapping without invalidating the original, with both
    beeing valid and sharing the same physical memory frames.

    Tested with the reproducer from the issue on qemu-riscv64.
    Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3105 
<https://gitlab.com/qemu-project/qemu/-/issues/3105>
    Signed-off-by: Razvan Ghiorghe <[email protected] 
<mailto:[email protected]>>
    ---
      linux-user/mmap.c | 32 ++++++++++++++++++++++++++++++++
      1 file changed, 32 insertions(+)

    diff --git a/linux-user/mmap.c b/linux-user/mmap.c
    index 4bcfaf7894..b1a84eb60a 100644
    --- a/linux-user/mmap.c
    +++ b/linux-user/mmap.c
    @@ -1117,6 +1117,38 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong 
old_size,
              errno = EINVAL;
              return -1;
          }
    +
    +    if (!old_size) {
    +        if (!(flags & MREMAP_MAYMOVE)) {
    +            errno = EINVAL;
    +            return -1;
    +        }
    +        mmap_lock();
    +        if (flags & MREMAP_FIXED) {
    +            host_addr = mremap(g2h_untagged(old_addr), old_size, new_size,
    +                             flags, g2h_untagged(new_addr));
    +        } else {
    +            host_addr = mremap(g2h_untagged(old_addr), old_size, new_size,
    +                             flags);
    +        }
    +
    +        if (host_addr == MAP_FAILED) {
    +            mmap_unlock();
    +            return -1;
    +        }
    +        new_addr = h2g(host_addr);
    +        prot = page_get_flags(old_addr);
    +        /*
    +         * For old_size zero, there is nothing to clear at old_addr.
    +         * Only set the flags for the new mapping. They both are valid.
    +         */
    +        page_set_flags(new_addr, new_addr + new_size - 1,
    +                       prot | PAGE_VALID, PAGE_VALID);
    +        shm_region_rm_complete(new_addr, new_addr + new_size - 1);
    +        mmap_unlock();
    +        return new_addr;
    +    }
    +
          if (!guest_range_valid_untagged(old_addr, old_size)) {
              errno = EFAULT;
              return -1;
-- 2.43.0



Reply via email to