From: Leon Romanovsky leonro@nvidia.com
pci_acs_flags_enabled() and the Intel SPT PCH quirk use ACS registers without checking config-space read errors. A failed read may leave control state indeterminate yet allow the device to satisfy requested isolation controls. So can a read that returns all ones with a successful status, which is what a device that does not answer usually produces.
Return false when either ACS capability or control state cannot be read or reads as all ones, which neither register can legitimately hold. An unknown state cannot prove isolation.
Reviewed-by: Logan Gunthorpe logang@deltatee.com Tested-by: Tushar Dave tdave@nvidia.com Signed-off-by: Leon Romanovsky leonro@nvidia.com --- drivers/pci/pci.c | 4 +++- drivers/pci/quirks.c | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b2879a6be5f8..5f6db2416cee 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3594,7 +3594,9 @@ static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags) */ acs_flags &= (pdev->acs_capabilities | PCI_ACS_EC);
- pci_read_config_word(pdev, pos + PCI_ACS_CTRL, &ctrl); + if (pci_read_config_word(pdev, pos + PCI_ACS_CTRL, &ctrl) || + PCI_POSSIBLE_ERROR(ctrl)) + return false; return (ctrl & acs_flags) == acs_flags; }
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index de9bbccda21f..849619e270fd 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -4992,10 +4992,14 @@ static int pci_quirk_intel_spt_pch_acs(struct pci_dev *dev, u16 acs_flags) return -ENOTTY;
/* see pci_acs_flags_enabled() */ - pci_read_config_dword(dev, pos + PCI_ACS_CAP, &cap); + if (pci_read_config_dword(dev, pos + PCI_ACS_CAP, &cap) || + PCI_POSSIBLE_ERROR(cap)) + return 0; acs_flags &= (cap | PCI_ACS_EC);
- pci_read_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, &ctrl); + if (pci_read_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, &ctrl) || + PCI_POSSIBLE_ERROR(ctrl)) + return 0;
return pci_acs_ctrl_enabled(acs_flags, ctrl); }