Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Michael S. Tsirkin and committed by
Bjorn Helgaas
1851617c 6a25f5e3

+18 -12
-12
drivers/pci/msi.c
··· 1041 1041 void pci_msi_init_pci_dev(struct pci_dev *dev) 1042 1042 { 1043 1043 INIT_LIST_HEAD(&dev->msi_list); 1044 - 1045 - /* Disable the msi hardware to avoid screaming interrupts 1046 - * during boot. This is the power on reset default so 1047 - * usually this should be a noop. 1048 - */ 1049 - dev->msi_cap = pci_find_capability(dev, PCI_CAP_ID_MSI); 1050 - if (dev->msi_cap) 1051 - pci_msi_set_enable(dev, 0); 1052 - 1053 - dev->msix_cap = pci_find_capability(dev, PCI_CAP_ID_MSIX); 1054 - if (dev->msix_cap) 1055 - pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0); 1056 1044 } 1057 1045 1058 1046 /**
+18
drivers/pci/probe.c
··· 1085 1085 1086 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 1105 * pci_setup_device - fill in class and map information of a device 1090 1106 * @dev: the device structure to fill ··· 1155 1139 1156 1140 /* "Unknown power state" */ 1157 1141 dev->current_state = PCI_UNKNOWN; 1142 + 1143 + pci_msi_setup_pci_dev(dev); 1158 1144 1159 1145 /* Early fixups, before probing the BARs */ 1160 1146 pci_fixup_device(pci_fixup_early, dev);