[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251202-pci_acs-v2-2-5d2759a71489@oss.qualcomm.com>
Date: Tue, 02 Dec 2025 19:52:49 +0530
From: Manivannan Sadhasivam <manivannan.sadhasivam@....qualcomm.com>
To: Bjorn Helgaas <bhelgaas@...gle.com>
Cc: linux-pci@...r.kernel.org, linux-kernel@...r.kernel.org,
iommu@...ts.linux.dev, Naresh Kamboju <naresh.kamboju@...aro.org>,
Pavankumar Kondeti <quic_pkondeti@...cinc.com>,
Xingang Wang <wangxingang5@...wei.com>,
Marek Szyprowski <m.szyprowski@...sung.com>,
Robin Murphy <robin.murphy@....com>, Jason Gunthorpe <jgg@...pe.ca>,
Manivannan Sadhasivam <mani@...nel.org>,
Manivannan Sadhasivam <manivannan.sadhasivam@....qualcomm.com>
Subject: [PATCH v2 2/4] PCI: Cache ACS capabilities
ACS capabilities are the RO values set by the hardware. Cache them to avoid
reading it all the time when required and also to override any capability
in quirks.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@....qualcomm.com>
---
drivers/pci/pci.c | 26 +++++++++++++++-----------
include/linux/pci.h | 1 +
2 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 9f594fc6dade..4eb5b487c982 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -892,7 +892,6 @@ static const char *disable_acs_redir_param;
static const char *config_acs_param;
struct pci_acs {
- u16 cap;
u16 ctrl;
u16 fw_ctrl;
};
@@ -995,27 +994,27 @@ static void __pci_config_acs(struct pci_dev *dev, struct pci_acs *caps,
static void pci_std_enable_acs(struct pci_dev *dev, struct pci_acs *caps)
{
/* Source Validation */
- caps->ctrl |= (caps->cap & PCI_ACS_SV);
+ caps->ctrl |= (dev->acs_capabilities & PCI_ACS_SV);
/* P2P Request Redirect */
- caps->ctrl |= (caps->cap & PCI_ACS_RR);
+ caps->ctrl |= (dev->acs_capabilities & PCI_ACS_RR);
/* P2P Completion Redirect */
- caps->ctrl |= (caps->cap & PCI_ACS_CR);
+ caps->ctrl |= (dev->acs_capabilities & PCI_ACS_CR);
/* Upstream Forwarding */
- caps->ctrl |= (caps->cap & PCI_ACS_UF);
+ caps->ctrl |= (dev->acs_capabilities & PCI_ACS_UF);
/* Enable Translation Blocking for external devices and noats */
if (pci_ats_disabled() || dev->external_facing || dev->untrusted)
- caps->ctrl |= (caps->cap & PCI_ACS_TB);
+ caps->ctrl |= (dev->acs_capabilities & PCI_ACS_TB);
}
/**
* pci_enable_acs - enable ACS if hardware support it
* @dev: the PCI device
*/
-static void pci_enable_acs(struct pci_dev *dev)
+void pci_enable_acs(struct pci_dev *dev)
{
struct pci_acs caps;
bool enable_acs = false;
@@ -1031,7 +1030,6 @@ static void pci_enable_acs(struct pci_dev *dev)
if (!pos)
return;
- pci_read_config_word(dev, pos + PCI_ACS_CAP, &caps.cap);
pci_read_config_word(dev, pos + PCI_ACS_CTRL, &caps.ctrl);
caps.fw_ctrl = caps.ctrl;
@@ -3543,7 +3541,7 @@ void pci_configure_ari(struct pci_dev *dev)
static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags)
{
int pos;
- u16 cap, ctrl;
+ u16 ctrl;
pos = pdev->acs_cap;
if (!pos)
@@ -3554,8 +3552,7 @@ static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags)
* or only required if controllable. Features missing from the
* capability field can therefore be assumed as hard-wired enabled.
*/
- pci_read_config_word(pdev, pos + PCI_ACS_CAP, &cap);
- acs_flags &= (cap | PCI_ACS_EC);
+ acs_flags &= (pdev->acs_capabilities | PCI_ACS_EC);
pci_read_config_word(pdev, pos + PCI_ACS_CTRL, &ctrl);
return (ctrl & acs_flags) == acs_flags;
@@ -3676,7 +3673,14 @@ bool pci_acs_path_enabled(struct pci_dev *start,
*/
void pci_acs_init(struct pci_dev *dev)
{
+ int pos;
+
dev->acs_cap = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
+ pos = dev->acs_cap;
+ if (!pos)
+ return;
+
+ pci_read_config_word(dev, pos + PCI_ACS_CAP, &dev->acs_capabilities);
}
void pci_rebar_init(struct pci_dev *pdev)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index bf97d49c23cf..c6ee1dfdb0fb 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -543,6 +543,7 @@ struct pci_dev {
struct npem *npem; /* Native PCIe Enclosure Management */
#endif
u16 acs_cap; /* ACS Capability offset */
+ u16 acs_capabilities; /* ACS Capabilities */
u8 supported_speeds; /* Supported Link Speeds Vector */
phys_addr_t rom; /* Physical address if not from BAR */
size_t romlen; /* Length if not from BAR */
--
2.48.1
Powered by blists - more mailing lists