All of lore.kernel.org
 help / color / mirror / Atom feed
From: mark.rutland@arm.com (Mark Rutland)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 3/4] arm64: unwind: reference pt_regs via embedded stack frame
Date: Tue, 25 Jul 2017 10:53:55 +0100	[thread overview]
Message-ID: <20170725095354.GA25283@leverpostej> (raw)
In-Reply-To: <CAKv+Gu_Xcdrn7rKc3F-e2QmUpjMUVhx-Qdrgn8NHZ1h2G+=YOw@mail.gmail.com>

On Mon, Jul 24, 2017 at 08:09:08PM +0100, Ard Biesheuvel wrote:
> On 24 July 2017 at 19:34, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> > On 24 July 2017 at 18:54, Mark Rutland <mark.rutland@arm.com> wrote:
> >> So here, we're using information from three records (where the last
> >> might have been faked from the current FP + LR). We look at the previous
> >> frame's LR value to determine whether the current frame's fp points to a
> >> next frame that's associated with some regs:
> >>
> >>          +----+----------------+
> >>          | fp | interrupted PC | /* embedded in pt_regs */
> >>          +----+----------------+
> >>            /\
> >>            ||
> >>          +----+----------------+
> >> where => | fp | < entry PC >   |
> >>          +----+----------------+
> >>            /\
> >>            ||
> >>          +----+----------------+
> >>          | fp | where          | /* "where" is in exception text */
> >>          +----+----------------+
> >>
> >> Which (IIUC) has three problems, inherited from the existing approach.

> >> 3) The entry assembly can enable exceptions before calling C code, so if
> >>    an exception is taken at the right time, these will eb in the
> >>    backtrace without a surrounding frame in the exception text.

[...]

> > I guess that's an improvement, yes. At least we won't have false
> > positives where a stack frame is misidentified as being on embedded in
> > pt_regs. But it does rely on the bl instruction being used even in
> > cases where we know we won't be returning, i.e., jumps to bad_mode,
> > do_sp_pc_abort and do_undef_instr from .entry.text

Good point, yes.

This would be good for backtracing, regardless.

> I guess we could do something along the lines of
> 
> """
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index 45947b36f1ff..37f67c2080dc 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -60,6 +60,22 @@
>  #endif
>         .endm
> 
> +       .macro          b_e, target, b=b
> +       .pushsection    ".rodata.entrycalls", "a", @progbits
> +       .align          2
> +       .long           6767f - .
> +       .popsection
> +6767:  \b              \target
> +       .endm
> +
> +       .macro          bl_e, target
> +       b_e             \target, bl
> +       .endm
> +
> +       .macro          blr_e, target
> +       b_e             \target, blr
> +       .endm
> +
>  /*
>   * Bad Abort numbers
>   *-----------------
> @@ -352,7 +368,7 @@ tsk .req    x28             // current thread_info
>         ldr_l   x1, handle_arch_irq
>         mov     x0, sp
>         irq_stack_entry
> -       blr     x1
> +       blr_e   x1
>         irq_stack_exit
>         .endm
> 
> @@ -381,7 +397,7 @@ __bad_stack:
>         mov     x0, sp
> 
>         /* Time to die */
> -       bl      handle_bad_stack
> +       bl_e    handle_bad_stack
>         nop                             // ensure lr points somewhere sane
>  ENDPROC(__bad_stack)
>  #endif /* CONFIG_VMAP_STACK */
> @@ -429,7 +445,7 @@ END(vectors)
>         mov     x0, sp
>         mov     x1, #\reason
>         mrs     x2, esr_el1
> -       b       bad_mode
> +       b_e     bad_mode
>         .endm
> 
>  el0_sync_invalid:
> """
> 
> etc to explicitly record the places where we call out of the entry
> code with a pt_regs struct on the top of the stack.
> 
> Then, we can use
> 
> static bool is_entry_call(unsigned long pc)
> {
>     extern s32 __entrycalls_start[], __entrycalls_end[];
>     s32 *p;
> 
>     for (p = __entrycalls_start; p < __entrycalls_end; p++)
>         if ((unsigned long)p + *p == pc - 4)
>             return true;
>     return false;
> }
> 
> to identify values of frame.pc that coincide with such calls.

Unfortunately, I believe that fails for case (3), where entry code is
interrupted before calling C code. e.g. if an interrupt was taken during
data abort handling:

	kernel_entry 1
	...
el1_da:
	...
	enable_irq
	< interrupted here >
	...
	bl      do_mem_abort

... as we'd dump the regs for the interrupt, but not those for the data
abort.

Thanks,
Mark.

  reply	other threads:[~2017-07-25  9:53 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-24 11:26 [PATCH 0/4] arm64: unwind: fix broken exception stack dump Ard Biesheuvel
2017-07-24 11:26 ` [PATCH 1/4] arm64: avoid percpu indirection for irq stack ops Ard Biesheuvel
2017-07-24 11:26 ` [PATCH 2/4] arm64: unwind: disregard frame.sp when validating frame pointer Ard Biesheuvel
2017-07-24 11:26 ` [PATCH 3/4] arm64: unwind: reference pt_regs via embedded stack frame Ard Biesheuvel
2017-07-24 17:54   ` Mark Rutland
2017-07-24 18:34     ` Ard Biesheuvel
2017-07-24 19:09       ` Ard Biesheuvel
2017-07-25  9:53         ` Mark Rutland [this message]
2017-07-25 10:07           ` Ard Biesheuvel
2017-07-25 13:13     ` Will Deacon
2017-07-25 13:58       ` Mark Rutland
2017-07-24 11:26 ` [PATCH 4/4] arm64: unwind: remove sp from struct stackframe Ard Biesheuvel

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=20170725095354.GA25283@leverpostej \
    --to=mark.rutland@arm.com \
    --cc=linux-arm-kernel@lists.infradead.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 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.