MIPS: Use unsigned int when reading CP0 registers
authorChris Packham <judge.packham@gmail.com>
Tue, 14 Jul 2015 22:44:30 +0000 (10:44 +1200)
committerRalf Baechle <ralf@linux-mips.org>
Thu, 3 Sep 2015 10:07:41 +0000 (12:07 +0200)
Update __read_32bit_c0_register() and __read_32bit_c0_ctrl_register() to
use "unsigned int res;" instead of "int res;". There is little reason to
treat these register values as signed. They are either counters (which
by definition are unsigned) or are made up of various bit fields to be
interpreted as per the CPU datasheet.

This has come up via u-boot[1] which sync's asm/mipsregs.h with the
kernel. In u-boots case the value read from read_c0_count() is assigned
to an unsigned long [2] which triggers a sign extension and causes a
bug.

U-boot should probably be more explicit about the types used for the
timer_read_counter() API but that aside is there any reason to treat
these values as signed integers? A quick grep around the arch/mips makes
me thing that there may be some bugs lurking when read_c0_count() starts
to yield a negative value but I haven't really explored any of them.

[1] - http://lists.denx.de/pipermail/u-boot/2015-July/219086.html
[2] - http://git.denx.de/?p=u-boot.git;a=blob;f=arch/mips/cpu/time.c#l11

Signed-off-by: Chris Packham <judge.packham@gmail.com>
Cc: linux-mips@linux-mips.org
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Cc: Chris Packham <judge.packham@gmail.com>
Cc: Steven J. Hill <Steven.Hill@imgtec.com>
Cc: Maciej W. Rozycki <macro@linux-mips.org>
Cc: linux-kernel@vger.kernel.org
Cc: James Hogan <james.hogan@imgtec.com>
Cc: Markos Chandras <markos.chandras@imgtec.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Patchwork: https://patchwork.linux-mips.org/patch/10718/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/include/asm/mipsregs.h

index 723ee3c7849d2a1947eb876405e83f7cd22d1c62..07bf4e7109acf22dc5cad16a9f06f62fda3088e5 100644 (file)
@@ -934,7 +934,7 @@ do {                                                                \
  */
 
 #define __read_32bit_c0_register(source, sel)                          \
-({ int __res;                                                          \
+({ unsigned int __res;                                                 \
        if (sel == 0)                                                   \
                __asm__ __volatile__(                                   \
                        "mfc0\t%0, " #source "\n\t"                     \
@@ -1016,7 +1016,7 @@ do {                                                                      \
  * On RM7000/RM9000 these are uses to access cop0 set 1 registers
  */
 #define __read_32bit_c0_ctrl_register(source)                          \
-({ int __res;                                                          \
+({ unsigned int __res;                                                 \
        __asm__ __volatile__(                                           \
                "cfc0\t%0, " #source "\n\t"                             \
                : "=r" (__res));                                        \