[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2 3/3] x86/hpet: Restore old configuration if Legacy Replacement mode doesn't help


  • To: Xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
  • Date: Fri, 26 Mar 2021 18:59:47 +0000
  • Authentication-results: esa1.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Jan Beulich <JBeulich@xxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Ian Jackson <iwj@xxxxxxxxxxxxxx>, Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>, Frédéric Pierret <frederic.pierret@xxxxxxxxxxxx>
  • Delivery-date: Fri, 26 Mar 2021 19:00:13 +0000
  • Ironport-hdrordr: A9a23:m83dP606WrBnf0xHY/R78gqjBal2eYIsi2QD101hICF9Wvez0+ izgfUW0gL1gj4NWHcm3euNIrWEXGm0z/FIyKErF/OHUBP9sGWlaLtj44zr3iH6F0TFmtJ1/Z xLN5JzANiYNzVHpO7x6gWgDpIEyN6I7KiniY7lvg1QZCthApsQtTtRIACdD0FwWU1iDZ02CJ KT6qN81kedUF4Qadm2AWRAYvjbq7Tw5d7bSDMlJzpi0gmBiju09KX3eiL34j4yWy5CqI1Sl1 TtvBf+4syYwpKG4z/ak1Te9pFH3Obmo+Ezf/CkrugwBnHShh2zZIJnMofy8wwdhO208l4lnJ 3tjn4bTr1OwkjcdG20vhfhsjOIuF1Fih/f4GSVjnf5rcvySChSMbs4uatibhDb50A81esMtZ 5j4mODu5JbSTPGkSjtjuK4MC1Cq0uurXIu1dMUlnxUOLFuDIN5kIp3xjI2LL4wWAbBrKw3Gu hnC8/RoNxMd0mBUnzftm5zhPSxQ3UaBH69Mwk/k/3Q9wITsGFyzkMeysBatGwH7ogBR55N4P mBGrh0lYtJUtQdYctGdac8aPryLlaIbQPHMWqUL1iiProAIWjxp5n+56hww+22ZpoSzt8XlI 7aWF1V8U4+EnieSvGm7dluyFTgUW+9VTPixoV1/J5ioIDxQ7LtLGmNU1Yrn8y8o+gOA8HSVv qpUagmRsPLHC/LI8Jkzgf+U55dJT01S8sOoOs2XFqIv4bKJ+TRx6jmWceWAICoPScvW2v5DH dGdiP0Pt984keiXWK9hBDQXnjqa1Hu5J4YKtmcw8EjjKw2cqFcuAkcjlq0ouuRLydZj6AwdE xiZLX9kq26omGy9X3S73pgPwdcCko92sSjb1p64Ssxd2/ke7cKvNuSPUpI2mGcGxN5R8TKVB JEq09v4qKxJZyIzSUkA9aqW1jqyUc7lTavddMxi6eD7cDqdtcEFZ4gQrV2DhiOPQdygxxWpG BKbxIkSkfTGij1s7isiIUZCYjkBoBBqTbuBfQRiHrE8W2AuMkkRxIgLkKTeP/SpTxreh15qR la9bQFjL+JhDC1QFFP/9gQARlrc2SYALVPEQKfQp5b84qbNj1YfCO0vBjfpzYYPlHH2WU3qg XaXHGpUMCOPWN4/l5i9JrStHNYH1/tIn5YWzREiKk4NEL9hx9IoLS2T5v27FK0Lns5hsAsGw rkTFIpU1xT7uHy6yew3BK5OzEH6/wVT7TgJbw+brDe3W6sIoWUlacAW+RZ5ophKcqGiJ50bc uFfROJIC7/YtlZrzC9tzIrPjJ5p2Ijlu6t0Br57HKg1Hp6GvbKJk96LotraO20/izhR/yS1o 9+gs9wteysMn/pYtru89CfUxdTbhfSq3WxVecmtNRdur8zrqJ6G93eXSHT3H9KmBU4I8Gcrj JXfI1rpLTAMJRoZcocZmZQ+Ucojs2GKA8zqRPta9VOCG0FnjveJZeE8rDIob0gDgmIoxbxI0 CW92lY8+3eVyWO2LYGA8sLUC5rQVl57G4n8PKJdoXWBgnvbe1F8VagOnK2cbNWSsG+aMMthw c/58vNk/6cdiL+1gyVoCByJbhW9X27Bcy1GwCBFIdzgpGHEEXJhrHv5sG9jD36E2TmL0sZgJ BIbkwWYIBIjCI4gIg+zyi1Tej2ryse4ihjyCAikkSo3I6spHrfFwVBNwbSh51NRzldMnSSl6 3+gJ+l/WW45CIAwIXJEUdbY8pHFNcRRJXmNisGE7lhgJe4u640xjlZaBggD2QgmCnw0uNv07 C+wujTUYTZeAXVEENE/yVECI5yljEqrm8Fc9HW1+PNXjkq
  • Ironport-sdr: zsK55gemVstwCTyRH4LtBkpgWq9VD3bgys0Wg2m345eRf9KH+ZOWQsUCzxvlpCQPx6z3eNtMRS u7T24eJQzpBkY42Covx4PExdpw+9NwYbNoO3rWzSrUz2fLYS34+n3g+RP1buqJZ2qv6JwcZFV+ OGmCxPiGC2QaT/ExROJqUGkf/3X2ot9zS1Tmx16i7HVpZnoZ6Jk/s+QcsQuUbrINkchvV0OiF9 2Y4CC/qWPy8FFXWPLGlPUDj0y2NavoMscCXumMKBsxmFQ+BMSmGmjfTyZZvyHXxa9XsbhybYdw nhA=
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

If Legacy Replacement mode doesn't help in check_timer(), restore the old
configuration before falling back to other workarounds.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>
CC: Wei Liu <wl@xxxxxxx>
CC: Ian Jackson <iwj@xxxxxxxxxxxxxx>
CC: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
CC: Frédéric Pierret <frederic.pierret@xxxxxxxxxxxx>

v2:
 * New.

For 4.15: Attempt to unbreak AMD Ryzen 1800X systems.

I'm tempted to fold this into the previous patch, but its presented here in
isolation for ease of review.

Tested by repositioning the timer_irq_works() calls on a system with a working
PIT.

(XEN) ENABLING IO-APIC IRQs
(XEN)  -> Using old ACK method
(XEN) ..TIMER: vector=0xF0 apic1=0 pin1=2 apic2=0 pin2=0
(XEN) ..no 8254 timer found - trying HPET Legacy Replacement Mode
(XEN) ..no HPET timer found - reverting Legacy Replacement Mode
(XEN) TSC deadline timer enabled
---
 xen/arch/x86/hpet.c        | 27 ++++++++++++++++++++++++++-
 xen/arch/x86/io_apic.c     |  4 ++++
 xen/include/asm-x86/hpet.h |  6 ++++++
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c
index bfa75f135a..afe104dc93 100644
--- a/xen/arch/x86/hpet.c
+++ b/xen/arch/x86/hpet.c
@@ -783,6 +783,9 @@ int hpet_legacy_irq_tick(void)
 
 static u32 *hpet_boot_cfg;
 static uint64_t __initdata hpet_rate;
+static __initdata struct {
+    uint32_t cmp, cfg;
+} pre_legacy_c0;
 
 bool __init hpet_enable_legacy_replacement_mode(void)
 {
@@ -796,8 +799,11 @@ bool __init hpet_enable_legacy_replacement_mode(void)
     /* Stop the main counter. */
     hpet_write32(cfg & ~HPET_CFG_ENABLE, HPET_CFG);
 
+    /* Stash channel 0's old CFG/CMP incase we need to undo. */
+    pre_legacy_c0.cfg = c0_cfg = hpet_read32(HPET_Tn_CFG(0));
+    pre_legacy_c0.cmp = hpet_read32(HPET_Tn_CMP(0));
+
     /* Reconfigure channel 0 to be 32bit periodic. */
-    c0_cfg = hpet_read32(HPET_Tn_CFG(0));
     c0_cfg |= (HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
                HPET_TN_32BIT);
     hpet_write32(c0_cfg, HPET_Tn_CFG(0));
@@ -843,6 +849,25 @@ bool __init hpet_enable_legacy_replacement_mode(void)
     return true;
 }
 
+void __init hpet_disable_legacy_replacement_mode(void)
+{
+    unsigned int cfg = hpet_read32(HPET_CFG);
+
+    ASSERT(hpet_rate);
+
+    cfg &= ~(HPET_CFG_LEGACY | HPET_CFG_ENABLE);
+
+    /* Stop the main counter and disable legacy mode. */
+    hpet_write32(cfg, HPET_CFG);
+
+    /* Restore pre-Legacy Replacement Mode settings. */
+    hpet_write32(pre_legacy_c0.cfg, HPET_Tn_CFG(0));
+    hpet_write32(pre_legacy_c0.cmp, HPET_Tn_CMP(0));
+
+    /* Restart the main counter. */
+    hpet_write32(cfg | HPET_CFG_ENABLE, HPET_CFG);
+}
+
 u64 __init hpet_setup(void)
 {
     unsigned int hpet_id, hpet_period;
diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c
index 3f131a81fb..58b26d962c 100644
--- a/xen/arch/x86/io_apic.c
+++ b/xen/arch/x86/io_apic.c
@@ -1955,6 +1955,10 @@ static void __init check_timer(void)
                 local_irq_restore(flags);
                 return;
             }
+
+            /* Legacy Replacement mode hasn't helped.  Undo it. */
+            printk(XENLOG_ERR "..no HPET timer found - reverting Legacy 
Replacement Mode\n");
+            hpet_disable_legacy_replacement_mode();
         }
 
         clear_IO_APIC_pin(apic1, pin1);
diff --git a/xen/include/asm-x86/hpet.h b/xen/include/asm-x86/hpet.h
index 07bc8d6079..8f9725a95e 100644
--- a/xen/include/asm-x86/hpet.h
+++ b/xen/include/asm-x86/hpet.h
@@ -80,6 +80,12 @@ int hpet_legacy_irq_tick(void);
 bool hpet_enable_legacy_replacement_mode(void);
 
 /*
+ * Undo the effects of hpet_disable_legacy_replacement_mode().  Must not be
+ * called unless enable() returned true.
+ */
+void hpet_disable_legacy_replacement_mode(void);
+
+/*
  * Temporarily use an HPET event counter for timer interrupt handling,
  * rather than using the LAPIC timer. Used for Cx state entry.
  */
-- 
2.11.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.