lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <alpine.DEB.2.21.1811121001140.14703@nanos.tec.linutronix.de>
Date:   Mon, 12 Nov 2018 10:37:28 -0800 (PST)
From:   Thomas Gleixner <tglx@...utronix.de>
To:     Finn Thain <fthain@...egraphics.com.au>
cc:     Geert Uytterhoeven <geert@...ux-m68k.org>,
        Arnd Bergmann <arnd@...db.de>,
        Stephen N Chivers <schivers@....com.au>,
        Daniel Lezcano <daniel.lezcano@...aro.org>,
        John Stultz <john.stultz@...aro.org>,
        linux-m68k@...ts.linux-m68k.org, linux-kernel@...r.kernel.org
Subject: Re: [RFC PATCH 13/13] m68k: mvme16x: Convert to clocksource API

Finn,

On Mon, 12 Nov 2018, Finn Thain wrote:

First of all, thanks for tackling this!

> +static u32 clk_total;
> +
> +#define PCC_TIMER_CLOCK_FREQ 1000000
> +#define PCC_TIMER_CYCLES     (PCC_TIMER_CLOCK_FREQ / HZ)
> +
>  static irqreturn_t mvme16x_timer_int (int irq, void *dev_id)
>  {
> +    irq_handler_t tick_handler = dev_id;
> +    unsigned long flags;
> +
> +    local_irq_save(flags);

No need for local_irq_save() here. Interrupt handlers are guaranteed to be
called with interrupts disabled.

>      *(volatile unsigned char *)0xfff4201b |= 8;
> +    clk_total += PCC_TIMER_CYCLES;

Looking at the read function below, I assume that this magic 0xfff42008
register counts up to PCC_TIMER_CYCLES, which triggers the timer interrupt
and then starts from 0 again. And looking at the programming manual
actually confirms that assumption (COC is set in the control reg).

> -u32 mvme16x_gettimeoffset(void)
> +static u64 mvme16x_read_clk(struct clocksource *cs)
>  {
> -    return (*(volatile u32 *)0xfff42008) * 1000;
> +    u32 count = *(volatile u32 *)0xfff42008;
> +
> +    return clk_total + count;
>  }

There is a problem with that approach. Assume the following situation:

				Counter value (HZ = 100)
       local_irq_disable()	
       ...
       ktime_get()		9999
       ....			10000 -> 0 (interrupt is triggered)
       ktime_get()		1

IOW, time goes backwards.

There are two ways to solve that:

 1) Take the overflow bits in the timer control register into account,
    which makes time readout even slower because you need to do it like
    this:

    do {
       ovfl = read(TCR1);
       now = read(TCNT1);
    while (ovfl != read(TCR1));
    ....
  

 2) Use Timer2 in freerunning mode which means it will use the full 32bit
    and then wrap back to 0. That's fine and the clocksource core handles
    that.

    That removes the clk_total thing and just works.

Thanks,

	tglx

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ