diff options
Diffstat (limited to 'dist/acso.patch')
| -rw-r--r-- | dist/acso.patch | 152 | 
1 files changed, 152 insertions, 0 deletions
| diff --git a/dist/acso.patch b/dist/acso.patch new file mode 100644 index 0000000..07c454c --- /dev/null +++ b/dist/acso.patch @@ -0,0 +1,152 @@ +From 6d05bc1343b9ecce154f551ee09c15e0e9db70bb Mon Sep 17 00:00:00 2001 +From: xiota <> +Date: Wed, 13 Mar 2024 02:36:37 +0000 +Subject: [PATCH 1/2] add-acs-overrides + +--- + .../admin-guide/kernel-parameters.txt         |   8 ++ + drivers/pci/quirks.c                          | 102 ++++++++++++++++++ + 2 files changed, 110 insertions(+) + +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index 31b3a2568..b8ab436d1 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -4370,6 +4370,14 @@ + 		nomsi		[MSI] If the PCI_MSI kernel config parameter is + 				enabled, this kernel boot option can be used to + 				disable the use of MSI interrupts system-wide. ++		pci_acs_override [PCIE] Override missing PCIe ACS support for: ++				downstream ++					All downstream ports - full ACS capabilities ++				multifunction ++					Add multifunction devices - multifunction ACS subset ++				id:nnnn:nnnn ++					Specific device - full ACS capabilities ++					Specified as vid:did (vendor/device ID) in hex + 		noioapicquirk	[APIC] Disable all boot interrupt quirks. + 				Safety option to keep boot IRQs enabled. This + 				should never be necessary. +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index d797df6e5..9b41773bf 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -4996,6 +4996,106 @@ static int  pci_quirk_wangxun_nic_acs(struct pci_dev *dev, u16 acs_flags) + 	return false; + } +  ++static bool acs_on_downstream; ++static bool acs_on_multifunction; ++ ++#define NUM_ACS_IDS 16 ++struct acs_on_id { ++	unsigned short vendor; ++	unsigned short device; ++}; ++static struct acs_on_id acs_on_ids[NUM_ACS_IDS]; ++static u8 max_acs_id; ++ ++static __init int pcie_acs_override_setup(char *p) ++{ ++	if (!p) ++		return -EINVAL; ++ ++	while (*p) { ++		if (!strncmp(p, "downstream", 10)) ++			acs_on_downstream = true; ++		if (!strncmp(p, "multifunction", 13)) ++			acs_on_multifunction = true; ++		if (!strncmp(p, "id:", 3)) { ++			char opt[5]; ++			int ret; ++			long val; ++ ++			if (max_acs_id >= NUM_ACS_IDS - 1) { ++				pr_warn("Out of PCIe ACS override slots (%d)\n", ++						NUM_ACS_IDS); ++				goto next; ++			} ++ ++			p += 3; ++			snprintf(opt, 5, "%s", p); ++			ret = kstrtol(opt, 16, &val); ++			if (ret) { ++				pr_warn("PCIe ACS ID parse error %d\n", ret); ++				goto next; ++			} ++			acs_on_ids[max_acs_id].vendor = val; ++		p += strcspn(p, ":"); ++		if (*p != ':') { ++			pr_warn("PCIe ACS invalid ID\n"); ++			goto next; ++			} ++ ++			p++; ++			snprintf(opt, 5, "%s", p); ++			ret = kstrtol(opt, 16, &val); ++			if (ret) { ++				pr_warn("PCIe ACS ID parse error %d\n", ret); ++				goto next; ++			} ++			acs_on_ids[max_acs_id].device = val; ++			max_acs_id++; ++		} ++next: ++		p += strcspn(p, ","); ++		if (*p == ',') ++			p++; ++	} ++ ++	if (acs_on_downstream || acs_on_multifunction || max_acs_id) ++		pr_warn("Warning: PCIe ACS overrides enabled; This may allow non-IOMMU protected peer-to-peer DMA\n"); ++ ++	return 0; ++} ++early_param("pcie_acs_override", pcie_acs_override_setup); ++ ++static int pcie_acs_overrides(struct pci_dev *dev, u16 acs_flags) ++{ ++	int i; ++ ++	/* Never override ACS for legacy devices or devices with ACS caps */ ++	if (!pci_is_pcie(dev) || ++		pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS)) ++			return -ENOTTY; ++ ++	for (i = 0; i < max_acs_id; i++) ++		if (acs_on_ids[i].vendor == dev->vendor && ++			acs_on_ids[i].device == dev->device) ++				return 1; ++ ++switch (pci_pcie_type(dev)) { ++	case PCI_EXP_TYPE_DOWNSTREAM: ++	case PCI_EXP_TYPE_ROOT_PORT: ++		if (acs_on_downstream) ++			return 1; ++		break; ++	case PCI_EXP_TYPE_ENDPOINT: ++	case PCI_EXP_TYPE_UPSTREAM: ++	case PCI_EXP_TYPE_LEG_END: ++	case PCI_EXP_TYPE_RC_END: ++		if (acs_on_multifunction && dev->multifunction) ++			return 1; ++	} ++ ++	return -ENOTTY; ++} ++ + static const struct pci_dev_acs_enabled { + 	u16 vendor; + 	u16 device; +@@ -5143,6 +5243,8 @@ static const struct pci_dev_acs_enabled { + 	{ PCI_VENDOR_ID_ZHAOXIN, PCI_ANY_ID, pci_quirk_zhaoxin_pcie_ports_acs }, + 	/* Wangxun nics */ + 	{ PCI_VENDOR_ID_WANGXUN, PCI_ANY_ID, pci_quirk_wangxun_nic_acs }, ++	/* allow acs for any */ ++	{ PCI_ANY_ID, PCI_ANY_ID, pcie_acs_overrides }, + 	{ 0 } + }; +  +--  +2.44.0 + | 
