Advertisement
schreiberstein

linux-iommu-patchset-3.15.x

Jun 23rd, 2014
311
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 44.86 KB | None | 0 0
  1. #Patch-collection from https://github.com/awilliam/linux-vfio/tree/dma-alias-v4
  2. #Diff between 3.15-rc6 and his patched 3.15-rc6 tree - successfully patched 3.15.1-STABLE with this.
  3. #cd linux-3.15.1 && patch -p1 < ../iommupatches.patch # where the latter file is the properly formed patch .
  4. #Might not be a professional approach, but this is just for my internal use, anyway.
  5. #I take ABSOLUTELY no credit for it.
  6.  
  7. diff -Naur linux-3.15-rc6/drivers/iommu/amd_iommu.c linux-awilliam/drivers/iommu/amd_iommu.c
  8. --- linux-3.15-rc6/drivers/iommu/amd_iommu.c    2014-05-21 23:42:02.000000000 +0200
  9. +++ linux-awilliam/drivers/iommu/amd_iommu.c    2014-06-23 23:00:25.000000000 +0200
  10. @@ -46,7 +46,6 @@
  11.  #include "amd_iommu_proto.h"
  12.  #include "amd_iommu_types.h"
  13.  #include "irq_remapping.h"
  14. -#include "pci.h"
  15.  
  16.  #define CMD_SET_TYPE(cmd, t) ((cmd)->data[1] |= ((t) << 28))
  17.  
  18. @@ -133,9 +132,6 @@
  19.     list_del(&dev_data->dev_data_list);
  20.     spin_unlock_irqrestore(&dev_data_list_lock, flags);
  21.  
  22. -   if (dev_data->group)
  23. -       iommu_group_put(dev_data->group);
  24. -
  25.     kfree(dev_data);
  26.  }
  27.  
  28. @@ -264,167 +260,79 @@
  29.     return true;
  30.  }
  31.  
  32. -static struct pci_bus *find_hosted_bus(struct pci_bus *bus)
  33. -{
  34. -   while (!bus->self) {
  35. -       if (!pci_is_root_bus(bus))
  36. -           bus = bus->parent;
  37. -       else
  38. -           return ERR_PTR(-ENODEV);
  39. -   }
  40. -
  41. -   return bus;
  42. -}
  43. -
  44. -#define REQ_ACS_FLAGS  (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF)
  45. -
  46. -static struct pci_dev *get_isolation_root(struct pci_dev *pdev)
  47. +static int init_iommu_group(struct device *dev)
  48.  {
  49. -   struct pci_dev *dma_pdev = pdev;
  50. -
  51. -   /* Account for quirked devices */
  52. -   swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev));
  53. -
  54. -   /*
  55. -    * If it's a multifunction device that does not support our
  56. -    * required ACS flags, add to the same group as lowest numbered
  57. -    * function that also does not suport the required ACS flags.
  58. -    */
  59. -   if (dma_pdev->multifunction &&
  60. -       !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) {
  61. -       u8 i, slot = PCI_SLOT(dma_pdev->devfn);
  62. -
  63. -       for (i = 0; i < 8; i++) {
  64. -           struct pci_dev *tmp;
  65. -
  66. -           tmp = pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot, i));
  67. -           if (!tmp)
  68. -               continue;
  69. -
  70. -           if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) {
  71. -               swap_pci_ref(&dma_pdev, tmp);
  72. -               break;
  73. -           }
  74. -           pci_dev_put(tmp);
  75. -       }
  76. -   }
  77. +   struct iommu_group *group;
  78.  
  79. -   /*
  80. -    * Devices on the root bus go through the iommu.  If that's not us,
  81. -    * find the next upstream device and test ACS up to the root bus.
  82. -    * Finding the next device may require skipping virtual buses.
  83. -    */
  84. -   while (!pci_is_root_bus(dma_pdev->bus)) {
  85. -       struct pci_bus *bus = find_hosted_bus(dma_pdev->bus);
  86. -       if (IS_ERR(bus))
  87. -           break;
  88. +   group = iommu_group_get_for_dev(dev);
  89.  
  90. -       if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS))
  91. -           break;
  92. +   if (IS_ERR(group))
  93. +       return PTR_ERR(group);
  94.  
  95. -       swap_pci_ref(&dma_pdev, pci_dev_get(bus->self));
  96. -   }
  97. -
  98. -   return dma_pdev;
  99. +   iommu_group_put(group);
  100. +   return 0;
  101.  }
  102.  
  103. -static int use_pdev_iommu_group(struct pci_dev *pdev, struct device *dev)
  104. +static int __last_alias(struct pci_dev *pdev, u16 alias, void *data)
  105.  {
  106. -   struct iommu_group *group = iommu_group_get(&pdev->dev);
  107. -   int ret;
  108. -
  109. -   if (!group) {
  110. -       group = iommu_group_alloc();
  111. -       if (IS_ERR(group))
  112. -           return PTR_ERR(group);
  113. -
  114. -       WARN_ON(&pdev->dev != dev);
  115. -   }
  116. -
  117. -   ret = iommu_group_add_device(group, dev);
  118. -   iommu_group_put(group);
  119. -   return ret;
  120. +   *(u16 *)data = alias;
  121. +   return 0;
  122.  }
  123.  
  124. -static int use_dev_data_iommu_group(struct iommu_dev_data *dev_data,
  125. -                   struct device *dev)
  126. +static u16 get_alias(struct device *dev)
  127.  {
  128. -   if (!dev_data->group) {
  129. -       struct iommu_group *group = iommu_group_alloc();
  130. -       if (IS_ERR(group))
  131. -           return PTR_ERR(group);
  132. +   struct pci_dev *pdev = to_pci_dev(dev);
  133. +   u16 devid, ivrs_alias, pci_alias;
  134.  
  135. -       dev_data->group = group;
  136. -   }
  137. +   devid = get_device_id(dev);
  138. +   ivrs_alias = amd_iommu_alias_table[devid];
  139. +   pci_for_each_dma_alias(pdev, __last_alias, &pci_alias);
  140.  
  141. -   return iommu_group_add_device(dev_data->group, dev);
  142. -}
  143. +   if (ivrs_alias == pci_alias)
  144. +       return ivrs_alias;
  145.  
  146. -static int init_iommu_group(struct device *dev)
  147. -{
  148. -   struct iommu_dev_data *dev_data;
  149. -   struct iommu_group *group;
  150. -   struct pci_dev *dma_pdev;
  151. -   int ret;
  152. +   /*
  153. +    * DMA alias showdown
  154. +    *
  155. +    * The IVRS is fairly reliable in telling us about aliases, but it
  156. +    * can't know about every screwy device.  If we don't have an IVRS
  157. +    * reported alias, use the PCI reported alias.  In that case we may
  158. +    * still need to initialize the rlookup and dev_table entries if the
  159. +    * alias is to a non-existent device.
  160. +    */
  161. +   if (ivrs_alias == devid) {
  162. +       if (!amd_iommu_rlookup_table[pci_alias]) {
  163. +           amd_iommu_rlookup_table[pci_alias] =
  164. +               amd_iommu_rlookup_table[devid];
  165. +           memcpy(amd_iommu_dev_table[pci_alias].data,
  166. +                  amd_iommu_dev_table[devid].data,
  167. +                  sizeof(amd_iommu_dev_table[pci_alias].data));
  168. +       }
  169.  
  170. -   group = iommu_group_get(dev);
  171. -   if (group) {
  172. -       iommu_group_put(group);
  173. -       return 0;
  174. +       return pci_alias;
  175.     }
  176.  
  177. -   dev_data = find_dev_data(get_device_id(dev));
  178. -   if (!dev_data)
  179. -       return -ENOMEM;
  180. -
  181. -   if (dev_data->alias_data) {
  182. -       u16 alias;
  183. -       struct pci_bus *bus;
  184. -
  185. -       if (dev_data->alias_data->group)
  186. -           goto use_group;
  187. +   pr_info("AMD-Vi: Using IVRS reported alias %02x:%02x.%d "
  188. +       "for device %s[%04x:%04x], kernel reported alias "
  189. +       "%02x:%02x.%d\n", PCI_BUS_NUM(ivrs_alias), PCI_SLOT(ivrs_alias),
  190. +       PCI_FUNC(ivrs_alias), dev_name(dev), pdev->vendor, pdev->device,
  191. +       PCI_BUS_NUM(pci_alias), PCI_SLOT(pci_alias),
  192. +       PCI_FUNC(pci_alias));
  193.  
  194. -       /*
  195. -        * If the alias device exists, it's effectively just a first
  196. -        * level quirk for finding the DMA source.
  197. -        */
  198. -       alias = amd_iommu_alias_table[dev_data->devid];
  199. -       dma_pdev = pci_get_bus_and_slot(alias >> 8, alias & 0xff);
  200. -       if (dma_pdev) {
  201. -           dma_pdev = get_isolation_root(dma_pdev);
  202. -           goto use_pdev;
  203. -       }
  204. +   /*
  205. +    * If we don't have a PCI DMA alias and the IVRS alias is on the same
  206. +    * bus, then the IVRS table may know about a quirk that we don't.
  207. +    */
  208. +   if (pci_alias == devid &&
  209. +       PCI_BUS_NUM(ivrs_alias) == pdev->bus->number) {
  210. +       pdev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN;
  211. +       pdev->dma_alias_devfn = ivrs_alias & 0xff;
  212. +       pr_info("AMD-Vi: Added PCI DMA alias %02x.%d for %s\n",
  213. +           PCI_SLOT(ivrs_alias), PCI_FUNC(ivrs_alias),
  214. +           dev_name(dev));
  215. +   }
  216.  
  217. -       /*
  218. -        * If the alias is virtual, try to find a parent device
  219. -        * and test whether the IOMMU group is actualy rooted above
  220. -        * the alias.  Be careful to also test the parent device if
  221. -        * we think the alias is the root of the group.
  222. -        */
  223. -       bus = pci_find_bus(0, alias >> 8);
  224. -       if (!bus)
  225. -           goto use_group;
  226. -
  227. -       bus = find_hosted_bus(bus);
  228. -       if (IS_ERR(bus) || !bus->self)
  229. -           goto use_group;
  230. -
  231. -       dma_pdev = get_isolation_root(pci_dev_get(bus->self));
  232. -       if (dma_pdev != bus->self || (dma_pdev->multifunction &&
  233. -           !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)))
  234. -           goto use_pdev;
  235. -
  236. -       pci_dev_put(dma_pdev);
  237. -       goto use_group;
  238. -   }
  239. -
  240. -   dma_pdev = get_isolation_root(pci_dev_get(to_pci_dev(dev)));
  241. -use_pdev:
  242. -   ret = use_pdev_iommu_group(dma_pdev, dev);
  243. -   pci_dev_put(dma_pdev);
  244. -   return ret;
  245. -use_group:
  246. -   return use_dev_data_iommu_group(dev_data->alias_data, dev);
  247. +   return ivrs_alias;
  248.  }
  249.  
  250.  static int iommu_init_device(struct device *dev)
  251. @@ -441,7 +349,8 @@
  252.     if (!dev_data)
  253.         return -ENOMEM;
  254.  
  255. -   alias = amd_iommu_alias_table[dev_data->devid];
  256. +   alias = get_alias(dev);
  257. +
  258.     if (alias != dev_data->devid) {
  259.         struct iommu_dev_data *alias_data;
  260.  
  261. @@ -489,12 +398,19 @@
  262.  
  263.  static void iommu_uninit_device(struct device *dev)
  264.  {
  265. +   struct iommu_dev_data *dev_data = search_dev_data(get_device_id(dev));
  266. +
  267. +   if (!dev_data)
  268. +       return;
  269. +
  270.     iommu_group_remove_device(dev);
  271.  
  272. +   /* Unlink from alias, it may change if another device is re-plugged */
  273. +   dev_data->alias_data = NULL;
  274. +
  275.     /*
  276. -    * Nothing to do here - we keep dev_data around for unplugged devices
  277. -    * and reuse it when the device is re-plugged - not doing so would
  278. -    * introduce a ton of races.
  279. +    * We keep dev_data around for unplugged devices and reuse it when the
  280. +    * device is re-plugged - not doing so would introduce a ton of races.
  281.      */
  282.  }
  283.  
  284. diff -Naur linux-3.15-rc6/drivers/iommu/amd_iommu_types.h linux-awilliam/drivers/iommu/amd_iommu_types.h
  285. --- linux-3.15-rc6/drivers/iommu/amd_iommu_types.h  2014-05-21 23:42:02.000000000 +0200
  286. +++ linux-awilliam/drivers/iommu/amd_iommu_types.h  2014-06-23 23:00:25.000000000 +0200
  287. @@ -432,7 +432,6 @@
  288.     struct iommu_dev_data *alias_data;/* The alias dev_data */
  289.     struct protection_domain *domain; /* Domain the device is bound to */
  290.     atomic_t bind;            /* Domain attach reference count */
  291. -   struct iommu_group *group;    /* IOMMU group for virtual aliases */
  292.     u16 devid;            /* PCI Device ID */
  293.     bool iommu_v2;            /* Device can make use of IOMMUv2 */
  294.     bool passthrough;         /* Default for device is pt_domain */
  295. diff -Naur linux-3.15-rc6/drivers/iommu/fsl_pamu_domain.c linux-awilliam/drivers/iommu/fsl_pamu_domain.c
  296. --- linux-3.15-rc6/drivers/iommu/fsl_pamu_domain.c  2014-05-21 23:42:02.000000000 +0200
  297. +++ linux-awilliam/drivers/iommu/fsl_pamu_domain.c  2014-06-23 23:00:25.000000000 +0200
  298. @@ -38,7 +38,6 @@
  299.  #include <sysdev/fsl_pci.h>
  300.  
  301.  #include "fsl_pamu_domain.h"
  302. -#include "pci.h"
  303.  
  304.  /*
  305.   * Global spinlock that needs to be held while
  306. @@ -892,8 +891,6 @@
  307.     return ret;
  308.  }
  309.  
  310. -#define REQ_ACS_FLAGS  (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF)
  311. -
  312.  static struct iommu_group *get_device_iommu_group(struct device *dev)
  313.  {
  314.     struct iommu_group *group;
  315. @@ -950,74 +947,13 @@
  316.     struct pci_controller *pci_ctl;
  317.     bool pci_endpt_partioning;
  318.     struct iommu_group *group = NULL;
  319. -   struct pci_dev *bridge, *dma_pdev = NULL;
  320.  
  321.     pci_ctl = pci_bus_to_host(pdev->bus);
  322.     pci_endpt_partioning = check_pci_ctl_endpt_part(pci_ctl);
  323.     /* We can partition PCIe devices so assign device group to the device */
  324.     if (pci_endpt_partioning) {
  325. -       bridge = pci_find_upstream_pcie_bridge(pdev);
  326. -       if (bridge) {
  327. -           if (pci_is_pcie(bridge))
  328. -               dma_pdev = pci_get_domain_bus_and_slot(
  329. -                       pci_domain_nr(pdev->bus),
  330. -                       bridge->subordinate->number, 0);
  331. -           if (!dma_pdev)
  332. -               dma_pdev = pci_dev_get(bridge);
  333. -       } else
  334. -           dma_pdev = pci_dev_get(pdev);
  335. -
  336. -       /* Account for quirked devices */
  337. -       swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev));
  338. -
  339. -       /*
  340. -        * If it's a multifunction device that does not support our
  341. -        * required ACS flags, add to the same group as lowest numbered
  342. -        * function that also does not suport the required ACS flags.
  343. -        */
  344. -       if (dma_pdev->multifunction &&
  345. -           !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) {
  346. -           u8 i, slot = PCI_SLOT(dma_pdev->devfn);
  347. -
  348. -           for (i = 0; i < 8; i++) {
  349. -               struct pci_dev *tmp;
  350. -
  351. -               tmp = pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot, i));
  352. -               if (!tmp)
  353. -                   continue;
  354. -
  355. -               if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) {
  356. -                   swap_pci_ref(&dma_pdev, tmp);
  357. -                   break;
  358. -               }
  359. -               pci_dev_put(tmp);
  360. -           }
  361. -       }
  362. -
  363. -       /*
  364. -        * Devices on the root bus go through the iommu.  If that's not us,
  365. -        * find the next upstream device and test ACS up to the root bus.
  366. -        * Finding the next device may require skipping virtual buses.
  367. -        */
  368. -       while (!pci_is_root_bus(dma_pdev->bus)) {
  369. -           struct pci_bus *bus = dma_pdev->bus;
  370. -
  371. -           while (!bus->self) {
  372. -               if (!pci_is_root_bus(bus))
  373. -                   bus = bus->parent;
  374. -               else
  375. -                   goto root_bus;
  376. -           }
  377. -
  378. -           if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS))
  379. -               break;
  380. -
  381. -           swap_pci_ref(&dma_pdev, pci_dev_get(bus->self));
  382. -       }
  383. +       group = iommu_group_get_for_dev(&pdev->dev);
  384.  
  385. -root_bus:
  386. -       group = get_device_iommu_group(&dma_pdev->dev);
  387. -       pci_dev_put(dma_pdev);
  388.         /*
  389.          * PCIe controller is not a paritionable entity
  390.          * free the controller device iommu_group.
  391. diff -Naur linux-3.15-rc6/drivers/iommu/intel-iommu.c linux-awilliam/drivers/iommu/intel-iommu.c
  392. --- linux-3.15-rc6/drivers/iommu/intel-iommu.c  2014-05-21 23:42:02.000000000 +0200
  393. +++ linux-awilliam/drivers/iommu/intel-iommu.c  2014-06-23 23:00:25.000000000 +0200
  394. @@ -44,7 +44,6 @@
  395.  #include <asm/iommu.h>
  396.  
  397.  #include "irq_remapping.h"
  398. -#include "pci.h"
  399.  
  400.  #define ROOT_SIZE      VTD_PAGE_SIZE
  401.  #define CONTEXT_SIZE       VTD_PAGE_SIZE
  402. @@ -1841,54 +1840,56 @@
  403.     return 0;
  404.  }
  405.  
  406. +struct domain_context_mapping_data {
  407. +   struct dmar_domain *domain;
  408. +   struct intel_iommu *iommu;
  409. +   int translation;
  410. +};
  411. +
  412. +static int domain_context_mapping_cb(struct pci_dev *pdev,
  413. +                    u16 alias, void *opaque)
  414. +{
  415. +   struct domain_context_mapping_data *data = opaque;
  416. +
  417. +   return domain_context_mapping_one(data->domain, data->iommu,
  418. +                     PCI_BUS_NUM(alias), alias & 0xff,
  419. +                     data->translation);
  420. +}
  421. +
  422.  static int
  423.  domain_context_mapping(struct dmar_domain *domain, struct device *dev,
  424.                int translation)
  425.  {
  426. -   int ret;
  427. -   struct pci_dev *pdev, *tmp, *parent;
  428.     struct intel_iommu *iommu;
  429.     u8 bus, devfn;
  430. +   struct domain_context_mapping_data data;
  431.  
  432.     iommu = device_to_iommu(dev, &bus, &devfn);
  433.     if (!iommu)
  434.         return -ENODEV;
  435.  
  436. -   ret = domain_context_mapping_one(domain, iommu, bus, devfn,
  437. -                    translation);
  438. -   if (ret || !dev_is_pci(dev))
  439. -       return ret;
  440. -
  441. -   /* dependent device mapping */
  442. -   pdev = to_pci_dev(dev);
  443. -   tmp = pci_find_upstream_pcie_bridge(pdev);
  444. -   if (!tmp)
  445. -       return 0;
  446. -   /* Secondary interface's bus number and devfn 0 */
  447. -   parent = pdev->bus->self;
  448. -   while (parent != tmp) {
  449. -       ret = domain_context_mapping_one(domain, iommu,
  450. -                        parent->bus->number,
  451. -                        parent->devfn, translation);
  452. -       if (ret)
  453. -           return ret;
  454. -       parent = parent->bus->self;
  455. -   }
  456. -   if (pci_is_pcie(tmp)) /* this is a PCIe-to-PCI bridge */
  457. -       return domain_context_mapping_one(domain, iommu,
  458. -                   tmp->subordinate->number, 0,
  459. -                   translation);
  460. -   else /* this is a legacy PCI bridge */
  461. -       return domain_context_mapping_one(domain, iommu,
  462. -                         tmp->bus->number,
  463. -                         tmp->devfn,
  464. +   if (!dev_is_pci(dev))
  465. +       return domain_context_mapping_one(domain, iommu, bus, devfn,
  466.                           translation);
  467. +
  468. +   data.domain = domain;
  469. +   data.iommu = iommu;
  470. +   data.translation = translation;
  471. +
  472. +   return pci_for_each_dma_alias(to_pci_dev(dev),
  473. +                     &domain_context_mapping_cb, &data);
  474. +}
  475. +
  476. +static int domain_context_mapped_cb(struct pci_dev *pdev,
  477. +                   u16 alias, void *opaque)
  478. +{
  479. +   struct intel_iommu *iommu = opaque;
  480. +
  481. +   return !device_context_mapped(iommu, PCI_BUS_NUM(alias), alias & 0xff);
  482.  }
  483.  
  484.  static int domain_context_mapped(struct device *dev)
  485.  {
  486. -   int ret;
  487. -   struct pci_dev *pdev, *tmp, *parent;
  488.     struct intel_iommu *iommu;
  489.     u8 bus, devfn;
  490.  
  491. @@ -1896,30 +1897,11 @@
  492.     if (!iommu)
  493.         return -ENODEV;
  494.  
  495. -   ret = device_context_mapped(iommu, bus, devfn);
  496. -   if (!ret || !dev_is_pci(dev))
  497. -       return ret;
  498. +   if (!dev_is_pci(dev))
  499. +       return device_context_mapped(iommu, bus, devfn);
  500.  
  501. -   /* dependent device mapping */
  502. -   pdev = to_pci_dev(dev);
  503. -   tmp = pci_find_upstream_pcie_bridge(pdev);
  504. -   if (!tmp)
  505. -       return ret;
  506. -   /* Secondary interface's bus number and devfn 0 */
  507. -   parent = pdev->bus->self;
  508. -   while (parent != tmp) {
  509. -       ret = device_context_mapped(iommu, parent->bus->number,
  510. -                       parent->devfn);
  511. -       if (!ret)
  512. -           return ret;
  513. -       parent = parent->bus->self;
  514. -   }
  515. -   if (pci_is_pcie(tmp))
  516. -       return device_context_mapped(iommu, tmp->subordinate->number,
  517. -                        0);
  518. -   else
  519. -       return device_context_mapped(iommu, tmp->bus->number,
  520. -                        tmp->devfn);
  521. +   return !pci_for_each_dma_alias(to_pci_dev(dev),
  522. +                      domain_context_mapped_cb, iommu);
  523.  }
  524.  
  525.  /* Returns a number of VTD pages, but aligned to MM page size */
  526. @@ -2208,79 +2190,86 @@
  527.     return domain;
  528.  }
  529.  
  530. +static int get_last_alias(struct pci_dev *pdev, u16 alias, void *opaque)
  531. +{
  532. +   *(u16 *)opaque = alias;
  533. +   return 0;
  534. +}
  535. +
  536.  /* domain is initialized */
  537.  static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
  538.  {
  539. -   struct dmar_domain *domain, *free = NULL;
  540. -   struct intel_iommu *iommu = NULL;
  541. +   struct dmar_domain *domain, *tmp;
  542. +   struct intel_iommu *iommu;
  543.     struct device_domain_info *info;
  544. -   struct pci_dev *dev_tmp = NULL;
  545. +   u16 dma_alias;
  546.     unsigned long flags;
  547. -   u8 bus, devfn, bridge_bus, bridge_devfn;
  548. +   u8 bus, devfn;
  549.  
  550.     domain = find_domain(dev);
  551.     if (domain)
  552.         return domain;
  553.  
  554. +   iommu = device_to_iommu(dev, &bus, &devfn);
  555. +   if (!iommu)
  556. +       return NULL;
  557. +
  558.     if (dev_is_pci(dev)) {
  559.         struct pci_dev *pdev = to_pci_dev(dev);
  560. -       u16 segment;
  561.  
  562. -       segment = pci_domain_nr(pdev->bus);
  563. -       dev_tmp = pci_find_upstream_pcie_bridge(pdev);
  564. -       if (dev_tmp) {
  565. -           if (pci_is_pcie(dev_tmp)) {
  566. -               bridge_bus = dev_tmp->subordinate->number;
  567. -               bridge_devfn = 0;
  568. -           } else {
  569. -               bridge_bus = dev_tmp->bus->number;
  570. -               bridge_devfn = dev_tmp->devfn;
  571. -           }
  572. -           spin_lock_irqsave(&device_domain_lock, flags);
  573. -           info = dmar_search_domain_by_dev_info(segment,
  574. -                                 bridge_bus,
  575. -                                 bridge_devfn);
  576. -           if (info) {
  577. -               iommu = info->iommu;
  578. -               domain = info->domain;
  579. -           }
  580. -           spin_unlock_irqrestore(&device_domain_lock, flags);
  581. -           /* pcie-pci bridge already has a domain, uses it */
  582. -           if (info)
  583. -               goto found_domain;
  584. +       pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
  585. +
  586. +       spin_lock_irqsave(&device_domain_lock, flags);
  587. +       info = dmar_search_domain_by_dev_info(pci_domain_nr(pdev->bus),
  588. +                             PCI_BUS_NUM(dma_alias),
  589. +                             dma_alias & 0xff);
  590. +       if (info) {
  591. +           iommu = info->iommu;
  592. +           domain = info->domain;
  593.         }
  594. -   }
  595. +       spin_unlock_irqrestore(&device_domain_lock, flags);
  596.  
  597. -   iommu = device_to_iommu(dev, &bus, &devfn);
  598. -   if (!iommu)
  599. -       goto error;
  600. +       /* DMA alias already has a domain, uses it */
  601. +       if (info)
  602. +           goto found_domain;
  603. +   }
  604.  
  605.     /* Allocate and initialize new domain for the device */
  606.     domain = alloc_domain(false);
  607.     if (!domain)
  608. -       goto error;
  609. +       return NULL;
  610. +
  611.     if (iommu_attach_domain(domain, iommu)) {
  612.         free_domain_mem(domain);
  613. -       domain = NULL;
  614. -       goto error;
  615. +       return NULL;
  616. +   }
  617. +
  618. +   if (domain_init(domain, gaw)) {
  619. +       domain_exit(domain);
  620. +       return NULL;
  621.     }
  622. -   free = domain;
  623. -   if (domain_init(domain, gaw))
  624. -       goto error;
  625.  
  626. -   /* register pcie-to-pci device */
  627. -   if (dev_tmp) {
  628. -       domain = dmar_insert_dev_info(iommu, bridge_bus, bridge_devfn,
  629. -                         NULL, domain);
  630. +   /* register PCI DMA alias device */
  631. +   if (dev_is_pci(dev)) {
  632. +       tmp = dmar_insert_dev_info(iommu, PCI_BUS_NUM(dma_alias),
  633. +                      dma_alias & 0xff, NULL, domain);
  634. +
  635. +       if (!tmp || tmp != domain) {
  636. +           domain_exit(domain);
  637. +           domain = tmp;
  638. +       }
  639. +
  640.         if (!domain)
  641. -           goto error;
  642. +           return NULL;
  643.     }
  644.  
  645.  found_domain:
  646. -   domain = dmar_insert_dev_info(iommu, bus, devfn, dev, domain);
  647. -error:
  648. -   if (free != domain)
  649. -       domain_exit(free);
  650. +   tmp = dmar_insert_dev_info(iommu, bus, devfn, dev, domain);
  651. +
  652. +   if (!tmp || tmp != domain) {
  653. +       domain_exit(domain);
  654. +       domain = tmp;
  655. +   }
  656.  
  657.     return domain;
  658.  }
  659. @@ -4030,33 +4019,27 @@
  660.     return ret;
  661.  }
  662.  
  663. +static int iommu_detach_dev_cb(struct pci_dev *pdev, u16 alias, void *opaque)
  664. +{
  665. +   struct intel_iommu *iommu = opaque;
  666. +
  667. +   iommu_detach_dev(iommu, PCI_BUS_NUM(alias), alias & 0xff);
  668. +   return 0;
  669. +}
  670. +
  671. +/*
  672. + * NB - intel-iommu lacks any sort of reference counting for the users of
  673. + * dependent devices.  If multiple endpoints have intersecting dependent
  674. + * devices, unbinding the driver from any one of them will possibly leave
  675. + * the others unable to operate.
  676. + */
  677.  static void iommu_detach_dependent_devices(struct intel_iommu *iommu,
  678.                        struct device *dev)
  679.  {
  680. -   struct pci_dev *tmp, *parent, *pdev;
  681. -
  682.     if (!iommu || !dev || !dev_is_pci(dev))
  683.         return;
  684.  
  685. -   pdev = to_pci_dev(dev);
  686. -
  687. -   /* dependent device detach */
  688. -   tmp = pci_find_upstream_pcie_bridge(pdev);
  689. -   /* Secondary interface's bus number and devfn 0 */
  690. -   if (tmp) {
  691. -       parent = pdev->bus->self;
  692. -       while (parent != tmp) {
  693. -           iommu_detach_dev(iommu, parent->bus->number,
  694. -                    parent->devfn);
  695. -           parent = parent->bus->self;
  696. -       }
  697. -       if (pci_is_pcie(tmp)) /* this is a PCIe-to-PCI bridge */
  698. -           iommu_detach_dev(iommu,
  699. -               tmp->subordinate->number, 0);
  700. -       else /* this is a legacy PCI bridge */
  701. -           iommu_detach_dev(iommu, tmp->bus->number,
  702. -                    tmp->devfn);
  703. -   }
  704. +   pci_for_each_dma_alias(to_pci_dev(dev), &iommu_detach_dev_cb, iommu);
  705.  }
  706.  
  707.  static void domain_remove_one_dev_info(struct dmar_domain *domain,
  708. @@ -4359,91 +4342,21 @@
  709.     return 0;
  710.  }
  711.  
  712. -#define REQ_ACS_FLAGS  (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF)
  713. -
  714.  static int intel_iommu_add_device(struct device *dev)
  715.  {
  716. -   struct pci_dev *pdev = to_pci_dev(dev);
  717. -   struct pci_dev *bridge, *dma_pdev = NULL;
  718.     struct iommu_group *group;
  719. -   int ret;
  720.     u8 bus, devfn;
  721.  
  722.     if (!device_to_iommu(dev, &bus, &devfn))
  723.         return -ENODEV;
  724.  
  725. -   bridge = pci_find_upstream_pcie_bridge(pdev);
  726. -   if (bridge) {
  727. -       if (pci_is_pcie(bridge))
  728. -           dma_pdev = pci_get_domain_bus_and_slot(
  729. -                       pci_domain_nr(pdev->bus),
  730. -                       bridge->subordinate->number, 0);
  731. -       if (!dma_pdev)
  732. -           dma_pdev = pci_dev_get(bridge);
  733. -   } else
  734. -       dma_pdev = pci_dev_get(pdev);
  735. -
  736. -   /* Account for quirked devices */
  737. -   swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev));
  738. -
  739. -   /*
  740. -    * If it's a multifunction device that does not support our
  741. -    * required ACS flags, add to the same group as lowest numbered
  742. -    * function that also does not suport the required ACS flags.
  743. -    */
  744. -   if (dma_pdev->multifunction &&
  745. -       !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) {
  746. -       u8 i, slot = PCI_SLOT(dma_pdev->devfn);
  747. -
  748. -       for (i = 0; i < 8; i++) {
  749. -           struct pci_dev *tmp;
  750. -
  751. -           tmp = pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot, i));
  752. -           if (!tmp)
  753. -               continue;
  754. +   group = iommu_group_get_for_dev(dev);
  755.  
  756. -           if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) {
  757. -               swap_pci_ref(&dma_pdev, tmp);
  758. -               break;
  759. -           }
  760. -           pci_dev_put(tmp);
  761. -       }
  762. -   }
  763. -
  764. -   /*
  765. -    * Devices on the root bus go through the iommu.  If that's not us,
  766. -    * find the next upstream device and test ACS up to the root bus.
  767. -    * Finding the next device may require skipping virtual buses.
  768. -    */
  769. -   while (!pci_is_root_bus(dma_pdev->bus)) {
  770. -       struct pci_bus *bus = dma_pdev->bus;
  771. -
  772. -       while (!bus->self) {
  773. -           if (!pci_is_root_bus(bus))
  774. -               bus = bus->parent;
  775. -           else
  776. -               goto root_bus;
  777. -       }
  778. -
  779. -       if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS))
  780. -           break;
  781. -
  782. -       swap_pci_ref(&dma_pdev, pci_dev_get(bus->self));
  783. -   }
  784. -
  785. -root_bus:
  786. -   group = iommu_group_get(&dma_pdev->dev);
  787. -   pci_dev_put(dma_pdev);
  788. -   if (!group) {
  789. -       group = iommu_group_alloc();
  790. -       if (IS_ERR(group))
  791. -           return PTR_ERR(group);
  792. -   }
  793. -
  794. -   ret = iommu_group_add_device(group, dev);
  795. +   if (IS_ERR(group))
  796. +       return PTR_ERR(group);
  797.  
  798.     iommu_group_put(group);
  799. -   return ret;
  800. +   return 0;
  801.  }
  802.  
  803.  static void intel_iommu_remove_device(struct device *dev)
  804. diff -Naur linux-3.15-rc6/drivers/iommu/intel_irq_remapping.c linux-awilliam/drivers/iommu/intel_irq_remapping.c
  805. --- linux-3.15-rc6/drivers/iommu/intel_irq_remapping.c  2014-05-21 23:42:02.000000000 +0200
  806. +++ linux-awilliam/drivers/iommu/intel_irq_remapping.c  2014-06-23 23:00:25.000000000 +0200
  807. @@ -369,29 +369,52 @@
  808.     return 0;
  809.  }
  810.  
  811. +struct set_msi_sid_data {
  812. +   struct pci_dev *pdev;
  813. +   u16 alias;
  814. +};
  815. +
  816. +static int set_msi_sid_cb(struct pci_dev *pdev, u16 alias, void *opaque)
  817. +{
  818. +   struct set_msi_sid_data *data = opaque;
  819. +
  820. +   data->pdev = pdev;
  821. +   data->alias = alias;
  822. +
  823. +   return 0;
  824. +}
  825. +
  826.  static int set_msi_sid(struct irte *irte, struct pci_dev *dev)
  827.  {
  828. -   struct pci_dev *bridge;
  829. +   struct set_msi_sid_data data;
  830.  
  831.     if (!irte || !dev)
  832.         return -1;
  833.  
  834. -   /* PCIe device or Root Complex integrated PCI device */
  835. -   if (pci_is_pcie(dev) || !dev->bus->parent) {
  836. -       set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16,
  837. -                (dev->bus->number << 8) | dev->devfn);
  838. -       return 0;
  839. -   }
  840. +   pci_for_each_dma_alias(dev, set_msi_sid_cb, &data);
  841.  
  842. -   bridge = pci_find_upstream_pcie_bridge(dev);
  843. -   if (bridge) {
  844. -       if (pci_is_pcie(bridge))/* this is a PCIe-to-PCI/PCIX bridge */
  845. -           set_irte_sid(irte, SVT_VERIFY_BUS, SQ_ALL_16,
  846. -               (bridge->bus->number << 8) | dev->bus->number);
  847. -       else /* this is a legacy PCI bridge */
  848. -           set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16,
  849. -               (bridge->bus->number << 8) | bridge->devfn);
  850. -   }
  851. +   /*
  852. +    * DMA alias provides us with a PCI device and alias.  The only case
  853. +    * where the it will return an alias on a different bus than the
  854. +    * device is the case of a PCIe-to-PCI bridge, where the alias is for
  855. +    * the subordinate bus.  In this case we can only verify the bus.
  856. +    *
  857. +    * If the alias device is on a different bus than our source device
  858. +    * then we have a topology based alias, use it.
  859. +    *
  860. +    * Otherwise, the alias is for a device DMA quirk and we cannot
  861. +    * assume that MSI uses the same requester ID.  Therefore use the
  862. +    * original device.
  863. +    */
  864. +   if (PCI_BUS_NUM(data.alias) != data.pdev->bus->number)
  865. +       set_irte_sid(irte, SVT_VERIFY_BUS, SQ_ALL_16,
  866. +                PCI_DEVID(PCI_BUS_NUM(data.alias),
  867. +                      dev->bus->number));
  868. +   else if (data.pdev->bus->number != dev->bus->number)
  869. +       set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16, data.alias);
  870. +   else
  871. +       set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16,
  872. +                PCI_DEVID(dev->bus->number, dev->devfn));
  873.  
  874.     return 0;
  875.  }
  876. diff -Naur linux-3.15-rc6/drivers/iommu/iommu.c linux-awilliam/drivers/iommu/iommu.c
  877. --- linux-3.15-rc6/drivers/iommu/iommu.c    2014-05-21 23:42:02.000000000 +0200
  878. +++ linux-awilliam/drivers/iommu/iommu.c    2014-06-23 23:00:25.000000000 +0200
  879. @@ -29,6 +29,7 @@
  880.  #include <linux/idr.h>
  881.  #include <linux/notifier.h>
  882.  #include <linux/err.h>
  883. +#include <linux/pci.h>
  884.  #include <trace/events/iommu.h>
  885.  
  886.  static struct kset *iommu_group_kset;
  887. @@ -514,6 +515,186 @@
  888.  }
  889.  EXPORT_SYMBOL_GPL(iommu_group_id);
  890.  
  891. +/*
  892. + * To consider a PCI device isolated, we require ACS to support Source
  893. + * Validation, Request Redirection, Completer Redirection, and Upstream
  894. + * Forwarding.  This effectively means that devices cannot spoof their
  895. + * requester ID, requests and completions cannot be redirected, and all
  896. + * transactions are forwarded upstream, even as it passes through a
  897. + * bridge where the target device is downstream.
  898. + */
  899. +#define REQ_ACS_FLAGS   (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF)
  900. +
  901. +struct group_for_pci_data {
  902. +   struct pci_dev *pdev;
  903. +   struct iommu_group *group;
  904. +};
  905. +
  906. +/*
  907. + * DMA alias iterator callback, return the last seen device.  Stop and return
  908. + * the IOMMU group if we find one along the way.
  909. + */
  910. +static int get_pci_alias_or_group(struct pci_dev *pdev, u16 alias, void *opaque)
  911. +{
  912. +   struct group_for_pci_data *data = opaque;
  913. +
  914. +   data->pdev = pdev;
  915. +   data->group = iommu_group_get(&pdev->dev);
  916. +
  917. +   return data->group != NULL;
  918. +}
  919. +
  920. +/*
  921. + * Use standard PCI bus topology, isolation features, and DMA alias quirks
  922. + * to find or create an IOMMU group for a device.
  923. + */
  924. +static struct iommu_group *iommu_group_get_for_pci_dev(struct pci_dev *pdev)
  925. +{
  926. +   struct group_for_pci_data data;
  927. +   struct pci_bus *bus;
  928. +   struct iommu_group *group = NULL;
  929. +   struct pci_dev *tmp;
  930. +
  931. +   /*
  932. +    * Find the upstream DMA alias for the device.  A device must not
  933. +    * be aliased due to topology in order to have its own IOMMU group.
  934. +    * If we find an alias along the way that already belongs to a
  935. +    * group, use it.
  936. +    */
  937. +   if (pci_for_each_dma_alias(pdev, get_pci_alias_or_group, &data))
  938. +       return data.group;
  939. +
  940. +   pdev = data.pdev;
  941. +
  942. +   /*
  943. +    * Continue upstream from the point of minimum IOMMU granularity
  944. +    * due to aliases to the point where devices are protected from
  945. +    * peer-to-peer DMA by PCI ACS.  Again, if we find an existing
  946. +    * group, use it.
  947. +    */
  948. +   for (bus = pdev->bus; !pci_is_root_bus(bus); bus = bus->parent) {
  949. +       if (!bus->self)
  950. +           continue;
  951. +
  952. +       if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS))
  953. +           break;
  954. +
  955. +       pdev = bus->self;
  956. +
  957. +       group = iommu_group_get(&pdev->dev);
  958. +       if (group)
  959. +           return group;
  960. +   }
  961. +
  962. +   /*
  963. +    * Next we need to consider DMA alias quirks.  If one device aliases
  964. +    * to another, they should be grouped together.  It's theoretically
  965. +    * possible that aliases could create chains of devices where each
  966. +    * device aliases another device.  If we then factor in multifunction
  967. +    * ACS grouping requirements, each alias could incorporate a new slot
  968. +    * with multiple functions, each with aliases.  This is all extremely
  969. +    * unlikely as DMA alias quirks are typically only used for PCIe
  970. +    * devices where we usually have a single slot per bus.  Furthermore,
  971. +    * the alias quirk is usually to another function within the slot
  972. +    * (and ACS multifunction is not supported) or to a different slot
  973. +    * that doesn't physically exist.  The likely scenario is therefore
  974. +    * that everything on the bus gets grouped together.  To reduce the
  975. +    * problem space, share the IOMMU group for all devices on the bus
  976. +    * if a DMA alias quirk is present on the bus.
  977. +    */
  978. +   tmp = NULL;
  979. +   for_each_pci_dev(tmp) {
  980. +       if (tmp->bus != pdev->bus ||
  981. +           !(tmp->dev_flags & PCI_DEV_FLAGS_DMA_ALIAS_DEVFN))
  982. +           continue;
  983. +
  984. +       pci_dev_put(tmp);
  985. +       tmp = NULL;
  986. +
  987. +       /* We have an alias quirk, search for an existing group */
  988. +       for_each_pci_dev(tmp) {
  989. +           struct iommu_group *group_tmp;
  990. +           if (tmp->bus != pdev->bus)
  991. +               continue;
  992. +
  993. +           group_tmp = iommu_group_get(&tmp->dev);
  994. +           if (!group) {
  995. +               group = group_tmp;
  996. +               continue;
  997. +           }
  998. +
  999. +           if (group_tmp) {
  1000. +               WARN_ON(group != group_tmp);
  1001. +               iommu_group_put(group_tmp);
  1002. +           }
  1003. +       }
  1004. +
  1005. +       return group ? group : iommu_group_alloc();
  1006. +   }
  1007. +
  1008. +   /*
  1009. +    * Non-multifunction devices or multifunction devices supporting
  1010. +    * ACS get their own group.
  1011. +    */
  1012. +   if (!pdev->multifunction || pci_acs_enabled(pdev, REQ_ACS_FLAGS))
  1013. +       return iommu_group_alloc();
  1014. +
  1015. +   /*
  1016. +    * Multifunction devices not supporting ACS share a group with other
  1017. +    * similar devices in the same slot.
  1018. +    */
  1019. +   tmp = NULL;
  1020. +   for_each_pci_dev(tmp) {
  1021. +       if (tmp == pdev || tmp->bus != pdev->bus ||
  1022. +           PCI_SLOT(tmp->devfn) !=  PCI_SLOT(pdev->devfn) ||
  1023. +           pci_acs_enabled(tmp, REQ_ACS_FLAGS))
  1024. +           continue;
  1025. +
  1026. +       group = iommu_group_get(&tmp->dev);
  1027. +       if (group) {
  1028. +           pci_dev_put(tmp);
  1029. +           return group;
  1030. +       }
  1031. +   }
  1032. +
  1033. +   /* No shared group found, allocate new */
  1034. +   return iommu_group_alloc();
  1035. +}
  1036. +
  1037. +/**
  1038. + * iommu_group_get_for_dev - Find or create the IOMMU group for a device
  1039. + * @dev: target device
  1040. + *
  1041. + * This function is intended to be called by IOMMU drivers and extended to
  1042. + * support common, bus-defined algorithms when determining or creating the
  1043. + * IOMMU group for a device.  On success, the caller will hold a reference
  1044. + * to the returned IOMMU group, which will already include the provided
  1045. + * device.  The reference should be released with iommu_group_put().
  1046. + */
  1047. +struct iommu_group *iommu_group_get_for_dev(struct device *dev)
  1048. +{
  1049. +   struct iommu_group *group = ERR_PTR(-EIO);
  1050. +   int ret;
  1051. +
  1052. +   group = iommu_group_get(dev);
  1053. +   if (group)
  1054. +       return group;
  1055. +
  1056. +   if (dev_is_pci(dev))
  1057. +       group = iommu_group_get_for_pci_dev(to_pci_dev(dev));
  1058. +
  1059. +   if (IS_ERR(group))
  1060. +       return group;
  1061. +
  1062. +   ret = iommu_group_add_device(group, dev);
  1063. +   if (ret) {
  1064. +       iommu_group_put(group);
  1065. +       return ERR_PTR(ret);
  1066. +   }
  1067. +
  1068. +   return group;
  1069. +}
  1070. +
  1071.  static int add_iommu_group(struct device *dev, void *data)
  1072.  {
  1073.     struct iommu_ops *ops = data;
  1074. diff -Naur linux-3.15-rc6/drivers/iommu/pci.h linux-awilliam/drivers/iommu/pci.h
  1075. --- linux-3.15-rc6/drivers/iommu/pci.h  2014-05-21 23:42:02.000000000 +0200
  1076. +++ linux-awilliam/drivers/iommu/pci.h  1970-01-01 01:00:00.000000000 +0100
  1077. @@ -1,29 +0,0 @@
  1078. -/*
  1079. - * This program is free software; you can redistribute it and/or modify
  1080. - * it under the terms of the GNU General Public License, version 2, as
  1081. - * published by the Free Software Foundation.
  1082. - *
  1083. - * This program is distributed in the hope that it will be useful,
  1084. - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1085. - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1086. - * GNU General Public License for more details.
  1087. - *
  1088. - * You should have received a copy of the GNU General Public License
  1089. - * along with this program; if not, write to the Free Software
  1090. - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  1091. - *
  1092. - * Copyright (C) 2013 Red Hat, Inc.
  1093. - * Copyright (C) 2013 Freescale Semiconductor, Inc.
  1094. - *
  1095. - */
  1096. -#ifndef __IOMMU_PCI_H
  1097. -#define __IOMMU_PCI_H
  1098. -
  1099. -/* Helper function for swapping pci device reference */
  1100. -static inline void swap_pci_ref(struct pci_dev **from, struct pci_dev *to)
  1101. -{
  1102. -   pci_dev_put(*from);
  1103. -   *from = to;
  1104. -}
  1105. -
  1106. -#endif  /* __IOMMU_PCI_H */
  1107. diff -Naur linux-3.15-rc6/drivers/pci/quirks.c linux-awilliam/drivers/pci/quirks.c
  1108. --- linux-3.15-rc6/drivers/pci/quirks.c 2014-05-21 23:42:02.000000000 +0200
  1109. +++ linux-awilliam/drivers/pci/quirks.c 2014-06-23 23:00:25.000000000 +0200
  1110. @@ -3333,58 +3333,82 @@
  1111.     return -ENOTTY;
  1112.  }
  1113.  
  1114. -static struct pci_dev *pci_func_0_dma_source(struct pci_dev *dev)
  1115. +static void quirk_dma_func0_alias(struct pci_dev *dev)
  1116.  {
  1117. -   if (!PCI_FUNC(dev->devfn))
  1118. -       return pci_dev_get(dev);
  1119. -
  1120. -   return pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
  1121. +   if (PCI_FUNC(dev->devfn) != 0) {
  1122. +       dev->dma_alias_devfn = PCI_DEVFN(PCI_SLOT(dev->devfn), 0);
  1123. +       dev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN;
  1124. +   }
  1125.  }
  1126.  
  1127. -static const struct pci_dev_dma_source {
  1128. -   u16 vendor;
  1129. -   u16 device;
  1130. -   struct pci_dev *(*dma_source)(struct pci_dev *dev);
  1131. -} pci_dev_dma_source[] = {
  1132. -   /*
  1133. -    * https://bugzilla.redhat.com/show_bug.cgi?id=605888
  1134. -    *
  1135. -    * Some Ricoh devices use the function 0 source ID for DMA on
  1136. -    * other functions of a multifunction device.  The DMA devices
  1137. -    * is therefore function 0, which will have implications of the
  1138. -    * iommu grouping of these devices.
  1139. -    */
  1140. -   { PCI_VENDOR_ID_RICOH, 0xe822, pci_func_0_dma_source },
  1141. -   { PCI_VENDOR_ID_RICOH, 0xe230, pci_func_0_dma_source },
  1142. -   { PCI_VENDOR_ID_RICOH, 0xe832, pci_func_0_dma_source },
  1143. -   { PCI_VENDOR_ID_RICOH, 0xe476, pci_func_0_dma_source },
  1144. -   { 0 }
  1145. -};
  1146. -
  1147.  /*
  1148. - * IOMMUs with isolation capabilities need to be programmed with the
  1149. - * correct source ID of a device.  In most cases, the source ID matches
  1150. - * the device doing the DMA, but sometimes hardware is broken and will
  1151. - * tag the DMA as being sourced from a different device.  This function
  1152. - * allows that translation.  Note that the reference count of the
  1153. - * returned device is incremented on all paths.
  1154. + * https://bugzilla.redhat.com/show_bug.cgi?id=605888
  1155. + *
  1156. + * Some Ricoh devices use function 0 as the PCIe requester ID for DMA.
  1157.   */
  1158. -struct pci_dev *pci_get_dma_source(struct pci_dev *dev)
  1159. -{
  1160. -   const struct pci_dev_dma_source *i;
  1161. +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_RICOH, 0xe832, quirk_dma_func0_alias);
  1162. +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_RICOH, 0xe476, quirk_dma_func0_alias);
  1163.  
  1164. -   for (i = pci_dev_dma_source; i->dma_source; i++) {
  1165. -       if ((i->vendor == dev->vendor ||
  1166. -            i->vendor == (u16)PCI_ANY_ID) &&
  1167. -           (i->device == dev->device ||
  1168. -            i->device == (u16)PCI_ANY_ID))
  1169. -           return i->dma_source(dev);
  1170. +static void quirk_dma_func1_alias(struct pci_dev *dev)
  1171. +{
  1172. +   if (PCI_FUNC(dev->devfn) != 1) {
  1173. +       dev->dma_alias_devfn = PCI_DEVFN(PCI_SLOT(dev->devfn), 1);
  1174. +       dev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN;
  1175.     }
  1176. -
  1177. -   return pci_dev_get(dev);
  1178.  }
  1179.  
  1180.  /*
  1181. + * Marvell 88SE9123 uses function 1 as the requester ID for DMA.  In some
  1182. + * SKUs function 1 is present and is a legacy IDE controller, in other
  1183. + * SKUs this function is not present, making this a ghost requester.
  1184. + * https://bugzilla.kernel.org/show_bug.cgi?id=42679
  1185. + */
  1186. +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9123,
  1187. +            quirk_dma_func1_alias);
  1188. +/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c14 */
  1189. +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9130,
  1190. +            quirk_dma_func1_alias);
  1191. +/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c47 + c57 */
  1192. +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9172,
  1193. +            quirk_dma_func1_alias);
  1194. +/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c59 */
  1195. +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x917a,
  1196. +            quirk_dma_func1_alias);
  1197. +/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c46 */
  1198. +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x91a0,
  1199. +            quirk_dma_func1_alias);
  1200. +/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c49 */
  1201. +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9230,
  1202. +            quirk_dma_func1_alias);
  1203. +/* https://bugs.gentoo.org/show_bug.cgi?id=497630 */
  1204. +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_JMICRON,
  1205. +            PCI_DEVICE_ID_JMICRON_JMB388_ESD,
  1206. +            quirk_dma_func1_alias);
  1207. +
  1208. +/*
  1209. + * A few PCIe-to-PCI bridges fail to expose a PCIe capability, resulting in
  1210. + * using the wrong DMA alias for the device.  Some of these devices can be
  1211. + * used as either forward or reverse bridges, so we need to test whether the
  1212. + * device is operating in the correct mode.  We could probably apply this
  1213. + * quirk to PCI_ANY_ID, but for now we'll just use known offenders.  The test
  1214. + * is for a non-root, non-PCIe bridge where the upstream device is PCIe and
  1215. + * is not a PCIe-to-PCI bridge, then @pdev is actually a PCIe-to-PCI bridge.
  1216. + */
  1217. +static void quirk_use_pcie_bridge_dma_alias(struct pci_dev *pdev)
  1218. +{
  1219. +   if (!pci_is_root_bus(pdev->bus) &&
  1220. +       pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
  1221. +       !pci_is_pcie(pdev) && pci_is_pcie(pdev->bus->self) &&
  1222. +       pci_pcie_type(pdev->bus->self) != PCI_EXP_TYPE_PCI_BRIDGE)
  1223. +       pdev->dev_flags |= PCI_DEV_FLAG_PCIE_BRIDGE_ALIAS;
  1224. +}
  1225. +/* ASM1083/1085, https://bugzilla.kernel.org/show_bug.cgi?id=44881#c46 */
  1226. +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ASMEDIA, 0x1080,
  1227. +            quirk_use_pcie_bridge_dma_alias);
  1228. +/* Tundra 8113, https://bugzilla.kernel.org/show_bug.cgi?id=44881#c43 */
  1229. +DECLARE_PCI_FIXUP_HEADER(0x10e3, 0x8113, quirk_use_pcie_bridge_dma_alias);
  1230. +
  1231. +/*
  1232.   * AMD has indicated that the devices below do not support peer-to-peer
  1233.   * in any system where they are found in the southbridge with an AMD
  1234.   * IOMMU in the system.  Multifunction devices that do not support
  1235. diff -Naur linux-3.15-rc6/drivers/pci/search.c linux-awilliam/drivers/pci/search.c
  1236. --- linux-3.15-rc6/drivers/pci/search.c 2014-05-21 23:42:02.000000000 +0200
  1237. +++ linux-awilliam/drivers/pci/search.c 2014-06-23 23:00:25.000000000 +0200
  1238. @@ -18,38 +18,90 @@
  1239.  EXPORT_SYMBOL_GPL(pci_bus_sem);
  1240.  
  1241.  /*
  1242. - * find the upstream PCIe-to-PCI bridge of a PCI device
  1243. - * if the device is PCIE, return NULL
  1244. - * if the device isn't connected to a PCIe bridge (that is its parent is a
  1245. - * legacy PCI bridge and the bridge is directly connected to bus 0), return its
  1246. - * parent
  1247. + * pci_for_each_dma_alias - Iterate over DMA aliases for a device
  1248. + * @pdev: starting downstream device
  1249. + * @fn: function to call for each alias
  1250. + * @data: opaque data to pass to @fn
  1251. + *
  1252. + * Starting @pdev, walk up the bus calling @fn for each possible alias
  1253. + * of @pdev at the root bus.
  1254.   */
  1255. -struct pci_dev *
  1256. -pci_find_upstream_pcie_bridge(struct pci_dev *pdev)
  1257. -{
  1258. -   struct pci_dev *tmp = NULL;
  1259. +int pci_for_each_dma_alias(struct pci_dev *pdev,
  1260. +              int (*fn)(struct pci_dev *pdev,
  1261. +                    u16 alias, void *data), void *data)
  1262. +{
  1263. +   struct pci_bus *bus;
  1264. +   int ret;
  1265. +
  1266. +   ret = fn(pdev, PCI_DEVID(pdev->bus->number, pdev->devfn), data);
  1267. +   if (ret)
  1268. +       return ret;
  1269. +
  1270. +   /*
  1271. +    * If the device is broken and uses an alias requester ID for
  1272. +    * DMA, iterate over that too.
  1273. +    */
  1274. +   if (unlikely(pdev->dev_flags & PCI_DEV_FLAGS_DMA_ALIAS_DEVFN)) {
  1275. +       ret = fn(pdev, PCI_DEVID(pdev->bus->number,
  1276. +                    pdev->dma_alias_devfn), data);
  1277. +       if (ret)
  1278. +           return ret;
  1279. +   }
  1280.  
  1281. -   if (pci_is_pcie(pdev))
  1282. -       return NULL;
  1283. -   while (1) {
  1284. -       if (pci_is_root_bus(pdev->bus))
  1285. -           break;
  1286. -       pdev = pdev->bus->self;
  1287. -       /* a p2p bridge */
  1288. -       if (!pci_is_pcie(pdev)) {
  1289. -           tmp = pdev;
  1290. +   for (bus = pdev->bus; !pci_is_root_bus(bus); bus = bus->parent) {
  1291. +       struct pci_dev *tmp;
  1292. +
  1293. +       /* Skip virtual buses */
  1294. +       if (!bus->self)
  1295.             continue;
  1296. +
  1297. +       tmp = bus->self;
  1298. +
  1299. +       /*
  1300. +        * PCIe-to-PCI/X bridges alias transactions from downstream
  1301. +        * devices using the subordinate bus number (PCI Express to
  1302. +        * PCI/PCI-X Bridge Spec, rev 1.0, sec 2.3).  For all cases
  1303. +        * where the upstream bus is PCI/X we alias to the bridge
  1304. +        * (there are various conditions in the previous reference
  1305. +        * where the bridge may take ownership of transactions, even
  1306. +        * when the secondary interface is PCI-X).
  1307. +        */
  1308. +       if (pci_is_pcie(tmp)) {
  1309. +           switch (pci_pcie_type(tmp)) {
  1310. +           case PCI_EXP_TYPE_ROOT_PORT:
  1311. +           case PCI_EXP_TYPE_UPSTREAM:
  1312. +           case PCI_EXP_TYPE_DOWNSTREAM:
  1313. +               continue;
  1314. +           case PCI_EXP_TYPE_PCI_BRIDGE:
  1315. +               ret = fn(tmp,
  1316. +                    PCI_DEVID(tmp->subordinate->number,
  1317. +                          PCI_DEVFN(0, 0)), data);
  1318. +               if (ret)
  1319. +                   return ret;
  1320. +               continue;
  1321. +           case PCI_EXP_TYPE_PCIE_BRIDGE:
  1322. +               ret = fn(tmp,
  1323. +                    PCI_DEVID(tmp->bus->number,
  1324. +                          tmp->devfn), data);
  1325. +               if (ret)
  1326. +                   return ret;
  1327. +               continue;
  1328. +           }
  1329. +       } else {
  1330. +           if (tmp->dev_flags & PCI_DEV_FLAG_PCIE_BRIDGE_ALIAS)
  1331. +               ret = fn(tmp,
  1332. +                    PCI_DEVID(tmp->subordinate->number,
  1333. +                          PCI_DEVFN(0, 0)), data);
  1334. +           else
  1335. +               ret = fn(tmp,
  1336. +                    PCI_DEVID(tmp->bus->number,
  1337. +                          tmp->devfn), data);
  1338. +           if (ret)
  1339. +               return ret;
  1340.         }
  1341. -       /* PCI device should connect to a PCIe bridge */
  1342. -       if (pci_pcie_type(pdev) != PCI_EXP_TYPE_PCI_BRIDGE) {
  1343. -           /* Busted hardware? */
  1344. -           WARN_ON_ONCE(1);
  1345. -           return NULL;
  1346. -       }
  1347. -       return pdev;
  1348.     }
  1349.  
  1350. -   return tmp;
  1351. +   return ret;
  1352.  }
  1353.  
  1354.  static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr)
  1355. diff -Naur linux-3.15-rc6/include/linux/iommu.h linux-awilliam/include/linux/iommu.h
  1356. --- linux-3.15-rc6/include/linux/iommu.h    2014-05-21 23:42:02.000000000 +0200
  1357. +++ linux-awilliam/include/linux/iommu.h    2014-06-23 23:00:25.000000000 +0200
  1358. @@ -181,6 +181,7 @@
  1359.  extern int iommu_group_unregister_notifier(struct iommu_group *group,
  1360.                        struct notifier_block *nb);
  1361.  extern int iommu_group_id(struct iommu_group *group);
  1362. +extern struct iommu_group *iommu_group_get_for_dev(struct device *dev);
  1363.  
  1364.  extern int iommu_domain_get_attr(struct iommu_domain *domain, enum iommu_attr,
  1365.                  void *data);
  1366. diff -Naur linux-3.15-rc6/include/linux/pci.h linux-awilliam/include/linux/pci.h
  1367. --- linux-3.15-rc6/include/linux/pci.h  2014-05-21 23:42:02.000000000 +0200
  1368. +++ linux-awilliam/include/linux/pci.h  2014-06-23 23:00:25.000000000 +0200
  1369. @@ -164,13 +164,17 @@
  1370.     /* INTX_DISABLE in PCI_COMMAND register disables MSI
  1371.      * generation too.
  1372.      */
  1373. -   PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG = (__force pci_dev_flags_t) 1,
  1374. +   PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG = (__force pci_dev_flags_t) (1 << 0),
  1375.     /* Device configuration is irrevocably lost if disabled into D3 */
  1376. -   PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) 2,
  1377. +   PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) (1 << 1),
  1378.     /* Provide indication device is assigned by a Virtual Machine Manager */
  1379. -   PCI_DEV_FLAGS_ASSIGNED = (__force pci_dev_flags_t) 4,
  1380. +   PCI_DEV_FLAGS_ASSIGNED = (__force pci_dev_flags_t) (1 << 2),
  1381.     /* Flag for quirk use to store if quirk-specific ACS is enabled */
  1382. -   PCI_DEV_FLAGS_ACS_ENABLED_QUIRK = (__force pci_dev_flags_t) 8,
  1383. +   PCI_DEV_FLAGS_ACS_ENABLED_QUIRK = (__force pci_dev_flags_t) (1 << 3),
  1384. +   /* Flag to indicate the device uses dma_alias_devfn */
  1385. +   PCI_DEV_FLAGS_DMA_ALIAS_DEVFN = (__force pci_dev_flags_t) (1 << 4),
  1386. +   /* Use a PCIe-to-PCI bridge alias even if !pci_is_pcie */
  1387. +   PCI_DEV_FLAG_PCIE_BRIDGE_ALIAS = (__force pci_dev_flags_t) (1 << 5),
  1388.  };
  1389.  
  1390.  enum pci_irq_reroute_variant {
  1391. @@ -268,6 +272,7 @@
  1392.     u8      rom_base_reg;   /* which config register controls the ROM */
  1393.     u8      pin;        /* which interrupt pin this device uses */
  1394.     u16     pcie_flags_reg; /* cached PCIe Capabilities Register */
  1395. +   u8      dma_alias_devfn;/* devfn of DMA alias, if any */
  1396.  
  1397.     struct pci_driver *driver;  /* which driver has allocated this device */
  1398.     u64     dma_mask;   /* Mask of the bits of bus address this
  1399. @@ -1528,16 +1533,11 @@
  1400.  
  1401.  #ifdef CONFIG_PCI_QUIRKS
  1402.  void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
  1403. -struct pci_dev *pci_get_dma_source(struct pci_dev *dev);
  1404.  int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags);
  1405.  void pci_dev_specific_enable_acs(struct pci_dev *dev);
  1406.  #else
  1407.  static inline void pci_fixup_device(enum pci_fixup_pass pass,
  1408.                     struct pci_dev *dev) { }
  1409. -static inline struct pci_dev *pci_get_dma_source(struct pci_dev *dev)
  1410. -{
  1411. -   return pci_dev_get(dev);
  1412. -}
  1413.  static inline int pci_dev_specific_acs_enabled(struct pci_dev *dev,
  1414.                            u16 acs_flags)
  1415.  {
  1416. @@ -1795,15 +1795,8 @@
  1417.  }
  1418.  #endif
  1419.  
  1420. -/**
  1421. - * pci_find_upstream_pcie_bridge - find upstream PCIe-to-PCI bridge of a device
  1422. - * @pdev: the PCI device
  1423. - *
  1424. - * if the device is PCIE, return NULL
  1425. - * if the device isn't connected to a PCIe bridge (that is its parent is a
  1426. - * legacy PCI bridge and the bridge is directly connected to bus 0), return its
  1427. - * parent
  1428. - */
  1429. -struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev);
  1430. +int pci_for_each_dma_alias(struct pci_dev *pdev,
  1431. +              int (*fn)(struct pci_dev *pdev,
  1432. +                    u16 alias, void *data), void *data);
  1433.  
  1434.  #endif /* LINUX_PCI_H */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement