Commit 643d83f0 authored by Thomas Gleixner's avatar Thomas Gleixner

x86/hpet: Undo the early counter is counting check

Rui reported that on a Pentium D machine which has HPET forced enabled
because it is not advertised by ACPI, the early counter is counting check
leads to a silent boot hang.

The reason is that the ordering of checking the counter first and then
reconfiguring the HPET fails to work on that machine. As the HPET is not
advertised and presumably not initialized by the BIOS the early enable and
the following reconfiguration seems to bring it into a broken state. Adding
clocksource=jiffies to the command line results in the following
clocksource watchdog warning:

  clocksource: timekeeping watchdog on CPU1:
  Marking clocksource 'tsc-early' as unstable because the skew is too large:
  clocksource:  'hpet' wd_now: 33 wd_last: 33 mask: ffffffff

That clearly shows that the HPET is not counting after it got reconfigured
and reenabled. If the counter is not working then the HPET timer is not
expiring either, which explains the boot hang.

Move the counter is counting check after the full configuration again to
unbreak these systems.
Reported-by: default avatarRui Salvaterra <rsalvaterra@gmail.com>
Fixes: 3222daf9 ("x86/hpet: Separate counter check out of clocksource register code")
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Tested-by: default avatarRui Salvaterra <rsalvaterra@gmail.com>
Link: https://lkml.kernel.org/r/alpine.DEB.2.21.1907250810530.1791@nanos.tec.linutronix.de
parent b8f70953
...@@ -827,10 +827,6 @@ int __init hpet_enable(void) ...@@ -827,10 +827,6 @@ int __init hpet_enable(void)
if (!hpet_cfg_working()) if (!hpet_cfg_working())
goto out_nohpet; goto out_nohpet;
/* Validate that the counter is counting */
if (!hpet_counting())
goto out_nohpet;
/* /*
* Read the period and check for a sane value: * Read the period and check for a sane value:
*/ */
...@@ -896,6 +892,14 @@ int __init hpet_enable(void) ...@@ -896,6 +892,14 @@ int __init hpet_enable(void)
} }
hpet_print_config(); hpet_print_config();
/*
* Validate that the counter is counting. This needs to be done
* after sanitizing the config registers to properly deal with
* force enabled HPETs.
*/
if (!hpet_counting())
goto out_nohpet;
clocksource_register_hz(&clocksource_hpet, (u32)hpet_freq); clocksource_register_hz(&clocksource_hpet, (u32)hpet_freq);
if (id & HPET_ID_LEGSUP) { if (id & HPET_ID_LEGSUP) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment