Advertisement
Guest User

ACS_Override.patch

a guest
Jun 3rd, 2014
610
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.78 KB | None | 0 0
  1. diff -rupN linux-3.12-rc6.orig/Documentation/kernel-parameters.txt linux-3.12-rc6/Documentation/kernel-parameters.txt
  2. --- linux-3.12-rc6.orig/Documentation/kernel-parameters.txt 2013-10-19 19:28:15.000000000 +0000
  3. +++ linux-3.12-rc6/Documentation/kernel-parameters.txt  2013-10-23 18:06:02.963749702 +0000
  4. @@ -2454,6 +2454,16 @@ bytes respectively. Such letter suffixes
  5.         nomsi   Do not use MSI for native PCIe PME signaling (this makes
  6.             all PCIe root ports use INTx for all services).
  7.  
  8. +   pcie_acs_override =
  9. +           [PCIE] Override missing PCIe ACS support for:
  10. +       downstream
  11. +           All downstream ports - full ACS capabilties
  12. +       multifunction
  13. +           All multifunction devices - multifunction ACS subset
  14. +       id:nnnn:nnnn
  15. +           Specfic device - full ACS capabilities
  16. +           Specified as vid:did (vendor/device ID) in hex
  17. +
  18.     pcmv=       [HW,PCMCIA] BadgePAD 4
  19.  
  20.     pd.     [PARIDE]
  21. --- a/drivers/pci/quirks.c  2014-05-30 16:08:19.561232936 +0000
  22. +++ b/drivers/pci/quirks.c  2014-05-30 16:18:44.745241038 +0000
  23. @@ -3423,6 +3423,107 @@
  24.  #endif
  25.  }
  26.  
  27. +static bool acs_on_downstream;
  28. +static bool acs_on_multifunction;
  29. +
  30. +#define NUM_ACS_IDS 16
  31. +struct acs_on_id {
  32. +       unsigned short vendor;
  33. +       unsigned short device;
  34. +};
  35. +static struct acs_on_id acs_on_ids[NUM_ACS_IDS];
  36. +static u8 max_acs_id;
  37. +
  38. +static __init int pcie_acs_override_setup(char *p)
  39. +{
  40. +       if (!p)
  41. +               return -EINVAL;
  42. +
  43. +       while (*p) {
  44. +               if (!strncmp(p, "downstream", 10))
  45. +                       acs_on_downstream = true;
  46. +               if (!strncmp(p, "multifunction", 13))
  47. +                       acs_on_multifunction = true;
  48. +               if (!strncmp(p, "id:", 3)) {
  49. +                       char opt[5];
  50. +                       int ret;
  51. +                       long val;
  52. +
  53. +                       if (max_acs_id >= NUM_ACS_IDS - 1) {
  54. +                               pr_warn("Out of PCIe ACS override slots (%d)\n",
  55. +                                       NUM_ACS_IDS);
  56. +                               goto next;
  57. +                       }
  58. +
  59. +                       p += 3;
  60. +                       snprintf(opt, 5, "%s", p);
  61. +                       ret = kstrtol(opt, 16, &val);
  62. +                       if (ret) {
  63. +                               pr_warn("PCIe ACS ID parse error %d\n", ret);
  64. +                               goto next;
  65. +                       }
  66. +                       acs_on_ids[max_acs_id].vendor = val;
  67. +
  68. +                       p += strcspn(p, ":");
  69. +                       if (*p != ':') {
  70. +                               pr_warn("PCIe ACS invalid ID\n");
  71. +                               goto next;
  72. +                       }
  73. +
  74. +                       p++;
  75. +                       snprintf(opt, 5, "%s", p);
  76. +                       ret = kstrtol(opt, 16, &val);
  77. +                       if (ret) {
  78. +                               pr_warn("PCIe ACS ID parse error %d\n", ret);
  79. +                               goto next;
  80. +                       }
  81. +                       acs_on_ids[max_acs_id].device = val;
  82. +                       max_acs_id++;
  83. +               }
  84. +next:
  85. +               p += strcspn(p, ",");
  86. +               if (*p == ',')
  87. +                       p++;
  88. +       }
  89. +
  90. +       if (acs_on_downstream || acs_on_multifunction || max_acs_id)
  91. +               pr_warn("Warning: PCIe ACS overrides enabled; This may allow non-IOMMU protected peer-to-peer DMA\n");
  92. +
  93. +       return 0;
  94. +}
  95. +early_param("pcie_acs_override", pcie_acs_override_setup);
  96. +
  97. +static int pcie_acs_overrides(struct pci_dev *dev, u16 acs_flags)
  98. +{
  99. +       int i;
  100. +
  101. +       /* Never override ACS for legacy devices or devices with ACS caps */
  102. +       if (!pci_is_pcie(dev) ||
  103. +           pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS))
  104. +               return -ENOTTY;
  105. +
  106. +       for (i = 0; i < max_acs_id; i++)
  107. +               if (acs_on_ids[i].vendor == dev->vendor &&
  108. +                   acs_on_ids[i].device == dev->device)
  109. +                       return 1;
  110. +
  111. +       switch (pci_pcie_type(dev)) {
  112. +       case PCI_EXP_TYPE_DOWNSTREAM:
  113. +       case PCI_EXP_TYPE_ROOT_PORT:
  114. +               if (acs_on_downstream)
  115. +                       return 1;
  116. +               break;
  117. +       case PCI_EXP_TYPE_ENDPOINT:
  118. +       case PCI_EXP_TYPE_UPSTREAM:
  119. +       case PCI_EXP_TYPE_LEG_END:
  120. +       case PCI_EXP_TYPE_RC_END:
  121. +               if (acs_on_multifunction && dev->multifunction)
  122. +                       return 1;
  123. +       }
  124. +
  125. +       return -ENOTTY;
  126. +}
  127. +
  128.  static const struct pci_dev_acs_enabled {
  129.     u16 vendor;
  130.     u16 device;
  131. @@ -3434,6 +3535,7 @@
  132.     { PCI_VENDOR_ID_ATI, 0x439d, pci_quirk_amd_sb_acs },
  133.     { PCI_VENDOR_ID_ATI, 0x4384, pci_quirk_amd_sb_acs },
  134.     { PCI_VENDOR_ID_ATI, 0x4399, pci_quirk_amd_sb_acs },
  135. +   { PCI_ANY_ID, PCI_ANY_ID, pcie_acs_overrides },
  136.     { 0 }
  137.  };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement