]> xenbits.xensource.com Git - people/vhanquez/xen.git/commitdiff
Propagate information about bad (or good) REGSEL register
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Fri, 21 Apr 2006 09:45:31 +0000 (10:45 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Fri, 21 Apr 2006 09:45:31 +0000 (10:45 +0100)
of chipset IO-APICs to Xen. If REGSEL is bad (some old SiS
chipsets) then we have a slower read-modify-write routine.
Loosely based on an original patch from Jan Beulich.

Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c
xen/arch/x86/dom0_ops.c
xen/arch/x86/io_apic.c
xen/include/asm-x86/io_apic.h
xen/include/public/dom0_ops.h

index 47edb0524be37bda761d81274486b697255221b9..cf01b3506d27841a5ac7673c3a5a02c4a9cbc9b5 100644 (file)
@@ -2485,6 +2485,12 @@ static int __init io_apic_bug_finalize(void)
 {
        if(sis_apic_bug == -1)
                sis_apic_bug = 0;
+       if (xen_start_info->flags & SIF_INITDOMAIN) {
+               dom0_op_t op = { .cmd = DOM0_PLATFORM_QUIRK };
+               op.u.platform_quirk.quirk_id = sis_apic_bug ?
+                       QUIRK_IOAPIC_BAD_REGSEL : QUIRK_IOAPIC_GOOD_REGSEL;
+               HYPERVISOR_dom0_op(&op);
+       }
        return 0;
 }
 
index ab76b4e9f5a8982d4663e37d2bdd5e190a4b3039..a77c91973369722553060257835ab33e788ec681 100644 (file)
@@ -379,13 +379,24 @@ long arch_do_dom0_op(struct dom0_op *op, GUEST_HANDLE(dom0_op_t) u_dom0_op)
     case DOM0_PLATFORM_QUIRK:
     {
         extern int opt_noirqbalance;
-        switch ( op->u.platform_quirk.quirk_id )
+        int quirk_id = op->u.platform_quirk.quirk_id;
+        switch ( quirk_id )
         {
         case QUIRK_NOIRQBALANCING:
             printk("Platform quirk -- Disabling IRQ balancing/affinity.\n");
             opt_noirqbalance = 1;
             setup_ioapic_dest();
             break;
+        case QUIRK_IOAPIC_BAD_REGSEL:
+        case QUIRK_IOAPIC_GOOD_REGSEL:
+#ifndef sis_apic_bug
+            sis_apic_bug = (quirk_id == QUIRK_IOAPIC_BAD_REGSEL);
+            printk("Platform info -- IO-APIC REGSEL is %s\n",
+                   sis_apic_bug ? "bad" : "good");
+#else
+            BUG_ON(sis_apic_bug == (quirk_id == QUIRK_IOAPIC_BAD_REGSEL));
+#endif
+            break;
         default:
             ret = -EINVAL;
             break;
index 0659f50e81a3615d98b87419be3124c8f0a96e25..3a30ee1631a858d6a77714ee315866fd5d8009b1 100644 (file)
@@ -51,6 +51,14 @@ static DEFINE_SPINLOCK(ioapic_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
  */
index 4cacb8b419dca99f7c587fdaab4a8a7c45bf00f8..47cd148e1055e04b4234b61cf12ef32e69435435 100644 (file)
@@ -139,7 +139,11 @@ static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned i
  *
  * 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)
index 497a1c58d6ad3a0bf38ceb545cb4f84270532314..345e9f91f45327987feaa28750146463da78a39a 100644 (file)
@@ -404,7 +404,9 @@ typedef struct dom0_getdomaininfolist {
 DEFINE_GUEST_HANDLE(dom0_getdomaininfolist_t);
 
 #define DOM0_PLATFORM_QUIRK      39
-#define QUIRK_NOIRQBALANCING  1
+#define QUIRK_NOIRQBALANCING      1 /* Do not restrict IO-APIC RTE targets */
+#define QUIRK_IOAPIC_BAD_REGSEL   2 /* IO-APIC REGSEL forgets its value    */
+#define QUIRK_IOAPIC_GOOD_REGSEL  3 /* IO-APIC REGSEL behaves properly     */
 typedef struct dom0_platform_quirk {
     /* IN variables. */
     uint32_t quirk_id;