]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
x86/apic: Fix frequency in apic=verbose log output
authorJulian Stecklina <julian.stecklina@cyberus-technology.de>
Sat, 30 Oct 2021 14:21:48 +0000 (16:21 +0200)
committerBorislav Petkov (AMD) <bp@alien8.de>
Fri, 7 Nov 2025 16:48:14 +0000 (17:48 +0100)
When apic=verbose is specified, the LAPIC timer calibration prints its results
to the console. At least while debugging virtualization code, the CPU and bus
frequencies are printed incorrectly.

Specifically, for a 1.7 GHz CPU with 1 GHz bus frequency and HZ=1000,
the log includes a superfluous 0 after the period:

  ..... calibration result: 999978
  ..... CPU clock speed is 1696.0783 MHz.
  ..... host bus clock speed is 999.0978 MHz.

Looking at the code, this only worked as intended for HZ=100. After the fix,
the correct frequency is printed:

  ..... calibration result: 999828
  ..... CPU clock speed is 1696.507 MHz.
  ..... host bus clock speed is 999.828 MHz.

There is no functional change to the LAPIC calibration here, beyond the
printing format changes.

  [ bp: - Massage commit message
        - Figures it should apply this patch about ~4 years later
        - Massage it into the current code ]

Suggested-by: Markus Napierkowski <markus.napierkowski@cyberus-technology.de>
Signed-off-by: Julian Stecklina <julian.stecklina@cyberus-technology.de>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://patch.msgid.link/20211030142148.143261-1-js@alien8.de
arch/x86/kernel/apic/apic.c

index 680d305589a3acb32c7aebfc4e91a7c6966992af..ca1c8b70ac4456383aaaa0b939d1af776cf6bab7 100644 (file)
@@ -173,6 +173,7 @@ static struct resource lapic_resource = {
        .flags = IORESOURCE_MEM | IORESOURCE_BUSY,
 };
 
+/* Measured in ticks per HZ. */
 unsigned int lapic_timer_period = 0;
 
 static void apic_pm_activate(void);
@@ -792,6 +793,7 @@ static int __init calibrate_APIC_clock(void)
 {
        struct clock_event_device *levt = this_cpu_ptr(&lapic_events);
        u64 tsc_perj = 0, tsc_start = 0;
+       long delta_tsc_khz, bus_khz;
        unsigned long jif_start;
        unsigned long deltaj;
        long delta, deltatsc;
@@ -894,14 +896,15 @@ static int __init calibrate_APIC_clock(void)
        apic_pr_verbose("..... calibration result: %u\n", lapic_timer_period);
 
        if (boot_cpu_has(X86_FEATURE_TSC)) {
-               apic_pr_verbose("..... CPU clock speed is %ld.%04ld MHz.\n",
-                               (deltatsc / LAPIC_CAL_LOOPS) / (1000000 / HZ),
-                               (deltatsc / LAPIC_CAL_LOOPS) % (1000000 / HZ));
+               delta_tsc_khz = (deltatsc * HZ) / (1000 * LAPIC_CAL_LOOPS);
+
+               apic_pr_verbose("..... CPU clock speed is %ld.%03ld MHz.\n",
+                               delta_tsc_khz / 1000, delta_tsc_khz % 1000);
        }
 
-       apic_pr_verbose("..... host bus clock speed is %u.%04u MHz.\n",
-                       lapic_timer_period / (1000000 / HZ),
-                       lapic_timer_period % (1000000 / HZ));
+       bus_khz = (long)lapic_timer_period * HZ / 1000;
+       apic_pr_verbose("..... host bus clock speed is %ld.%03ld MHz.\n",
+                       bus_khz / 1000, bus_khz % 1000);
 
        /*
         * Do a sanity check on the APIC calibration result