]> git.ipfire.org Git - thirdparty/grub.git/commit
kern/i386/tsc_pmtimer: Make pmtimer tsc calibration not take 51 seconds to fail
authorPeter Jones <pjones@redhat.com>
Thu, 28 Jul 2022 18:34:16 +0000 (14:34 -0400)
committerDaniel Kiper <daniel.kiper@oracle.com>
Wed, 10 Aug 2022 12:24:46 +0000 (14:24 +0200)
commit8812755d971e35609b84bf6633df8ff25c42550a
treeda1dbc0684a98032910725900b5bdccff939f3dc
parenta768876c0df0c9258e9c7502cdb54675eeb5f7ec
kern/i386/tsc_pmtimer: Make pmtimer tsc calibration not take 51 seconds to fail

On my laptop running at 2.4GHz, if I run a VM where tsc calibration
using pmtimer will fail presuming a broken pmtimer, it takes ~51 seconds
to do so (as measured with the stopwatch on my phone), with a tsc delta
of 0x1cd1c85300, or around 125 billion cycles.

If instead of trying to wait for 5-200ms to show up on the pmtimer, we
try to wait for 5-200us, it decides it's broken in ~0x2626aa0 TSCs, aka
~2.4 million cycles, or more or less instantly.

Additionally, this reading the pmtimer was returning 0xffffffff anyway,
and that's obviously an invalid return. I've added a check for that and
0 so we don't bother waiting for the test if what we're seeing is dead
pins with no response at all.

If "debug" includes "pmtimer", you will see one of the following three
outcomes. If pmtimer gives all 0 or all 1 bits, you will see:

  pmtimer: 0xffffff bad_reads: 1
  pmtimer: 0xffffff bad_reads: 2
  pmtimer: 0xffffff bad_reads: 3
  pmtimer: 0xffffff bad_reads: 4
  pmtimer: 0xffffff bad_reads: 5
  pmtimer: 0xffffff bad_reads: 6
  pmtimer: 0xffffff bad_reads: 7
  pmtimer: 0xffffff bad_reads: 8
  pmtimer: 0xffffff bad_reads: 9
  pmtimer: 0xffffff bad_reads: 10
  timer is broken; giving up.

This outcome was tested using qemu+kvm with UEFI (OVMF) firmware and
these options: -machine pc-q35-2.10 -cpu Broadwell-noTSX

If pmtimer gives any other bit patterns but is not actually marching
forward fast enough to use for clock calibration, you will see:

  pmtimer delta is 0x0 (1904 iterations)
  tsc delta is implausible: 0x2626aa0

This outcome was tested using GRUB patched to not ignore bad reads using
qemu+kvm with UEFI (OVMF) firmware, and these options:
-machine pc-q35-2.10 -cpu Broadwell-noTSX

If pmtimer actually works, you'll see something like:

  pmtimer delta is 0xdff
  tsc delta is 0x278756

This outcome was tested using qemu+kvm with UEFI (OVMF) firmware, and
these options: -machine pc-i440fx-2.4 -cpu Broadwell-noTSX

I've also tested this outcome on a real Intel Xeon E3-1275v3 on an Intel
Server Board S1200V3RPS using the SDV.RP.B8 "Release" build here:
https://www.intel.com/content/www/us/en/download/674448/firmware-update-for-the-intel-server-board-s1200rp-uefi-development-kit-release-vb8.html

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
grub-core/kern/i386/tsc_pmtimer.c