Commit e795000e authored by Nicolas Pitre's avatar Nicolas Pitre Committed by Andrew Morton
Browse files

mul_u64_u64_div_u64: fix the division-by-zero behavior

The current implementation forces a compile-time 1/0 division, which
generates an undefined instruction (ud2 on x86) rather than a proper
runtime division-by-zero exception.

Change to trigger an actual div-by-0 exception at runtime, consistent with
other division operations.  Use a non-1 dividend to prevent the compiler
from optimizing the division into a comparison.

Link: https://lkml.kernel.org/r/q246p466-1453-qon9-29so-37105116009q@onlyvoer.pbz


Signed-off-by: default avatarNicolas Pitre <npitre@baylibre.com>
Cc: Biju Das <biju.das.jz@bp.renesas.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Weißschuh <linux@weissschuh.net>
Cc: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Cc: David Laight <david.laight.linux@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent d71b90e5
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -212,12 +212,13 @@ u64 mul_u64_u64_div_u64(u64 a, u64 b, u64 c)

#endif

	/* make sure c is not zero, trigger exception otherwise */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdiv-by-zero"
	if (unlikely(c == 0))
		return 1/0;
#pragma GCC diagnostic pop
	/* make sure c is not zero, trigger runtime exception otherwise */
	if (unlikely(c == 0)) {
		unsigned long zero = 0;

		OPTIMIZER_HIDE_VAR(zero);
		return ~0UL/zero;
	}

	int shift = __builtin_ctzll(c);