lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1212410707427-git-send-email-od@suse.de>
Date:	Mon,  2 Jun 2008 14:45:07 +0200
From:	Olaf Dabrunz <od@...e.de>
To:	Thomas Gleixner <tglx@...utronix.de>
Cc:	Ingo Molnar <mingo@...e.hu>, "H. Peter Anvin" <hpa@...or.com>,
	Jon Masters <jonathan@...masters.org>,
	linux-kernel@...r.kernel.org, Olaf Dabrunz <od@...e.de>,
	Stefan Assmann <sassmann@...e.de>
Subject: [PATCH 7/7] bootirqquirk= parameter to enable bootirq quirks for additional chips

From: Olaf Dabrunz <od@...e.de>

The existing bootirq quirks and the reroute workaround may work for other chips
where we could not test them. This parameter allows users to apply these to
other chips without the need to re-build the kernel.

This patch was conceived simultaneously by Stefan Assmann, Daniel Gollub and
Olaf Dabrunz. The implementation is the author's.

    bootirqquirk=0x<vendor>,0x<device>,<quirk_type>

    - quirk type  1 - 32 selects an IRQ reroute algorithm for devices
      connected to that PCI bridge (currently only algorithm "1" is
      implemented),

    - quirk type 33 -  x applies one of the known quirks to the PCI
      device, currently these:

        33 -> quirk_disable_intel_boot_interrupt
        34 -> quirk_disable_broadcom_boot_interrupt
        35 -> quirk_disable_amd_8111_boot_interrupt
        36 -> quirk_disable_amd_813x_boot_interrupt
        37 -> quirk_disable_amd_sb700s_boot_interrupt

Signed-off-by: Olaf Dabrunz <od@...e.de>
Signed-off-by: Stefan Assmann <sassmann@...e.de>
---
 drivers/pci/quirks.c |  118 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 118 insertions(+), 0 deletions(-)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 090ce38..bb7fa65 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1576,6 +1576,113 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_PXH_1,	quirk_re
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_PXHV,	quirk_reroute_to_boot_interrupts_intel);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_80332_0,	quirk_reroute_to_boot_interrupts_intel);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_80332_1,	quirk_reroute_to_boot_interrupts_intel);
+
+/*
+ * For additional boot irq quirks save boot time settings or call the quirks
+ * directly.
+ */
+
+#define MAX_BOOTTIME_CONFIG_PCI_FIXUPS_EARLY			32
+struct pci_fixup __start_bc_pci_fixups_early[MAX_BOOTTIME_CONFIG_PCI_FIXUPS_EARLY];
+struct pci_fixup *__end_bc_pci_fixups_early = __start_bc_pci_fixups_early +
+					MAX_BOOTTIME_CONFIG_PCI_FIXUPS_EARLY;
+
+static void (*bootirq_quirk_func[])(struct pci_dev *dev) = {
+	&quirk_disable_intel_boot_interrupt,
+	&quirk_disable_broadcom_boot_interrupt,
+	&quirk_disable_amd_8111_boot_interrupt,
+	&quirk_disable_amd_813x_boot_interrupt,
+	&quirk_disable_amd_sb700s_boot_interrupt,
+};
+
+int __init bootirqquirk_setup(char *str)
+{
+	int ints[4];
+	struct quirk_bootirq_reroute_dev tmp;
+	int i;
+
+	str = get_options(str, ARRAY_SIZE(ints), ints);
+	if (!str)
+		return 0;
+
+	if (nobootirqquirk)
+		return 1;
+
+	/* all parameters are required */
+	if (ints[0] != 3)
+		return 0;
+
+	/* save settings */
+	tmp.vendor = ints[1];
+	tmp.device = ints[2];
+	tmp.quirk_variant = ints[3];
+
+	/*
+	 * quirk variants > MAX_QUIRK_BOOTIRQ_REROUTE_VARIANTS select quirk
+	 * functions
+	 */
+	if (tmp.quirk_variant > MAX_QUIRK_BOOTIRQ_REROUTE_VARIANTS) {
+		for (i = 0; i < MAX_BOOTTIME_CONFIG_PCI_FIXUPS_EARLY; i++) {
+			if (__start_bc_pci_fixups_early[i].vendor == 0)
+				break;
+
+			if (__start_bc_pci_fixups_early[i].vendor == tmp.vendor &&
+			    __start_bc_pci_fixups_early[i].device == tmp.device)
+				return 1;	/* already in array */
+		}
+
+		if (i >= MAX_BOOTTIME_CONFIG_PCI_FIXUPS_EARLY) {
+			printk(KERN_INFO "PCI quirk: too many boottime "
+					"configurable early quirk entries when "
+					"trying to add 0x%04x:0x%04x\n",
+					tmp.vendor, tmp.device);
+			return 0;
+		}
+
+		if (tmp.quirk_variant > ARRAY_SIZE(bootirq_quirk_func) +
+				MAX_QUIRK_BOOTIRQ_REROUTE_VARIANTS) {
+			printk(KERN_INFO "PCI quirk: no such quirk function: "
+					"%d\n", tmp.quirk_variant);
+			return 0;
+		}
+
+		__start_bc_pci_fixups_early[i].vendor = tmp.vendor;
+		__start_bc_pci_fixups_early[i].device = tmp.device;
+		__start_bc_pci_fixups_early[i].hook =
+				bootirq_quirk_func[tmp.quirk_variant -
+				(MAX_QUIRK_BOOTIRQ_REROUTE_VARIANTS + 1)];
+	} else {
+		for (i = 0; i < MAX_QUIRK_BOOTIRQ_REROUTE_DEVS; i++) {
+			if (quirk_bootirq_reroute_devs[i].vendor == 0)
+				break;
+
+			if (quirk_bootirq_reroute_devs[i].vendor == tmp.vendor &&
+			    quirk_bootirq_reroute_devs[i].device == tmp.device)
+				return 1;	/* already in array */
+		}
+
+		if (i >= MAX_QUIRK_BOOTIRQ_REROUTE_DEVS) {
+			printk(KERN_INFO "PCI quirk: too many reroute entries when "
+					"trying to add 0x%04x:0x%04x\n",
+					tmp.vendor, tmp.device);
+			return 0;
+		}
+
+		quirk_bootirq_reroute_devs[i].vendor = tmp.vendor;
+		quirk_bootirq_reroute_devs[i].device = tmp.device;
+		quirk_bootirq_reroute_devs[i].quirk_variant = tmp.quirk_variant;
+
+		reroute_to_boot_interrupts = 1;
+	}
+
+	printk(KERN_INFO "PCI quirk: reroute interrupts for 0x%04x:0x%04x\n",
+			tmp.vendor, tmp.device);
+	return 1;
+}
+
+/* bootirqquirk=0x<vendor>,0x<device>,<quirk_type> */
+__setup("bootirqquirk=", bootirqquirk_setup);
+
 #endif /* CONFIG_X86_IO_APIC */
 
 /*
@@ -1773,6 +1880,17 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
 		return;
 	}
 	pci_do_fixups(dev, start, end);
+
+	switch(pass) {
+	case pci_fixup_early:
+		start = __start_bc_pci_fixups_early;
+		end = __end_bc_pci_fixups_early;
+		break;
+
+	default:
+		return;
+	}
+	pci_do_fixups(dev, start, end);
 }
 EXPORT_SYMBOL(pci_fixup_device);
 
-- 
1.5.2.4

-- 
Olaf Dabrunz (od/odabrunz), SUSE Linux Products GmbH, Nürnberg

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ