Patchwork MIPS: Fix logic errors in bitops.c

login
register
mail settings
Submitter David Daney
Date Feb. 26, 2013, 10:35 p.m.
Message ID <1361918123-19404-1-git-send-email-ddaney.cavm@gmail.com>
Download mbox | patch
Permalink /patch/4965/
State Accepted
Delegated to: Ralf Baechle
Headers show

Comments

David Daney - Feb. 26, 2013, 10:35 p.m.
From: David Daney <david.daney@cavium.com>

commit 92d11594f6 (MIPS: Remove irqflags.h dependency from bitops.h)
factored some of the bitops code out into a separate file
(arch/mips/lib/bitops.c).  Unfortunately the logic converting a bit
mask into a boolean result was lost in some of the functions.  We had:

   int res;
   unsigned long shifted_result_bit;
   .
   .
   .
   res = shifted_result_bit;
   return res;

Which truncates off the high 32 bits (thus yielding an incorrect
value) on 64-bit systems.

The manifestation of this is that a non-SMP 64-bit kernel will not
boot as the bitmap operations in bootmem.c are all screwed up.

Signed-off-by: David Daney <david.daney@cavium.com>
Cc: Jim Quinlan <jim2101024@gmail.com>
Cc: <stable@vger.kernel.org>
---
 arch/mips/lib/bitops.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
root - March 12, 2013, 11:07 a.m.
On Tue, Feb 26, 2013 at 02:35:23PM -0800, David Daney wrote:

Applied.

-stable folks - this patch should be applied to 3.7-stable and 3.8-stable.

Thanks,

  Ralf
gregkh@linuxfoundation.org - March 12, 2013, 1:29 p.m.
On Tue, Mar 12, 2013 at 12:07:18PM +0100, Ralf Baechle wrote:
> On Tue, Feb 26, 2013 at 02:35:23PM -0800, David Daney wrote:
> 
> Applied.
> 
> -stable folks - this patch should be applied to 3.7-stable and 3.8-stable.

What patch?  What is the git commit id of it in Linus's tree?

And there is no 3.7-stable tree anymore, sorry, that kernel is
end-of-life now.

greg k-h

Patch

diff --git a/arch/mips/lib/bitops.c b/arch/mips/lib/bitops.c
index 239a9c9..f3f7756 100644
--- a/arch/mips/lib/bitops.c
+++ b/arch/mips/lib/bitops.c
@@ -90,12 +90,12 @@  int __mips_test_and_set_bit(unsigned long nr,
 	unsigned bit = nr & SZLONG_MASK;
 	unsigned long mask;
 	unsigned long flags;
-	unsigned long res;
+	int res;
 
 	a += nr >> SZLONG_LOG;
 	mask = 1UL << bit;
 	raw_local_irq_save(flags);
-	res = (mask & *a);
+	res = (mask & *a) != 0;
 	*a |= mask;
 	raw_local_irq_restore(flags);
 	return res;
@@ -116,12 +116,12 @@  int __mips_test_and_set_bit_lock(unsigned long nr,
 	unsigned bit = nr & SZLONG_MASK;
 	unsigned long mask;
 	unsigned long flags;
-	unsigned long res;
+	int res;
 
 	a += nr >> SZLONG_LOG;
 	mask = 1UL << bit;
 	raw_local_irq_save(flags);
-	res = (mask & *a);
+	res = (mask & *a) != 0;
 	*a |= mask;
 	raw_local_irq_restore(flags);
 	return res;
@@ -141,12 +141,12 @@  int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
 	unsigned bit = nr & SZLONG_MASK;
 	unsigned long mask;
 	unsigned long flags;
-	unsigned long res;
+	int res;
 
 	a += nr >> SZLONG_LOG;
 	mask = 1UL << bit;
 	raw_local_irq_save(flags);
-	res = (mask & *a);
+	res = (mask & *a) != 0;
 	*a &= ~mask;
 	raw_local_irq_restore(flags);
 	return res;
@@ -166,12 +166,12 @@  int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
 	unsigned bit = nr & SZLONG_MASK;
 	unsigned long mask;
 	unsigned long flags;
-	unsigned long res;
+	int res;
 
 	a += nr >> SZLONG_LOG;
 	mask = 1UL << bit;
 	raw_local_irq_save(flags);
-	res = (mask & *a);
+	res = (mask & *a) != 0;
 	*a ^= mask;
 	raw_local_irq_restore(flags);
 	return res;