[RFC PATCH 0/7] linux-user: Streamline handling of SIGSEGV/SIGBUS

Richard Henderson posted 7 patches 2 years, 7 months ago
Test checkpatch passed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20210913220552.604064-1-richard.henderson@linaro.org
Maintainers: Chris Wulff <crwulff@gmail.com>, Richard Henderson <richard.henderson@linaro.org>, Marek Vasut <marex@denx.de>, Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>, Aleksandar Rikalo <aleksandar.rikalo@syrmia.com>, Riku Voipio <riku.voipio@iki.fi>, David Hildenbrand <david@redhat.com>, Laurent Vivier <laurent@vivier.eu>, Stafford Horne <shorne@gmail.com>, Peter Maydell <peter.maydell@linaro.org>, Bin Meng <bin.meng@windriver.com>, Artyom Tarasenko <atar4qemu@gmail.com>, David Gibson <david@gibson.dropbear.id.au>, Jiaxun Yang <jiaxun.yang@flygoat.com>, "Philippe Mathieu-Daudé" <f4bug@amsat.org>, Thomas Huth <thuth@redhat.com>, Aurelien Jarno <aurelien@aurel32.net>, Palmer Dabbelt <palmer@dabbelt.com>, Greg Kurz <groug@kaod.org>, Alistair Francis <alistair.francis@wdc.com>, Yoshinori Sato <ysato@users.sourceforge.jp>, "Edgar E. Iglesias" <edgar.iglesias@gmail.com>, Taylor Simpson <tsimpson@quicinc.com>, Max Filippov <jcmvbkbc@gmail.com>, Bastian Koppelmann <kbastian@mail.uni-paderborn.de>, Michael Rolnik <mrolnik@gmail.com>, Cornelia Huck <cohuck@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>
include/exec/exec-all.h               |  21 +
linux-user/host/aarch64/host-signal.h |  73 +++
linux-user/host/alpha/host-signal.h   |  41 ++
linux-user/host/arm/host-signal.h     |  30 +
linux-user/host/i386/host-signal.h    |  24 +
linux-user/host/mips/host-signal.h    |  61 ++
linux-user/host/ppc/host-signal.h     |  24 +
linux-user/host/ppc64/host-signal.h   |   1 +
linux-user/host/riscv32/host-signal.h |  57 ++
linux-user/host/riscv64/host-signal.h |   1 +
linux-user/host/s390/host-signal.h    |  92 +++
linux-user/host/s390x/host-signal.h   |   1 +
linux-user/host/sparc/host-signal.h   |  53 ++
linux-user/host/sparc64/host-signal.h |   1 +
linux-user/host/x86_64/host-signal.h  |  24 +
target/alpha/cpu.h                    |   6 -
target/arm/cpu.h                      |   7 -
target/avr/cpu.h                      |   2 -
target/cris/cpu.h                     |   8 -
target/hexagon/cpu.h                  |   3 -
target/hppa/cpu.h                     |   3 -
target/i386/cpu.h                     |   7 -
target/m68k/cpu.h                     |   8 -
target/microblaze/cpu.h               |   7 -
target/mips/cpu.h                     |   3 -
target/mips/internal.h                |   2 -
target/nios2/cpu.h                    |   2 -
target/openrisc/cpu.h                 |   2 -
target/ppc/cpu.h                      |   7 -
target/riscv/cpu.h                    |   2 -
target/rx/cpu.h                       |   4 -
target/s390x/cpu.h                    |   7 -
target/sh4/cpu.h                      |   3 -
target/sparc/cpu.h                    |   2 -
target/tricore/cpu.h                  |   2 -
target/xtensa/cpu.h                   |   2 -
accel/tcg/cpu-exec.c                  |   3 +-
accel/tcg/user-exec.c                 | 807 ++------------------------
linux-user/signal.c                   | 102 ++--
39 files changed, 635 insertions(+), 870 deletions(-)
create mode 100644 linux-user/host/aarch64/host-signal.h
create mode 100644 linux-user/host/alpha/host-signal.h
create mode 100644 linux-user/host/arm/host-signal.h
create mode 100644 linux-user/host/i386/host-signal.h
create mode 100644 linux-user/host/mips/host-signal.h
create mode 100644 linux-user/host/ppc/host-signal.h
create mode 100644 linux-user/host/ppc64/host-signal.h
create mode 100644 linux-user/host/riscv32/host-signal.h
create mode 100644 linux-user/host/riscv64/host-signal.h
create mode 100644 linux-user/host/s390/host-signal.h
create mode 100644 linux-user/host/s390x/host-signal.h
create mode 100644 linux-user/host/sparc/host-signal.h
create mode 100644 linux-user/host/sparc64/host-signal.h
create mode 100644 linux-user/host/x86_64/host-signal.h
[RFC PATCH 0/7] linux-user: Streamline handling of SIGSEGV/SIGBUS
Posted by Richard Henderson 2 years, 7 months ago
Our current setup is:

  host_signal_handler
  cpu_signal_handler
     handle_cpu_signal
        cc->tcg_ops->tlb_fill
           raise_exception
  cpu_loop
     queue_signal

and in the process lose information from the host siginfo_t,
which we (mostly) do not recreate properly.  Moreover, the
intermediate cpu_signal_handler handles the host-specific
portions of extracting pc + is_write from the ucontext_t.

I'm replacing this with

  host_signal_handler
    host_signal_pc
    host_sigsegv_write
    adjust_signal_pc
    handle_sigsegv_accerr_write
    queue_signal
    raise_exception
  cpu_loop

All of the really tcg-specific portions are still in user-exec.c,
and all of the really host-specific portions are now ditributed
across linux-user/host/<arch>/.  Importantly, SEGV_MAPERR and
SEGV_ACCERR are now passed through from the host kernel -- or at
least there's a single place from which to manage it [1].

Note that I've dropped all of the BSD (and Solaris!) code from
user-exec.c.  I thought about moving it similar to linux-user,
but I've caught Warner in the middle of his re-org and the whole
of bsd-user/signal.c is currently empty.  I think it will be
easier to create the new interfaces from scratch when ready.

Still to-do:
  * Make cc->tcg_ops->tlb_fill sysemu only (once again).
  * Drop all of the code from cpu_loop that interfaced with tlb_fill.


r~


[1] I've just this minute realized that the reserved_va mapping that we
do for emulating 32-bit guests will incorrectly give SEGV_ACCERR for pages
that are not mapped by the guest, and should result in SEGV_MAPERR.


Richard Henderson (7):
  include/exec: Move cpu_signal_handler declaration
  accel/tcg: Split out adjust_signal_pc
  accel/tcg: Split out handle_sigsegv_accerr_write
  accel/tcg: Move clear_helper_retaddr to cpu loop
  accel/tcg: Fold cpu_exit_tb_from_sighandler into caller
  linux-user: Handle SIGSEGV/SIGBUS in host_to_target_siginfo_noswap
  linux-user: Reorg cpu_signal_handler

 include/exec/exec-all.h               |  21 +
 linux-user/host/aarch64/host-signal.h |  73 +++
 linux-user/host/alpha/host-signal.h   |  41 ++
 linux-user/host/arm/host-signal.h     |  30 +
 linux-user/host/i386/host-signal.h    |  24 +
 linux-user/host/mips/host-signal.h    |  61 ++
 linux-user/host/ppc/host-signal.h     |  24 +
 linux-user/host/ppc64/host-signal.h   |   1 +
 linux-user/host/riscv32/host-signal.h |  57 ++
 linux-user/host/riscv64/host-signal.h |   1 +
 linux-user/host/s390/host-signal.h    |  92 +++
 linux-user/host/s390x/host-signal.h   |   1 +
 linux-user/host/sparc/host-signal.h   |  53 ++
 linux-user/host/sparc64/host-signal.h |   1 +
 linux-user/host/x86_64/host-signal.h  |  24 +
 target/alpha/cpu.h                    |   6 -
 target/arm/cpu.h                      |   7 -
 target/avr/cpu.h                      |   2 -
 target/cris/cpu.h                     |   8 -
 target/hexagon/cpu.h                  |   3 -
 target/hppa/cpu.h                     |   3 -
 target/i386/cpu.h                     |   7 -
 target/m68k/cpu.h                     |   8 -
 target/microblaze/cpu.h               |   7 -
 target/mips/cpu.h                     |   3 -
 target/mips/internal.h                |   2 -
 target/nios2/cpu.h                    |   2 -
 target/openrisc/cpu.h                 |   2 -
 target/ppc/cpu.h                      |   7 -
 target/riscv/cpu.h                    |   2 -
 target/rx/cpu.h                       |   4 -
 target/s390x/cpu.h                    |   7 -
 target/sh4/cpu.h                      |   3 -
 target/sparc/cpu.h                    |   2 -
 target/tricore/cpu.h                  |   2 -
 target/xtensa/cpu.h                   |   2 -
 accel/tcg/cpu-exec.c                  |   3 +-
 accel/tcg/user-exec.c                 | 807 ++------------------------
 linux-user/signal.c                   | 102 ++--
 39 files changed, 635 insertions(+), 870 deletions(-)
 create mode 100644 linux-user/host/aarch64/host-signal.h
 create mode 100644 linux-user/host/alpha/host-signal.h
 create mode 100644 linux-user/host/arm/host-signal.h
 create mode 100644 linux-user/host/i386/host-signal.h
 create mode 100644 linux-user/host/mips/host-signal.h
 create mode 100644 linux-user/host/ppc/host-signal.h
 create mode 100644 linux-user/host/ppc64/host-signal.h
 create mode 100644 linux-user/host/riscv32/host-signal.h
 create mode 100644 linux-user/host/riscv64/host-signal.h
 create mode 100644 linux-user/host/s390/host-signal.h
 create mode 100644 linux-user/host/s390x/host-signal.h
 create mode 100644 linux-user/host/sparc/host-signal.h
 create mode 100644 linux-user/host/sparc64/host-signal.h
 create mode 100644 linux-user/host/x86_64/host-signal.h

-- 
2.25.1


Re: [RFC PATCH 0/7] linux-user: Streamline handling of SIGSEGV/SIGBUS
Posted by Richard Henderson 2 years, 7 months ago
On 9/13/21 3:05 PM, Richard Henderson wrote:
> All of the really tcg-specific portions are still in user-exec.c,
> and all of the really host-specific portions are now ditributed
> across linux-user/host/<arch>/.  Importantly, SEGV_MAPERR and
> SEGV_ACCERR are now passed through from the host kernel -- or at
> least there's a single place from which to manage it [1].

Hum.  And then there's the special case of s390x, where the hw does not provide the exact 
address on faults, but only the page.  We have code for that in cpu_loop, but I have to 
invent some new hook in this new scheme.


r~