Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/hpet: Use the FSEC_PER_SEC constant for femto-second periods

The current computation, introduced with f12a15be63, of FSEC_PER_SEC using
the multiplication of (FSEC_PER_NSEC * NSEC_PER_SEC) is performed only
with 32bit integers on small machines, resulting in an overflow and a
*very* short intervals being programmed. An interrupt storm follows.

Note that we also have to specify FSEC_PER_SEC as being long long to
overcome the same limitations.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: John Stultz <johnstul@us.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Ingo Molnar <mingo@elte.hu>
Acked-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Chris Wilson and committed by
Linus Torvalds
4936a3b9 deda2e81

+3 -3
+2 -2
arch/x86/kernel/hpet.c
··· 582 582 * scaled math multiplication factor for nanosecond to hpet tick 583 583 * conversion. 584 584 */ 585 - hpet_freq = 1000000000000000ULL; 585 + hpet_freq = FSEC_PER_SEC; 586 586 do_div(hpet_freq, hpet_period); 587 587 evt->mult = div_sc((unsigned long) hpet_freq, 588 588 NSEC_PER_SEC, evt->shift); ··· 837 837 * cyc/sec = FSEC_PER_SEC/hpet_period(fsec/cyc) 838 838 * cyc/sec = (FSEC_PER_NSEC * NSEC_PER_SEC)/hpet_period 839 839 */ 840 - hpet_freq = FSEC_PER_NSEC * NSEC_PER_SEC; 840 + hpet_freq = FSEC_PER_SEC; 841 841 do_div(hpet_freq, hpet_period); 842 842 clocksource_register_hz(&clocksource_hpet, (u32)hpet_freq); 843 843
+1 -1
include/linux/time.h
··· 38 38 #define NSEC_PER_MSEC 1000000L 39 39 #define USEC_PER_SEC 1000000L 40 40 #define NSEC_PER_SEC 1000000000L 41 - #define FSEC_PER_SEC 1000000000000000L 41 + #define FSEC_PER_SEC 1000000000000000LL 42 42 43 43 #define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1) 44 44