diff mbox series

[v2,19/41] hw/core: Add TCGCPUOps.record_sigsegv

Message ID 20210918184527.408540-20-richard.henderson@linaro.org
State Superseded
Headers show
Series linux-user: Streamline handling of SIGSEGV | expand

Commit Message

Richard Henderson Sept. 18, 2021, 6:45 p.m. UTC
Add a new user-only interface for updating cpu state before
raising a signal.  This will replace tlb_fill for user-only
and should result in less boilerplate for each guest.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 include/hw/core/tcg-cpu-ops.h | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

-- 
2.25.1

Comments

Philippe Mathieu-Daudé Sept. 19, 2021, 6:22 p.m. UTC | #1
On 9/18/21 20:45, Richard Henderson wrote:
> Add a new user-only interface for updating cpu state before

> raising a signal.  This will replace tlb_fill for user-only

> and should result in less boilerplate for each guest.

> 

> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

> ---

>  include/hw/core/tcg-cpu-ops.h | 26 ++++++++++++++++++++++++++

>  1 file changed, 26 insertions(+)

> 

> diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h

> index 4a4c4053e3..e229a40772 100644

> --- a/include/hw/core/tcg-cpu-ops.h

> +++ b/include/hw/core/tcg-cpu-ops.h

> @@ -114,6 +114,32 @@ struct TCGCPUOps {

>       */

>      bool (*io_recompile_replay_branch)(CPUState *cpu,

>                                         const TranslationBlock *tb);

> +#else

> +    /**

> +     * record_sigsegv:

> +     * @cpu: cpu context

> +     * @addr: faulting guest address

> +     * @access_type: access was read/write/execute

> +     * @maperr: true for invalid page, false for permission fault

> +     * @ra: host pc for unwinding

> +     *

> +     * We are about to raise SIGSEGV with si_code set for @maperr,

> +     * and si_addr set for @addr.  Record anything further needed

> +     * for the signal ucontext_t.

> +     *

> +     * If the emulated kernel does not provide anything to the signal

> +     * handler with anything besides the user context registers, and

> +     * the siginfo_t, then this hook need do nothing and may be omitted.

> +     * Otherwise, record the data and return; the caller will raise

> +     * the signal, unwind the cpu state, and return to the main loop.

> +     *

> +     * If it is simpler to re-use the sysemu tlb_fill code, @ra is provided

> +     * so that a "normal" cpu exception can be raised.  In this case,

> +     * the signal must be raised by the architecture cpu_loop.

> +     */


Shouldn't it have the QEMU_NORETURN attribute?

> +    void (*record_sigsegv)(CPUState *cpu, vaddr addr,

> +                           MMUAccessType access_type,

> +                           bool maperr, uintptr_t ra);

>  #endif /* CONFIG_SOFTMMU */

>  #endif /* NEED_CPU_H */

>  

>
Philippe Mathieu-Daudé Sept. 19, 2021, 6:24 p.m. UTC | #2
On 9/19/21 20:22, Philippe Mathieu-Daudé wrote:
> On 9/18/21 20:45, Richard Henderson wrote:

>> Add a new user-only interface for updating cpu state before

>> raising a signal.  This will replace tlb_fill for user-only

>> and should result in less boilerplate for each guest.

>>

>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

>> ---

>>  include/hw/core/tcg-cpu-ops.h | 26 ++++++++++++++++++++++++++

>>  1 file changed, 26 insertions(+)

>>

>> diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h

>> index 4a4c4053e3..e229a40772 100644

>> --- a/include/hw/core/tcg-cpu-ops.h

>> +++ b/include/hw/core/tcg-cpu-ops.h

>> @@ -114,6 +114,32 @@ struct TCGCPUOps {

>>       */

>>      bool (*io_recompile_replay_branch)(CPUState *cpu,

>>                                         const TranslationBlock *tb);

>> +#else

>> +    /**

>> +     * record_sigsegv:

>> +     * @cpu: cpu context

>> +     * @addr: faulting guest address

>> +     * @access_type: access was read/write/execute

>> +     * @maperr: true for invalid page, false for permission fault

>> +     * @ra: host pc for unwinding

>> +     *

>> +     * We are about to raise SIGSEGV with si_code set for @maperr,

>> +     * and si_addr set for @addr.  Record anything further needed

>> +     * for the signal ucontext_t.

>> +     *

>> +     * If the emulated kernel does not provide anything to the signal

>> +     * handler with anything besides the user context registers, and

>> +     * the siginfo_t, then this hook need do nothing and may be omitted.

>> +     * Otherwise, record the data and return; the caller will raise

>> +     * the signal, unwind the cpu state, and return to the main loop.

>> +     *

>> +     * If it is simpler to re-use the sysemu tlb_fill code, @ra is provided

>> +     * so that a "normal" cpu exception can be raised.  In this case,

>> +     * the signal must be raised by the architecture cpu_loop.

>> +     */

> 

> Shouldn't it have the QEMU_NORETURN attribute?


Eh now I saw the next patch and understood raise_sigsegv() is
where QEMU_NORETURN belong :)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


> 

>> +    void (*record_sigsegv)(CPUState *cpu, vaddr addr,

>> +                           MMUAccessType access_type,

>> +                           bool maperr, uintptr_t ra);

>>  #endif /* CONFIG_SOFTMMU */

>>  #endif /* NEED_CPU_H */

>>  

>>

> 

>
Richard Henderson Sept. 19, 2021, 6:32 p.m. UTC | #3
On 9/19/21 11:24 AM, Philippe Mathieu-Daudé wrote:
> On 9/19/21 20:22, Philippe Mathieu-Daudé wrote:

>> On 9/18/21 20:45, Richard Henderson wrote:

>>> Add a new user-only interface for updating cpu state before

>>> raising a signal.  This will replace tlb_fill for user-only

>>> and should result in less boilerplate for each guest.

>>>

>>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

>>> ---

>>>   include/hw/core/tcg-cpu-ops.h | 26 ++++++++++++++++++++++++++

>>>   1 file changed, 26 insertions(+)

>>>

>>> diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h

>>> index 4a4c4053e3..e229a40772 100644

>>> --- a/include/hw/core/tcg-cpu-ops.h

>>> +++ b/include/hw/core/tcg-cpu-ops.h

>>> @@ -114,6 +114,32 @@ struct TCGCPUOps {

>>>        */

>>>       bool (*io_recompile_replay_branch)(CPUState *cpu,

>>>                                          const TranslationBlock *tb);

>>> +#else

>>> +    /**

>>> +     * record_sigsegv:

>>> +     * @cpu: cpu context

>>> +     * @addr: faulting guest address

>>> +     * @access_type: access was read/write/execute

>>> +     * @maperr: true for invalid page, false for permission fault

>>> +     * @ra: host pc for unwinding

>>> +     *

>>> +     * We are about to raise SIGSEGV with si_code set for @maperr,

>>> +     * and si_addr set for @addr.  Record anything further needed

>>> +     * for the signal ucontext_t.

>>> +     *

>>> +     * If the emulated kernel does not provide anything to the signal

>>> +     * handler with anything besides the user context registers, and

>>> +     * the siginfo_t, then this hook need do nothing and may be omitted.

>>> +     * Otherwise, record the data and return; the caller will raise

>>> +     * the signal, unwind the cpu state, and return to the main loop.

>>> +     *

>>> +     * If it is simpler to re-use the sysemu tlb_fill code, @ra is provided

>>> +     * so that a "normal" cpu exception can be raised.  In this case,

>>> +     * the signal must be raised by the architecture cpu_loop.

>>> +     */

>>

>> Shouldn't it have the QEMU_NORETURN attribute?

> 

> Eh now I saw the next patch and understood raise_sigsegv() is

> where QEMU_NORETURN belong :)


Well, I had intended the hook to be able to return, so that the hook can merely set some 
env->fields, and return to raise the signal.  But in the end, all 4 targets that use the 
hook raise the exception themselves -- sometimes because env->exception_index is part of 
the data to be passed to the signal handler.


r~
diff mbox series

Patch

diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
index 4a4c4053e3..e229a40772 100644
--- a/include/hw/core/tcg-cpu-ops.h
+++ b/include/hw/core/tcg-cpu-ops.h
@@ -114,6 +114,32 @@  struct TCGCPUOps {
      */
     bool (*io_recompile_replay_branch)(CPUState *cpu,
                                        const TranslationBlock *tb);
+#else
+    /**
+     * record_sigsegv:
+     * @cpu: cpu context
+     * @addr: faulting guest address
+     * @access_type: access was read/write/execute
+     * @maperr: true for invalid page, false for permission fault
+     * @ra: host pc for unwinding
+     *
+     * We are about to raise SIGSEGV with si_code set for @maperr,
+     * and si_addr set for @addr.  Record anything further needed
+     * for the signal ucontext_t.
+     *
+     * If the emulated kernel does not provide anything to the signal
+     * handler with anything besides the user context registers, and
+     * the siginfo_t, then this hook need do nothing and may be omitted.
+     * Otherwise, record the data and return; the caller will raise
+     * the signal, unwind the cpu state, and return to the main loop.
+     *
+     * If it is simpler to re-use the sysemu tlb_fill code, @ra is provided
+     * so that a "normal" cpu exception can be raised.  In this case,
+     * the signal must be raised by the architecture cpu_loop.
+     */
+    void (*record_sigsegv)(CPUState *cpu, vaddr addr,
+                           MMUAccessType access_type,
+                           bool maperr, uintptr_t ra);
 #endif /* CONFIG_SOFTMMU */
 #endif /* NEED_CPU_H */