aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_chardev.c315
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c15
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c2
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_priv.h18
-rw-r--r--drivers/gpu/drm/amd/include/kgd_kfd_interface.h2
-rw-r--r--drivers/gpu/drm/radeon/cikd.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_kfd.c11
-rw-r--r--include/uapi/linux/kfd_ioctl.h37
8 files changed, 235 insertions, 167 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index fe5c543599b0..fcfdf23e1913 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -126,17 +126,14 @@ static int kfd_open(struct inode *inode, struct file *filep)
126 return 0; 126 return 0;
127} 127}
128 128
129static long kfd_ioctl_get_version(struct file *filep, struct kfd_process *p, 129static int kfd_ioctl_get_version(struct file *filep, struct kfd_process *p,
130 void __user *arg) 130 void *data)
131{ 131{
132 struct kfd_ioctl_get_version_args args; 132 struct kfd_ioctl_get_version_args *args = data;
133 int err = 0; 133 int err = 0;
134 134
135 args.major_version = KFD_IOCTL_MAJOR_VERSION; 135 args->major_version = KFD_IOCTL_MAJOR_VERSION;
136 args.minor_version = KFD_IOCTL_MINOR_VERSION; 136 args->minor_version = KFD_IOCTL_MINOR_VERSION;
137
138 if (copy_to_user(arg, &args, sizeof(args)))
139 err = -EFAULT;
140 137
141 return err; 138 return err;
142} 139}
@@ -220,10 +217,10 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
220 return 0; 217 return 0;
221} 218}
222 219
223static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, 220static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
224 void __user *arg) 221 void *data)
225{ 222{
226 struct kfd_ioctl_create_queue_args args; 223 struct kfd_ioctl_create_queue_args *args = data;
227 struct kfd_dev *dev; 224 struct kfd_dev *dev;
228 int err = 0; 225 int err = 0;
229 unsigned int queue_id; 226 unsigned int queue_id;
@@ -232,16 +229,13 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
232 229
233 memset(&q_properties, 0, sizeof(struct queue_properties)); 230 memset(&q_properties, 0, sizeof(struct queue_properties));
234 231
235 if (copy_from_user(&args, arg, sizeof(args)))
236 return -EFAULT;
237
238 pr_debug("kfd: creating queue ioctl\n"); 232 pr_debug("kfd: creating queue ioctl\n");
239 233
240 err = set_queue_properties_from_user(&q_properties, &args); 234 err = set_queue_properties_from_user(&q_properties, args);
241 if (err) 235 if (err)
242 return err; 236 return err;
243 237
244 dev = kfd_device_by_id(args.gpu_id); 238 dev = kfd_device_by_id(args->gpu_id);
245 if (dev == NULL) 239 if (dev == NULL)
246 return -EINVAL; 240 return -EINVAL;
247 241
@@ -249,7 +243,7 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
249 243
250 pdd = kfd_bind_process_to_device(dev, p); 244 pdd = kfd_bind_process_to_device(dev, p);
251 if (IS_ERR(pdd)) { 245 if (IS_ERR(pdd)) {
252 err = PTR_ERR(pdd); 246 err = -ESRCH;
253 goto err_bind_process; 247 goto err_bind_process;
254 } 248 }
255 249
@@ -262,33 +256,26 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
262 if (err != 0) 256 if (err != 0)
263 goto err_create_queue; 257 goto err_create_queue;
264 258
265 args.queue_id = queue_id; 259 args->queue_id = queue_id;
266 260
267 /* Return gpu_id as doorbell offset for mmap usage */ 261 /* Return gpu_id as doorbell offset for mmap usage */
268 args.doorbell_offset = args.gpu_id << PAGE_SHIFT; 262 args->doorbell_offset = args->gpu_id << PAGE_SHIFT;
269
270 if (copy_to_user(arg, &args, sizeof(args))) {
271 err = -EFAULT;
272 goto err_copy_args_out;
273 }
274 263
275 mutex_unlock(&p->mutex); 264 mutex_unlock(&p->mutex);
276 265
277 pr_debug("kfd: queue id %d was created successfully\n", args.queue_id); 266 pr_debug("kfd: queue id %d was created successfully\n", args->queue_id);
278 267
279 pr_debug("ring buffer address == 0x%016llX\n", 268 pr_debug("ring buffer address == 0x%016llX\n",
280 args.ring_base_address); 269 args->ring_base_address);
281 270
282 pr_debug("read ptr address == 0x%016llX\n", 271 pr_debug("read ptr address == 0x%016llX\n",
283 args.read_pointer_address); 272 args->read_pointer_address);
284 273
285 pr_debug("write ptr address == 0x%016llX\n", 274 pr_debug("write ptr address == 0x%016llX\n",
286 args.write_pointer_address); 275 args->write_pointer_address);
287 276
288 return 0; 277 return 0;
289 278
290err_copy_args_out:
291 pqm_destroy_queue(&p->pqm, queue_id);
292err_create_queue: 279err_create_queue:
293err_bind_process: 280err_bind_process:
294 mutex_unlock(&p->mutex); 281 mutex_unlock(&p->mutex);
@@ -296,99 +283,90 @@ err_bind_process:
296} 283}
297 284
298static int kfd_ioctl_destroy_queue(struct file *filp, struct kfd_process *p, 285static int kfd_ioctl_destroy_queue(struct file *filp, struct kfd_process *p,
299 void __user *arg) 286 void *data)
300{ 287{
301 int retval; 288 int retval;
302 struct kfd_ioctl_destroy_queue_args args; 289 struct kfd_ioctl_destroy_queue_args *args = data;
303
304 if (copy_from_user(&args, arg, sizeof(args)))
305 return -EFAULT;
306 290
307 pr_debug("kfd: destroying queue id %d for PASID %d\n", 291 pr_debug("kfd: destroying queue id %d for PASID %d\n",
308 args.queue_id, 292 args->queue_id,
309 p->pasid); 293 p->pasid);
310 294
311 mutex_lock(&p->mutex); 295 mutex_lock(&p->mutex);
312 296
313 retval = pqm_destroy_queue(&p->pqm, args.queue_id); 297 retval = pqm_destroy_queue(&p->pqm, args->queue_id);
314 298
315 mutex_unlock(&p->mutex); 299 mutex_unlock(&p->mutex);
316 return retval; 300 return retval;
317} 301}
318 302
319static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p, 303static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p,
320 void __user *arg) 304 void *data)
321{ 305{
322 int retval; 306 int retval;
323 struct kfd_ioctl_update_queue_args args; 307 struct kfd_ioctl_update_queue_args *args = data;
324 struct queue_properties properties; 308 struct queue_properties properties;
325 309
326 if (copy_from_user(&args, arg, sizeof(args))) 310 if (args->queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) {
327 return -EFAULT;
328
329 if (args.queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) {
330 pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n"); 311 pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n");
331 return -EINVAL; 312 return -EINVAL;
332 } 313 }
333 314
334 if (args.queue_priority > KFD_MAX_QUEUE_PRIORITY) { 315 if (args->queue_priority > KFD_MAX_QUEUE_PRIORITY) {
335 pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n"); 316 pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n");
336 return -EINVAL; 317 return -EINVAL;
337 } 318 }
338 319
339 if ((args.ring_base_address) && 320 if ((args->ring_base_address) &&
340 (!access_ok(VERIFY_WRITE, 321 (!access_ok(VERIFY_WRITE,
341 (const void __user *) args.ring_base_address, 322 (const void __user *) args->ring_base_address,
342 sizeof(uint64_t)))) { 323 sizeof(uint64_t)))) {
343 pr_err("kfd: can't access ring base address\n"); 324 pr_err("kfd: can't access ring base address\n");
344 return -EFAULT; 325 return -EFAULT;
345 } 326 }
346 327
347 if (!is_power_of_2(args.ring_size) && (args.ring_size != 0)) { 328 if (!is_power_of_2(args->ring_size) && (args->ring_size != 0)) {
348 pr_err("kfd: ring size must be a power of 2 or 0\n"); 329 pr_err("kfd: ring size must be a power of 2 or 0\n");
349 return -EINVAL; 330 return -EINVAL;
350 } 331 }
351 332
352 properties.queue_address = args.ring_base_address; 333 properties.queue_address = args->ring_base_address;
353 properties.queue_size = args.ring_size; 334 properties.queue_size = args->ring_size;
354 properties.queue_percent = args.queue_percentage; 335 properties.queue_percent = args->queue_percentage;
355 properties.priority = args.queue_priority; 336 properties.priority = args->queue_priority;
356 337
357 pr_debug("kfd: updating queue id %d for PASID %d\n", 338 pr_debug("kfd: updating queue id %d for PASID %d\n",
358 args.queue_id, p->pasid); 339 args->queue_id, p->pasid);
359 340
360 mutex_lock(&p->mutex); 341 mutex_lock(&p->mutex);
361 342
362 retval = pqm_update_queue(&p->pqm, args.queue_id, &properties); 343 retval = pqm_update_queue(&p->pqm, args->queue_id, &properties);
363 344
364 mutex_unlock(&p->mutex); 345 mutex_unlock(&p->mutex);
365 346
366 return retval; 347 return retval;
367} 348}
368 349
369static long kfd_ioctl_set_memory_policy(struct file *filep, 350static int kfd_ioctl_set_memory_policy(struct file *filep,
370 struct kfd_process *p, void __user *arg) 351 struct kfd_process *p, void *data)
371{ 352{
372 struct kfd_ioctl_set_memory_policy_args args; 353 struct kfd_ioctl_set_memory_policy_args *args = data;
373 struct kfd_dev *dev; 354 struct kfd_dev *dev;
374 int err = 0; 355 int err = 0;
375 struct kfd_process_device *pdd; 356 struct kfd_process_device *pdd;
376 enum cache_policy default_policy, alternate_policy; 357 enum cache_policy default_policy, alternate_policy;
377 358
378 if (copy_from_user(&args, arg, sizeof(args))) 359 if (args->default_policy != KFD_IOC_CACHE_POLICY_COHERENT
379 return -EFAULT; 360 && args->default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {
380
381 if (args.default_policy != KFD_IOC_CACHE_POLICY_COHERENT
382 && args.default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {
383 return -EINVAL; 361 return -EINVAL;
384 } 362 }
385 363
386 if (args.alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT 364 if (args->alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT
387 && args.alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { 365 && args->alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {
388 return -EINVAL; 366 return -EINVAL;
389 } 367 }
390 368
391 dev = kfd_device_by_id(args.gpu_id); 369 dev = kfd_device_by_id(args->gpu_id);
392 if (dev == NULL) 370 if (dev == NULL)
393 return -EINVAL; 371 return -EINVAL;
394 372
@@ -396,23 +374,23 @@ static long kfd_ioctl_set_memory_policy(struct file *filep,
396 374
397 pdd = kfd_bind_process_to_device(dev, p); 375 pdd = kfd_bind_process_to_device(dev, p);
398 if (IS_ERR(pdd)) { 376 if (IS_ERR(pdd)) {
399 err = PTR_ERR(pdd); 377 err = -ESRCH;
400 goto out; 378 goto out;
401 } 379 }
402 380
403 default_policy = (args.default_policy == KFD_IOC_CACHE_POLICY_COHERENT) 381 default_policy = (args->default_policy == KFD_IOC_CACHE_POLICY_COHERENT)
404 ? cache_policy_coherent : cache_policy_noncoherent; 382 ? cache_policy_coherent : cache_policy_noncoherent;
405 383
406 alternate_policy = 384 alternate_policy =
407 (args.alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT) 385 (args->alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT)
408 ? cache_policy_coherent : cache_policy_noncoherent; 386 ? cache_policy_coherent : cache_policy_noncoherent;
409 387
410 if (!dev->dqm->set_cache_memory_policy(dev->dqm, 388 if (!dev->dqm->set_cache_memory_policy(dev->dqm,
411 &pdd->qpd, 389 &pdd->qpd,
412 default_policy, 390 default_policy,
413 alternate_policy, 391 alternate_policy,
414 (void __user *)args.alternate_aperture_base, 392 (void __user *)args->alternate_aperture_base,
415 args.alternate_aperture_size)) 393 args->alternate_aperture_size))
416 err = -EINVAL; 394 err = -EINVAL;
417 395
418out: 396out:
@@ -421,53 +399,44 @@ out:
421 return err; 399 return err;
422} 400}
423 401
424static long kfd_ioctl_get_clock_counters(struct file *filep, 402static int kfd_ioctl_get_clock_counters(struct file *filep,
425 struct kfd_process *p, void __user *arg) 403 struct kfd_process *p, void *data)
426{ 404{
427 struct kfd_ioctl_get_clock_counters_args args; 405 struct kfd_ioctl_get_clock_counters_args *args = data;
428 struct kfd_dev *dev; 406 struct kfd_dev *dev;
429 struct timespec time; 407 struct timespec time;
430 408
431 if (copy_from_user(&args, arg, sizeof(args))) 409 dev = kfd_device_by_id(args->gpu_id);
432 return -EFAULT;
433
434 dev = kfd_device_by_id(args.gpu_id);
435 if (dev == NULL) 410 if (dev == NULL)
436 return -EINVAL; 411 return -EINVAL;
437 412
438 /* Reading GPU clock counter from KGD */ 413 /* Reading GPU clock counter from KGD */
439 args.gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd); 414 args->gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd);
440 415
441 /* No access to rdtsc. Using raw monotonic time */ 416 /* No access to rdtsc. Using raw monotonic time */
442 getrawmonotonic(&time); 417 getrawmonotonic(&time);
443 args.cpu_clock_counter = (uint64_t)timespec_to_ns(&time); 418 args->cpu_clock_counter = (uint64_t)timespec_to_ns(&time);
444 419
445 get_monotonic_boottime(&time); 420 get_monotonic_boottime(&time);
446 args.system_clock_counter = (uint64_t)timespec_to_ns(&time); 421 args->system_clock_counter = (uint64_t)timespec_to_ns(&time);
447 422
448 /* Since the counter is in nano-seconds we use 1GHz frequency */ 423 /* Since the counter is in nano-seconds we use 1GHz frequency */
449 args.system_clock_freq = 1000000000; 424 args->system_clock_freq = 1000000000;
450
451 if (copy_to_user(arg, &args, sizeof(args)))
452 return -EFAULT;
453 425
454 return 0; 426 return 0;
455} 427}
456 428
457 429
458static int kfd_ioctl_get_process_apertures(struct file *filp, 430static int kfd_ioctl_get_process_apertures(struct file *filp,
459 struct kfd_process *p, void __user *arg) 431 struct kfd_process *p, void *data)
460{ 432{
461 struct kfd_ioctl_get_process_apertures_args args; 433 struct kfd_ioctl_get_process_apertures_args *args = data;
462 struct kfd_process_device_apertures *pAperture; 434 struct kfd_process_device_apertures *pAperture;
463 struct kfd_process_device *pdd; 435 struct kfd_process_device *pdd;
464 436
465 dev_dbg(kfd_device, "get apertures for PASID %d", p->pasid); 437 dev_dbg(kfd_device, "get apertures for PASID %d", p->pasid);
466 438
467 if (copy_from_user(&args, arg, sizeof(args))) 439 args->num_of_nodes = 0;
468 return -EFAULT;
469
470 args.num_of_nodes = 0;
471 440
472 mutex_lock(&p->mutex); 441 mutex_lock(&p->mutex);
473 442
@@ -476,7 +445,8 @@ static int kfd_ioctl_get_process_apertures(struct file *filp,
476 /* Run over all pdd of the process */ 445 /* Run over all pdd of the process */
477 pdd = kfd_get_first_process_device_data(p); 446 pdd = kfd_get_first_process_device_data(p);
478 do { 447 do {
479 pAperture = &args.process_apertures[args.num_of_nodes]; 448 pAperture =
449 &args->process_apertures[args->num_of_nodes];
480 pAperture->gpu_id = pdd->dev->id; 450 pAperture->gpu_id = pdd->dev->id;
481 pAperture->lds_base = pdd->lds_base; 451 pAperture->lds_base = pdd->lds_base;
482 pAperture->lds_limit = pdd->lds_limit; 452 pAperture->lds_limit = pdd->lds_limit;
@@ -486,7 +456,7 @@ static int kfd_ioctl_get_process_apertures(struct file *filp,
486 pAperture->scratch_limit = pdd->scratch_limit; 456 pAperture->scratch_limit = pdd->scratch_limit;
487 457
488 dev_dbg(kfd_device, 458 dev_dbg(kfd_device,
489 "node id %u\n", args.num_of_nodes); 459 "node id %u\n", args->num_of_nodes);
490 dev_dbg(kfd_device, 460 dev_dbg(kfd_device,
491 "gpu id %u\n", pdd->dev->id); 461 "gpu id %u\n", pdd->dev->id);
492 dev_dbg(kfd_device, 462 dev_dbg(kfd_device,
@@ -502,80 +472,131 @@ static int kfd_ioctl_get_process_apertures(struct file *filp,
502 dev_dbg(kfd_device, 472 dev_dbg(kfd_device,
503 "scratch_limit %llX\n", pdd->scratch_limit); 473 "scratch_limit %llX\n", pdd->scratch_limit);
504 474
505 args.num_of_nodes++; 475 args->num_of_nodes++;
506 } while ((pdd = kfd_get_next_process_device_data(p, pdd)) != NULL && 476 } while ((pdd = kfd_get_next_process_device_data(p, pdd)) != NULL &&
507 (args.num_of_nodes < NUM_OF_SUPPORTED_GPUS)); 477 (args->num_of_nodes < NUM_OF_SUPPORTED_GPUS));
508 } 478 }
509 479
510 mutex_unlock(&p->mutex); 480 mutex_unlock(&p->mutex);
511 481
512 if (copy_to_user(arg, &args, sizeof(args)))
513 return -EFAULT;
514
515 return 0; 482 return 0;
516} 483}
517 484
485#define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \
486 [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl}
487
488/** Ioctl table */
489static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
490 AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_VERSION,
491 kfd_ioctl_get_version, 0),
492
493 AMDKFD_IOCTL_DEF(AMDKFD_IOC_CREATE_QUEUE,
494 kfd_ioctl_create_queue, 0),
495
496 AMDKFD_IOCTL_DEF(AMDKFD_IOC_DESTROY_QUEUE,
497 kfd_ioctl_destroy_queue, 0),
498
499 AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_MEMORY_POLICY,
500 kfd_ioctl_set_memory_policy, 0),
501
502 AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_CLOCK_COUNTERS,
503 kfd_ioctl_get_clock_counters, 0),
504
505 AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_PROCESS_APERTURES,
506 kfd_ioctl_get_process_apertures, 0),
507
508 AMDKFD_IOCTL_DEF(AMDKFD_IOC_UPDATE_QUEUE,
509 kfd_ioctl_update_queue, 0),
510};
511
512#define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls)
513
518static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) 514static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
519{ 515{
520 struct kfd_process *process; 516 struct kfd_process *process;
521 long err = -EINVAL; 517 amdkfd_ioctl_t *func;
518 const struct amdkfd_ioctl_desc *ioctl = NULL;
519 unsigned int nr = _IOC_NR(cmd);
520 char stack_kdata[128];
521 char *kdata = NULL;
522 unsigned int usize, asize;
523 int retcode = -EINVAL;
522 524
523 dev_dbg(kfd_device, 525 if (nr >= AMDKFD_CORE_IOCTL_COUNT)
524 "ioctl cmd 0x%x (#%d), arg 0x%lx\n", 526 goto err_i1;
525 cmd, _IOC_NR(cmd), arg); 527
528 if ((nr >= AMDKFD_COMMAND_START) && (nr < AMDKFD_COMMAND_END)) {
529 u32 amdkfd_size;
530
531 ioctl = &amdkfd_ioctls[nr];
532
533 amdkfd_size = _IOC_SIZE(ioctl->cmd);
534 usize = asize = _IOC_SIZE(cmd);
535 if (amdkfd_size > asize)
536 asize = amdkfd_size;
537
538 cmd = ioctl->cmd;
539 } else
540 goto err_i1;
541
542 dev_dbg(kfd_device, "ioctl cmd 0x%x (#%d), arg 0x%lx\n", cmd, nr, arg);
526 543
527 process = kfd_get_process(current); 544 process = kfd_get_process(current);
528 if (IS_ERR(process)) 545 if (IS_ERR(process)) {
529 return PTR_ERR(process); 546 dev_dbg(kfd_device, "no process\n");
547 goto err_i1;
548 }
530 549
531 switch (cmd) { 550 /* Do not trust userspace, use our own definition */
532 case KFD_IOC_GET_VERSION: 551 func = ioctl->func;
533 err = kfd_ioctl_get_version(filep, process, (void __user *)arg); 552
534 break; 553 if (unlikely(!func)) {
535 case KFD_IOC_CREATE_QUEUE: 554 dev_dbg(kfd_device, "no function\n");
536 err = kfd_ioctl_create_queue(filep, process, 555 retcode = -EINVAL;
537 (void __user *)arg); 556 goto err_i1;
538 break;
539
540 case KFD_IOC_DESTROY_QUEUE:
541 err = kfd_ioctl_destroy_queue(filep, process,
542 (void __user *)arg);
543 break;
544
545 case KFD_IOC_SET_MEMORY_POLICY:
546 err = kfd_ioctl_set_memory_policy(filep, process,
547 (void __user *)arg);
548 break;
549
550 case KFD_IOC_GET_CLOCK_COUNTERS:
551 err = kfd_ioctl_get_clock_counters(filep, process,
552 (void __user *)arg);
553 break;
554
555 case KFD_IOC_GET_PROCESS_APERTURES:
556 err = kfd_ioctl_get_process_apertures(filep, process,
557 (void __user *)arg);
558 break;
559
560 case KFD_IOC_UPDATE_QUEUE:
561 err = kfd_ioctl_update_queue(filep, process,
562 (void __user *)arg);
563 break;
564
565 default:
566 dev_err(kfd_device,
567 "unknown ioctl cmd 0x%x, arg 0x%lx)\n",
568 cmd, arg);
569 err = -EINVAL;
570 break;
571 } 557 }
572 558
573 if (err < 0) 559 if (cmd & (IOC_IN | IOC_OUT)) {
574 dev_err(kfd_device, 560 if (asize <= sizeof(stack_kdata)) {
575 "ioctl error %ld for ioctl cmd 0x%x (#%d)\n", 561 kdata = stack_kdata;
576 err, cmd, _IOC_NR(cmd)); 562 } else {
563 kdata = kmalloc(asize, GFP_KERNEL);
564 if (!kdata) {
565 retcode = -ENOMEM;
566 goto err_i1;
567 }
568 }
569 if (asize > usize)
570 memset(kdata + usize, 0, asize - usize);
571 }
577 572
578 return err; 573 if (cmd & IOC_IN) {
574 if (copy_from_user(kdata, (void __user *)arg, usize) != 0) {
575 retcode = -EFAULT;
576 goto err_i1;
577 }
578 } else if (cmd & IOC_OUT) {
579 memset(kdata, 0, usize);
580 }
581
582 retcode = func(filep, process, kdata);
583
584 if (cmd & IOC_OUT)
585 if (copy_to_user((void __user *)arg, kdata, usize) != 0)
586 retcode = -EFAULT;
587
588err_i1:
589 if (!ioctl)
590 dev_dbg(kfd_device, "invalid ioctl: pid=%d, cmd=0x%02x, nr=0x%02x\n",
591 task_pid_nr(current), cmd, nr);
592
593 if (kdata != stack_kdata)
594 kfree(kdata);
595
596 if (retcode)
597 dev_dbg(kfd_device, "ret = %d\n", retcode);
598
599 return retcode;
579} 600}
580 601
581static int kfd_mmap(struct file *filp, struct vm_area_struct *vma) 602static int kfd_mmap(struct file *filp, struct vm_area_struct *vma)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index f44d6737b65a..9c8961d22360 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -161,6 +161,9 @@ static void deallocate_vmid(struct device_queue_manager *dqm,
161{ 161{
162 int bit = qpd->vmid - KFD_VMID_START_OFFSET; 162 int bit = qpd->vmid - KFD_VMID_START_OFFSET;
163 163
164 /* Release the vmid mapping */
165 set_pasid_vmid_mapping(dqm, 0, qpd->vmid);
166
164 set_bit(bit, (unsigned long *)&dqm->vmid_bitmap); 167 set_bit(bit, (unsigned long *)&dqm->vmid_bitmap);
165 qpd->vmid = 0; 168 qpd->vmid = 0;
166 q->properties.vmid = 0; 169 q->properties.vmid = 0;
@@ -272,6 +275,18 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm,
272 return retval; 275 return retval;
273 } 276 }
274 277
278 pr_debug("kfd: loading mqd to hqd on pipe (%d) queue (%d)\n",
279 q->pipe,
280 q->queue);
281
282 retval = mqd->load_mqd(mqd, q->mqd, q->pipe,
283 q->queue, q->properties.write_ptr);
284 if (retval != 0) {
285 deallocate_hqd(dqm, q);
286 mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
287 return retval;
288 }
289
275 return 0; 290 return 0;
276} 291}
277 292
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
index adc31474e786..4c3828cf45bf 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
@@ -184,7 +184,7 @@ static bool is_occupied(struct mqd_manager *mm, void *mqd,
184 uint32_t queue_id) 184 uint32_t queue_id)
185{ 185{
186 186
187 return kfd2kgd->hqd_is_occupies(mm->dev->kgd, queue_address, 187 return kfd2kgd->hqd_is_occupied(mm->dev->kgd, queue_address,
188 pipe_id, queue_id); 188 pipe_id, queue_id);
189 189
190} 190}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index f9fb81e3bb09..a5edb29507e3 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -463,6 +463,24 @@ struct kfd_process {
463 bool is_32bit_user_mode; 463 bool is_32bit_user_mode;
464}; 464};
465 465
466/**
467 * Ioctl function type.
468 *
469 * \param filep pointer to file structure.
470 * \param p amdkfd process pointer.
471 * \param data pointer to arg that was copied from user.
472 */
473typedef int amdkfd_ioctl_t(struct file *filep, struct kfd_process *p,
474 void *data);
475
476struct amdkfd_ioctl_desc {
477 unsigned int cmd;
478 int flags;
479 amdkfd_ioctl_t *func;
480 unsigned int cmd_drv;
481 const char *name;
482};
483
466void kfd_process_create_wq(void); 484void kfd_process_create_wq(void);
467void kfd_process_destroy_wq(void); 485void kfd_process_destroy_wq(void);
468struct kfd_process *kfd_create_process(const struct task_struct *); 486struct kfd_process *kfd_create_process(const struct task_struct *);
diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
index 47b551970a14..96a512208fad 100644
--- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
@@ -183,7 +183,7 @@ struct kfd2kgd_calls {
183 int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, 183 int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
184 uint32_t queue_id, uint32_t __user *wptr); 184 uint32_t queue_id, uint32_t __user *wptr);
185 185
186 bool (*hqd_is_occupies)(struct kgd_dev *kgd, uint64_t queue_address, 186 bool (*hqd_is_occupied)(struct kgd_dev *kgd, uint64_t queue_address,
187 uint32_t pipe_id, uint32_t queue_id); 187 uint32_t pipe_id, uint32_t queue_id);
188 188
189 int (*hqd_destroy)(struct kgd_dev *kgd, uint32_t reset_type, 189 int (*hqd_destroy)(struct kgd_dev *kgd, uint32_t reset_type,
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h
index ba85986febea..03003f8a6de6 100644
--- a/drivers/gpu/drm/radeon/cikd.h
+++ b/drivers/gpu/drm/radeon/cikd.h
@@ -2156,4 +2156,6 @@
2156#define ATC_VM_APERTURE1_HIGH_ADDR 0x330Cu 2156#define ATC_VM_APERTURE1_HIGH_ADDR 0x330Cu
2157#define ATC_VM_APERTURE1_LOW_ADDR 0x3304u 2157#define ATC_VM_APERTURE1_LOW_ADDR 0x3304u
2158 2158
2159#define IH_VMID_0_LUT 0x3D40u
2160
2159#endif 2161#endif
diff --git a/drivers/gpu/drm/radeon/radeon_kfd.c b/drivers/gpu/drm/radeon/radeon_kfd.c
index d3e78b4a6b75..8bf87f1203cc 100644
--- a/drivers/gpu/drm/radeon/radeon_kfd.c
+++ b/drivers/gpu/drm/radeon/radeon_kfd.c
@@ -72,7 +72,7 @@ static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,
72static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, 72static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
73 uint32_t queue_id, uint32_t __user *wptr); 73 uint32_t queue_id, uint32_t __user *wptr);
74 74
75static bool kgd_hqd_is_occupies(struct kgd_dev *kgd, uint64_t queue_address, 75static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
76 uint32_t pipe_id, uint32_t queue_id); 76 uint32_t pipe_id, uint32_t queue_id);
77 77
78static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type, 78static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
@@ -92,7 +92,7 @@ static const struct kfd2kgd_calls kfd2kgd = {
92 .init_memory = kgd_init_memory, 92 .init_memory = kgd_init_memory,
93 .init_pipeline = kgd_init_pipeline, 93 .init_pipeline = kgd_init_pipeline,
94 .hqd_load = kgd_hqd_load, 94 .hqd_load = kgd_hqd_load,
95 .hqd_is_occupies = kgd_hqd_is_occupies, 95 .hqd_is_occupied = kgd_hqd_is_occupied,
96 .hqd_destroy = kgd_hqd_destroy, 96 .hqd_destroy = kgd_hqd_destroy,
97 .get_fw_version = get_fw_version 97 .get_fw_version = get_fw_version
98}; 98};
@@ -390,6 +390,10 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid,
390 cpu_relax(); 390 cpu_relax();
391 write_register(kgd, ATC_VMID_PASID_MAPPING_UPDATE_STATUS, 1U << vmid); 391 write_register(kgd, ATC_VMID_PASID_MAPPING_UPDATE_STATUS, 1U << vmid);
392 392
393 /* Mapping vmid to pasid also for IH block */
394 write_register(kgd, IH_VMID_0_LUT + vmid * sizeof(uint32_t),
395 pasid_mapping);
396
393 return 0; 397 return 0;
394} 398}
395 399
@@ -529,7 +533,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
529 return 0; 533 return 0;
530} 534}
531 535
532static bool kgd_hqd_is_occupies(struct kgd_dev *kgd, uint64_t queue_address, 536static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
533 uint32_t pipe_id, uint32_t queue_id) 537 uint32_t pipe_id, uint32_t queue_id)
534{ 538{
535 uint32_t act; 539 uint32_t act;
@@ -568,6 +572,7 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
568 if (timeout == 0) { 572 if (timeout == 0) {
569 pr_err("kfd: cp queue preemption time out (%dms)\n", 573 pr_err("kfd: cp queue preemption time out (%dms)\n",
570 temp); 574 temp);
575 release_queue(kgd);
571 return -ETIME; 576 return -ETIME;
572 } 577 }
573 msleep(20); 578 msleep(20);
diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h
index 7acef41fc209..af94f31e33ac 100644
--- a/include/uapi/linux/kfd_ioctl.h
+++ b/include/uapi/linux/kfd_ioctl.h
@@ -128,27 +128,34 @@ struct kfd_ioctl_get_process_apertures_args {
128 uint32_t pad; 128 uint32_t pad;
129}; 129};
130 130
131#define KFD_IOC_MAGIC 'K' 131#define AMDKFD_IOCTL_BASE 'K'
132#define AMDKFD_IO(nr) _IO(AMDKFD_IOCTL_BASE, nr)
133#define AMDKFD_IOR(nr, type) _IOR(AMDKFD_IOCTL_BASE, nr, type)
134#define AMDKFD_IOW(nr, type) _IOW(AMDKFD_IOCTL_BASE, nr, type)
135#define AMDKFD_IOWR(nr, type) _IOWR(AMDKFD_IOCTL_BASE, nr, type)
132 136
133#define KFD_IOC_GET_VERSION \ 137#define AMDKFD_IOC_GET_VERSION \
134 _IOR(KFD_IOC_MAGIC, 1, struct kfd_ioctl_get_version_args) 138 AMDKFD_IOR(0x01, struct kfd_ioctl_get_version_args)
135 139
136#define KFD_IOC_CREATE_QUEUE \ 140#define AMDKFD_IOC_CREATE_QUEUE \
137 _IOWR(KFD_IOC_MAGIC, 2, struct kfd_ioctl_create_queue_args) 141 AMDKFD_IOWR(0x02, struct kfd_ioctl_create_queue_args)
138 142
139#define KFD_IOC_DESTROY_QUEUE \ 143#define AMDKFD_IOC_DESTROY_QUEUE \
140 _IOWR(KFD_IOC_MAGIC, 3, struct kfd_ioctl_destroy_queue_args) 144 AMDKFD_IOWR(0x03, struct kfd_ioctl_destroy_queue_args)
141 145
142#define KFD_IOC_SET_MEMORY_POLICY \ 146#define AMDKFD_IOC_SET_MEMORY_POLICY \
143 _IOW(KFD_IOC_MAGIC, 4, struct kfd_ioctl_set_memory_policy_args) 147 AMDKFD_IOW(0x04, struct kfd_ioctl_set_memory_policy_args)
144 148
145#define KFD_IOC_GET_CLOCK_COUNTERS \ 149#define AMDKFD_IOC_GET_CLOCK_COUNTERS \
146 _IOWR(KFD_IOC_MAGIC, 5, struct kfd_ioctl_get_clock_counters_args) 150 AMDKFD_IOWR(0x05, struct kfd_ioctl_get_clock_counters_args)
147 151
148#define KFD_IOC_GET_PROCESS_APERTURES \ 152#define AMDKFD_IOC_GET_PROCESS_APERTURES \
149 _IOR(KFD_IOC_MAGIC, 6, struct kfd_ioctl_get_process_apertures_args) 153 AMDKFD_IOR(0x06, struct kfd_ioctl_get_process_apertures_args)
150 154
151#define KFD_IOC_UPDATE_QUEUE \ 155#define AMDKFD_IOC_UPDATE_QUEUE \
152 _IOW(KFD_IOC_MAGIC, 7, struct kfd_ioctl_update_queue_args) 156 AMDKFD_IOW(0x07, struct kfd_ioctl_update_queue_args)
157
158#define AMDKFD_COMMAND_START 0x01
159#define AMDKFD_COMMAND_END 0x08
153 160
154#endif 161#endif