* mips64 kgdb fpu access bug
@ 2006-04-13 20:54 Pete Popov
2006-04-14 3:09 ` Atsushi Nemoto
0 siblings, 1 reply; 5+ messages in thread
From: Pete Popov @ 2006-04-13 20:54 UTC (permalink / raw)
To: 'linux-mips@linux-mips.org'
I'm running into a random problem with a mips64 kernel (2.6.14 based). I
see the problem on the MIPS Malta 5kf board but it seems like a generic
bug to me. What happens is that CP0 FR bit is zero and an add register
is accessed by an instruction whose datatype is 64 bits. That results in
a reserved instruction kernel fault. I see this bug in gdb-low.S - the
code checks to see if CU1 is enabled but then it seems to assume that FR
is always 1 when running a 64bit kernel. However, I also randomly see
the bug without kgdb being enabled when we hit _save_fp and this macro:
.macro fpu_save_double thread status tmp1 tmp2
sll \tmp2, \tmp1, 5
bgez \tmp2, 2f
fpu_save_16odd \thread
2:
fpu_save_16even \thread \tmp1 # clobbers t1
.endm
tmp1 is "t0" and it's not clear to me why we're checking t0 instead of
status in order to decide whether to save the odd registers or not. I
must be missing something because others would have hit this bug by now.
Any clues would be appreciated.
Thanks,
Pete
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: mips64 kgdb fpu access bug
2006-04-13 20:54 mips64 kgdb fpu access bug Pete Popov
@ 2006-04-14 3:09 ` Atsushi Nemoto
2006-04-14 9:50 ` Pete Popov
2006-04-27 14:29 ` [PATCH] fix fpu_save_double on 64-bit (Was: mips64 kgdb fpu access bug) Atsushi Nemoto
0 siblings, 2 replies; 5+ messages in thread
From: Atsushi Nemoto @ 2006-04-14 3:09 UTC (permalink / raw)
To: ppopov; +Cc: linux-mips
On Thu, 13 Apr 2006 13:54:59 -0700, Pete Popov <ppopov@embeddedalley.com> wrote:
> .macro fpu_save_double thread status tmp1 tmp2
> sll \tmp2, \tmp1, 5
> bgez \tmp2, 2f
> fpu_save_16odd \thread
> 2:
> fpu_save_16even \thread \tmp1 # clobbers t1
> .endm
>
> tmp1 is "t0" and it's not clear to me why we're checking t0 instead of
> status in order to decide whether to save the odd registers or not. I
> must be missing something because others would have hit this bug by now.
> Any clues would be appreciated.
It seems commit d0fd5c21d07d6e13993a77f4471d8003a271a12b was somewhat
broken.
Could you try this patch?
fix register usage in fpu_save_double() and make fpu_restore_double()
more symmetric with fpu_save_double().
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
index 0b1b54a..db94e55 100644
--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -75,8 +75,8 @@
and t0, t0, t1
LONG_S t0, ST_OFF(t3)
- fpu_save_double a0 t1 t0 t2 # c0_status passed in t1
- # clobbers t0 and t2
+ fpu_save_double a0 t0 t1 # c0_status passed in t0
+ # clobbers t1
1:
/*
@@ -129,9 +129,9 @@
*/
LEAF(_save_fp)
#ifdef CONFIG_64BIT
- mfc0 t1, CP0_STATUS
+ mfc0 t0, CP0_STATUS
#endif
- fpu_save_double a0 t1 t0 t2 # clobbers t1
+ fpu_save_double a0 t0 t1 # clobbers t1
jr ra
END(_save_fp)
@@ -139,7 +139,10 @@ LEAF(_save_fp)
* Restore a thread's fp context.
*/
LEAF(_restore_fp)
- fpu_restore_double a0, t1 # clobbers t1
+#ifdef CONFIG_64BIT
+ mfc0 t0, CP0_STATUS
+#endif
+ fpu_restore_double a0 t0 t1 # clobbers t1
jr ra
END(_restore_fp)
diff --git a/include/asm-mips/asmmacro-32.h b/include/asm-mips/asmmacro-32.h
index 11daf5c..5de3963 100644
--- a/include/asm-mips/asmmacro-32.h
+++ b/include/asm-mips/asmmacro-32.h
@@ -12,7 +12,7 @@
#include <asm/fpregdef.h>
#include <asm/mipsregs.h>
- .macro fpu_save_double thread status tmp1=t0 tmp2
+ .macro fpu_save_double thread status tmp1=t0
cfc1 \tmp1, fcr31
sdc1 $f0, THREAD_FPR0(\thread)
sdc1 $f2, THREAD_FPR2(\thread)
@@ -70,7 +70,7 @@
sw \tmp, THREAD_FCR31(\thread)
.endm
- .macro fpu_restore_double thread tmp=t0
+ .macro fpu_restore_double thread status tmp=t0
lw \tmp, THREAD_FCR31(\thread)
ldc1 $f0, THREAD_FPR0(\thread)
ldc1 $f2, THREAD_FPR2(\thread)
diff --git a/include/asm-mips/asmmacro-64.h b/include/asm-mips/asmmacro-64.h
index 559c355..225feef 100644
--- a/include/asm-mips/asmmacro-64.h
+++ b/include/asm-mips/asmmacro-64.h
@@ -53,12 +53,12 @@
sdc1 $f31, THREAD_FPR31(\thread)
.endm
- .macro fpu_save_double thread status tmp1 tmp2
- sll \tmp2, \tmp1, 5
- bgez \tmp2, 2f
+ .macro fpu_save_double thread status tmp
+ sll \tmp, \status, 5
+ bgez \tmp, 2f
fpu_save_16odd \thread
2:
- fpu_save_16even \thread \tmp1 # clobbers t1
+ fpu_save_16even \thread \tmp
.endm
.macro fpu_restore_16even thread tmp=t0
@@ -101,13 +101,12 @@
ldc1 $f31, THREAD_FPR31(\thread)
.endm
- .macro fpu_restore_double thread tmp
- mfc0 t0, CP0_STATUS
- sll t1, t0, 5
- bgez t1, 1f # 16 register mode?
+ .macro fpu_restore_double thread status tmp
+ sll \tmp, \status, 5
+ bgez \tmp, 1f # 16 register mode?
- fpu_restore_16odd a0
-1: fpu_restore_16even a0, t0 # clobbers t0
+ fpu_restore_16odd \thread
+1: fpu_restore_16even \thread \tmp
.endm
.macro cpu_save_nonscratch thread
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: mips64 kgdb fpu access bug
2006-04-14 3:09 ` Atsushi Nemoto
@ 2006-04-14 9:50 ` Pete Popov
2006-04-27 14:29 ` [PATCH] fix fpu_save_double on 64-bit (Was: mips64 kgdb fpu access bug) Atsushi Nemoto
1 sibling, 0 replies; 5+ messages in thread
From: Pete Popov @ 2006-04-14 9:50 UTC (permalink / raw)
To: Atsushi Nemoto; +Cc: linux-mips
Looks good on inspection and my kernel boots fine now. It used to crash
consistently with this particular configuration and root file system.
Now I need to cook up something similar for the kgdb support :)
Thanks!
Pete
On Fri, 2006-04-14 at 12:09 +0900, Atsushi Nemoto wrote:
> On Thu, 13 Apr 2006 13:54:59 -0700, Pete Popov <ppopov@embeddedalley.com> wrote:
> > .macro fpu_save_double thread status tmp1 tmp2
> > sll \tmp2, \tmp1, 5
> > bgez \tmp2, 2f
> > fpu_save_16odd \thread
> > 2:
> > fpu_save_16even \thread \tmp1 # clobbers t1
> > .endm
> >
> > tmp1 is "t0" and it's not clear to me why we're checking t0 instead of
> > status in order to decide whether to save the odd registers or not. I
> > must be missing something because others would have hit this bug by now.
> > Any clues would be appreciated.
>
> It seems commit d0fd5c21d07d6e13993a77f4471d8003a271a12b was somewhat
> broken.
>
> Could you try this patch?
>
>
> fix register usage in fpu_save_double() and make fpu_restore_double()
> more symmetric with fpu_save_double().
>
> Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
>
> diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
> index 0b1b54a..db94e55 100644
> --- a/arch/mips/kernel/r4k_switch.S
> +++ b/arch/mips/kernel/r4k_switch.S
> @@ -75,8 +75,8 @@
> and t0, t0, t1
> LONG_S t0, ST_OFF(t3)
>
> - fpu_save_double a0 t1 t0 t2 # c0_status passed in t1
> - # clobbers t0 and t2
> + fpu_save_double a0 t0 t1 # c0_status passed in t0
> + # clobbers t1
> 1:
>
> /*
> @@ -129,9 +129,9 @@
> */
> LEAF(_save_fp)
> #ifdef CONFIG_64BIT
> - mfc0 t1, CP0_STATUS
> + mfc0 t0, CP0_STATUS
> #endif
> - fpu_save_double a0 t1 t0 t2 # clobbers t1
> + fpu_save_double a0 t0 t1 # clobbers t1
> jr ra
> END(_save_fp)
>
> @@ -139,7 +139,10 @@ LEAF(_save_fp)
> * Restore a thread's fp context.
> */
> LEAF(_restore_fp)
> - fpu_restore_double a0, t1 # clobbers t1
> +#ifdef CONFIG_64BIT
> + mfc0 t0, CP0_STATUS
> +#endif
> + fpu_restore_double a0 t0 t1 # clobbers t1
> jr ra
> END(_restore_fp)
>
> diff --git a/include/asm-mips/asmmacro-32.h b/include/asm-mips/asmmacro-32.h
> index 11daf5c..5de3963 100644
> --- a/include/asm-mips/asmmacro-32.h
> +++ b/include/asm-mips/asmmacro-32.h
> @@ -12,7 +12,7 @@
> #include <asm/fpregdef.h>
> #include <asm/mipsregs.h>
>
> - .macro fpu_save_double thread status tmp1=t0 tmp2
> + .macro fpu_save_double thread status tmp1=t0
> cfc1 \tmp1, fcr31
> sdc1 $f0, THREAD_FPR0(\thread)
> sdc1 $f2, THREAD_FPR2(\thread)
> @@ -70,7 +70,7 @@
> sw \tmp, THREAD_FCR31(\thread)
> .endm
>
> - .macro fpu_restore_double thread tmp=t0
> + .macro fpu_restore_double thread status tmp=t0
> lw \tmp, THREAD_FCR31(\thread)
> ldc1 $f0, THREAD_FPR0(\thread)
> ldc1 $f2, THREAD_FPR2(\thread)
> diff --git a/include/asm-mips/asmmacro-64.h b/include/asm-mips/asmmacro-64.h
> index 559c355..225feef 100644
> --- a/include/asm-mips/asmmacro-64.h
> +++ b/include/asm-mips/asmmacro-64.h
> @@ -53,12 +53,12 @@
> sdc1 $f31, THREAD_FPR31(\thread)
> .endm
>
> - .macro fpu_save_double thread status tmp1 tmp2
> - sll \tmp2, \tmp1, 5
> - bgez \tmp2, 2f
> + .macro fpu_save_double thread status tmp
> + sll \tmp, \status, 5
> + bgez \tmp, 2f
> fpu_save_16odd \thread
> 2:
> - fpu_save_16even \thread \tmp1 # clobbers t1
> + fpu_save_16even \thread \tmp
> .endm
>
> .macro fpu_restore_16even thread tmp=t0
> @@ -101,13 +101,12 @@
> ldc1 $f31, THREAD_FPR31(\thread)
> .endm
>
> - .macro fpu_restore_double thread tmp
> - mfc0 t0, CP0_STATUS
> - sll t1, t0, 5
> - bgez t1, 1f # 16 register mode?
> + .macro fpu_restore_double thread status tmp
> + sll \tmp, \status, 5
> + bgez \tmp, 1f # 16 register mode?
>
> - fpu_restore_16odd a0
> -1: fpu_restore_16even a0, t0 # clobbers t0
> + fpu_restore_16odd \thread
> +1: fpu_restore_16even \thread \tmp
> .endm
>
> .macro cpu_save_nonscratch thread
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] fix fpu_save_double on 64-bit (Was: mips64 kgdb fpu access bug)
2006-04-14 3:09 ` Atsushi Nemoto
2006-04-14 9:50 ` Pete Popov
@ 2006-04-27 14:29 ` Atsushi Nemoto
2006-05-22 15:47 ` [PATCH] fix fpu_save_double on 64-bit Atsushi Nemoto
1 sibling, 1 reply; 5+ messages in thread
From: Atsushi Nemoto @ 2006-04-27 14:29 UTC (permalink / raw)
To: linux-mips; +Cc: ralf, ppopov
On Fri, 14 Apr 2006 12:09:44 +0900 (JST), Atsushi Nemoto <anemo@mba.ocn.ne.jp> wrote:
> It seems commit d0fd5c21d07d6e13993a77f4471d8003a271a12b was somewhat
> broken.
>
> Could you try this patch?
This is actually irrelevant to kgdb. Without this fix, _save_fp() in
64-bit kernel is seriously broken.
ffffffff8010bec0 <_save_fp>:
ffffffff8010bec0: 400d6000 mfc0 t1,c0_status
ffffffff8010bec4: 000c7140 sll t2,t0,0x5
ffffffff8010bec8: 05c10011 bgez t2,ffffffff8010bf10 <_save_fp+0x50>
ffffffff8010becc: 00000000 nop
ffffffff8010bed0: f4810328 sdc1 $f1,808(a0)
...
Ralf, could you apply?
Fix register usage in fpu_save_double() and make fpu_restore_double()
more symmetric with fpu_save_double().
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
index 0b1b54a..db94e55 100644
--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -75,8 +75,8 @@
and t0, t0, t1
LONG_S t0, ST_OFF(t3)
- fpu_save_double a0 t1 t0 t2 # c0_status passed in t1
- # clobbers t0 and t2
+ fpu_save_double a0 t0 t1 # c0_status passed in t0
+ # clobbers t1
1:
/*
@@ -129,9 +129,9 @@
*/
LEAF(_save_fp)
#ifdef CONFIG_64BIT
- mfc0 t1, CP0_STATUS
+ mfc0 t0, CP0_STATUS
#endif
- fpu_save_double a0 t1 t0 t2 # clobbers t1
+ fpu_save_double a0 t0 t1 # clobbers t1
jr ra
END(_save_fp)
@@ -139,7 +139,10 @@ LEAF(_save_fp)
* Restore a thread's fp context.
*/
LEAF(_restore_fp)
- fpu_restore_double a0, t1 # clobbers t1
+#ifdef CONFIG_64BIT
+ mfc0 t0, CP0_STATUS
+#endif
+ fpu_restore_double a0 t0 t1 # clobbers t1
jr ra
END(_restore_fp)
diff --git a/include/asm-mips/asmmacro-32.h b/include/asm-mips/asmmacro-32.h
index 11daf5c..5de3963 100644
--- a/include/asm-mips/asmmacro-32.h
+++ b/include/asm-mips/asmmacro-32.h
@@ -12,7 +12,7 @@
#include <asm/fpregdef.h>
#include <asm/mipsregs.h>
- .macro fpu_save_double thread status tmp1=t0 tmp2
+ .macro fpu_save_double thread status tmp1=t0
cfc1 \tmp1, fcr31
sdc1 $f0, THREAD_FPR0(\thread)
sdc1 $f2, THREAD_FPR2(\thread)
@@ -70,7 +70,7 @@
sw \tmp, THREAD_FCR31(\thread)
.endm
- .macro fpu_restore_double thread tmp=t0
+ .macro fpu_restore_double thread status tmp=t0
lw \tmp, THREAD_FCR31(\thread)
ldc1 $f0, THREAD_FPR0(\thread)
ldc1 $f2, THREAD_FPR2(\thread)
diff --git a/include/asm-mips/asmmacro-64.h b/include/asm-mips/asmmacro-64.h
index 559c355..225feef 100644
--- a/include/asm-mips/asmmacro-64.h
+++ b/include/asm-mips/asmmacro-64.h
@@ -53,12 +53,12 @@
sdc1 $f31, THREAD_FPR31(\thread)
.endm
- .macro fpu_save_double thread status tmp1 tmp2
- sll \tmp2, \tmp1, 5
- bgez \tmp2, 2f
+ .macro fpu_save_double thread status tmp
+ sll \tmp, \status, 5
+ bgez \tmp, 2f
fpu_save_16odd \thread
2:
- fpu_save_16even \thread \tmp1 # clobbers t1
+ fpu_save_16even \thread \tmp
.endm
.macro fpu_restore_16even thread tmp=t0
@@ -101,13 +101,12 @@
ldc1 $f31, THREAD_FPR31(\thread)
.endm
- .macro fpu_restore_double thread tmp
- mfc0 t0, CP0_STATUS
- sll t1, t0, 5
- bgez t1, 1f # 16 register mode?
+ .macro fpu_restore_double thread status tmp
+ sll \tmp, \status, 5
+ bgez \tmp, 1f # 16 register mode?
- fpu_restore_16odd a0
-1: fpu_restore_16even a0, t0 # clobbers t0
+ fpu_restore_16odd \thread
+1: fpu_restore_16even \thread \tmp
.endm
.macro cpu_save_nonscratch thread
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] fix fpu_save_double on 64-bit
2006-04-27 14:29 ` [PATCH] fix fpu_save_double on 64-bit (Was: mips64 kgdb fpu access bug) Atsushi Nemoto
@ 2006-05-22 15:47 ` Atsushi Nemoto
0 siblings, 0 replies; 5+ messages in thread
From: Atsushi Nemoto @ 2006-05-22 15:47 UTC (permalink / raw)
To: linux-mips; +Cc: ralf
On Thu, 27 Apr 2006 23:29:04 +0900 (JST), Atsushi Nemoto <anemo@mba.ocn.ne.jp> wrote:
> This is actually irrelevant to kgdb. Without this fix, _save_fp() in
> 64-bit kernel is seriously broken.
>
> ffffffff8010bec0 <_save_fp>:
> ffffffff8010bec0: 400d6000 mfc0 t1,c0_status
> ffffffff8010bec4: 000c7140 sll t2,t0,0x5
> ffffffff8010bec8: 05c10011 bgez t2,ffffffff8010bf10 <_save_fp+0x50>
> ffffffff8010becc: 00000000 nop
> ffffffff8010bed0: f4810328 sdc1 $f1,808(a0)
> ...
ping.
Fix register usage in fpu_save_double() and make fpu_restore_double()
more symmetric with fpu_save_double().
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
index 0b1b54a..db94e55 100644
--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -75,8 +75,8 @@
and t0, t0, t1
LONG_S t0, ST_OFF(t3)
- fpu_save_double a0 t1 t0 t2 # c0_status passed in t1
- # clobbers t0 and t2
+ fpu_save_double a0 t0 t1 # c0_status passed in t0
+ # clobbers t1
1:
/*
@@ -129,9 +129,9 @@
*/
LEAF(_save_fp)
#ifdef CONFIG_64BIT
- mfc0 t1, CP0_STATUS
+ mfc0 t0, CP0_STATUS
#endif
- fpu_save_double a0 t1 t0 t2 # clobbers t1
+ fpu_save_double a0 t0 t1 # clobbers t1
jr ra
END(_save_fp)
@@ -139,7 +139,10 @@ LEAF(_save_fp)
* Restore a thread's fp context.
*/
LEAF(_restore_fp)
- fpu_restore_double a0, t1 # clobbers t1
+#ifdef CONFIG_64BIT
+ mfc0 t0, CP0_STATUS
+#endif
+ fpu_restore_double a0 t0 t1 # clobbers t1
jr ra
END(_restore_fp)
diff --git a/include/asm-mips/asmmacro-32.h b/include/asm-mips/asmmacro-32.h
index 11daf5c..5de3963 100644
--- a/include/asm-mips/asmmacro-32.h
+++ b/include/asm-mips/asmmacro-32.h
@@ -12,7 +12,7 @@
#include <asm/fpregdef.h>
#include <asm/mipsregs.h>
- .macro fpu_save_double thread status tmp1=t0 tmp2
+ .macro fpu_save_double thread status tmp1=t0
cfc1 \tmp1, fcr31
sdc1 $f0, THREAD_FPR0(\thread)
sdc1 $f2, THREAD_FPR2(\thread)
@@ -70,7 +70,7 @@
sw \tmp, THREAD_FCR31(\thread)
.endm
- .macro fpu_restore_double thread tmp=t0
+ .macro fpu_restore_double thread status tmp=t0
lw \tmp, THREAD_FCR31(\thread)
ldc1 $f0, THREAD_FPR0(\thread)
ldc1 $f2, THREAD_FPR2(\thread)
diff --git a/include/asm-mips/asmmacro-64.h b/include/asm-mips/asmmacro-64.h
index 559c355..225feef 100644
--- a/include/asm-mips/asmmacro-64.h
+++ b/include/asm-mips/asmmacro-64.h
@@ -53,12 +53,12 @@
sdc1 $f31, THREAD_FPR31(\thread)
.endm
- .macro fpu_save_double thread status tmp1 tmp2
- sll \tmp2, \tmp1, 5
- bgez \tmp2, 2f
+ .macro fpu_save_double thread status tmp
+ sll \tmp, \status, 5
+ bgez \tmp, 2f
fpu_save_16odd \thread
2:
- fpu_save_16even \thread \tmp1 # clobbers t1
+ fpu_save_16even \thread \tmp
.endm
.macro fpu_restore_16even thread tmp=t0
@@ -101,13 +101,12 @@
ldc1 $f31, THREAD_FPR31(\thread)
.endm
- .macro fpu_restore_double thread tmp
- mfc0 t0, CP0_STATUS
- sll t1, t0, 5
- bgez t1, 1f # 16 register mode?
+ .macro fpu_restore_double thread status tmp
+ sll \tmp, \status, 5
+ bgez \tmp, 1f # 16 register mode?
- fpu_restore_16odd a0
-1: fpu_restore_16even a0, t0 # clobbers t0
+ fpu_restore_16odd \thread
+1: fpu_restore_16even \thread \tmp
.endm
.macro cpu_save_nonscratch thread
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2006-05-22 15:47 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-04-13 20:54 mips64 kgdb fpu access bug Pete Popov
2006-04-14 3:09 ` Atsushi Nemoto
2006-04-14 9:50 ` Pete Popov
2006-04-27 14:29 ` [PATCH] fix fpu_save_double on 64-bit (Was: mips64 kgdb fpu access bug) Atsushi Nemoto
2006-05-22 15:47 ` [PATCH] fix fpu_save_double on 64-bit Atsushi Nemoto
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.