Skip to content

Commit 03bbcb2

Browse files
nhormanjoergroedel
authored andcommitted
iommu/vt-d: add quirk for broken interrupt remapping on 55XX chipsets
A few years back intel published a spec update: http://www.intel.com/content/dam/doc/specification-update/5520-and-5500-chipset-ioh-specification-update.pdf For the 5520 and 5500 chipsets which contained an errata (specificially errata 53), which noted that these chipsets can't properly do interrupt remapping, and as a result the recommend that interrupt remapping be disabled in bios. While many vendors have a bios update to do exactly that, not all do, and of course not all users update their bios to a level that corrects the problem. As a result, occasionally interrupts can arrive at a cpu even after affinity for that interrupt has be moved, leading to lost or spurrious interrupts (usually characterized by the message: kernel: do_IRQ: 7.71 No irq handler for vector (irq -1) There have been several incidents recently of people seeing this error, and investigation has shown that they have system for which their BIOS level is such that this feature was not properly turned off. As such, it would be good to give them a reminder that their systems are vulnurable to this problem. For details of those that reported the problem, please see: https://bugzilla.redhat.com/show_bug.cgi?id=887006 [ Joerg: Removed CONFIG_IRQ_REMAP ifdef from early-quirks.c ] Signed-off-by: Neil Horman <[email protected]> CC: Prarit Bhargava <[email protected]> CC: Don Zickus <[email protected]> CC: Don Dutile <[email protected]> CC: Bjorn Helgaas <[email protected]> CC: Asit Mallick <[email protected]> CC: David Woodhouse <[email protected]> CC: [email protected] CC: Joerg Roedel <[email protected]> CC: Konrad Rzeszutek Wilk <[email protected]> CC: Arkadiusz Miśkiewicz <[email protected]> Signed-off-by: Joerg Roedel <[email protected]>
1 parent bd5cdad commit 03bbcb2

File tree

5 files changed

+40
-0
lines changed

5 files changed

+40
-0
lines changed

arch/x86/include/asm/irq_remapping.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
extern void setup_irq_remapping_ops(void);
3030
extern int irq_remapping_supported(void);
31+
extern void set_irq_remapping_broken(void);
3132
extern int irq_remapping_prepare(void);
3233
extern int irq_remapping_enable(void);
3334
extern void irq_remapping_disable(void);
@@ -54,6 +55,7 @@ void irq_remap_modify_chip_defaults(struct irq_chip *chip);
5455

5556
static inline void setup_irq_remapping_ops(void) { }
5657
static inline int irq_remapping_supported(void) { return 0; }
58+
static inline void set_irq_remapping_broken(void) { }
5759
static inline int irq_remapping_prepare(void) { return -ENODEV; }
5860
static inline int irq_remapping_enable(void) { return -ENODEV; }
5961
static inline void irq_remapping_disable(void) { }

arch/x86/kernel/early-quirks.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <asm/apic.h>
1919
#include <asm/iommu.h>
2020
#include <asm/gart.h>
21+
#include <asm/irq_remapping.h>
2122

2223
static void __init fix_hypertransport_config(int num, int slot, int func)
2324
{
@@ -192,6 +193,21 @@ static void __init ati_bugs_contd(int num, int slot, int func)
192193
}
193194
#endif
194195

196+
static void __init intel_remapping_check(int num, int slot, int func)
197+
{
198+
u8 revision;
199+
200+
revision = read_pci_config_byte(num, slot, func, PCI_REVISION_ID);
201+
202+
/*
203+
* Revision 0x13 of this chipset supports irq remapping
204+
* but has an erratum that breaks its behavior, flag it as such
205+
*/
206+
if (revision == 0x13)
207+
set_irq_remapping_broken();
208+
209+
}
210+
195211
#define QFLAG_APPLY_ONCE 0x1
196212
#define QFLAG_APPLIED 0x2
197213
#define QFLAG_DONE (QFLAG_APPLY_ONCE|QFLAG_APPLIED)
@@ -221,6 +237,10 @@ static struct chipset early_qrk[] __initdata = {
221237
PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs },
222238
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS,
223239
PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs_contd },
240+
{ PCI_VENDOR_ID_INTEL, 0x3403, PCI_CLASS_BRIDGE_HOST,
241+
PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check },
242+
{ PCI_VENDOR_ID_INTEL, 0x3406, PCI_CLASS_BRIDGE_HOST,
243+
PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check },
224244
{}
225245
};
226246

drivers/iommu/intel_irq_remapping.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,16 @@ static int __init intel_irq_remapping_supported(void)
524524

525525
if (disable_irq_remap)
526526
return 0;
527+
if (irq_remap_broken) {
528+
WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND,
529+
"This system BIOS has enabled interrupt remapping\n"
530+
"on a chipset that contains an erratum making that\n"
531+
"feature unstable. To maintain system stability\n"
532+
"interrupt remapping is being disabled. Please\n"
533+
"contact your BIOS vendor for an update\n");
534+
disable_irq_remap = 1;
535+
return 0;
536+
}
527537

528538
if (!dmar_ir_support())
529539
return 0;

drivers/iommu/irq_remapping.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
int irq_remapping_enabled;
2020

2121
int disable_irq_remap;
22+
int irq_remap_broken;
2223
int disable_sourceid_checking;
2324
int no_x2apic_optout;
2425

@@ -211,6 +212,11 @@ void __init setup_irq_remapping_ops(void)
211212
#endif
212213
}
213214

215+
void set_irq_remapping_broken(void)
216+
{
217+
irq_remap_broken = 1;
218+
}
219+
214220
int irq_remapping_supported(void)
215221
{
216222
if (disable_irq_remap)

drivers/iommu/irq_remapping.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct pci_dev;
3232
struct msi_msg;
3333

3434
extern int disable_irq_remap;
35+
extern int irq_remap_broken;
3536
extern int disable_sourceid_checking;
3637
extern int no_x2apic_optout;
3738
extern int irq_remapping_enabled;
@@ -89,6 +90,7 @@ extern struct irq_remap_ops amd_iommu_irq_ops;
8990

9091
#define irq_remapping_enabled 0
9192
#define disable_irq_remap 1
93+
#define irq_remap_broken 0
9294

9395
#endif /* CONFIG_IRQ_REMAP */
9496

0 commit comments

Comments
 (0)