[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] x86: disable AMD's C1E mode
In C1E the APIC timer stops ticking, which Xen cannot tolerate. (As I don't have a system that's affected, the patch must be considered untested). Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> Index: 2007-10-10/xen/arch/x86/acpi/boot.c =================================================================== --- 2007-10-10.orig/xen/arch/x86/acpi/boot.c 2007-09-27 10:42:44.000000000 +0200 +++ 2007-10-10/xen/arch/x86/acpi/boot.c 2007-10-10 17:14:46.000000000 +0200 @@ -70,6 +70,9 @@ int acpi_skip_timer_override __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; } Index: 2007-10-10/xen/arch/x86/cpu/amd.c =================================================================== --- 2007-10-10.orig/xen/arch/x86/cpu/amd.c 2007-10-10 17:12:29.000000000 +0200 +++ 2007-10-10/xen/arch/x86/cpu/amd.c 2007-10-10 17:14:05.000000000 +0200 @@ -100,6 +100,32 @@ static void disable_c1_ramping(void) } } +#ifdef CONFIG_SMP +/* + * Disable C1E mode, as the APIC timer stops in that mode. + */ +static void disable_c1e(void *unused) +{ + u32 lo, hi; + + if (rdmsr_safe(0xC0010055, lo, hi) == 0 + && (lo & ((1 << 27) | (1 << 28))) + && wrmsr_safe(0xC0010055, + lo & ~((1 << 27) | (1 << 28)), + 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) +{ + if (port == acpi_smi_cmd && value == acpi_enable_value) + on_each_cpu(disable_c1e, NULL, 1, 1); +} +#else +#define check_disable_c1e NULL +#endif + static void __init init_amd(struct cpuinfo_x86 *c) { u32 l, h; @@ -280,6 +306,10 @@ static void __init init_amd(struct cpuin switch (c->x86) { case 15 ... 17: set_bit(X86_FEATURE_K8, c->x86_capability); + if (acpi_smi_cmd && (acpi_enable_value | acpi_disable_value)) { + disable_c1e(NULL); + pv_post_outb_hook = check_disable_c1e; + } break; case 6: set_bit(X86_FEATURE_K7, c->x86_capability); Index: 2007-10-10/xen/arch/x86/traps.c =================================================================== --- 2007-10-10.orig/xen/arch/x86/traps.c 2007-10-10 17:11:34.000000000 +0200 +++ 2007-10-10/xen/arch/x86/traps.c 2007-10-10 17:14:05.000000000 +0200 @@ -1191,6 +1191,8 @@ void host_to_guest_gpr_switch(struct cpu 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) \ ({ unsigned long _rc, _ptr = (base) + (eip); \ @@ -1419,7 +1421,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; @@ -1537,7 +1543,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; Index: 2007-10-10/xen/include/asm-x86/acpi.h =================================================================== --- 2007-10-10.orig/xen/include/asm-x86/acpi.h 2007-09-27 10:42:44.000000000 +0200 +++ 2007-10-10/xen/include/asm-x86/acpi.h 2007-10-10 17:14:05.000000000 +0200 @@ -114,6 +114,8 @@ extern int acpi_strict; 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; Index: 2007-10-10/xen/include/asm-x86/io.h =================================================================== --- 2007-10-10.orig/xen/include/asm-x86/io.h 2006-08-21 18:02:24.000000000 +0200 +++ 2007-10-10/xen/include/asm-x86/io.h 2007-10-10 17:14:05.000000000 +0200 @@ -50,4 +50,6 @@ __OUT(b,"b",char) __OUT(w,"w",short) __OUT(l,,int) +extern void (*pv_post_outb_hook)(unsigned int port, u8 value); + #endif _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |