lkml.org 
[lkml]   [2012]   [Apr]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    SubjectPossible integer overflow in mach-bcmring with FPGA11107
    Date
    Hi,

    due to statical analysis, i think i found a possible integer overflow
    in the timer (sp804) code, when mach-bcmring is used together with
    FPGA11107. All following line numbers are according to Linux v3.2, but
    the problem should be still in Linux HEAD (if i haven't missed anything).

    Ok here is the Problem:

    ,----[arch/arm/mach-bcmring/clock.h:24]------------------
    | struct clk {
    | [..]
    | unsigned long rate_hz; /* clock rate in Hz */
    | [..]
    | };
    `----

    ,----
    | % arm-linux-gnueabihf-cpp-4.6 -dM /dev/null | grep __SIZEOF_LONG__
    | #define __SIZEOF_LONG__ 4
    `----

    As you see rate_hz is defined as long, but long is according to
    gnueabihf (and gnueabi) 4 bytes long. I hope i got the right compiler
    here.

    ,----[arch/arm/mach-bcmring/include/mach/csp/tmrHw_reg.h]----
    | #if defined(CFG_GLOBAL_CHIP) && (CFG_GLOBAL_CHIP == FPGA11107)
    | #define tmrHw_HIGH_FREQUENCY_MHZ 150 /* Always 150MHz for FPGA */
    | #define tmrHw_HIGH_FREQUENCY_HZ 150000000
    | #else
    | [..]
    | #endif
    `----

    When FPGA11107 is used the frequency is set to 150 000 000 Hz.

    ,----[arch/arm/mach-bcmring/core.c:100]---
    | #if defined(CONFIG_ARCH_FPGA11107)
    | /* fpga cpu/bus are currently 30 times slower so scale frequency as well to */
    | /* slow down Linux's sense of time */
    | [..]
    | #define TIMER3_FREQUENCY_KHZ (tmrHw_HIGH_FREQUENCY_HZ / 1000 * 30)
    | #else
    | [..]
    | #define TIMER3_FREQUENCY_KHZ (tmrHw_HIGH_FREQUENCY_HZ / 1000)
    | #endif
    `----

    ,----[arch/arm/mach-bcmring/core.c:121]---
    | static struct clk sp804_timer3_clk = {
    | .name = "sp804-timer-3",
    | .type = CLK_TYPE_PRIMARY,
    | .mode = CLK_MODE_XTAL,
    | .rate_hz = TIMER3_FREQUENCY_KHZ * 1000,
    | };
    `----

    This seems totally innocent, but when doing the caluculation for
    rate_hz by hand (or python) the result is slighly bigger than
    2^32-1. Therfore an integer overflow should occur and the rate_hz rate
    will be far too low. It may be that there is a sanity check in
    hardware, but i don't know the used hardware at all.

    ,----[python shell]
    | >>> tmrHw_HIGH_FREQUENCY_HZ = 150000000
    | >>> TIMER3_FREQUENCY_KHZ = (tmrHw_HIGH_FREQUENCY_HZ / 1000 * 30)
    | >>> rate_hz = TIMER3_FREQUENCY_KHZ * 1000
    | >>>
    | >>> import math
    | >>> math.log(rate_hz, 2) # Bits used
    | 32.06727785542857
    | >>> rate_hz % 2**32
    | 205032704L
    `----

    I hope my observations are correct, and this is a real bug and i
    didn't just waste your time. For better testing the issue i will
    append the used configuration. I just did:

    ,----
    | cp ~/mach-bcmring.config .config
    | ARCH=arm make silentoldconfig
    | ARCH=arm SUBARCH=arm KERNELVERSION="v3.2" make arch/arm/mach-bcmring/core.o CC=arm-linux-gnueabi-gcc-4.5
    | [...]
    | CC arch/arm/mach-bcmring/core.o
    | arch/arm/mach-bcmring/core.c:125:34: warning: integer overflow in expression
    `----

    chris

    [unhandled content-type:application/octet-stream]--
    (λ x . x x) (λ x . x x) -- See how beautiful the lambda is
    ∧ No documentation is better than bad documentation
    ∧ and always be awesome to each other, always.
    \
     
     \ /
      Last update: 2012-04-23 15:05    [W:0.057 / U:0.240 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site