kfd_chardev.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. /*
  2. * Copyright 2014 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/device.h>
  23. #include <linux/export.h>
  24. #include <linux/err.h>
  25. #include <linux/fs.h>
  26. #include <linux/sched.h>
  27. #include <linux/slab.h>
  28. #include <linux/uaccess.h>
  29. #include <linux/compat.h>
  30. #include <uapi/linux/kfd_ioctl.h>
  31. #include <linux/time.h>
  32. #include <linux/mm.h>
  33. #include <linux/uaccess.h>
  34. #include <uapi/asm-generic/mman-common.h>
  35. #include <asm/processor.h>
  36. #include "kfd_priv.h"
  37. #include "kfd_device_queue_manager.h"
  38. static long kfd_ioctl(struct file *, unsigned int, unsigned long);
  39. static int kfd_open(struct inode *, struct file *);
  40. static int kfd_mmap(struct file *, struct vm_area_struct *);
  41. static const char kfd_dev_name[] = "kfd";
  42. static const struct file_operations kfd_fops = {
  43. .owner = THIS_MODULE,
  44. .unlocked_ioctl = kfd_ioctl,
  45. .compat_ioctl = kfd_ioctl,
  46. .open = kfd_open,
  47. .mmap = kfd_mmap,
  48. };
  49. static int kfd_char_dev_major = -1;
  50. static struct class *kfd_class;
  51. struct device *kfd_device;
  52. int kfd_chardev_init(void)
  53. {
  54. int err = 0;
  55. kfd_char_dev_major = register_chrdev(0, kfd_dev_name, &kfd_fops);
  56. err = kfd_char_dev_major;
  57. if (err < 0)
  58. goto err_register_chrdev;
  59. kfd_class = class_create(THIS_MODULE, kfd_dev_name);
  60. err = PTR_ERR(kfd_class);
  61. if (IS_ERR(kfd_class))
  62. goto err_class_create;
  63. kfd_device = device_create(kfd_class, NULL,
  64. MKDEV(kfd_char_dev_major, 0),
  65. NULL, kfd_dev_name);
  66. err = PTR_ERR(kfd_device);
  67. if (IS_ERR(kfd_device))
  68. goto err_device_create;
  69. return 0;
  70. err_device_create:
  71. class_destroy(kfd_class);
  72. err_class_create:
  73. unregister_chrdev(kfd_char_dev_major, kfd_dev_name);
  74. err_register_chrdev:
  75. return err;
  76. }
  77. void kfd_chardev_exit(void)
  78. {
  79. device_destroy(kfd_class, MKDEV(kfd_char_dev_major, 0));
  80. class_destroy(kfd_class);
  81. unregister_chrdev(kfd_char_dev_major, kfd_dev_name);
  82. }
  83. struct device *kfd_chardev(void)
  84. {
  85. return kfd_device;
  86. }
  87. static int kfd_open(struct inode *inode, struct file *filep)
  88. {
  89. struct kfd_process *process;
  90. bool is_32bit_user_mode;
  91. if (iminor(inode) != 0)
  92. return -ENODEV;
  93. is_32bit_user_mode = is_compat_task();
  94. if (is_32bit_user_mode == true) {
  95. dev_warn(kfd_device,
  96. "Process %d (32-bit) failed to open /dev/kfd\n"
  97. "32-bit processes are not supported by amdkfd\n",
  98. current->pid);
  99. return -EPERM;
  100. }
  101. process = kfd_create_process(current);
  102. if (IS_ERR(process))
  103. return PTR_ERR(process);
  104. dev_dbg(kfd_device, "process %d opened, compat mode (32 bit) - %d\n",
  105. process->pasid, process->is_32bit_user_mode);
  106. return 0;
  107. }
  108. static long kfd_ioctl_get_version(struct file *filep, struct kfd_process *p,
  109. void __user *arg)
  110. {
  111. struct kfd_ioctl_get_version_args args;
  112. int err = 0;
  113. args.major_version = KFD_IOCTL_MAJOR_VERSION;
  114. args.minor_version = KFD_IOCTL_MINOR_VERSION;
  115. if (copy_to_user(arg, &args, sizeof(args)))
  116. err = -EFAULT;
  117. return err;
  118. }
  119. static int set_queue_properties_from_user(struct queue_properties *q_properties,
  120. struct kfd_ioctl_create_queue_args *args)
  121. {
  122. if (args->queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) {
  123. pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n");
  124. return -EINVAL;
  125. }
  126. if (args->queue_priority > KFD_MAX_QUEUE_PRIORITY) {
  127. pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n");
  128. return -EINVAL;
  129. }
  130. if ((args->ring_base_address) &&
  131. (!access_ok(VERIFY_WRITE,
  132. (const void __user *) args->ring_base_address,
  133. sizeof(uint64_t)))) {
  134. pr_err("kfd: can't access ring base address\n");
  135. return -EFAULT;
  136. }
  137. if (!is_power_of_2(args->ring_size) && (args->ring_size != 0)) {
  138. pr_err("kfd: ring size must be a power of 2 or 0\n");
  139. return -EINVAL;
  140. }
  141. if (!access_ok(VERIFY_WRITE,
  142. (const void __user *) args->read_pointer_address,
  143. sizeof(uint32_t))) {
  144. pr_err("kfd: can't access read pointer\n");
  145. return -EFAULT;
  146. }
  147. if (!access_ok(VERIFY_WRITE,
  148. (const void __user *) args->write_pointer_address,
  149. sizeof(uint32_t))) {
  150. pr_err("kfd: can't access write pointer\n");
  151. return -EFAULT;
  152. }
  153. q_properties->is_interop = false;
  154. q_properties->queue_percent = args->queue_percentage;
  155. q_properties->priority = args->queue_priority;
  156. q_properties->queue_address = args->ring_base_address;
  157. q_properties->queue_size = args->ring_size;
  158. q_properties->read_ptr = (uint32_t *) args->read_pointer_address;
  159. q_properties->write_ptr = (uint32_t *) args->write_pointer_address;
  160. if (args->queue_type == KFD_IOC_QUEUE_TYPE_COMPUTE ||
  161. args->queue_type == KFD_IOC_QUEUE_TYPE_COMPUTE_AQL)
  162. q_properties->type = KFD_QUEUE_TYPE_COMPUTE;
  163. else
  164. return -ENOTSUPP;
  165. if (args->queue_type == KFD_IOC_QUEUE_TYPE_COMPUTE_AQL)
  166. q_properties->format = KFD_QUEUE_FORMAT_AQL;
  167. else
  168. q_properties->format = KFD_QUEUE_FORMAT_PM4;
  169. pr_debug("Queue Percentage (%d, %d)\n",
  170. q_properties->queue_percent, args->queue_percentage);
  171. pr_debug("Queue Priority (%d, %d)\n",
  172. q_properties->priority, args->queue_priority);
  173. pr_debug("Queue Address (0x%llX, 0x%llX)\n",
  174. q_properties->queue_address, args->ring_base_address);
  175. pr_debug("Queue Size (0x%llX, %u)\n",
  176. q_properties->queue_size, args->ring_size);
  177. pr_debug("Queue r/w Pointers (0x%llX, 0x%llX)\n",
  178. (uint64_t) q_properties->read_ptr,
  179. (uint64_t) q_properties->write_ptr);
  180. pr_debug("Queue Format (%d)\n", q_properties->format);
  181. return 0;
  182. }
  183. static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
  184. void __user *arg)
  185. {
  186. struct kfd_ioctl_create_queue_args args;
  187. struct kfd_dev *dev;
  188. int err = 0;
  189. unsigned int queue_id;
  190. struct kfd_process_device *pdd;
  191. struct queue_properties q_properties;
  192. memset(&q_properties, 0, sizeof(struct queue_properties));
  193. if (copy_from_user(&args, arg, sizeof(args)))
  194. return -EFAULT;
  195. pr_debug("kfd: creating queue ioctl\n");
  196. err = set_queue_properties_from_user(&q_properties, &args);
  197. if (err)
  198. return err;
  199. dev = kfd_device_by_id(args.gpu_id);
  200. if (dev == NULL)
  201. return -EINVAL;
  202. mutex_lock(&p->mutex);
  203. pdd = kfd_bind_process_to_device(dev, p);
  204. if (IS_ERR(pdd)) {
  205. err = PTR_ERR(pdd);
  206. goto err_bind_process;
  207. }
  208. pr_debug("kfd: creating queue for PASID %d on GPU 0x%x\n",
  209. p->pasid,
  210. dev->id);
  211. err = pqm_create_queue(&p->pqm, dev, filep, &q_properties, 0,
  212. KFD_QUEUE_TYPE_COMPUTE, &queue_id);
  213. if (err != 0)
  214. goto err_create_queue;
  215. args.queue_id = queue_id;
  216. /* Return gpu_id as doorbell offset for mmap usage */
  217. args.doorbell_offset = args.gpu_id << PAGE_SHIFT;
  218. if (copy_to_user(arg, &args, sizeof(args))) {
  219. err = -EFAULT;
  220. goto err_copy_args_out;
  221. }
  222. mutex_unlock(&p->mutex);
  223. pr_debug("kfd: queue id %d was created successfully\n", args.queue_id);
  224. pr_debug("ring buffer address == 0x%016llX\n",
  225. args.ring_base_address);
  226. pr_debug("read ptr address == 0x%016llX\n",
  227. args.read_pointer_address);
  228. pr_debug("write ptr address == 0x%016llX\n",
  229. args.write_pointer_address);
  230. return 0;
  231. err_copy_args_out:
  232. pqm_destroy_queue(&p->pqm, queue_id);
  233. err_create_queue:
  234. err_bind_process:
  235. mutex_unlock(&p->mutex);
  236. return err;
  237. }
  238. static int kfd_ioctl_destroy_queue(struct file *filp, struct kfd_process *p,
  239. void __user *arg)
  240. {
  241. int retval;
  242. struct kfd_ioctl_destroy_queue_args args;
  243. if (copy_from_user(&args, arg, sizeof(args)))
  244. return -EFAULT;
  245. pr_debug("kfd: destroying queue id %d for PASID %d\n",
  246. args.queue_id,
  247. p->pasid);
  248. mutex_lock(&p->mutex);
  249. retval = pqm_destroy_queue(&p->pqm, args.queue_id);
  250. mutex_unlock(&p->mutex);
  251. return retval;
  252. }
  253. static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p,
  254. void __user *arg)
  255. {
  256. int retval;
  257. struct kfd_ioctl_update_queue_args args;
  258. struct queue_properties properties;
  259. if (copy_from_user(&args, arg, sizeof(args)))
  260. return -EFAULT;
  261. if (args.queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) {
  262. pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n");
  263. return -EINVAL;
  264. }
  265. if (args.queue_priority > KFD_MAX_QUEUE_PRIORITY) {
  266. pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n");
  267. return -EINVAL;
  268. }
  269. if ((args.ring_base_address) &&
  270. (!access_ok(VERIFY_WRITE,
  271. (const void __user *) args.ring_base_address,
  272. sizeof(uint64_t)))) {
  273. pr_err("kfd: can't access ring base address\n");
  274. return -EFAULT;
  275. }
  276. if (!is_power_of_2(args.ring_size) && (args.ring_size != 0)) {
  277. pr_err("kfd: ring size must be a power of 2 or 0\n");
  278. return -EINVAL;
  279. }
  280. properties.queue_address = args.ring_base_address;
  281. properties.queue_size = args.ring_size;
  282. properties.queue_percent = args.queue_percentage;
  283. properties.priority = args.queue_priority;
  284. pr_debug("kfd: updating queue id %d for PASID %d\n",
  285. args.queue_id, p->pasid);
  286. mutex_lock(&p->mutex);
  287. retval = pqm_update_queue(&p->pqm, args.queue_id, &properties);
  288. mutex_unlock(&p->mutex);
  289. return retval;
  290. }
  291. static long kfd_ioctl_set_memory_policy(struct file *filep,
  292. struct kfd_process *p, void __user *arg)
  293. {
  294. struct kfd_ioctl_set_memory_policy_args args;
  295. struct kfd_dev *dev;
  296. int err = 0;
  297. struct kfd_process_device *pdd;
  298. enum cache_policy default_policy, alternate_policy;
  299. if (copy_from_user(&args, arg, sizeof(args)))
  300. return -EFAULT;
  301. if (args.default_policy != KFD_IOC_CACHE_POLICY_COHERENT
  302. && args.default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {
  303. return -EINVAL;
  304. }
  305. if (args.alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT
  306. && args.alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {
  307. return -EINVAL;
  308. }
  309. dev = kfd_device_by_id(args.gpu_id);
  310. if (dev == NULL)
  311. return -EINVAL;
  312. mutex_lock(&p->mutex);
  313. pdd = kfd_bind_process_to_device(dev, p);
  314. if (IS_ERR(pdd)) {
  315. err = PTR_ERR(pdd);
  316. goto out;
  317. }
  318. default_policy = (args.default_policy == KFD_IOC_CACHE_POLICY_COHERENT)
  319. ? cache_policy_coherent : cache_policy_noncoherent;
  320. alternate_policy =
  321. (args.alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT)
  322. ? cache_policy_coherent : cache_policy_noncoherent;
  323. if (!dev->dqm->set_cache_memory_policy(dev->dqm,
  324. &pdd->qpd,
  325. default_policy,
  326. alternate_policy,
  327. (void __user *)args.alternate_aperture_base,
  328. args.alternate_aperture_size))
  329. err = -EINVAL;
  330. out:
  331. mutex_unlock(&p->mutex);
  332. return err;
  333. }
  334. static long kfd_ioctl_get_clock_counters(struct file *filep,
  335. struct kfd_process *p, void __user *arg)
  336. {
  337. struct kfd_ioctl_get_clock_counters_args args;
  338. struct kfd_dev *dev;
  339. struct timespec time;
  340. if (copy_from_user(&args, arg, sizeof(args)))
  341. return -EFAULT;
  342. dev = kfd_device_by_id(args.gpu_id);
  343. if (dev == NULL)
  344. return -EINVAL;
  345. /* Reading GPU clock counter from KGD */
  346. args.gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd);
  347. /* No access to rdtsc. Using raw monotonic time */
  348. getrawmonotonic(&time);
  349. args.cpu_clock_counter = (uint64_t)timespec_to_ns(&time);
  350. get_monotonic_boottime(&time);
  351. args.system_clock_counter = (uint64_t)timespec_to_ns(&time);
  352. /* Since the counter is in nano-seconds we use 1GHz frequency */
  353. args.system_clock_freq = 1000000000;
  354. if (copy_to_user(arg, &args, sizeof(args)))
  355. return -EFAULT;
  356. return 0;
  357. }
  358. static int kfd_ioctl_get_process_apertures(struct file *filp,
  359. struct kfd_process *p, void __user *arg)
  360. {
  361. struct kfd_ioctl_get_process_apertures_args args;
  362. struct kfd_process_device_apertures *pAperture;
  363. struct kfd_process_device *pdd;
  364. dev_dbg(kfd_device, "get apertures for PASID %d", p->pasid);
  365. if (copy_from_user(&args, arg, sizeof(args)))
  366. return -EFAULT;
  367. args.num_of_nodes = 0;
  368. mutex_lock(&p->mutex);
  369. /*if the process-device list isn't empty*/
  370. if (kfd_has_process_device_data(p)) {
  371. /* Run over all pdd of the process */
  372. pdd = kfd_get_first_process_device_data(p);
  373. do {
  374. pAperture = &args.process_apertures[args.num_of_nodes];
  375. pAperture->gpu_id = pdd->dev->id;
  376. pAperture->lds_base = pdd->lds_base;
  377. pAperture->lds_limit = pdd->lds_limit;
  378. pAperture->gpuvm_base = pdd->gpuvm_base;
  379. pAperture->gpuvm_limit = pdd->gpuvm_limit;
  380. pAperture->scratch_base = pdd->scratch_base;
  381. pAperture->scratch_limit = pdd->scratch_limit;
  382. dev_dbg(kfd_device,
  383. "node id %u\n", args.num_of_nodes);
  384. dev_dbg(kfd_device,
  385. "gpu id %u\n", pdd->dev->id);
  386. dev_dbg(kfd_device,
  387. "lds_base %llX\n", pdd->lds_base);
  388. dev_dbg(kfd_device,
  389. "lds_limit %llX\n", pdd->lds_limit);
  390. dev_dbg(kfd_device,
  391. "gpuvm_base %llX\n", pdd->gpuvm_base);
  392. dev_dbg(kfd_device,
  393. "gpuvm_limit %llX\n", pdd->gpuvm_limit);
  394. dev_dbg(kfd_device,
  395. "scratch_base %llX\n", pdd->scratch_base);
  396. dev_dbg(kfd_device,
  397. "scratch_limit %llX\n", pdd->scratch_limit);
  398. args.num_of_nodes++;
  399. } while ((pdd = kfd_get_next_process_device_data(p, pdd)) != NULL &&
  400. (args.num_of_nodes < NUM_OF_SUPPORTED_GPUS));
  401. }
  402. mutex_unlock(&p->mutex);
  403. if (copy_to_user(arg, &args, sizeof(args)))
  404. return -EFAULT;
  405. return 0;
  406. }
  407. static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
  408. {
  409. struct kfd_process *process;
  410. long err = -EINVAL;
  411. dev_dbg(kfd_device,
  412. "ioctl cmd 0x%x (#%d), arg 0x%lx\n",
  413. cmd, _IOC_NR(cmd), arg);
  414. process = kfd_get_process(current);
  415. if (IS_ERR(process))
  416. return PTR_ERR(process);
  417. switch (cmd) {
  418. case KFD_IOC_GET_VERSION:
  419. err = kfd_ioctl_get_version(filep, process, (void __user *)arg);
  420. break;
  421. case KFD_IOC_CREATE_QUEUE:
  422. err = kfd_ioctl_create_queue(filep, process,
  423. (void __user *)arg);
  424. break;
  425. case KFD_IOC_DESTROY_QUEUE:
  426. err = kfd_ioctl_destroy_queue(filep, process,
  427. (void __user *)arg);
  428. break;
  429. case KFD_IOC_SET_MEMORY_POLICY:
  430. err = kfd_ioctl_set_memory_policy(filep, process,
  431. (void __user *)arg);
  432. break;
  433. case KFD_IOC_GET_CLOCK_COUNTERS:
  434. err = kfd_ioctl_get_clock_counters(filep, process,
  435. (void __user *)arg);
  436. break;
  437. case KFD_IOC_GET_PROCESS_APERTURES:
  438. err = kfd_ioctl_get_process_apertures(filep, process,
  439. (void __user *)arg);
  440. break;
  441. case KFD_IOC_UPDATE_QUEUE:
  442. err = kfd_ioctl_update_queue(filep, process,
  443. (void __user *)arg);
  444. break;
  445. default:
  446. dev_err(kfd_device,
  447. "unknown ioctl cmd 0x%x, arg 0x%lx)\n",
  448. cmd, arg);
  449. err = -EINVAL;
  450. break;
  451. }
  452. if (err < 0)
  453. dev_err(kfd_device,
  454. "ioctl error %ld for ioctl cmd 0x%x (#%d)\n",
  455. err, cmd, _IOC_NR(cmd));
  456. return err;
  457. }
  458. static int kfd_mmap(struct file *filp, struct vm_area_struct *vma)
  459. {
  460. struct kfd_process *process;
  461. process = kfd_get_process(current);
  462. if (IS_ERR(process))
  463. return PTR_ERR(process);
  464. return kfd_doorbell_mmap(process, vma);
  465. }