8812755 kern/i386/tsc_pmtimer: Make pmtimer tsc calibration not take 51 seconds to fail

1 file Authored by pjones 2 years ago, Committed by Daniel Kiper 2 years ago,
    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>