[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH] cpu-exec: Don't mask out external interrupts wh
From: |
Peter Maydell |
Subject: |
Re: [Qemu-devel] [PATCH] cpu-exec: Don't mask out external interrupts when single-stepping an invalid instruction. |
Date: |
Thu, 11 Sep 2014 23:13:52 +0100 |
[cc'ing RTH who may have a better grasp on how the builtin single step is
supposed to work.]
On 11 September 2014 22:02, Martin Galvan
<address@hidden> wrote:
> When using Gdb to remote-debug a program, if we try to single-step an
> invalid instruction,
> Qemu will never return control to the remote Gdb.
> The source of this problem is external interrupts being masked out
> in cpu_exec if cpu->singlestep_enabled has the SSTEP_NOIRQ flag set.
> To solve this I've added an additional flag, SSTEP_EXCEPTION,
> that will be set in the exception_with_syndrome instruction generated
> when trying to translate the invalid instruction and will be cleared
> after checking for cpu->singlestep_enabled in cpu_exec.
>
> Signed-off-by: Martin Galvan <address@hidden>
> ---
>
> The long story: Qemu generates an exception_with_syndrome instruction
> when it realizes the instruction it's trying to translate is invalid.
> That instruction in turn modifies cs->exception_index and calls cpu_loop_exit.
> Normally, the value in cs->exception_index would cause do_interrupt to set
> the PC to point to the corresponding exception handler.
> However, since we're masking out IRQs, the PC will never be set correctly.
> Even worse, since Qemu will have generated an internal exception
> to return control back to the remote Gdb *after* it generated the syndrome
> one,
> its code will appear after the call to cpu_loop_exit.
> Since the PC won't have changed, we'll try to excecute
> the same translation block as before, thus calling cpu_loop_exit
> again, and so on.
>
> Here's the bug tracker link: https://bugs.launchpad.net/qemu/+bug/1364501
>
> cpu-exec.c | 6 +++++-
> include/qom/cpu.h | 5 +++++
> target-arm/op_helper.c | 5 +++++
> 3 files changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/cpu-exec.c b/cpu-exec.c
> index 5fa172c..5d9f231 100644
> --- a/cpu-exec.c
> +++ b/cpu-exec.c
> @@ -448,9 +448,13 @@ int cpu_exec(CPUArchState *env)
> for(;;) {
> interrupt_request = cpu->interrupt_request;
> if (unlikely(interrupt_request)) {
> - if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) {
> + if (unlikely((cpu->singlestep_enabled & SSTEP_NOIRQ) &&
> + !(cpu->singlestep_enabled & SSTEP_EXCEPTION))) {
> /* Mask out external interrupts for this step. */
> interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
> + } else { /* An exception occured; don't mask out
> this one */
> + /* Mask out any future external interrupts */
> + cpu->singlestep_enabled &= ~SSTEP_EXCEPTION;
> }
> if (interrupt_request & CPU_INTERRUPT_DEBUG) {
> cpu->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index f2df033..a57800f 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -607,6 +607,11 @@ void qemu_init_vcpu(CPUState *cpu);
> #define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */
> #define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */
> #define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */
> +#define SSTEP_EXCEPTION 0x8 /* Don't mask out exception-related
> IRQs. Set only if
> + * we have to process an exception while single-
> + * stepping (such as when
> single-stepping an invalid
> + * instruction).
> + */
>
> /**
> * cpu_single_step:
> diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
> index fe40358..2139ea6 100644
> --- a/target-arm/op_helper.c
> +++ b/target-arm/op_helper.c
> @@ -251,6 +251,11 @@ void HELPER(exception_with_syndrome)(CPUARMState
> *env, uint32_t excp,
> CPUState *cs = CPU(arm_env_get_cpu(env));
>
> assert(!excp_is_internal(excp));
> +
> + if (unlikely(cs->singlestep_enabled & SSTEP_NOIRQ)) {
> + cs->singlestep_enabled |= SSTEP_EXCEPTION;
> + }
> +
> cs->exception_index = excp;
> env->exception.syndrome = syndrome;
> cpu_loop_exit(cs);
> --
> 1.9.1
>
> --
>
> Martín Galván
>
> Software Engineer
>
> Taller Technologies Argentina
>
> San Lorenzo 47, 3rd Floor, Office 5
>
> Córdoba, Argentina
>
> Phone: 54 351 4217888 / +54 351 4218211
thanks
-- PMM
- [Qemu-devel] [PATCH] cpu-exec: Don't mask out external interrupts when single-stepping an invalid instruction., Martin Galvan, 2014/09/11
- Re: [Qemu-devel] [PATCH] cpu-exec: Don't mask out external interrupts when single-stepping an invalid instruction.,
Peter Maydell <=
- Re: [Qemu-devel] [PATCH] cpu-exec: Don't mask out external interrupts when single-stepping an invalid instruction., Richard Henderson, 2014/09/11
- Re: [Qemu-devel] [PATCH] cpu-exec: Don't mask out external interrupts when single-stepping an invalid instruction., Martin Galvan, 2014/09/12
- Re: [Qemu-devel] [PATCH] cpu-exec: Don't mask out external interrupts when single-stepping an invalid instruction., Richard Henderson, 2014/09/12
- Re: [Qemu-devel] [PATCH] cpu-exec: Don't mask out external interrupts when single-stepping an invalid instruction., Martin Galvan, 2014/09/12
- Re: [Qemu-devel] [PATCH] cpu-exec: Don't mask out external interrupts when single-stepping an invalid instruction., Martin Galvan, 2014/09/15
- Re: [Qemu-devel] [PATCH] cpu-exec: Don't mask out external interrupts when single-stepping an invalid instruction., Peter Maydell, 2014/09/15
- Re: [Qemu-devel] [PATCH] cpu-exec: Don't mask out external interrupts when single-stepping an invalid instruction., Andreas Färber, 2014/09/15
- Re: [Qemu-devel] [PATCH] cpu-exec: Don't mask out external interrupts when single-stepping an invalid instruction., Peter Maydell, 2014/09/15