mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-11 15:49:56 +00:00
hpet: fix the possibility of insane return value of hpet_calibrate() against SMI
hpet_calibrate() has a possibility of miss-calibration due to SMI. If SMI interrupts in the while loop of calibration, then return value will be big. This change calibrates until stabilizing by the return value with a small value. [akpm@linux-foundation.org: trivial style tweaks] Signed-off-by: Yasunori Goto <y-goto@jp.fujitsu.com> Acked-by: Clemens Ladisch <clemens@ladisch.de> Acked-by: Vojtech Pavlik <vojtech@suse.cz> Cc: Robert Picco <Robert.Picco@hp.com> Cc: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Cc: Ingo Molnar <mingo@elte.hu> Acked-by: Paul Gortmaker <paul.gortmaker@windriver.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
1f80769ffd
commit
303d379c54
@ -713,7 +713,7 @@ static struct ctl_table_header *sysctl_header;
|
|||||||
*/
|
*/
|
||||||
#define TICK_CALIBRATE (1000UL)
|
#define TICK_CALIBRATE (1000UL)
|
||||||
|
|
||||||
static unsigned long hpet_calibrate(struct hpets *hpetp)
|
static unsigned long __hpet_calibrate(struct hpets *hpetp)
|
||||||
{
|
{
|
||||||
struct hpet_timer __iomem *timer = NULL;
|
struct hpet_timer __iomem *timer = NULL;
|
||||||
unsigned long t, m, count, i, flags, start;
|
unsigned long t, m, count, i, flags, start;
|
||||||
@ -750,6 +750,26 @@ static unsigned long hpet_calibrate(struct hpets *hpetp)
|
|||||||
return (m - start) / i;
|
return (m - start) / i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned long hpet_calibrate(struct hpets *hpetp)
|
||||||
|
{
|
||||||
|
unsigned long ret = -1;
|
||||||
|
unsigned long tmp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to calibrate until return value becomes stable small value.
|
||||||
|
* If SMI interruption occurs in calibration loop, the return value
|
||||||
|
* will be big. This avoids its impact.
|
||||||
|
*/
|
||||||
|
for ( ; ; ) {
|
||||||
|
tmp = __hpet_calibrate(hpetp);
|
||||||
|
if (ret <= tmp)
|
||||||
|
break;
|
||||||
|
ret = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int hpet_alloc(struct hpet_data *hdp)
|
int hpet_alloc(struct hpet_data *hdp)
|
||||||
{
|
{
|
||||||
u64 cap, mcfg;
|
u64 cap, mcfg;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user