All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sergey Fedorov <serge.fdrv@gmail.com>
To: Peter Maydell <peter.maydell@linaro.org>, qemu-devel@nongnu.org
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	Riku Voipio <riku.voipio@iki.fi>,
	Richard Henderson <rth@twiddle.net>,
	Eduardo Habkost <ehabkost@redhat.com>,
	patches@linaro.org
Subject: Re: [Qemu-devel] [PATCH 2/5] user-exec: Push resume-from-signal code out to handle_cpu_signal()
Date: Mon, 16 May 2016 20:57:44 +0300	[thread overview]
Message-ID: <573A0A18.9050909@gmail.com> (raw)
In-Reply-To: <1463414992-8357-3-git-send-email-peter.maydell@linaro.org>

On 16/05/16 19:09, Peter Maydell wrote:
> Since the only caller of page_unprotect() which might cause it to
> need to call cpu_resume_from_signal() is handle_cpu_signal() in
> the user-mode code, push the longjump handling out to that function.
>
> Since this is the only caller of cpu_resume_from_signal() which
> passes a non-NULL puc argument, split the non-NULL handling into
> a new cpu_exit_tb_from_sighandler() function. This allows us
> to merge the softmmu and usermode implementations of the
> cpu_resume_from_signal() function, which are now identical.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Sergey Fedorov <sergey.fedorov@linaro.org>

> ---
>  cpu-exec-common.c |  2 +-
>  translate-all.c   | 12 ++++++++----
>  translate-all.h   |  2 +-
>  user-exec.c       | 41 +++++++++++++++++++++++++++++------------
>  4 files changed, 39 insertions(+), 18 deletions(-)
>
> diff --git a/cpu-exec-common.c b/cpu-exec-common.c
> index 6bdda6b..62f5d6b 100644
> --- a/cpu-exec-common.c
> +++ b/cpu-exec-common.c
> @@ -28,7 +28,6 @@ CPUState *tcg_current_cpu;
>  /* exit the current TB from a signal handler. The host registers are
>     restored in a state compatible with the CPU emulator
>   */
> -#if defined(CONFIG_SOFTMMU)
>  void cpu_resume_from_signal(CPUState *cpu, void *puc)
>  {
>      /* XXX: restore cpu registers saved in host registers */
> @@ -37,6 +36,7 @@ void cpu_resume_from_signal(CPUState *cpu, void *puc)
>      siglongjmp(cpu->jmp_env, 1);
>  }
>  
> +#if defined(CONFIG_SOFTMMU)
>  void cpu_reloading_memory_map(void)
>  {
>      if (qemu_in_vcpu_thread()) {
> diff --git a/translate-all.c b/translate-all.c
> index 4820d2e..52a571e 100644
> --- a/translate-all.c
> +++ b/translate-all.c
> @@ -1955,7 +1955,7 @@ int page_check_range(target_ulong start, target_ulong len, int flags)
>              /* unprotect the page if it was put read-only because it
>                 contains translated code */
>              if (!(p->flags & PAGE_WRITE)) {
> -                if (!page_unprotect(addr, 0, NULL)) {
> +                if (!page_unprotect(addr, 0)) {
>                      return -1;
>                  }
>              }
> @@ -1965,8 +1965,12 @@ int page_check_range(target_ulong start, target_ulong len, int flags)
>  }
>  
>  /* called from signal handler: invalidate the code and unprotect the
> -   page. Return TRUE if the fault was successfully handled. */
> -int page_unprotect(target_ulong address, uintptr_t pc, void *puc)
> + * page. Return 0 if the fault was not handled, 1 if it was handled,
> + * and 2 if it was handled but the caller must cause the TB to be
> + * immediately exited. (We can only return 2 if the 'pc' argument is
> + * non-zero.)
> + */
> +int page_unprotect(target_ulong address, uintptr_t pc)
>  {
>      unsigned int prot;
>      PageDesc *p;
> @@ -1999,7 +2003,7 @@ int page_unprotect(target_ulong address, uintptr_t pc, void *puc)
>                 the corresponding translated code. */
>              if (tb_invalidate_phys_page(addr, pc)) {
>                  mmap_unlock();
> -                cpu_resume_from_signal(current_cpu, puc);
> +                return 2;
>              }
>  #ifdef DEBUG_TB_CHECK
>              tb_invalidate_check(addr);
> diff --git a/translate-all.h b/translate-all.h
> index 0384640..ce6071b 100644
> --- a/translate-all.h
> +++ b/translate-all.h
> @@ -27,7 +27,7 @@ void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end);
>  void tb_check_watchpoint(CPUState *cpu);
>  
>  #ifdef CONFIG_USER_ONLY
> -int page_unprotect(target_ulong address, uintptr_t pc, void *puc);
> +int page_unprotect(target_ulong address, uintptr_t pc);
>  #endif
>  
>  #endif /* TRANSLATE_ALL_H */
> diff --git a/user-exec.c b/user-exec.c
> index d8d597b..1d02e24 100644
> --- a/user-exec.c
> +++ b/user-exec.c
> @@ -54,7 +54,7 @@ static void exception_action(CPUState *cpu)
>  /* exit the current TB from a signal handler. The host registers are
>     restored in a state compatible with the CPU emulator
>   */
> -void cpu_resume_from_signal(CPUState *cpu, void *puc)
> +static void cpu_exit_tb_from_sighandler(CPUState *cpu, void *puc)
>  {
>  #ifdef __linux__
>      struct ucontext *uc = puc;
> @@ -62,20 +62,18 @@ void cpu_resume_from_signal(CPUState *cpu, void *puc)
>      struct sigcontext *uc = puc;
>  #endif
>  
> -    if (puc) {
> -        /* XXX: use siglongjmp ? */
> +    /* XXX: use siglongjmp ? */
>  #ifdef __linux__
>  #ifdef __ia64
> -        sigprocmask(SIG_SETMASK, (sigset_t *)&uc->uc_sigmask, NULL);
> +    sigprocmask(SIG_SETMASK, (sigset_t *)&uc->uc_sigmask, NULL);
>  #else
> -        sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
> +    sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
>  #endif
>  #elif defined(__OpenBSD__)
> -        sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL);
> +    sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL);
>  #endif
> -    }
> -    cpu->exception_index = -1;
> -    siglongjmp(cpu->jmp_env, 1);
> +
> +    cpu_resume_from_signal(cpu, NULL);
>  }
>  
>  /* 'pc' is the host PC at which the exception was raised. 'address' is
> @@ -95,9 +93,28 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
>             pc, address, is_write, *(unsigned long *)old_set);
>  #endif
>      /* XXX: locking issue */
> -    if (is_write && h2g_valid(address)
> -        && page_unprotect(h2g(address), pc, puc)) {
> -        return 1;
> +    if (is_write && h2g_valid(address)) {
> +        switch (page_unprotect(h2g(address), pc)) {
> +        case 0:
> +            /* Fault not caused by a page marked unwritable to protect
> +             * cached translations, must be the guest binary's problem
> +             */
> +            break;
> +        case 1:
> +            /* Fault caused by protection of cached translation; TBs
> +             * invalidated, so resume execution
> +             */
> +            return 1;
> +        case 2:
> +            /* Fault caused by protection of cached translation, and the
> +             * currently executing TB was modified and must be exited
> +             * immediately.
> +             */
> +            cpu_exit_tb_from_sighandler(current_cpu, puc);
> +            g_assert_not_reached();
> +        default:
> +            g_assert_not_reached();
> +        }
>      }
>  
>      /* Convert forcefully to guest address space, invalid addresses

  reply	other threads:[~2016-05-16 17:57 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-16 16:09 [Qemu-devel] [PATCH 0/5] user-exec: cpu_resume_from_signal() cleanups Peter Maydell
2016-05-16 16:09 ` [Qemu-devel] [PATCH 1/5] translate-all.c: Don't pass puc, locked to tb_invalidate_phys_page() Peter Maydell
2016-05-16 17:13   ` Sergey Fedorov
2016-05-16 17:15     ` Peter Maydell
2016-05-16 17:24       ` Sergey Fedorov
2016-05-16 16:09 ` [Qemu-devel] [PATCH 2/5] user-exec: Push resume-from-signal code out to handle_cpu_signal() Peter Maydell
2016-05-16 17:57   ` Sergey Fedorov [this message]
2016-05-16 16:09 ` [Qemu-devel] [PATCH 3/5] cpu-exec: Rename cpu_resume_from_signal() to cpu_loop_exit_noexc() Peter Maydell
2016-05-16 17:58   ` Sergey Fedorov
2016-05-16 16:09 ` [Qemu-devel] [PATCH 4/5] user-exec: Don't reextract sigmask from usercontext pointer Peter Maydell
2016-05-16 18:00   ` Sergey Fedorov
2016-05-16 16:09 ` [Qemu-devel] [PATCH 5/5] target-i386: Move user-mode exception actions out of user-exec.c Peter Maydell
2016-05-16 17:54   ` Sergey Fedorov
2016-05-16 18:33     ` Peter Maydell
2016-05-16 20:24       ` Peter Maydell
2016-05-17 13:47     ` Peter Maydell

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=573A0A18.9050909@gmail.com \
    --to=serge.fdrv@gmail.com \
    --cc=ehabkost@redhat.com \
    --cc=patches@linaro.org \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=riku.voipio@iki.fi \
    --cc=rth@twiddle.net \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.