[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-4.1-testing] x86/hpet: disable before reboot or kexec
# HG changeset patch # User Jan Beulich <jbeulich@xxxxxxxx> # Date 1334648109 -3600 # Node ID 494aa5ecd2e19384b5ad6c2d30867b86b7f2b405 # Parent 182633356cd4f285fb0e4b777f76a286eca9543a x86/hpet: disable before reboot or kexec Linux up to now is not smart enough to properly clear the HPET when it boots, which is particularly a problem when a kdump attempt from running under Xen is being made. Linux itself added code to work around this to its shutdown paths quite some time ago, so let's do something similar in Xen: Save the configuration register settings during boot, and restore them during shutdown. This should cover the majority of cases where the secondary kernel might not come up because timer interrupts don't work. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Acked-by: Keir Fraser <keir@xxxxxxx> xen-unstable changeset: 25101:f06ff3dfde08 xen-unstable date: Tue Mar 27 15:20:23 2012 +0200 --- diff -r 182633356cd4 -r 494aa5ecd2e1 xen/arch/x86/crash.c --- a/xen/arch/x86/crash.c Tue Apr 17 08:34:28 2012 +0100 +++ b/xen/arch/x86/crash.c Tue Apr 17 08:35:09 2012 +0100 @@ -94,6 +94,7 @@ static void nmi_shootdown_cpus(void) x2apic_enabled = (current_local_apic_mode() == APIC_MODE_X2APIC); disable_IO_APIC(); + hpet_disable(); } void machine_crash_shutdown(void) diff -r 182633356cd4 -r 494aa5ecd2e1 xen/arch/x86/hpet.c --- a/xen/arch/x86/hpet.c Tue Apr 17 08:34:28 2012 +0100 +++ b/xen/arch/x86/hpet.c Tue Apr 17 08:35:09 2012 +0100 @@ -744,12 +744,14 @@ int hpet_legacy_irq_tick(void) return 1; } +static u32 *hpet_boot_cfg; + u64 hpet_setup(void) { static u64 hpet_rate; static u32 system_reset_latch; u32 hpet_id, hpet_period, cfg; - int i; + unsigned int i, last; if ( system_reset_latch == system_reset_counter ) return hpet_rate; @@ -775,13 +777,20 @@ u64 hpet_setup(void) return 0; } + last = (hpet_id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT; + hpet_boot_cfg = xmalloc_array(u32, 2 + last); + cfg = hpet_read32(HPET_CFG); + if ( hpet_boot_cfg ) + *hpet_boot_cfg = cfg; cfg &= ~(HPET_CFG_ENABLE | HPET_CFG_LEGACY); hpet_write32(cfg, HPET_CFG); - for ( i = 0; i <= ((hpet_id >> 8) & 31); i++ ) + for ( i = 0; i <= last; ++i ) { cfg = hpet_read32(HPET_Tn_CFG(i)); + if ( hpet_boot_cfg ) + hpet_boot_cfg[i + 1] = cfg; cfg &= ~HPET_TN_ENABLE; hpet_write32(cfg, HPET_Tn_CFG(i)); } @@ -795,3 +804,21 @@ u64 hpet_setup(void) return hpet_rate; } + +void hpet_disable(void) +{ + unsigned int i; + u32 id; + + if ( !hpet_boot_cfg ) + return; + + hpet_write32(*hpet_boot_cfg & ~HPET_CFG_ENABLE, HPET_CFG); + + id = hpet_read32(HPET_ID); + for ( i = 0; i <= ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT); ++i ) + hpet_write32(hpet_boot_cfg[i + 1], HPET_Tn_CFG(i)); + + if ( *hpet_boot_cfg & HPET_CFG_ENABLE ) + hpet_write32(*hpet_boot_cfg, HPET_CFG); +} diff -r 182633356cd4 -r 494aa5ecd2e1 xen/arch/x86/smp.c --- a/xen/arch/x86/smp.c Tue Apr 17 08:34:28 2012 +0100 +++ b/xen/arch/x86/smp.c Tue Apr 17 08:35:09 2012 +0100 @@ -19,6 +19,7 @@ #include <asm/mc146818rtc.h> #include <asm/flushtlb.h> #include <asm/hardirq.h> +#include <asm/hpet.h> #include <asm/hvm/support.h> #include <mach_apic.h> @@ -372,6 +373,7 @@ void smp_send_stop(void) local_irq_disable(); __stop_this_cpu(); disable_IO_APIC(); + hpet_disable(); local_irq_enable(); } diff -r 182633356cd4 -r 494aa5ecd2e1 xen/include/asm-x86/hpet.h --- a/xen/include/asm-x86/hpet.h Tue Apr 17 08:34:28 2012 +0100 +++ b/xen/include/asm-x86/hpet.h Tue Apr 17 08:35:09 2012 +0100 @@ -67,6 +67,11 @@ extern unsigned long hpet_address; u64 hpet_setup(void); /* + * Disable HPET hardware: restore it to boot time state. + */ +void hpet_disable(void); + +/* * Callback from legacy timer (PIT channel 0) IRQ handler. * Returns 1 if tick originated from HPET; else 0. */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |