[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 3/3] x86/hpet: Restore old configuration if Legacy Replacement mode doesn't help
On Fri, Mar 26, 2021 at 06:59:47PM +0000, Andrew Cooper wrote: > If Legacy Replacement mode doesn't help in check_timer(), restore the old > configuration before falling back to other workarounds. Oh, I guess this answers my question from the previous patch. > Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Reviewed-by: Roger Pau Monné <roger.pau@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. Is this really the fix for AMD 1800X? I assumed not setting the HPET into legacy replacement mode unconditionally was the fix for those 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(); I think you could also get away just calling hpet_disable and hpet_resume? (bypassing the system_reset_counter check) Thanks, Roger.
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |