diff mbox

linux-user: fix mremap for 64bit targets on 32bit hosts

Message ID 20160918012014.GA11017@nyan
State New
Headers show

Commit Message

Felix Janda Sept. 18, 2016, 1:20 a.m. UTC
Signed-off-by: Felix Janda <felix.janda@posteo.de>
---
 linux-user/mmap.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Riku Voipio Sept. 22, 2016, 6:22 a.m. UTC | #1
Hi,

On Sat, Sep 17, 2016 at 09:20:14PM -0400, Felix Janda wrote:
> Signed-off-by: Felix Janda <felix.janda@posteo.de>

Have you run the mremap tests of ltp with this on your host/guest
combo? 

> ---
>  linux-user/mmap.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/linux-user/mmap.c b/linux-user/mmap.c
> index c4371d9..4882816 100644
> --- a/linux-user/mmap.c
> +++ b/linux-user/mmap.c
> @@ -682,7 +682,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
>  
>      if (flags & MREMAP_FIXED) {
>          host_addr = (void *) syscall(__NR_mremap, g2h(old_addr),
> -                                     old_size, new_size,
> +                                     (size_t) old_size, (size_t) new_size,
>                                       flags,
>                                       g2h(new_addr));
>  
> @@ -701,7 +701,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
>              host_addr = MAP_FAILED;
>          } else {
>              host_addr = (void *) syscall(__NR_mremap, g2h(old_addr),
> -                                         old_size, new_size,
> +                                         (size_t) old_size, (size_t) new_size,
>                                           flags | MREMAP_FIXED,
>                                           g2h(mmap_start));
>              if (reserved_va) {
> -- 
> 2.7.3
>
Felix Janda Sept. 23, 2016, 12:36 a.m. UTC | #2
Riku Voipio wrote:
> Hi,
> 
> On Sat, Sep 17, 2016 at 09:20:14PM -0400, Felix Janda wrote:
> > Signed-off-by: Felix Janda <felix.janda@posteo.de>
> 
> Have you run the mremap tests of ltp with this on your host/guest
> combo? 

I have just run the tests. My host is arm and my guest is aarch64.
Without the patch all but mremap02 fail. With the patch all but
mremap04 pass. The mremap04 test indicates that shmat is broken.

> > ---
> >  linux-user/mmap.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/linux-user/mmap.c b/linux-user/mmap.c
> > index c4371d9..4882816 100644
> > --- a/linux-user/mmap.c
> > +++ b/linux-user/mmap.c
> > @@ -682,7 +682,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
> >  
> >      if (flags & MREMAP_FIXED) {
> >          host_addr = (void *) syscall(__NR_mremap, g2h(old_addr),
> > -                                     old_size, new_size,
> > +                                     (size_t) old_size, (size_t) new_size,
> >                                       flags,
> >                                       g2h(new_addr));
> >  
> > @@ -701,7 +701,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
> >              host_addr = MAP_FAILED;
> >          } else {
> >              host_addr = (void *) syscall(__NR_mremap, g2h(old_addr),
> > -                                         old_size, new_size,
> > +                                         (size_t) old_size, (size_t) new_size,
> >                                           flags | MREMAP_FIXED,
> >                                           g2h(mmap_start));
> >              if (reserved_va) {
> > -- 
> > 2.7.3
> >
Peter Maydell Sept. 28, 2016, 11:30 p.m. UTC | #3
On 17 September 2016 at 18:20, Felix Janda <felix.janda@posteo.de> wrote:
> Signed-off-by: Felix Janda <felix.janda@posteo.de>
> ---
>  linux-user/mmap.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/linux-user/mmap.c b/linux-user/mmap.c
> index c4371d9..4882816 100644
> --- a/linux-user/mmap.c
> +++ b/linux-user/mmap.c
> @@ -682,7 +682,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
>
>      if (flags & MREMAP_FIXED) {
>          host_addr = (void *) syscall(__NR_mremap, g2h(old_addr),
> -                                     old_size, new_size,
> +                                     (size_t) old_size, (size_t) new_size,
>                                       flags,
>                                       g2h(new_addr));
>
> @@ -701,7 +701,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
>              host_addr = MAP_FAILED;
>          } else {
>              host_addr = (void *) syscall(__NR_mremap, g2h(old_addr),
> -                                         old_size, new_size,
> +                                         (size_t) old_size, (size_t) new_size,
>                                           flags | MREMAP_FIXED,
>                                           g2h(mmap_start));
>              if (reserved_va) {
> --
> 2.7.3

Rather than this, I think it would be better to switch to
using the mremap() library call rather than direct syscall
here, which then matches the other mremap()s later in the
function. (That will work right because mremap()'s prototype
says it takes size_t arguments, whereas syscall() is a
generic thing which doesn't, and so the C default promotions
do the wrong thing with the abi_ulongs.)

The use of syscall(__NR_mremap, ...) originally dates back to 2008:
https://lists.gnu.org/archive/html/qemu-devel/2008-12/msg01087.html
https://lists.gnu.org/archive/html/qemu-devel/2008-12/msg00480.html

and was to permit compilation with glibc 2.4 which didn't
support the 5-argument mremap() or define MREMAP_FIXED.

Since glibc 2.4 dates back to a decade ago now, we no longer
need to carry this ugly (and buggy) workaround for it.

thanks
-- PMM
Felix Janda Sept. 29, 2016, 2:46 a.m. UTC | #4
Peter Maydell wrote:
> On 17 September 2016 at 18:20, Felix Janda <felix.janda@posteo.de> wrote:
> > Signed-off-by: Felix Janda <felix.janda@posteo.de>
> > ---
> >  linux-user/mmap.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/linux-user/mmap.c b/linux-user/mmap.c
> > index c4371d9..4882816 100644
> > --- a/linux-user/mmap.c
> > +++ b/linux-user/mmap.c
> > @@ -682,7 +682,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
> >
> >      if (flags & MREMAP_FIXED) {
> >          host_addr = (void *) syscall(__NR_mremap, g2h(old_addr),
> > -                                     old_size, new_size,
> > +                                     (size_t) old_size, (size_t) new_size,
> >                                       flags,
> >                                       g2h(new_addr));
> >
> > @@ -701,7 +701,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
> >              host_addr = MAP_FAILED;
> >          } else {
> >              host_addr = (void *) syscall(__NR_mremap, g2h(old_addr),
> > -                                         old_size, new_size,
> > +                                         (size_t) old_size, (size_t) new_size,
> >                                           flags | MREMAP_FIXED,
> >                                           g2h(mmap_start));
> >              if (reserved_va) {
> > --
> > 2.7.3
> 
> Rather than this, I think it would be better to switch to
> using the mremap() library call rather than direct syscall
> here, which then matches the other mremap()s later in the
> function. (That will work right because mremap()'s prototype
> says it takes size_t arguments, whereas syscall() is a
> generic thing which doesn't, and so the C default promotions
> do the wrong thing with the abi_ulongs.)
> 
> The use of syscall(__NR_mremap, ...) originally dates back to 2008:
> https://lists.gnu.org/archive/html/qemu-devel/2008-12/msg01087.html
> https://lists.gnu.org/archive/html/qemu-devel/2008-12/msg00480.html
> 
> and was to permit compilation with glibc 2.4 which didn't
> support the 5-argument mremap() or define MREMAP_FIXED.
> 
> Since glibc 2.4 dates back to a decade ago now, we no longer
> need to carry this ugly (and buggy) workaround for it.

This sounds like a good idea. Thanks also for digging up the history.

I will prepare a new patch.

Thanks,
Felix
diff mbox

Patch

diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index c4371d9..4882816 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -682,7 +682,7 @@  abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
 
     if (flags & MREMAP_FIXED) {
         host_addr = (void *) syscall(__NR_mremap, g2h(old_addr),
-                                     old_size, new_size,
+                                     (size_t) old_size, (size_t) new_size,
                                      flags,
                                      g2h(new_addr));
 
@@ -701,7 +701,7 @@  abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
             host_addr = MAP_FAILED;
         } else {
             host_addr = (void *) syscall(__NR_mremap, g2h(old_addr),
-                                         old_size, new_size,
+                                         (size_t) old_size, (size_t) new_size,
                                          flags | MREMAP_FIXED,
                                          g2h(mmap_start));
             if (reserved_va) {