[PATCH] x86-64: Avoid overflows during apic timer calibration
- Use 64bit TSC calculations to avoid handling overflow - Use 32bit unsigned arithmetic for the APIC timer. This way overflows are handled correctly. - Fix exit check of loop to account for apic timer counting down Signed-off-by: dpreed@reed.com Signed-off-by: Andi Kleen <ak@suse.de>
This commit is contained in:
parent
9d016dd43b
commit
4637a74cf2
@ -839,14 +839,15 @@ static void setup_APIC_timer(unsigned int clocks)
|
|||||||
|
|
||||||
static int __init calibrate_APIC_clock(void)
|
static int __init calibrate_APIC_clock(void)
|
||||||
{
|
{
|
||||||
int apic, apic_start, tsc, tsc_start;
|
unsigned apic, apic_start;
|
||||||
|
unsigned long tsc, tsc_start;
|
||||||
int result;
|
int result;
|
||||||
/*
|
/*
|
||||||
* Put whatever arbitrary (but long enough) timeout
|
* Put whatever arbitrary (but long enough) timeout
|
||||||
* value into the APIC clock, we just want to get the
|
* value into the APIC clock, we just want to get the
|
||||||
* counter running for calibration.
|
* counter running for calibration.
|
||||||
*/
|
*/
|
||||||
__setup_APIC_LVTT(1000000000);
|
__setup_APIC_LVTT(4000000000);
|
||||||
|
|
||||||
apic_start = apic_read(APIC_TMCCT);
|
apic_start = apic_read(APIC_TMCCT);
|
||||||
#ifdef CONFIG_X86_PM_TIMER
|
#ifdef CONFIG_X86_PM_TIMER
|
||||||
@ -857,13 +858,13 @@ static int __init calibrate_APIC_clock(void)
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
rdtscl(tsc_start);
|
rdtscll(tsc_start);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
apic = apic_read(APIC_TMCCT);
|
apic = apic_read(APIC_TMCCT);
|
||||||
rdtscl(tsc);
|
rdtscll(tsc);
|
||||||
} while ((tsc - tsc_start) < TICK_COUNT &&
|
} while ((tsc - tsc_start) < TICK_COUNT &&
|
||||||
(apic - apic_start) < TICK_COUNT);
|
(apic_start - apic) < TICK_COUNT);
|
||||||
|
|
||||||
result = (apic_start - apic) * 1000L * tsc_khz /
|
result = (apic_start - apic) * 1000L * tsc_khz /
|
||||||
(tsc - tsc_start);
|
(tsc - tsc_start);
|
||||||
|
Loading…
Reference in New Issue
Block a user