ARM: 8027/1: fix do_div() bug in big-endian systems
authorXiangyu Lu <luxiangyu@huawei.com>
Tue, 15 Apr 2014 08:38:17 +0000 (09:38 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 22 Apr 2014 21:23:57 +0000 (22:23 +0100)
In big-endian systems, "%1" get the most significant part of the value, cause the instruction to get the wrong result.

When viewing ftrace record in big-endian ARM systems, we found that
the timestamp errors:

swapper-0   [001] 1325.970000:   0:120:R ==> [001]    16:120:R events/1
events/1-16 [001] 1325.970000:   16:120:S ==> [001]    0:120:R swapper
swapper-0   [000] 1325.1000000:  0:120:R   + [000]    15:120:R events/0
swapper-0   [000] 1325.1000000:  0:120:R ==> [000]    15:120:R events/0
swapper-0   [000] 1326.030000:   0:120:R   + [000]  1150:120:R sshd
swapper-0   [000] 1326.030000:   0:120:R ==> [000]  1150:120:R sshd

When viewed ftrace records, it will call the do_div(n, base) function, which achieved arch/arm/include/asm/div64.h in. When n = 10000000, base = 1000000, in do_div(n, base) will execute "umull %Q0, %R0, %1, %Q2".

Reviewed-by: Dave Martin <Dave.Martin@arm.com>
Reviewed-by: Nicolas Pitre <nico@linaro.org>
Cc: <stable@vger.kernel.org> # 2.6.20+
Signed-off-by: Alex Wu <wuquanming@huawei.com>
Signed-off-by: Xiangyu Lu <luxiangyu@huawei.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/include/asm/div64.h

index 191ada6e4d2db3393270ef9595e9cc083e441909..662c7bd061081b2fadfc0e790e719d14cc526d77 100644 (file)
                /* Select the best insn combination to perform the   */ \
                /* actual __m * __n / (__p << 64) operation.         */ \
                if (!__c) {                                             \
-                       asm (   "umull  %Q0, %R0, %1, %Q2\n\t"          \
+                       asm (   "umull  %Q0, %R0, %Q1, %Q2\n\t"         \
                                "mov    %Q0, #0"                        \
                                : "=&r" (__res)                         \
                                : "r" (__m), "r" (__n)                  \