• Thomas Gleixner's avatar
    tick: Ensure that the broadcast device is initialized · b9a6a235
    Thomas Gleixner authored
    Santosh found another trap when we avoid to initialize the broadcast
    device in the switch_to_oneshot code. The broadcast device might be
    still in SHUTDOWN state when we actually need to use it. That
    obviously breaks, as set_next_event() is called on a shutdown
    device. This did not break on x86, but Suresh analyzed it:
    
    From the review, most likely on Sven's system we are force enabling
    the hpet using the pci quirk's method very late. And in this case,
    hpet_clockevent (which will be global_clock_event) handler can be
    null, specifically as this platform might not be using deeper c-states
    and using the reliable APIC timer.
    
    Prior to commit 'fa4da365', that handler will be set to
    'tick_handle_oneshot_broadcast' when we switch the broadcast timer to
    oneshot mode, even though we don't use it. Post commit
    'fa4da365', we stopped switching the broadcast mode to oneshot
    as this is not really needed and his platform's global_clock_event's
    handler will remain null. While on my SNB laptop, same is set to
    'clockevents_handle_noop' because hpet gets enabled very early. (noop
    handler on my platform set when the early enabled hpet timer gets
    replaced by the lapic timer).
    
    But the commit 'fa4da365' tracked the broadcast timer mode in
    the SW as oneshot, even though it didn't touch the HW timer. During
    resume however, tick_resume_broadcast() saw the SW broadcast mode as
    oneshot and actually programmed the broadcast device also into oneshot
    mode. So this triggered the null pointer de-reference after the hpet
    wraps around and depending on what the hpet counter is set to. On the
    normal platforms where hpet gets enabled early we should be seeing a
    spurious interrupt (in my SNB laptop I see one spurious interrupt
    after around 5 minutes ;) which is 32-bit hpet counter wraparound
    time), but that's a separate issue.
    
    Enforce the mode setting when trying to set an event.
    Reported-and-tested-by: default avatarSantosh Shilimkar <santosh.shilimkar@ti.com>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Acked-by: default avatarSuresh Siddha <suresh.b.siddha@intel.com>
    Cc: torvalds@linux-foundation.org
    Cc: svenjoac@gmx.de
    Cc: rjw@sisk.pl
    Link: http://lkml.kernel.org/r/alpine.LFD.2.02.1204181723350.2542@ionos
    b9a6a235
tick-broadcast.c 15.6 KB