kfd_iommu.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /*
  2. * Copyright 2018 Advanced Micro Devices, Inc.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. * OTHER DEALINGS IN THE SOFTWARE.
  21. */
  22. #include <linux/kconfig.h>
  23. #if IS_REACHABLE(CONFIG_AMD_IOMMU_V2)
  24. #include <linux/printk.h>
  25. #include <linux/device.h>
  26. #include <linux/slab.h>
  27. #include <linux/pci.h>
  28. #include <linux/amd-iommu.h>
  29. #include "kfd_priv.h"
  30. #include "kfd_dbgmgr.h"
  31. #include "kfd_topology.h"
  32. #include "kfd_iommu.h"
  33. static const u32 required_iommu_flags = AMD_IOMMU_DEVICE_FLAG_ATS_SUP |
  34. AMD_IOMMU_DEVICE_FLAG_PRI_SUP |
  35. AMD_IOMMU_DEVICE_FLAG_PASID_SUP;
  36. /** kfd_iommu_check_device - Check whether IOMMU is available for device
  37. */
  38. int kfd_iommu_check_device(struct kfd_dev *kfd)
  39. {
  40. struct amd_iommu_device_info iommu_info;
  41. int err;
  42. if (!kfd->device_info->needs_iommu_device)
  43. return -ENODEV;
  44. iommu_info.flags = 0;
  45. err = amd_iommu_device_info(kfd->pdev, &iommu_info);
  46. if (err)
  47. return err;
  48. if ((iommu_info.flags & required_iommu_flags) != required_iommu_flags)
  49. return -ENODEV;
  50. return 0;
  51. }
  52. /** kfd_iommu_device_init - Initialize IOMMU for device
  53. */
  54. int kfd_iommu_device_init(struct kfd_dev *kfd)
  55. {
  56. struct amd_iommu_device_info iommu_info;
  57. unsigned int pasid_limit;
  58. int err;
  59. struct kfd_topology_device *top_dev;
  60. top_dev = kfd_topology_device_by_id(kfd->id);
  61. /*
  62. * Overwrite ATS capability according to needs_iommu_device to fix
  63. * potential missing corresponding bit in CRAT of BIOS.
  64. */
  65. if (!kfd->device_info->needs_iommu_device) {
  66. top_dev->node_props.capability &= ~HSA_CAP_ATS_PRESENT;
  67. return 0;
  68. }
  69. top_dev->node_props.capability |= HSA_CAP_ATS_PRESENT;
  70. iommu_info.flags = 0;
  71. err = amd_iommu_device_info(kfd->pdev, &iommu_info);
  72. if (err < 0) {
  73. dev_err(kfd_device,
  74. "error getting iommu info. is the iommu enabled?\n");
  75. return -ENODEV;
  76. }
  77. if ((iommu_info.flags & required_iommu_flags) != required_iommu_flags) {
  78. dev_err(kfd_device,
  79. "error required iommu flags ats %i, pri %i, pasid %i\n",
  80. (iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_ATS_SUP) != 0,
  81. (iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_PRI_SUP) != 0,
  82. (iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_PASID_SUP)
  83. != 0);
  84. return -ENODEV;
  85. }
  86. pasid_limit = min_t(unsigned int,
  87. (unsigned int)(1 << kfd->device_info->max_pasid_bits),
  88. iommu_info.max_pasids);
  89. if (!kfd_set_pasid_limit(pasid_limit)) {
  90. dev_err(kfd_device, "error setting pasid limit\n");
  91. return -EBUSY;
  92. }
  93. return 0;
  94. }
  95. /** kfd_iommu_bind_process_to_device - Have the IOMMU bind a process
  96. *
  97. * Binds the given process to the given device using its PASID. This
  98. * enables IOMMUv2 address translation for the process on the device.
  99. *
  100. * This function assumes that the process mutex is held.
  101. */
  102. int kfd_iommu_bind_process_to_device(struct kfd_process_device *pdd)
  103. {
  104. struct kfd_dev *dev = pdd->dev;
  105. struct kfd_process *p = pdd->process;
  106. int err;
  107. if (!dev->device_info->needs_iommu_device || pdd->bound == PDD_BOUND)
  108. return 0;
  109. if (unlikely(pdd->bound == PDD_BOUND_SUSPENDED)) {
  110. pr_err("Binding PDD_BOUND_SUSPENDED pdd is unexpected!\n");
  111. return -EINVAL;
  112. }
  113. err = amd_iommu_bind_pasid(dev->pdev, p->pasid, p->lead_thread);
  114. if (!err)
  115. pdd->bound = PDD_BOUND;
  116. return err;
  117. }
  118. /** kfd_iommu_unbind_process - Unbind process from all devices
  119. *
  120. * This removes all IOMMU device bindings of the process. To be used
  121. * before process termination.
  122. */
  123. void kfd_iommu_unbind_process(struct kfd_process *p)
  124. {
  125. struct kfd_process_device *pdd;
  126. list_for_each_entry(pdd, &p->per_device_data, per_device_list)
  127. if (pdd->bound == PDD_BOUND)
  128. amd_iommu_unbind_pasid(pdd->dev->pdev, p->pasid);
  129. }
  130. /* Callback for process shutdown invoked by the IOMMU driver */
  131. static void iommu_pasid_shutdown_callback(struct pci_dev *pdev, int pasid)
  132. {
  133. struct kfd_dev *dev = kfd_device_by_pci_dev(pdev);
  134. struct kfd_process *p;
  135. struct kfd_process_device *pdd;
  136. if (!dev)
  137. return;
  138. /*
  139. * Look for the process that matches the pasid. If there is no such
  140. * process, we either released it in amdkfd's own notifier, or there
  141. * is a bug. Unfortunately, there is no way to tell...
  142. */
  143. p = kfd_lookup_process_by_pasid(pasid);
  144. if (!p)
  145. return;
  146. pr_debug("Unbinding process %d from IOMMU\n", pasid);
  147. mutex_lock(kfd_get_dbgmgr_mutex());
  148. if (dev->dbgmgr && dev->dbgmgr->pasid == p->pasid) {
  149. if (!kfd_dbgmgr_unregister(dev->dbgmgr, p)) {
  150. kfd_dbgmgr_destroy(dev->dbgmgr);
  151. dev->dbgmgr = NULL;
  152. }
  153. }
  154. mutex_unlock(kfd_get_dbgmgr_mutex());
  155. mutex_lock(&p->mutex);
  156. pdd = kfd_get_process_device_data(dev, p);
  157. if (pdd)
  158. /* For GPU relying on IOMMU, we need to dequeue here
  159. * when PASID is still bound.
  160. */
  161. kfd_process_dequeue_from_device(pdd);
  162. mutex_unlock(&p->mutex);
  163. kfd_unref_process(p);
  164. }
  165. /* This function called by IOMMU driver on PPR failure */
  166. static int iommu_invalid_ppr_cb(struct pci_dev *pdev, int pasid,
  167. unsigned long address, u16 flags)
  168. {
  169. struct kfd_dev *dev;
  170. dev_warn_ratelimited(kfd_device,
  171. "Invalid PPR device %x:%x.%x pasid %d address 0x%lX flags 0x%X",
  172. PCI_BUS_NUM(pdev->devfn),
  173. PCI_SLOT(pdev->devfn),
  174. PCI_FUNC(pdev->devfn),
  175. pasid,
  176. address,
  177. flags);
  178. dev = kfd_device_by_pci_dev(pdev);
  179. if (!WARN_ON(!dev))
  180. kfd_signal_iommu_event(dev, pasid, address,
  181. flags & PPR_FAULT_WRITE, flags & PPR_FAULT_EXEC);
  182. return AMD_IOMMU_INV_PRI_RSP_INVALID;
  183. }
  184. /*
  185. * Bind processes do the device that have been temporarily unbound
  186. * (PDD_BOUND_SUSPENDED) in kfd_unbind_processes_from_device.
  187. */
  188. static int kfd_bind_processes_to_device(struct kfd_dev *kfd)
  189. {
  190. struct kfd_process_device *pdd;
  191. struct kfd_process *p;
  192. unsigned int temp;
  193. int err = 0;
  194. int idx = srcu_read_lock(&kfd_processes_srcu);
  195. hash_for_each_rcu(kfd_processes_table, temp, p, kfd_processes) {
  196. mutex_lock(&p->mutex);
  197. pdd = kfd_get_process_device_data(kfd, p);
  198. if (WARN_ON(!pdd) || pdd->bound != PDD_BOUND_SUSPENDED) {
  199. mutex_unlock(&p->mutex);
  200. continue;
  201. }
  202. err = amd_iommu_bind_pasid(kfd->pdev, p->pasid,
  203. p->lead_thread);
  204. if (err < 0) {
  205. pr_err("Unexpected pasid %d binding failure\n",
  206. p->pasid);
  207. mutex_unlock(&p->mutex);
  208. break;
  209. }
  210. pdd->bound = PDD_BOUND;
  211. mutex_unlock(&p->mutex);
  212. }
  213. srcu_read_unlock(&kfd_processes_srcu, idx);
  214. return err;
  215. }
  216. /*
  217. * Mark currently bound processes as PDD_BOUND_SUSPENDED. These
  218. * processes will be restored to PDD_BOUND state in
  219. * kfd_bind_processes_to_device.
  220. */
  221. static void kfd_unbind_processes_from_device(struct kfd_dev *kfd)
  222. {
  223. struct kfd_process_device *pdd;
  224. struct kfd_process *p;
  225. unsigned int temp;
  226. int idx = srcu_read_lock(&kfd_processes_srcu);
  227. hash_for_each_rcu(kfd_processes_table, temp, p, kfd_processes) {
  228. mutex_lock(&p->mutex);
  229. pdd = kfd_get_process_device_data(kfd, p);
  230. if (WARN_ON(!pdd)) {
  231. mutex_unlock(&p->mutex);
  232. continue;
  233. }
  234. if (pdd->bound == PDD_BOUND)
  235. pdd->bound = PDD_BOUND_SUSPENDED;
  236. mutex_unlock(&p->mutex);
  237. }
  238. srcu_read_unlock(&kfd_processes_srcu, idx);
  239. }
  240. /** kfd_iommu_suspend - Prepare IOMMU for suspend
  241. *
  242. * This unbinds processes from the device and disables the IOMMU for
  243. * the device.
  244. */
  245. void kfd_iommu_suspend(struct kfd_dev *kfd)
  246. {
  247. if (!kfd->device_info->needs_iommu_device)
  248. return;
  249. kfd_unbind_processes_from_device(kfd);
  250. amd_iommu_set_invalidate_ctx_cb(kfd->pdev, NULL);
  251. amd_iommu_set_invalid_ppr_cb(kfd->pdev, NULL);
  252. amd_iommu_free_device(kfd->pdev);
  253. }
  254. /** kfd_iommu_resume - Restore IOMMU after resume
  255. *
  256. * This reinitializes the IOMMU for the device and re-binds previously
  257. * suspended processes to the device.
  258. */
  259. int kfd_iommu_resume(struct kfd_dev *kfd)
  260. {
  261. unsigned int pasid_limit;
  262. int err;
  263. if (!kfd->device_info->needs_iommu_device)
  264. return 0;
  265. pasid_limit = kfd_get_pasid_limit();
  266. err = amd_iommu_init_device(kfd->pdev, pasid_limit);
  267. if (err)
  268. return -ENXIO;
  269. amd_iommu_set_invalidate_ctx_cb(kfd->pdev,
  270. iommu_pasid_shutdown_callback);
  271. amd_iommu_set_invalid_ppr_cb(kfd->pdev,
  272. iommu_invalid_ppr_cb);
  273. err = kfd_bind_processes_to_device(kfd);
  274. if (err) {
  275. amd_iommu_set_invalidate_ctx_cb(kfd->pdev, NULL);
  276. amd_iommu_set_invalid_ppr_cb(kfd->pdev, NULL);
  277. amd_iommu_free_device(kfd->pdev);
  278. return err;
  279. }
  280. return 0;
  281. }
  282. extern bool amd_iommu_pc_supported(void);
  283. extern u8 amd_iommu_pc_get_max_banks(u16 devid);
  284. extern u8 amd_iommu_pc_get_max_counters(u16 devid);
  285. /** kfd_iommu_add_perf_counters - Add IOMMU performance counters to topology
  286. */
  287. int kfd_iommu_add_perf_counters(struct kfd_topology_device *kdev)
  288. {
  289. struct kfd_perf_properties *props;
  290. if (!(kdev->node_props.capability & HSA_CAP_ATS_PRESENT))
  291. return 0;
  292. if (!amd_iommu_pc_supported())
  293. return 0;
  294. props = kfd_alloc_struct(props);
  295. if (!props)
  296. return -ENOMEM;
  297. strcpy(props->block_name, "iommu");
  298. props->max_concurrent = amd_iommu_pc_get_max_banks(0) *
  299. amd_iommu_pc_get_max_counters(0); /* assume one iommu */
  300. list_add_tail(&props->list, &kdev->perf_props);
  301. return 0;
  302. }
  303. #endif