All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.