* Breakage in arch/mips/kernel/traps.c for 64bit
@ 2008-05-01 16:33 Thomas Bogendoerfer
2008-05-01 21:01 ` Maciej W. Rozycki
2008-05-02 10:11 ` Ralf Baechle
0 siblings, 2 replies; 10+ messages in thread
From: Thomas Bogendoerfer @ 2008-05-01 16:33 UTC (permalink / raw)
To: linux-mips
Hi,
it would be nice, if people started thinking before supplying such
crappy^Winteresting code:
arch/mips/kernel/traps.c:
#define IS_KVA01(a) ((((unsigned int)a) & 0xc0000000) == 0x80000000)
Kills every 64bit kernel build...
Why is this needed at all ?
Thomas.
--
Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Breakage in arch/mips/kernel/traps.c for 64bit
2008-05-01 16:33 Breakage in arch/mips/kernel/traps.c for 64bit Thomas Bogendoerfer
@ 2008-05-01 21:01 ` Maciej W. Rozycki
2008-05-02 10:11 ` Ralf Baechle
1 sibling, 0 replies; 10+ messages in thread
From: Maciej W. Rozycki @ 2008-05-01 21:01 UTC (permalink / raw)
To: Thomas Bogendoerfer; +Cc: linux-mips
On Thu, 1 May 2008, Thomas Bogendoerfer wrote:
> it would be nice, if people started thinking before supplying such
> crappy^Winteresting code:
>
> arch/mips/kernel/traps.c:
>
> #define IS_KVA01(a) ((((unsigned int)a) & 0xc0000000) == 0x80000000)
>
> Kills every 64bit kernel build...
Not everybody tests 64-bit stuff as some people limit themselves to
32-bit systems only. It looks like a step backwards, but there you go.
> Why is this needed at all ?
It looks like an attempt to avoid TLB exceptions for the stack dump -- if
that is the case, then obviously a piece of code like one in
arch/mips/lib/uncached.c should be used to check for CKSEG0/1 and XKPHYS.
If there are two uses of this code, then it should be wrapped in an inline
function and put in a header; <asm/addrspace.h>, perhaps.
Maciej
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Breakage in arch/mips/kernel/traps.c for 64bit
2008-05-01 16:33 Breakage in arch/mips/kernel/traps.c for 64bit Thomas Bogendoerfer
2008-05-01 21:01 ` Maciej W. Rozycki
@ 2008-05-02 10:11 ` Ralf Baechle
2008-05-03 16:16 ` Atsushi Nemoto
1 sibling, 1 reply; 10+ messages in thread
From: Ralf Baechle @ 2008-05-02 10:11 UTC (permalink / raw)
To: Thomas Bogendoerfer; +Cc: linux-mips
On Thu, May 01, 2008 at 06:33:14PM +0200, Thomas Bogendoerfer wrote:
> it would be nice, if people started thinking before supplying such
> crappy^Winteresting code:
>
> arch/mips/kernel/traps.c:
>
> #define IS_KVA01(a) ((((unsigned int)a) & 0xc0000000) == 0x80000000)
>
> Kills every 64bit kernel build...
>
> Why is this needed at all ?
It came as part of 39b8d5254246ac56342b72f812255c8f7a74dca9 which is a
patch amalgated from several other patches. Below is the original patch
it came with. I think the idea of the patch is valid but the idea needs a
bit of mending.
From: Chris Dearman <chris@mips.com>
Date: Wed, 3 Oct 2007 10:19:18 +0100
Subject: [PATCH] Skip raw backtrace for non KSEG stack addresses
This is to avoid recursive stackdumps as the kernel kernel falls off
of the user stack.
Signed-off-by: Chris Dearman <chris@mips.com>
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 2948b86..3d56171 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -79,19 +79,22 @@ void (*board_bind_eic_interrupt)(int irq, int regset);
static void show_raw_backtrace(unsigned long reg29)
{
- unsigned long *sp = (unsigned long *)reg29;
+ unsigned long *sp = (unsigned long *)(reg29 & ~3);
unsigned long addr;
printk("Call Trace:");
#ifdef CONFIG_KALLSYMS
printk("\n");
#endif
- while (!kstack_end(sp)) {
- addr = *sp++;
- if (__kernel_text_address(addr))
- print_ip_sym(addr);
+#define IS_KVA01(a) ((((unsigned int)a) & 0xc0000000) == 0x80000000)
+ if (IS_KVA01(sp)) {
+ while (!kstack_end(sp)) {
+ addr = *sp++;
+ if (__kernel_text_address(addr))
+ print_ip_sym(addr);
+ }
+ printk("\n");
}
- printk("\n");
}
#ifdef CONFIG_KALLSYMS
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: Breakage in arch/mips/kernel/traps.c for 64bit
2008-05-02 10:11 ` Ralf Baechle
@ 2008-05-03 16:16 ` Atsushi Nemoto
2008-05-03 17:39 ` Ralf Baechle
2008-05-03 22:48 ` Thomas Bogendoerfer
0 siblings, 2 replies; 10+ messages in thread
From: Atsushi Nemoto @ 2008-05-03 16:16 UTC (permalink / raw)
To: ralf; +Cc: tsbogend, linux-mips
On Fri, 2 May 2008 11:11:13 +0100, Ralf Baechle <ralf@linux-mips.org> wrote:
> It came as part of 39b8d5254246ac56342b72f812255c8f7a74dca9 which is a
> patch amalgated from several other patches. Below is the original patch
> it came with. I think the idea of the patch is valid but the idea needs a
> bit of mending.
Then how about this fix?
---------------------------------------------------------------------
Subject: [PATCH] Fix detection of kernel segment on 64-bit
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
---
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index cb8b0e2..7893bb3 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -78,6 +78,19 @@ void (*board_nmi_handler_setup)(void);
void (*board_ejtag_handler_setup)(void);
void (*board_bind_eic_interrupt)(int irq, int regset);
+static inline int kernel_unmapped_seg(void *addr)
+{
+ unsigned long a = (unsigned long)addr;
+
+#ifdef CONFIG_32BIT
+ /* KSEG0 or KSEG1 */
+ return (a & 0xc0000000) == KSEG0;
+#else
+ /* CKSEG0, CKSEG1 or XKPHYS */
+ return ((a & 0xffffffffc0000000L) == CKSEG0) ||
+ ((a & 0xc000000000000000L) == XKPHYS);
+#endif
+}
static void show_raw_backtrace(unsigned long reg29)
{
@@ -88,8 +101,7 @@ static void show_raw_backtrace(unsigned long reg29)
#ifdef CONFIG_KALLSYMS
printk("\n");
#endif
-#define IS_KVA01(a) ((((unsigned int)a) & 0xc0000000) == 0x80000000)
- if (IS_KVA01(sp)) {
+ if (kernel_unmapped_seg(sp)) {
while (!kstack_end(sp)) {
addr = *sp++;
if (__kernel_text_address(addr))
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: Breakage in arch/mips/kernel/traps.c for 64bit
2008-05-03 16:16 ` Atsushi Nemoto
@ 2008-05-03 17:39 ` Ralf Baechle
2008-05-03 19:57 ` Maciej W. Rozycki
2008-05-03 22:48 ` Thomas Bogendoerfer
1 sibling, 1 reply; 10+ messages in thread
From: Ralf Baechle @ 2008-05-03 17:39 UTC (permalink / raw)
To: Atsushi Nemoto; +Cc: tsbogend, linux-mips
On Sun, May 04, 2008 at 01:16:47AM +0900, Atsushi Nemoto wrote:
> Then how about this fix?
>
> ---------------------------------------------------------------------
> Subject: [PATCH] Fix detection of kernel segment on 64-bit
>
> Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
> ---
> diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
> index cb8b0e2..7893bb3 100644
> --- a/arch/mips/kernel/traps.c
> +++ b/arch/mips/kernel/traps.c
> @@ -78,6 +78,19 @@ void (*board_nmi_handler_setup)(void);
> void (*board_ejtag_handler_setup)(void);
> void (*board_bind_eic_interrupt)(int irq, int regset);
>
> +static inline int kernel_unmapped_seg(void *addr)
> +{
> + unsigned long a = (unsigned long)addr;
> +
> +#ifdef CONFIG_32BIT
> + /* KSEG0 or KSEG1 */
> + return (a & 0xc0000000) == KSEG0;
Slightly cleaner:
return KSEGX(a) == KSEG0;
Unfortunately there is no such macro for the 64-bit segments nor does
the existing KSEGX() work correctly for non-CKSEGx 64-bit addresses.
Ralf
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: Breakage in arch/mips/kernel/traps.c for 64bit
2008-05-03 17:39 ` Ralf Baechle
@ 2008-05-03 19:57 ` Maciej W. Rozycki
0 siblings, 0 replies; 10+ messages in thread
From: Maciej W. Rozycki @ 2008-05-03 19:57 UTC (permalink / raw)
To: Ralf Baechle; +Cc: Atsushi Nemoto, tsbogend, linux-mips
On Sat, 3 May 2008, Ralf Baechle wrote:
> Slightly cleaner:
>
> return KSEGX(a) == KSEG0;
You mean:
return KSEGX(a) == KSEG0 || KSEGX(a) == KSEG1;
right?
> Unfortunately there is no such macro for the 64-bit segments nor does
> the existing KSEGX() work correctly for non-CKSEGx 64-bit addresses.
As I mentioned there is suitable code doing exactly this in
arch/mips/lib/uncached.c and it can be extracted to an inline function to
be put in <asm/addrspace.h> to be reused here and in the future possibly
elsewhere.
Maciej
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Breakage in arch/mips/kernel/traps.c for 64bit
2008-05-03 16:16 ` Atsushi Nemoto
2008-05-03 17:39 ` Ralf Baechle
@ 2008-05-03 22:48 ` Thomas Bogendoerfer
2008-05-04 13:39 ` Atsushi Nemoto
1 sibling, 1 reply; 10+ messages in thread
From: Thomas Bogendoerfer @ 2008-05-03 22:48 UTC (permalink / raw)
To: Atsushi Nemoto; +Cc: ralf, linux-mips
On Sun, May 04, 2008 at 01:16:47AM +0900, Atsushi Nemoto wrote:
> On Fri, 2 May 2008 11:11:13 +0100, Ralf Baechle <ralf@linux-mips.org> wrote:
> > It came as part of 39b8d5254246ac56342b72f812255c8f7a74dca9 which is a
> > patch amalgated from several other patches. Below is the original patch
> > it came with. I think the idea of the patch is valid but the idea needs a
> > bit of mending.
>
> Then how about this fix?
hmm, why not simply use __get_user() when accessing the stack content ?
show_stacktrace() already does it for stack dumping ? This would
avoid any work for whatever sick stack mappings. Below is a patch,
which does this.
Thomas.
The newly added check for valid stack pointer address breaks at least for
64bit kernels. Use __get_user() for accessing stack content to avoid crashes,
when doing the backtrace.
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
arch/mips/kernel/traps.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index cb8b0e2..c9ce8d6 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -81,22 +81,22 @@ void (*board_bind_eic_interrupt)(int irq, int regset);
static void show_raw_backtrace(unsigned long reg29)
{
- unsigned long *sp = (unsigned long *)(reg29 & ~3);
+ unsigned long __user *sp = (unsigned long __user *)(reg29 & ~3);
unsigned long addr;
printk("Call Trace:");
#ifdef CONFIG_KALLSYMS
printk("\n");
#endif
-#define IS_KVA01(a) ((((unsigned int)a) & 0xc0000000) == 0x80000000)
- if (IS_KVA01(sp)) {
- while (!kstack_end(sp)) {
- addr = *sp++;
- if (__kernel_text_address(addr))
- print_ip_sym(addr);
+ while (!kstack_end(sp)) {
+ if (__get_user(addr, sp++)) {
+ printk(" (Bad stack address)");
+ break;
}
- printk("\n");
+ if (__kernel_text_address(addr))
+ print_ip_sym(addr);
}
+ printk("\n");
}
#ifdef CONFIG_KALLSYMS
--
Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: Breakage in arch/mips/kernel/traps.c for 64bit
2008-05-03 22:48 ` Thomas Bogendoerfer
@ 2008-05-04 13:39 ` Atsushi Nemoto
2008-05-04 22:08 ` Thomas Bogendoerfer
0 siblings, 1 reply; 10+ messages in thread
From: Atsushi Nemoto @ 2008-05-04 13:39 UTC (permalink / raw)
To: tsbogend; +Cc: ralf, linux-mips
On Sun, 4 May 2008 00:48:49 +0200, tsbogend@alpha.franken.de (Thomas Bogendoerfer) wrote:
> hmm, why not simply use __get_user() when accessing the stack content ?
> show_stacktrace() already does it for stack dumping ? This would
> avoid any work for whatever sick stack mappings. Below is a patch,
> which does this.
I like this patch. One minor request:
> + unsigned long __user *sp = (unsigned long __user *)(reg29 & ~3);
...
> + while (!kstack_end(sp)) {
> + if (__get_user(addr, sp++)) {
This will leads a sparse warning since an argument for kstack_end is 'void *'.
while (!kstack_end((void *)(unsigned long)sp)) {
will make this part sparse-free, though it seems a bit ugly.
---
Atsushi Nemoto
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: Breakage in arch/mips/kernel/traps.c for 64bit
2008-05-04 13:39 ` Atsushi Nemoto
@ 2008-05-04 22:08 ` Thomas Bogendoerfer
2008-05-05 14:58 ` Atsushi Nemoto
0 siblings, 1 reply; 10+ messages in thread
From: Thomas Bogendoerfer @ 2008-05-04 22:08 UTC (permalink / raw)
To: Atsushi Nemoto; +Cc: ralf, linux-mips
On Sun, May 04, 2008 at 10:39:44PM +0900, Atsushi Nemoto wrote:
> > + unsigned long __user *sp = (unsigned long __user *)(reg29 & ~3);
> ...
> > + while (!kstack_end(sp)) {
> > + if (__get_user(addr, sp++)) {
>
> This will leads a sparse warning since an argument for kstack_end is 'void *'.
>
> while (!kstack_end((void *)(unsigned long)sp)) {
>
> will make this part sparse-free, though it seems a bit ugly.
hmm, would leaving sp as unsigned long * and casting it for __get_user()
make sparse happy ?
Thomas.
--
Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: Breakage in arch/mips/kernel/traps.c for 64bit
2008-05-04 22:08 ` Thomas Bogendoerfer
@ 2008-05-05 14:58 ` Atsushi Nemoto
0 siblings, 0 replies; 10+ messages in thread
From: Atsushi Nemoto @ 2008-05-05 14:58 UTC (permalink / raw)
To: tsbogend; +Cc: ralf, linux-mips
On Mon, 5 May 2008 00:08:04 +0200, tsbogend@alpha.franken.de (Thomas Bogendoerfer) wrote:
> > while (!kstack_end((void *)(unsigned long)sp)) {
> >
> > will make this part sparse-free, though it seems a bit ugly.
>
> hmm, would leaving sp as unsigned long * and casting it for __get_user()
> make sparse happy ?
Well, not as expected... Here is some warning patterns.
1. unsigned long __user *sp = (unsigned long __user *)(reg29 & ~3);
...
while (!kstack_end(sp)) {
if (__get_user(addr, sp++)) {
linux/arch/mips/kernel/traps.c:91:21: warning: incorrect type in argument 1 (different address spaces)
linux/arch/mips/kernel/traps.c:91:21: expected void *addr
linux/arch/mips/kernel/traps.c:91:21: got unsigned long [noderef] <asn:1>*sp
2. unsigned long *sp = (unsigned long *)(reg29 & ~3);
...
while (!kstack_end(sp)) {
if (__get_user(addr, (unsigned long __user *)sp++)) {
linux/arch/mips/kernel/traps.c:92:7: warning: cast adds address space to expression (<asn:1>)
linux/arch/mips/kernel/traps.c:92:7: warning: cast adds address space to expression (<asn:1>)
linux/arch/mips/kernel/traps.c:92:7: warning: cast adds address space to expression (<asn:1>)
linux/arch/mips/kernel/traps.c:92:7: warning: cast adds address space to expression (<asn:1>)
linux/arch/mips/kernel/traps.c:92:7: warning: cast adds address space to expression (<asn:1>)
linux/arch/mips/kernel/traps.c:92:7: warning: cast adds address space to expression (<asn:1>)
linux/arch/mips/kernel/traps.c:92:7: warning: cast adds address space to expression (<asn:1>)
linux/arch/mips/kernel/traps.c:92:7: warning: cast adds address space to expression (<asn:1>)
linux/arch/mips/kernel/traps.c:92:7: warning: cast adds address space to expression (<asn:1>)
3. unsigned long __user *sp = (unsigned long __user *)(reg29 & ~3);
...
while (!kstack_end((void *)(unsigned long)sp)) {
if (__get_user(addr, sp++)) {
No warnings.
4. unsigned long *sp = (unsigned long *)(reg29 & ~3);
...
while (!kstack_end(sp)) {
unsigned long __user *p = (unsigned long __user *)sp++;
if (__get_user(addr, p)) {
linux/arch/mips/kernel/traps.c:92:30: warning: cast adds address space to expression (<asn:1>)
4. unsigned long *sp = (unsigned long *)(reg29 & ~3);
...
while (!kstack_end(sp)) {
unsigned long __user *p =
(unsigned long __user *)(unsigned long)sp++;
if (__get_user(addr, p)) {
No warnings.
I think the "cast adds address space to expression" sparse warning is
not worth to handle so seriously. So I'm OK with any of (2) to (4).
---
Atsushi Nemoto
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2008-05-05 14:57 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-01 16:33 Breakage in arch/mips/kernel/traps.c for 64bit Thomas Bogendoerfer
2008-05-01 21:01 ` Maciej W. Rozycki
2008-05-02 10:11 ` Ralf Baechle
2008-05-03 16:16 ` Atsushi Nemoto
2008-05-03 17:39 ` Ralf Baechle
2008-05-03 19:57 ` Maciej W. Rozycki
2008-05-03 22:48 ` Thomas Bogendoerfer
2008-05-04 13:39 ` Atsushi Nemoto
2008-05-04 22:08 ` Thomas Bogendoerfer
2008-05-05 14:58 ` Atsushi Nemoto
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox