viot.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Virtual I/O topology
  4. *
  5. * The Virtual I/O Translation Table (VIOT) describes the topology of
  6. * para-virtual IOMMUs and the endpoints they manage. The OS uses it to
  7. * initialize devices in the right order, preventing endpoints from issuing DMA
  8. * before their IOMMU is ready.
  9. *
  10. * When binding a driver to a device, before calling the device driver's probe()
  11. * method, the driver infrastructure calls dma_configure(). At that point the
  12. * VIOT driver looks for an IOMMU associated to the device in the VIOT table.
  13. * If an IOMMU exists and has been initialized, the VIOT driver initializes the
  14. * device's IOMMU fwspec, allowing the DMA infrastructure to invoke the IOMMU
  15. * ops when the device driver configures DMA mappings. If an IOMMU exists and
  16. * hasn't yet been initialized, VIOT returns -EPROBE_DEFER to postpone probing
  17. * the device until the IOMMU is available.
  18. */
  19. #define pr_fmt(fmt) "ACPI: VIOT: " fmt
  20. #include <linux/acpi_viot.h>
  21. #include <linux/fwnode.h>
  22. #include <linux/iommu.h>
  23. #include <linux/list.h>
  24. #include <linux/pci.h>
  25. #include <linux/platform_device.h>
  26. struct viot_iommu {
  27. /* Node offset within the table */
  28. unsigned int offset;
  29. struct fwnode_handle *fwnode;
  30. struct list_head list;
  31. };
  32. struct viot_endpoint {
  33. union {
  34. /* PCI range */
  35. struct {
  36. u16 segment_start;
  37. u16 segment_end;
  38. u16 bdf_start;
  39. u16 bdf_end;
  40. };
  41. /* MMIO */
  42. u64 address;
  43. };
  44. u32 endpoint_id;
  45. struct viot_iommu *viommu;
  46. struct list_head list;
  47. };
  48. static struct acpi_table_viot *viot;
  49. static LIST_HEAD(viot_iommus);
  50. static LIST_HEAD(viot_pci_ranges);
  51. static LIST_HEAD(viot_mmio_endpoints);
  52. static int __init viot_check_bounds(const struct acpi_viot_header *hdr)
  53. {
  54. struct acpi_viot_header *start, *end, *hdr_end;
  55. start = ACPI_ADD_PTR(struct acpi_viot_header, viot,
  56. max_t(size_t, sizeof(*viot), viot->node_offset));
  57. end = ACPI_ADD_PTR(struct acpi_viot_header, viot, viot->header.length);
  58. hdr_end = ACPI_ADD_PTR(struct acpi_viot_header, hdr, sizeof(*hdr));
  59. if (hdr < start || hdr_end > end) {
  60. pr_err(FW_BUG "Node pointer overflows\n");
  61. return -EOVERFLOW;
  62. }
  63. if (hdr->length < sizeof(*hdr)) {
  64. pr_err(FW_BUG "Empty node\n");
  65. return -EINVAL;
  66. }
  67. return 0;
  68. }
  69. static int __init viot_get_pci_iommu_fwnode(struct viot_iommu *viommu,
  70. u16 segment, u16 bdf)
  71. {
  72. struct pci_dev *pdev;
  73. struct fwnode_handle *fwnode;
  74. pdev = pci_get_domain_bus_and_slot(segment, PCI_BUS_NUM(bdf),
  75. bdf & 0xff);
  76. if (!pdev) {
  77. pr_err("Could not find PCI IOMMU\n");
  78. return -ENODEV;
  79. }
  80. fwnode = dev_fwnode(&pdev->dev);
  81. if (!fwnode) {
  82. /*
  83. * PCI devices aren't necessarily described by ACPI. Create a
  84. * fwnode so the IOMMU subsystem can identify this device.
  85. */
  86. fwnode = acpi_alloc_fwnode_static();
  87. if (!fwnode) {
  88. pci_dev_put(pdev);
  89. return -ENOMEM;
  90. }
  91. set_primary_fwnode(&pdev->dev, fwnode);
  92. }
  93. viommu->fwnode = dev_fwnode(&pdev->dev);
  94. pci_dev_put(pdev);
  95. return 0;
  96. }
  97. static int __init viot_get_mmio_iommu_fwnode(struct viot_iommu *viommu,
  98. u64 address)
  99. {
  100. struct acpi_device *adev;
  101. struct resource res = {
  102. .start = address,
  103. .end = address,
  104. .flags = IORESOURCE_MEM,
  105. };
  106. adev = acpi_resource_consumer(&res);
  107. if (!adev) {
  108. pr_err("Could not find MMIO IOMMU\n");
  109. return -EINVAL;
  110. }
  111. viommu->fwnode = &adev->fwnode;
  112. return 0;
  113. }
  114. static struct viot_iommu * __init viot_get_iommu(unsigned int offset)
  115. {
  116. int ret;
  117. struct viot_iommu *viommu;
  118. struct acpi_viot_header *hdr = ACPI_ADD_PTR(struct acpi_viot_header,
  119. viot, offset);
  120. union {
  121. struct acpi_viot_virtio_iommu_pci pci;
  122. struct acpi_viot_virtio_iommu_mmio mmio;
  123. } *node = (void *)hdr;
  124. list_for_each_entry(viommu, &viot_iommus, list)
  125. if (viommu->offset == offset)
  126. return viommu;
  127. if (viot_check_bounds(hdr))
  128. return NULL;
  129. viommu = kzalloc(sizeof(*viommu), GFP_KERNEL);
  130. if (!viommu)
  131. return NULL;
  132. viommu->offset = offset;
  133. switch (hdr->type) {
  134. case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI:
  135. if (hdr->length < sizeof(node->pci))
  136. goto err_free;
  137. ret = viot_get_pci_iommu_fwnode(viommu, node->pci.segment,
  138. node->pci.bdf);
  139. break;
  140. case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO:
  141. if (hdr->length < sizeof(node->mmio))
  142. goto err_free;
  143. ret = viot_get_mmio_iommu_fwnode(viommu,
  144. node->mmio.base_address);
  145. break;
  146. default:
  147. ret = -EINVAL;
  148. }
  149. if (ret)
  150. goto err_free;
  151. list_add(&viommu->list, &viot_iommus);
  152. return viommu;
  153. err_free:
  154. kfree(viommu);
  155. return NULL;
  156. }
  157. static int __init viot_parse_node(const struct acpi_viot_header *hdr)
  158. {
  159. int ret = -EINVAL;
  160. struct list_head *list;
  161. struct viot_endpoint *ep;
  162. union {
  163. struct acpi_viot_mmio mmio;
  164. struct acpi_viot_pci_range pci;
  165. } *node = (void *)hdr;
  166. if (viot_check_bounds(hdr))
  167. return -EINVAL;
  168. if (hdr->type == ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI ||
  169. hdr->type == ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO)
  170. return 0;
  171. ep = kzalloc(sizeof(*ep), GFP_KERNEL);
  172. if (!ep)
  173. return -ENOMEM;
  174. switch (hdr->type) {
  175. case ACPI_VIOT_NODE_PCI_RANGE:
  176. if (hdr->length < sizeof(node->pci)) {
  177. pr_err(FW_BUG "Invalid PCI node size\n");
  178. goto err_free;
  179. }
  180. ep->segment_start = node->pci.segment_start;
  181. ep->segment_end = node->pci.segment_end;
  182. ep->bdf_start = node->pci.bdf_start;
  183. ep->bdf_end = node->pci.bdf_end;
  184. ep->endpoint_id = node->pci.endpoint_start;
  185. ep->viommu = viot_get_iommu(node->pci.output_node);
  186. list = &viot_pci_ranges;
  187. break;
  188. case ACPI_VIOT_NODE_MMIO:
  189. if (hdr->length < sizeof(node->mmio)) {
  190. pr_err(FW_BUG "Invalid MMIO node size\n");
  191. goto err_free;
  192. }
  193. ep->address = node->mmio.base_address;
  194. ep->endpoint_id = node->mmio.endpoint;
  195. ep->viommu = viot_get_iommu(node->mmio.output_node);
  196. list = &viot_mmio_endpoints;
  197. break;
  198. default:
  199. pr_warn("Unsupported node %x\n", hdr->type);
  200. ret = 0;
  201. goto err_free;
  202. }
  203. if (!ep->viommu) {
  204. pr_warn("No IOMMU node found\n");
  205. /*
  206. * A future version of the table may use the node for other
  207. * purposes. Keep parsing.
  208. */
  209. ret = 0;
  210. goto err_free;
  211. }
  212. list_add(&ep->list, list);
  213. return 0;
  214. err_free:
  215. kfree(ep);
  216. return ret;
  217. }
  218. /**
  219. * acpi_viot_early_init - Test the presence of VIOT and enable ACS
  220. *
  221. * If the VIOT does exist, ACS must be enabled. This cannot be
  222. * done in acpi_viot_init() which is called after the bus scan
  223. */
  224. void __init acpi_viot_early_init(void)
  225. {
  226. #ifdef CONFIG_PCI
  227. acpi_status status;
  228. struct acpi_table_header *hdr;
  229. status = acpi_get_table(ACPI_SIG_VIOT, 0, &hdr);
  230. if (ACPI_FAILURE(status))
  231. return;
  232. pci_request_acs();
  233. acpi_put_table(hdr);
  234. #endif
  235. }
  236. /**
  237. * acpi_viot_init - Parse the VIOT table
  238. *
  239. * Parse the VIOT table, prepare the list of endpoints to be used during DMA
  240. * setup of devices.
  241. */
  242. void __init acpi_viot_init(void)
  243. {
  244. int i;
  245. acpi_status status;
  246. struct acpi_table_header *hdr;
  247. struct acpi_viot_header *node;
  248. status = acpi_get_table(ACPI_SIG_VIOT, 0, &hdr);
  249. if (ACPI_FAILURE(status)) {
  250. if (status != AE_NOT_FOUND) {
  251. const char *msg = acpi_format_exception(status);
  252. pr_err("Failed to get table, %s\n", msg);
  253. }
  254. return;
  255. }
  256. viot = (void *)hdr;
  257. node = ACPI_ADD_PTR(struct acpi_viot_header, viot, viot->node_offset);
  258. for (i = 0; i < viot->node_count; i++) {
  259. if (viot_parse_node(node))
  260. return;
  261. node = ACPI_ADD_PTR(struct acpi_viot_header, node,
  262. node->length);
  263. }
  264. acpi_put_table(hdr);
  265. }
  266. static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
  267. u32 epid)
  268. {
  269. const struct iommu_ops *ops;
  270. if (!viommu)
  271. return -ENODEV;
  272. /* We're not translating ourself */
  273. if (device_match_fwnode(dev, viommu->fwnode))
  274. return -EINVAL;
  275. ops = iommu_ops_from_fwnode(viommu->fwnode);
  276. if (!ops)
  277. return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
  278. -EPROBE_DEFER : -ENODEV;
  279. return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
  280. }
  281. static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
  282. {
  283. u32 epid;
  284. struct viot_endpoint *ep;
  285. struct device *aliased_dev = data;
  286. u32 domain_nr = pci_domain_nr(pdev->bus);
  287. list_for_each_entry(ep, &viot_pci_ranges, list) {
  288. if (domain_nr >= ep->segment_start &&
  289. domain_nr <= ep->segment_end &&
  290. dev_id >= ep->bdf_start &&
  291. dev_id <= ep->bdf_end) {
  292. epid = ((domain_nr - ep->segment_start) << 16) +
  293. dev_id - ep->bdf_start + ep->endpoint_id;
  294. return viot_dev_iommu_init(aliased_dev, ep->viommu,
  295. epid);
  296. }
  297. }
  298. return -ENODEV;
  299. }
  300. static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
  301. {
  302. struct resource *mem;
  303. struct viot_endpoint *ep;
  304. mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  305. if (!mem)
  306. return -ENODEV;
  307. list_for_each_entry(ep, &viot_mmio_endpoints, list) {
  308. if (ep->address == mem->start)
  309. return viot_dev_iommu_init(&pdev->dev, ep->viommu,
  310. ep->endpoint_id);
  311. }
  312. return -ENODEV;
  313. }
  314. /**
  315. * viot_iommu_configure - Setup IOMMU ops for an endpoint described by VIOT
  316. * @dev: the endpoint
  317. *
  318. * Return: 0 on success, <0 on failure
  319. */
  320. int viot_iommu_configure(struct device *dev)
  321. {
  322. if (dev_is_pci(dev))
  323. return pci_for_each_dma_alias(to_pci_dev(dev),
  324. viot_pci_dev_iommu_init, dev);
  325. else if (dev_is_platform(dev))
  326. return viot_mmio_dev_iommu_init(to_platform_device(dev));
  327. return -ENODEV;
  328. }