diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2015-05-07 10:52:21 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2015-05-07 10:52:21 -0400 |
commit | 1851617cd2da9cc53cdc1738f4148f4f042c0e56 (patch) | |
tree | 2c742020d1c4222bccaceb1cf118fde5eab3c0a7 /drivers/pci/probe.c | |
parent | 6a25f5e35ab742380742ebf2033f6d53518219db (diff) |
PCI/MSI: Disable MSI at enumeration even if kernel doesn't support MSI
If we enable MSI, then kexec a new kernel, the new kernel may receive MSIs
it is not prepared for. Commit d5dea7d95c48 ("PCI: msi: Disable msi
interrupts when we initialize a pci device") prevents this, but only if the
new kernel is built with CONFIG_PCI_MSI=y.
Move the "disable MSI" functionality from drivers/pci/msi.c to a new
pci_msi_setup_pci_dev() in drivers/pci/probe.c so we can disable MSIs when
we enumerate devices even if the kernel doesn't include full MSI support.
[bhelgaas: changelog, disable MSIs in pci_setup_device(), put
pci_msi_setup_pci_dev() at its final destination]
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6675a7a1b9fc..a9c5e63049a5 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -1085,6 +1085,22 @@ int pci_cfg_space_size(struct pci_dev *dev) | |||
1085 | 1085 | ||
1086 | #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) | 1086 | #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) |
1087 | 1087 | ||
1088 | static void pci_msi_setup_pci_dev(struct pci_dev *dev) | ||
1089 | { | ||
1090 | /* | ||
1091 | * Disable the MSI hardware to avoid screaming interrupts | ||
1092 | * during boot. This is the power on reset default so | ||
1093 | * usually this should be a noop. | ||
1094 | */ | ||
1095 | dev->msi_cap = pci_find_capability(dev, PCI_CAP_ID_MSI); | ||
1096 | if (dev->msi_cap) | ||
1097 | pci_msi_set_enable(dev, 0); | ||
1098 | |||
1099 | dev->msix_cap = pci_find_capability(dev, PCI_CAP_ID_MSIX); | ||
1100 | if (dev->msix_cap) | ||
1101 | pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0); | ||
1102 | } | ||
1103 | |||
1088 | /** | 1104 | /** |
1089 | * pci_setup_device - fill in class and map information of a device | 1105 | * pci_setup_device - fill in class and map information of a device |
1090 | * @dev: the device structure to fill | 1106 | * @dev: the device structure to fill |
@@ -1140,6 +1156,8 @@ int pci_setup_device(struct pci_dev *dev) | |||
1140 | /* "Unknown power state" */ | 1156 | /* "Unknown power state" */ |
1141 | dev->current_state = PCI_UNKNOWN; | 1157 | dev->current_state = PCI_UNKNOWN; |
1142 | 1158 | ||
1159 | pci_msi_setup_pci_dev(dev); | ||
1160 | |||
1143 | /* Early fixups, before probing the BARs */ | 1161 | /* Early fixups, before probing the BARs */ |
1144 | pci_fixup_device(pci_fixup_early, dev); | 1162 | pci_fixup_device(pci_fixup_early, dev); |
1145 | /* device class may be changed after fixup */ | 1163 | /* device class may be changed after fixup */ |