--- 2006-04-19/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c.0 2006-04-20 14:18:14.000000000 +0200 +++ 2006-04-19/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c 2006-04-20 14:26:17.000000000 +0200 @@ -2483,8 +2483,17 @@ __setup("enable_8254_timer", setup_enabl static int __init io_apic_bug_finalize(void) { - if(sis_apic_bug == -1) + if(sis_apic_bug == -1) { + if (xen_start_info->flags & SIF_INITDOMAIN) { + dom0_op_t op = { + .cmd = DOM0_PLATFORM_QUIRK, + .u.platform_quirk.quirk_id = QUIRK_IOAPICMODIFY + }; + + HYPERVISOR_dom0_op(&op); + } sis_apic_bug = 0; + } return 0; } --- 2006-04-19/xen/arch/x86/dom0_ops.c.0 2006-04-06 17:50:25.000000000 +0200 +++ 2006-04-19/xen/arch/x86/dom0_ops.c 2006-04-20 14:04:15.000000000 +0200 @@ -386,6 +386,12 @@ long arch_do_dom0_op(struct dom0_op *op, opt_noirqbalance = 1; setup_ioapic_dest(); break; + case QUIRK_IOAPICMODIFY: +#ifndef sis_apic_bug + printk("Platform info -- Allowing fast IO-APIC updates.\n"); + sis_apic_bug = 0; +#endif + break; default: ret = -EINVAL; break; --- 2006-04-19/xen/arch/x86/io_apic.c.0 2006-04-20 09:36:12.000000000 +0200 +++ 2006-04-19/xen/arch/x86/io_apic.c 2006-04-20 14:04:25.000000000 +0200 @@ -51,6 +51,14 @@ static DEFINE_SPINLOCK(vector_lock); int skip_ioapic_setup; +#ifndef sis_apic_bug +/* + * Is the SiS APIC rmw bug present ? + * -1 = don't know, 0 = no, 1 = yes + */ +int sis_apic_bug = -1; +#endif + /* * # of IRQ routing registers */ --- 2006-04-19/xen/include/public/dom0_ops.h.0 2006-04-20 09:30:23.000000000 +0200 +++ 2006-04-19/xen/include/public/dom0_ops.h 2006-04-20 13:09:17.000000000 +0200 @@ -405,6 +405,7 @@ DEFINE_GUEST_HANDLE(dom0_getdomaininfoli #define DOM0_PLATFORM_QUIRK 39 #define QUIRK_NOIRQBALANCING 1 +#define QUIRK_IOAPICMODIFY 2 typedef struct dom0_platform_quirk { /* IN variables. */ uint32_t quirk_id; --- 2006-04-19/xen/include/asm-x86/io_apic.h.0 2006-04-06 17:50:27.000000000 +0200 +++ 2006-04-19/xen/include/asm-x86/io_apic.h 2006-04-20 13:13:35.000000000 +0200 @@ -139,7 +139,11 @@ static inline void io_apic_write(unsigne * * Older SiS APIC requires we rewrite the index regiser */ -#define sis_apic_bug 0 /* This may need propagating from domain0. */ +#ifdef __i386__ +extern int sis_apic_bug; +#else +# define sis_apic_bug 0 +#endif static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value) { if (sis_apic_bug)