Guest User

acs override patch

a guest
Feb 7th, 2018
236
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.96 KB | None | 0 0
  1. --- a/drivers/pci/quirks.c 2017-11-12 13:46:13.000000000 -0500
  2. +++ b/drivers/pci/quirks.c 2017-11-17 08:28:09.424574234 -0500
  3. @@ -3388,4 +3388,105 @@
  4. PCI_CLASS_DISPLAY_VGA, 8, quirk_no_pm_reset);
  5.  
  6. +static bool acs_on_downstream;
  7. +static bool acs_on_multifunction;
  8. +
  9. +#define NUM_ACS_IDS 16
  10. +struct acs_on_id {
  11. + unsigned short vendor;
  12. + unsigned short device;
  13. +};
  14. +static struct acs_on_id acs_on_ids[NUM_ACS_IDS];
  15. +static u8 max_acs_id;
  16. +
  17. +static __init int pcie_acs_override_setup(char *p)
  18. +{
  19. + if (!p)
  20. + return -EINVAL;
  21. +
  22. + while (*p) {
  23. + if (!strncmp(p, "downstream", 10))
  24. + acs_on_downstream = true;
  25. + if (!strncmp(p, "multifunction", 13))
  26. + acs_on_multifunction = true;
  27. + if (!strncmp(p, "id:", 3)) {
  28. + char opt[5];
  29. + int ret;
  30. + long val;
  31. +
  32. + if (max_acs_id >= NUM_ACS_IDS - 1) {
  33. + pr_warn("Out of PCIe ACS override slots (%d)\n",
  34. + NUM_ACS_IDS);
  35. + goto next;
  36. + }
  37. +
  38. + p += 3;
  39. + snprintf(opt, 5, "%s", p);
  40. + ret = kstrtol(opt, 16, &val);
  41. + if (ret) {
  42. + pr_warn("PCIe ACS ID parse error %d\n", ret);
  43. + goto next;
  44. + }
  45. + acs_on_ids[max_acs_id].vendor = val;
  46. +
  47. + p += strcspn(p, ":");
  48. + if (*p != ':') {
  49. + pr_warn("PCIe ACS invalid ID\n");
  50. + goto next;
  51. + }
  52. +
  53. + p++;
  54. + snprintf(opt, 5, "%s", p);
  55. + ret = kstrtol(opt, 16, &val);
  56. + if (ret) {
  57. + pr_warn("PCIe ACS ID parse error %d\n", ret);
  58. + goto next;
  59. + }
  60. + acs_on_ids[max_acs_id].device = val;
  61. + max_acs_id++;
  62. + }
  63. +next:
  64. + p += strcspn(p, ",");
  65. + if (*p == ',')
  66. + p++;
  67. + }
  68. +
  69. + if (acs_on_downstream || acs_on_multifunction || max_acs_id)
  70. + pr_warn("Warning: PCIe ACS overrides enabled; This may allow non-IOMMU protected peer-to-peer DMA\n");
  71. +
  72. + return 0;
  73. +}
  74. +early_param("pcie_acs_override", pcie_acs_override_setup);
  75. +
  76. +static int pcie_acs_overrides(struct pci_dev *dev, u16 acs_flags)
  77. +{
  78. + int i;
  79. +
  80. + /* Never override ACS for legacy devices or devices with ACS caps */
  81. + if (!pci_is_pcie(dev) ||
  82. + pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS))
  83. + return -ENOTTY;
  84. +
  85. + for (i = 0; i < max_acs_id; i++)
  86. + if (acs_on_ids[i].vendor == dev->vendor &&
  87. + acs_on_ids[i].device == dev->device)
  88. + return 1;
  89. +
  90. + switch (pci_pcie_type(dev)) {
  91. + case PCI_EXP_TYPE_DOWNSTREAM:
  92. + case PCI_EXP_TYPE_ROOT_PORT:
  93. + if (acs_on_downstream)
  94. + return 1;
  95. + break;
  96. + case PCI_EXP_TYPE_ENDPOINT:
  97. + case PCI_EXP_TYPE_UPSTREAM:
  98. + case PCI_EXP_TYPE_LEG_END:
  99. + case PCI_EXP_TYPE_RC_END:
  100. + if (acs_on_multifunction && dev->multifunction)
  101. + return 1;
  102. + }
  103. +
  104. + return -ENOTTY;
  105. +}
  106. +
  107. /*
  108. * Thunderbolt controllers with broken MSI hotplug signaling:
  109. @@ -4409,4 +4510,5 @@
  110. }
  111.  
  112. +
  113. static const struct pci_dev_acs_enabled {
  114. u16 vendor;
  115. @@ -4489,4 +4591,5 @@
  116. /* Cavium ThunderX */
  117. { PCI_VENDOR_ID_CAVIUM, PCI_ANY_ID, pci_quirk_cavium_acs },
  118. + { PCI_ANY_ID, PCI_ANY_ID, pcie_acs_overrides },
  119. /* APM X-Gene */
  120. { PCI_VENDOR_ID_AMCC, 0xE004, pci_quirk_xgene_acs },
Advertisement
Add Comment
Please, Sign In to add comment