qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Brüns, Stefan" <Stefan.Bruens@rwth-aachen.de>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: QEMU Developers <qemu-devel@nongnu.org>
Subject: Re: [Qemu-devel] [PATCH] linux-user: remove MAX_ARG_PAGES limit
Date: Tue, 1 Sep 2015 17:27:11 +0000	[thread overview]
Message-ID: <48056319.nEOi1Yu0y0@sbruens-linux> (raw)
In-Reply-To: <CAFEAcA_YoTHgRyRJxy4RAYQSYcuJ+uORgPTcpfFmbF6zg06=2Q@mail.gmail.com>

On Tuesday, September 01, 2015 15:29:26 you wrote:
> On 27 August 2015 at 20:35, Stefan Brüns <stefan.bruens@rwth-aachen.de> 
wrote:
> > Instead of creating a temporary copy for the whole environment and
> > the arguments, directly copy everything to the target stack.
> > 
> > For this to work, we have to change the order of stack creation and
> > copying the arguments.
> > 
> > v2: fixed scratch pointer type, fixed checkpatch issues.
> 
> This sort of 'v1 to v2 diffs' comment should go below the '---'
> line, so it doesn't end up in the final git commit message.
> 
> > Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
> > ---
> > 
> >  linux-user/elfload.c   | 110
> >  ++++++++++++++++++++++++------------------------- linux-user/linuxload.c
> >  |   7 +---
> >  linux-user/qemu.h      |   7 ----
> >  linux-user/syscall.c   |   6 ---
> >  4 files changed, 56 insertions(+), 74 deletions(-)
> 
> Still doesn't compile:
> 
> /home/petmay01/linaro/qemu-from-laptop/qemu/linux-user/linuxload.c: In
> function ‘loader_exec’:
> /home/petmay01/linaro/qemu-from-laptop/qemu/linux-user/linuxload.c:138:9:
> error: unused variable ‘i’ [-Werror=unused-variable]
>      int i;
>          ^
> 
> Mostly this looks good; I have a few review comments below.
> 
> > diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> > index 9c999ac..991dd35 100644
> > --- a/linux-user/elfload.c
> > +++ b/linux-user/elfload.c
> > 
> > +            int bytes_to_copy = (len > offset) ? offset : len;
> > +            tmp -= bytes_to_copy;
> > +            p -= bytes_to_copy;
> > +            offset -= bytes_to_copy;
> > +            len -= bytes_to_copy;
> > +
> > +            if (bytes_to_copy == 1) {
> > +                *(scratch + offset) = *tmp;
> > +            } else {
> > +                memcpy_fromfs(scratch + offset, tmp, bytes_to_copy);
> 
> Why bother to special case the 1 byte case?

Taken from the old code. Probably not worth the extra code, will remove it.
 
> >              }
> > 
> > -            else {
> > -                int bytes_to_copy = (len > offset) ? offset : len;
> > -                tmp -= bytes_to_copy;
> > -                p -= bytes_to_copy;
> > -                offset -= bytes_to_copy;
> > -                len -= bytes_to_copy;
> > -                memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
> > +
> > +            if (offset == 0) {
> > +                memcpy_to_target(p, scratch, top - p);
> > +                top = p;
> > +                offset = TARGET_PAGE_SIZE;
> > 
> >              }
> >          
> >          }
> >      
> >      }
> > 
> > +    if (offset) {
> > +        memcpy_to_target(p, scratch + offset, top - p);
> > +    }
> > +
> > 
> >      return p;
> >  
> >  }
> > 
> > -static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm,
> > +static abi_ulong setup_arg_pages(struct linux_binprm *bprm,
> > 
> >                                   struct image_info *info)
> >  
> >  {
> > 
> > -    abi_ulong stack_base, size, error, guard;
> > -    int i;
> > +    abi_ulong size, error, guard;
> > +
> > +    /* Linux kernel limits argument/environment space to 1/4th of stack
> > size, +       but also has a floor of 32 pages. Mimic this behaviour.  */
> > +    #define MAX_ARG_PAGES 32
> 
> This sounds like a minimum, not a maximum, so the name is very
> misleading.
> 
> The comment says "limit to 1/4 of stack size" but the code doesn't
> seem to do anything like that.
> 
> Please move the #define to top-level in the file, not hidden
> inside a function definition.

MAX_ARG_PAGES is the name used in old kernels (and current, when there is
no MMU), so it is useful to keep this name (maybe in a comment).

What about:
---
/* Older linux kernels provide up to MAX_ARG_PAGES (default: 32) of
 * argument/environment space. Newer kernels (>2.6.33) provide up to
 * 1/4th of stack size, but guarantee at least 32 pages for backwards
 * compatibility. */
#define STACK_LOWER_LIMIT (32 * TARGET_PAGE_SIZE)
---

The 1/4th is not enforced, as our stack has to be big enough to hold args/env 
coming from the kernel, but is no problem if we provide more space.

Thinking about it, maybe we should provide some extra space, as qemu-linux-
user puts some more stuff (e.g. auxv) between env/args and user stack.
 
> > -    /* Create enough stack to hold everything.  If we don't use
> > -       it for args, we'll use it for something else.  */
> > 
> >      size = guest_stack_size;
> > 
> > -    if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) {
> > -        size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
> > +    if (size < MAX_ARG_PAGES * TARGET_PAGE_SIZE) {
> > +        size = MAX_ARG_PAGES * TARGET_PAGE_SIZE;
> > 
> >      }
> >      guard = TARGET_PAGE_SIZE;
> >      if (guard < qemu_real_host_page_size) {
> > 
> > @@ -1442,19 +1446,8 @@ static abi_ulong setup_arg_pages(abi_ulong p,
> > struct linux_binprm *bprm,> 
> >      target_mprotect(error, guard, PROT_NONE);
> >      
> >      info->stack_limit = error + guard;
> > 
> > -    stack_base = info->stack_limit + size -
> > MAX_ARG_PAGES*TARGET_PAGE_SIZE; -    p += stack_base;
> > -
> > -    for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
> > -        if (bprm->page[i]) {
> > -            info->rss++;
> 
> I think your patch has lost the calculation of info->rss.
> 
> (We don't actually use info->rss anywhere, though, so if you wanted
> to add a patch in front of this one explicitly removing it as useless
> that would be an OK way to handle this.)

Will add an explicit removal patch. info->mmap is not used either, ok to 
remove both in one go?

> > -            /* FIXME - check return value of memcpy_to_target() for
> > failure */ -            memcpy_to_target(stack_base, bprm->page[i],
> > TARGET_PAGE_SIZE); -            g_free(bprm->page[i]);
> > -        }
> > -        stack_base += TARGET_PAGE_SIZE;
> > -    }
> > -    return p;
> > +
> > +    return info->stack_limit + size - sizeof(void *);
> > 
> >  }
> >  
> >  /* Map and zero the bss.  We need to explicitly zero any fractional pages
> > 
> > diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c
> > index 506e837..09df934 100644
> > --- a/linux-user/linuxload.c
> > +++ b/linux-user/linuxload.c
> > @@ -137,8 +137,7 @@ int loader_exec(int fdexec, const char *filename, char
> > **argv, char **envp,> 
> >      int retval;
> >      int i;
> > 
> > -    bprm->p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
> > -    memset(bprm->page, 0, sizeof(bprm->page));
> > +    bprm->p = 0;
> 
> Nothing actually uses this value -- both the elfload and the flatload code
> paths now either ignore bprm->p or set it themselves. It would be
> better to delete this and also the dead assignment "p = bprm->p" at
> the top of load_flt_binary().

OK to do this in a followup patch?

> >      bprm->fd = fdexec;
> >      bprm->filename = (char *)filename;
> >      bprm->argc = count(argv);
> 
> thanks
> -- PMM

Kind regards, Stefan

-- 
Stefan Brüns  /  Bergstraße 21  /  52062 Aachen
home: +49 241 53809034     mobile: +49 151 50412019
work: +49 2405 49936-424

  reply	other threads:[~2015-09-01 17:27 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1439663161-13070-1-git-send-email-stefan.bruens@rwth-aachen.de>
2015-08-15 18:26 ` [Qemu-devel] [PATCH] linux-user: remove MAX_ARG_PAGES, allow dynamic growth of env/argv space Stefan Brüns
2015-08-19 21:57   ` Peter Maydell
2015-08-22 23:47     ` [Qemu-devel] [PATCH] linux-user: remove MAX_ARG_PAGES limit Stefan Brüns
2015-08-27 16:10       ` Stefan Bruens
2015-08-27 17:57       ` Peter Maydell
2015-08-27 19:35         ` Stefan Brüns
2015-08-30 15:52           ` Stefan Bruens
2015-08-30 16:37             ` Peter Maydell
2015-09-01 14:29           ` Peter Maydell
2015-09-01 17:27             ` Brüns, Stefan [this message]
2015-09-01 18:42               ` Peter Maydell
2015-09-02  1:15                 ` Stefan Bruens
2015-09-02  1:38                 ` [Qemu-devel] [PATCH 1/2] linux-user: remove unused image_info members Stefan Brüns
2015-09-03 17:19                   ` Peter Maydell
     [not found]                 ` <1441157933-12459-1-git-send-email-stefan.bruens@rwth-aachen.de>
2015-09-02  1:38                   ` [Qemu-devel] [PATCH 2/2] linux-user: remove MAX_ARG_PAGES limit Stefan Brüns
2015-09-03 17:27                     ` Peter Maydell
2015-09-14 19:37                       ` Stefan Bruens
2015-09-14 20:33                         ` Peter Maydell
2015-09-28 13:30                         ` Riku Voipio
2015-08-23  0:31     ` [Qemu-devel] [PATCH] linux-user: remove MAX_ARG_PAGES, allow dynamic growth of env/argv space Stefan Bruens

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=48056319.nEOi1Yu0y0@sbruens-linux \
    --to=stefan.bruens@rwth-aachen.de \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).