All of lore.kernel.org
 help / color / mirror / Atom feed
From: Haibo Li <haibo.li@mediatek.com>
To: Russell King <linux@armlinux.org.uk>,
	Alexandre Mergnat <amergnat@baylibre.com>,
	Linus Walleij <linus.walleij@linaro.org>
Cc: Matthias Brugger <matthias.bgg@gmail.com>,
	AngeloGioacchino Del Regno
	<angelogioacchino.delregno@collabora.com>,
	Haibo Li <haibo.li@mediatek.com>,
	"Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-kernel@vger.kernel.org>,
	<linux-mediatek@lists.infradead.org>, <xiaoming.yu@mediatek.com>
Subject: [PATCH] ARM: unwind: fix unwind started from IRQ stack in THUMB2 kernel
Date: Wed, 28 Feb 2024 15:32:47 +0800	[thread overview]
Message-ID: <20240228073247.13102-1-haibo.li@mediatek.com> (raw)

When unwinds started from IRQ stack,call_with_stack is the only
place to do stack switch.
It need to identify call_with_stack when unwinding.

In thumb2 kernel,it fails to identify call_with_stack.
In practice,(u32)&call_with_stack has bit 0 set.

	prel31_to_addr(&idx->addr_offset) is 0x806ed518,
	while (u32)&call_with_stack is 0x806ed519.
So it is impossible to do stack switch.

dump_stack from IRQ stack gets below result:
...
 call_timer_fn from __run_timers+0x163/0x25c
 __run_timers from run_timer_softirq+0x15/0x24
 run_timer_softirq from __do_softirq+0xe3/0x232
 __do_softirq from __irq_exit_rcu+0x3f/0xac
 __irq_exit_rcu from irq_exit+0x7/0xe
 irq_exit from call_with_stack+0xd/0x10
...
The stacktrace ends with call_with_stack.

Since bit 0 of pc in thumb2 is always 0,skip bit 0 when do compraing.
Then we get expected stacktrace:
...
 call_timer_fn from __run_timers+0x163/0x25c
 __run_timers from run_timer_softirq+0x15/0x24
 run_timer_softirq from __do_softirq+0xe3/0x232
 __do_softirq from __irq_exit_rcu+0x3f/0xac
 __irq_exit_rcu from irq_exit+0x7/0xe
 irq_exit from call_with_stack+0xd/0x10
 call_with_stack from __irq_svc+0x93/0xb6
Exception stack(0xf0875f60 to 0xf0875fa8)
5f60: ****
5f80: ****
5fa0: ****
 __irq_svc from arch_local_irq_enable+0x2/0x4
 arch_local_irq_enable from do_idle+0xad/0x1f6
...

Signed-off-by: Haibo Li <haibo.li@mediatek.com>
---
 arch/arm/kernel/unwind.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index 9d2192156087..89e1f440082c 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -482,7 +482,8 @@ int unwind_frame(struct stackframe *frame)
 
 	ctrl.check_each_pop = 0;
 
-	if (prel31_to_addr(&idx->addr_offset) == (u32)&call_with_stack) {
+	if (prel31_to_addr(&idx->addr_offset) ==
+		((u32)&call_with_stack & (~0x01))) {
 		/*
 		 * call_with_stack() is the only place where we permit SP to
 		 * jump from one stack to another, and since we know it is
-- 
2.18.0


WARNING: multiple messages have this Message-ID (diff)
From: Haibo Li <haibo.li@mediatek.com>
To: Russell King <linux@armlinux.org.uk>,
	Alexandre Mergnat <amergnat@baylibre.com>,
	Linus Walleij <linus.walleij@linaro.org>
Cc: Matthias Brugger <matthias.bgg@gmail.com>,
	AngeloGioacchino Del Regno
	<angelogioacchino.delregno@collabora.com>,
	Haibo Li <haibo.li@mediatek.com>,
	"Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-kernel@vger.kernel.org>,
	<linux-mediatek@lists.infradead.org>, <xiaoming.yu@mediatek.com>
Subject: [PATCH] ARM: unwind: fix unwind started from IRQ stack in THUMB2 kernel
Date: Wed, 28 Feb 2024 15:32:47 +0800	[thread overview]
Message-ID: <20240228073247.13102-1-haibo.li@mediatek.com> (raw)

When unwinds started from IRQ stack,call_with_stack is the only
place to do stack switch.
It need to identify call_with_stack when unwinding.

In thumb2 kernel,it fails to identify call_with_stack.
In practice,(u32)&call_with_stack has bit 0 set.

	prel31_to_addr(&idx->addr_offset) is 0x806ed518,
	while (u32)&call_with_stack is 0x806ed519.
So it is impossible to do stack switch.

dump_stack from IRQ stack gets below result:
...
 call_timer_fn from __run_timers+0x163/0x25c
 __run_timers from run_timer_softirq+0x15/0x24
 run_timer_softirq from __do_softirq+0xe3/0x232
 __do_softirq from __irq_exit_rcu+0x3f/0xac
 __irq_exit_rcu from irq_exit+0x7/0xe
 irq_exit from call_with_stack+0xd/0x10
...
The stacktrace ends with call_with_stack.

Since bit 0 of pc in thumb2 is always 0,skip bit 0 when do compraing.
Then we get expected stacktrace:
...
 call_timer_fn from __run_timers+0x163/0x25c
 __run_timers from run_timer_softirq+0x15/0x24
 run_timer_softirq from __do_softirq+0xe3/0x232
 __do_softirq from __irq_exit_rcu+0x3f/0xac
 __irq_exit_rcu from irq_exit+0x7/0xe
 irq_exit from call_with_stack+0xd/0x10
 call_with_stack from __irq_svc+0x93/0xb6
Exception stack(0xf0875f60 to 0xf0875fa8)
5f60: ****
5f80: ****
5fa0: ****
 __irq_svc from arch_local_irq_enable+0x2/0x4
 arch_local_irq_enable from do_idle+0xad/0x1f6
...

Signed-off-by: Haibo Li <haibo.li@mediatek.com>
---
 arch/arm/kernel/unwind.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index 9d2192156087..89e1f440082c 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -482,7 +482,8 @@ int unwind_frame(struct stackframe *frame)
 
 	ctrl.check_each_pop = 0;
 
-	if (prel31_to_addr(&idx->addr_offset) == (u32)&call_with_stack) {
+	if (prel31_to_addr(&idx->addr_offset) ==
+		((u32)&call_with_stack & (~0x01))) {
 		/*
 		 * call_with_stack() is the only place where we permit SP to
 		 * jump from one stack to another, and since we know it is
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

             reply	other threads:[~2024-02-28  7:32 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-28  7:32 Haibo Li [this message]
2024-02-28  7:32 ` [PATCH] ARM: unwind: fix unwind started from IRQ stack in THUMB2 kernel Haibo Li

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=20240228073247.13102-1-haibo.li@mediatek.com \
    --to=haibo.li@mediatek.com \
    --cc=amergnat@baylibre.com \
    --cc=angelogioacchino.delregno@collabora.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=linux@armlinux.org.uk \
    --cc=matthias.bgg@gmail.com \
    --cc=rmk+kernel@armlinux.org.uk \
    --cc=xiaoming.yu@mediatek.com \
    /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.