提交 328f3de2 编写于 作者: F Florian La Roche 提交者: Greg Kroah-Hartman

fix int_sqrt64() for very large numbers

commit fbfaf851902cd9293f392f3a1735e0543016d530 upstream.

If an input number x for int_sqrt64() has the highest bit set, then
fls64(x) is 64.  (1UL << 64) is an overflow and breaks the algorithm.

Subtracting 1 is a better guess for the initial value of m anyway and
that's what also done in int_sqrt() implicitly [*].

[*] Note how int_sqrt() uses __fls() with two underscores, which already
    returns the proper raw bit number.

    In contrast, int_sqrt64() used fls64(), and that returns bit numbers
    illogically starting at 1, because of error handling for the "no
    bits set" case. Will points out that he bug probably is due to a
    copy-and-paste error from the regular int_sqrt() case.
Signed-off-by: NFlorian La Roche <Florian.LaRoche@googlemail.com>
Acked-by: NWill Deacon <will.deacon@arm.com>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 89a9f049
...@@ -52,7 +52,7 @@ u32 int_sqrt64(u64 x) ...@@ -52,7 +52,7 @@ u32 int_sqrt64(u64 x)
if (x <= ULONG_MAX) if (x <= ULONG_MAX)
return int_sqrt((unsigned long) x); return int_sqrt((unsigned long) x);
m = 1ULL << (fls64(x) & ~1ULL); m = 1ULL << ((fls64(x) - 1) & ~1ULL);
while (m != 0) { while (m != 0) {
b = y + m; b = y + m;
y >>= 1; y >>= 1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册