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
|