Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 89877e42827f16fa5f86b1df0c2860b1 > files > 2417

kernel-2.6.18-128.1.10.el5.src.rpm

From: Neil Horman <nhorman@redhat.com>
Date: Wed, 19 Dec 2007 12:27:20 -0500
Subject: [x86] add pci quirk to HT enabled systems
Message-id: 20071219172720.GB28359@hmsendeavour.rdu.redhat.com
O-Subject: [RHEL 5.2 PATCH] add pci quirk to Hypertransport enabled systems (bz 336371)
Bugzilla: 336371

Hey all-
	LLNL reported a problem to us awhile back in which kdump kernel boots
were hanging in calibrate_delay.  The root cuase was tracked down interrupts not
being delivered to the booting cpu.  Hypertransport busses connecting AMD
Opteron processors have a configuration register that allows for the use of
extended 8 bit apic ids, and a secondary bit that defines a mask on the apic ID
destination (0 for 0xf, 1 for 0xff) when delivering legacy mode interrupts.  If
the mask bit is set to 0xf while extended apic id's are enabled, and kdump is
booting on a cpu with an extended apic id, then interrupts will not be delivered
to it, and we hang in calibrate_delay, as we wait for timer interrupts that will
never arrive.  This patch adds a pci quirk to K8 northbridge chips that hold
this config register. It checks to se if extended apic ids are enabled, and if
they are, forces the destination mask to be 0xff.  The upstream variant of this
patch is currently upstream as commit 16250610998946728f7814cae0662b8a7fd1585b
in Ingos x86 tree.  Fixes bz 336371

Regards
Neil

Acked-by: "John W. Linville" <linville@redhat.com>
Acked-by: Chip Coldwell <coldwell@redhat.com>
Acked-by: Jon Masters <jcm@redhat.com>
Acked-by: Dave Anderson <anderson@redhat.com>

diff --git a/arch/i386/kernel/quirks.c b/arch/i386/kernel/quirks.c
index 9f6ab17..30b4f9f 100644
--- a/arch/i386/kernel/quirks.c
+++ b/arch/i386/kernel/quirks.c
@@ -44,7 +44,30 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
 	if (!(config & 0x2))
 		pci_write_config_byte(dev, 0xf4, config);
 }
+
+static void __devinit fix_hypertransport_config(struct pci_dev *dev)
+{
+	u32 htcfg;
+	/*
+	 * we found a hypertransport bus
+	 * make sure that we are broadcasting
+	 * interrupts to all cpus on the ht bus
+	 * if we're using extended apic ids
+	 */
+	pci_read_config_dword(dev, 0x68, &htcfg);
+	if (htcfg & (1 << 18)) {
+		printk(KERN_INFO "Detected use of extended apic ids on hypertransport bus\n");
+		if ((htcfg & (1 << 17)) == 0) {
+			printk(KERN_INFO "Enabling hypertransport extended apic interrupt broadcast\n");
+			printk(KERN_INFO "Note this is a bios bug, please contact your vendor\n");
+			htcfg |= (1 << 17);
+			pci_write_config_dword(dev, 0x68, htcfg);
+		}
+	}
+}
+
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7320_MCH,	quirk_intel_irqbalance);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7525_MCH,	quirk_intel_irqbalance);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7520_MCH,	quirk_intel_irqbalance);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_K8_NB, fix_hypertransport_config);
 #endif