* [PATCH] m68k: truncate base in do_div
@ 2013-08-09 13:14 Andreas Schwab
2013-08-11 21:57 ` Thorsten Glaser
2013-08-13 14:50 ` Geert Uytterhoeven
0 siblings, 2 replies; 3+ messages in thread
From: Andreas Schwab @ 2013-08-09 13:14 UTC (permalink / raw)
To: linux-m68k; +Cc: debian-68k
Explicitly truncate the second operand of do_div to 32 bits to guard
against bogus code calling it with a 64bit divisor.
Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
---
arch/m68k/include/asm/div64.h | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/arch/m68k/include/asm/div64.h b/arch/m68k/include/asm/div64.h
index 444ea8a..ef881cf 100644
--- a/arch/m68k/include/asm/div64.h
+++ b/arch/m68k/include/asm/div64.h
@@ -15,16 +15,17 @@
unsigned long long n64; \
} __n; \
unsigned long __rem, __upper; \
+ unsigned long __base = (base); \
\
__n.n64 = (n); \
if ((__upper = __n.n32[0])) { \
asm ("divul.l %2,%1:%0" \
- : "=d" (__n.n32[0]), "=d" (__upper) \
- : "d" (base), "0" (__n.n32[0])); \
+ : "=d" (__n.n32[0]), "=d" (__upper) \
+ : "d" (__base), "0" (__n.n32[0])); \
} \
asm ("divu.l %2,%1:%0" \
- : "=d" (__n.n32[1]), "=d" (__rem) \
- : "d" (base), "1" (__upper), "0" (__n.n32[1])); \
+ : "=d" (__n.n32[1]), "=d" (__rem) \
+ : "d" (__base), "1" (__upper), "0" (__n.n32[1])); \
(n) = __n.n64; \
__rem; \
})
--
1.8.3.4
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] m68k: truncate base in do_div
2013-08-09 13:14 [PATCH] m68k: truncate base in do_div Andreas Schwab
@ 2013-08-11 21:57 ` Thorsten Glaser
2013-08-13 14:50 ` Geert Uytterhoeven
1 sibling, 0 replies; 3+ messages in thread
From: Thorsten Glaser @ 2013-08-11 21:57 UTC (permalink / raw)
To: Andreas Schwab; +Cc: linux-m68k, debian-68k
Andreas Schwab dixit:
>Explicitly truncate the second operand of do_div to 32 bits to guard
>against bogus code calling it with a 64bit divisor.
>
>Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
Tested-by: Thorsten Glaser <tg@debian.org>
>---
> arch/m68k/include/asm/div64.h | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
>diff --git a/arch/m68k/include/asm/div64.h b/arch/m68k/include/asm/div64.h
>index 444ea8a..ef881cf 100644
>--- a/arch/m68k/include/asm/div64.h
>+++ b/arch/m68k/include/asm/div64.h
>@@ -15,16 +15,17 @@
> unsigned long long n64; \
> } __n; \
> unsigned long __rem, __upper; \
>+ unsigned long __base = (base); \
> \
> __n.n64 = (n); \
> if ((__upper = __n.n32[0])) { \
> asm ("divul.l %2,%1:%0" \
>- : "=d" (__n.n32[0]), "=d" (__upper) \
>- : "d" (base), "0" (__n.n32[0])); \
>+ : "=d" (__n.n32[0]), "=d" (__upper) \
>+ : "d" (__base), "0" (__n.n32[0])); \
> } \
> asm ("divu.l %2,%1:%0" \
>- : "=d" (__n.n32[1]), "=d" (__rem) \
>- : "d" (base), "1" (__upper), "0" (__n.n32[1])); \
>+ : "=d" (__n.n32[1]), "=d" (__rem) \
>+ : "d" (__base), "1" (__upper), "0" (__n.n32[1])); \
> (n) = __n.n64; \
> __rem; \
> })
>--
>1.8.3.4
>
>
>--
>Andreas Schwab, schwab@linux-m68k.org
>GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
>"And now for something completely different."
>
>
>--
>To UNSUBSCRIBE, email to debian-68k-REQUEST@lists.debian.org
>with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
>Archive: http://lists.debian.org/871u633t27.fsf@igel.home
>
>
//mirabilos
--
17:08⎜«Vutral» früher gabs keine packenden smartphones und so
17:08⎜«Vutral» heute gibts frauen die sind facebooksüchtig
17:10⎜«Vutral» aber auch traurig; früher warst du als nerd voll am arsch
17:10⎜«Vutral» heute bist du als nerd der einzige der wirklich damit klarkommt
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] m68k: truncate base in do_div
2013-08-09 13:14 [PATCH] m68k: truncate base in do_div Andreas Schwab
2013-08-11 21:57 ` Thorsten Glaser
@ 2013-08-13 14:50 ` Geert Uytterhoeven
1 sibling, 0 replies; 3+ messages in thread
From: Geert Uytterhoeven @ 2013-08-13 14:50 UTC (permalink / raw)
To: Andreas Schwab; +Cc: Linux/m68k, Debian m68k, linux-kernel
On Fri, Aug 9, 2013 at 3:14 PM, Andreas Schwab <schwab@linux-m68k.org> wrote:
> Explicitly truncate the second operand of do_div to 32 bits to guard
> against bogus code calling it with a 64bit divisor.
>
> Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
I added
[Thorsten]
After upgrading from 3.2 to 3.10, mounting a btrfs volume fails with:
btrfs: setting nodatacow, compression disabled
btrfs: enabling auto recovery
btrfs: disk space caching is enabled
*** ZERO DIVIDE *** FORMAT=2
Current process id is 722
BAD KERNEL TRAP: 00000000
Modules linked in: evdev mac_hid ext4 crc16 jbd2 mbcache btrfs xor lzo_compr
PC: [<319535b2>] __btrfs_map_block+0x11c/0x119a [btrfs]
SR: 2000 SP: 30c1fab4 a2: 30f0faf0
d0: 00000000 d1: 00001000 d2: 00000000 d3: 00000000
d4: 00010000 d5: 00000000 a0: 3085c72c a1: 3085c72c
Process mount (pid: 722, task=30f0faf0)
Frame format=2 instr addr=319535ae
Stack from 30c1faec:
00000000 00000020 00000000 00001000 00000000 01401000 30253928 300ff
00a843ac 3026f640 00000000 00010000 0009e250 00d106c0 00011220 00000
00001000 301c6830 0009e32a 000000ff 00000009 3085c72c 00000000 00000
30c1fd14 00000000 00000020 00000000 30c1fd14 0009e26c 00000020 00000
00000000 0009dd8a 300b0b6c 30253928 00a843ac 00001000 00000000 00000
0000a008 3194e76a 30253928 00a843ac 00001000 00000000 00000000 00000
Call Trace: [<00001000>] kernel_pg_dir+0x0/0x1000
[...]
Code: 222e ff74 2a2e ff5c 2c2e ff60 4c45 1402 <2d40> ff64 2d41 ff68 2205 4c2
[Geert]
As diagnosed by Andreas, fs/btrfs/volumes.c:__btrfs_map_block()
calls
do_div(stripe_nr, stripe_len);
with stripe_len u64, while do_div() assumes the divisor is a 32-bit number.
Due to the lack of truncation in the m68k-specific implementation of
do_div(), the division is performed using the upper 32-bit word of
stripe_len, which is zero.
This was introduced by commit 53b381b3abeb86f12787a6c40fee9b2f71edc23b
("Btrfs: RAID5 and RAID6"), which changed the divisor from
map->stripe_len (struct map_lookup.stripe_len is int) to a 64-bit temporary.
Reported-by: Thorsten Glaser <tg@debian.org>
Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
Tested-by: Thorsten Glaser <tg@debian.org>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: stable@vger.kernel.org
> ---
> arch/m68k/include/asm/div64.h | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/arch/m68k/include/asm/div64.h b/arch/m68k/include/asm/div64.h
> index 444ea8a..ef881cf 100644
> --- a/arch/m68k/include/asm/div64.h
> +++ b/arch/m68k/include/asm/div64.h
> @@ -15,16 +15,17 @@
> unsigned long long n64; \
> } __n; \
> unsigned long __rem, __upper; \
> + unsigned long __base = (base); \
> \
> __n.n64 = (n); \
> if ((__upper = __n.n32[0])) { \
> asm ("divul.l %2,%1:%0" \
> - : "=d" (__n.n32[0]), "=d" (__upper) \
> - : "d" (base), "0" (__n.n32[0])); \
> + : "=d" (__n.n32[0]), "=d" (__upper) \
> + : "d" (__base), "0" (__n.n32[0])); \
> } \
> asm ("divu.l %2,%1:%0" \
> - : "=d" (__n.n32[1]), "=d" (__rem) \
> - : "d" (base), "1" (__upper), "0" (__n.n32[1])); \
> + : "=d" (__n.n32[1]), "=d" (__rem) \
> + : "d" (__base), "1" (__upper), "0" (__n.n32[1])); \
> (n) = __n.n64; \
> __rem; \
> })
> --
> 1.8.3.4
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-08-13 14:50 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-09 13:14 [PATCH] m68k: truncate base in do_div Andreas Schwab
2013-08-11 21:57 ` Thorsten Glaser
2013-08-13 14:50 ` Geert Uytterhoeven
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.