[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: disable AMD's C1E mode.
# HG changeset patch # User Keir Fraser <keir@xxxxxxxxxxxxx> # Date 1192105658 -3600 # Node ID cab326925ea6896d1b623629926d0011c29d1798 # Parent 0d7d6804af2204dece108959f4fa40764bd2734f x86: disable AMD's C1E mode. In C1E the APIC timer stops ticking, which Xen cannot tolerate. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> --- xen/arch/x86/acpi/boot.c | 8 ++++++++ xen/arch/x86/cpu/amd.c | 27 +++++++++++++++++++++++++++ xen/arch/x86/traps.c | 10 ++++++++++ xen/include/asm-x86/acpi.h | 2 ++ xen/include/asm-x86/io.h | 2 ++ 5 files changed, 49 insertions(+) diff -r 0d7d6804af22 -r cab326925ea6 xen/arch/x86/acpi/boot.c --- a/xen/arch/x86/acpi/boot.c Thu Oct 11 12:11:54 2007 +0100 +++ b/xen/arch/x86/acpi/boot.c Thu Oct 11 13:27:38 2007 +0100 @@ -70,6 +70,9 @@ static u64 acpi_lapic_addr __initdata = static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; #endif +u32 acpi_smi_cmd; +u8 acpi_enable_value, acpi_disable_value; + #ifndef __HAVE_ARCH_CMPXCHG #warning ACPI uses CMPXCHG, i486 and later hardware #endif @@ -509,9 +512,14 @@ static int __init acpi_parse_fadt(unsign pmtmr_ioport); #endif + acpi_smi_cmd = fadt->smi_cmd; + acpi_enable_value = fadt->acpi_enable; + acpi_disable_value = fadt->acpi_disable; + #ifdef CONFIG_ACPI_SLEEP acpi_fadt_parse_sleep_info(fadt); #endif + return 0; } diff -r 0d7d6804af22 -r cab326925ea6 xen/arch/x86/cpu/amd.c --- a/xen/arch/x86/cpu/amd.c Thu Oct 11 12:11:54 2007 +0100 +++ b/xen/arch/x86/cpu/amd.c Thu Oct 11 13:27:38 2007 +0100 @@ -102,6 +102,29 @@ static void disable_c1_ramping(void) int force_mwait __cpuinitdata; +static void disable_c1e(void *unused) +{ + u32 lo, hi; + + /* + * Disable C1E mode, as the APIC timer stops in that mode. + * The MSR does not exist in all FamilyF CPUs (only Rev F and above), + * but we safely catch the #GP in that case. + */ + if ((rdmsr_safe(MSR_K8_ENABLE_C1E, lo, hi) == 0) && + (lo & (3u << 27)) && + (wrmsr_safe(MSR_K8_ENABLE_C1E, lo & ~(3u << 27), hi) != 0)) + printk(KERN_ERR "Failed to disable C1E on CPU#%u (%08x)\n", + smp_processor_id(), lo); +} + +static void check_disable_c1e(unsigned int port, u8 value) +{ + /* C1E is sometimes enabled during entry to ACPI mode. */ + if ((port == acpi_smi_cmd) && (value == acpi_enable_value)) + on_each_cpu(disable_c1e, NULL, 1, 1); +} + static void __init init_amd(struct cpuinfo_x86 *c) { u32 l, h; @@ -282,6 +305,9 @@ static void __init init_amd(struct cpuin case 0x10: case 0x11: set_bit(X86_FEATURE_K8, c->x86_capability); + disable_c1e(NULL); + if (acpi_smi_cmd && (acpi_enable_value | acpi_disable_value)) + pv_post_outb_hook = check_disable_c1e; break; case 6: set_bit(X86_FEATURE_K7, c->x86_capability); @@ -335,6 +361,7 @@ static void __init init_amd(struct cpuin } #endif + /* Pointless to use MWAIT on Family10 as it does not deep sleep. */ if (c->x86 == 0x10 && !force_mwait) clear_bit(X86_FEATURE_MWAIT, c->x86_capability); diff -r 0d7d6804af22 -r cab326925ea6 xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c Thu Oct 11 12:11:54 2007 +0100 +++ b/xen/arch/x86/traps.c Thu Oct 11 13:27:38 2007 +0100 @@ -1183,6 +1183,8 @@ void host_to_guest_gpr_switch(struct cpu __attribute__((__regparm__(1))); unsigned long guest_to_host_gpr_switch(unsigned long) __attribute__((__regparm__(1))); + +void (*pv_post_outb_hook)(unsigned int port, u8 value); /* Instruction fetch with error handling. */ #define insn_fetch(type, base, eip, limit) \ @@ -1412,7 +1414,11 @@ static int emulate_privileged_op(struct { case 1: if ( guest_outb_okay(port, v, regs) ) + { outb((u8)data, port); + if ( pv_post_outb_hook ) + pv_post_outb_hook(port, data); + } else if ( port == 0x42 || port == 0x43 || port == 0x61 ) pv_pit_handler(port, data, 1); break; @@ -1530,7 +1536,11 @@ static int emulate_privileged_op(struct { case 1: if ( guest_outb_okay(port, v, regs) ) + { io_emul(regs); + if ( pv_post_outb_hook ) + pv_post_outb_hook(port, regs->eax); + } else if ( port == 0x42 || port == 0x43 || port == 0x61 ) pv_pit_handler(port, regs->eax, 1); break; diff -r 0d7d6804af22 -r cab326925ea6 xen/include/asm-x86/acpi.h --- a/xen/include/asm-x86/acpi.h Thu Oct 11 12:11:54 2007 +0100 +++ b/xen/include/asm-x86/acpi.h Thu Oct 11 13:27:38 2007 +0100 @@ -114,6 +114,8 @@ extern int acpi_disabled; extern int acpi_disabled; extern int acpi_ht; extern int acpi_pci_disabled; +extern u32 acpi_smi_cmd; +extern u8 acpi_enable_value, acpi_disable_value; static inline void disable_acpi(void) { acpi_disabled = 1; diff -r 0d7d6804af22 -r cab326925ea6 xen/include/asm-x86/io.h --- a/xen/include/asm-x86/io.h Thu Oct 11 12:11:54 2007 +0100 +++ b/xen/include/asm-x86/io.h Thu Oct 11 13:27:38 2007 +0100 @@ -50,4 +50,6 @@ __OUT(w,"w",short) __OUT(w,"w",short) __OUT(l,,int) +extern void (*pv_post_outb_hook)(unsigned int port, u8 value); + #endif _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |