aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-01-07 19:36:37 -0500
committerDave Airlie <airlied@redhat.com>2015-01-07 19:36:37 -0500
commit79305ec6e60d320832505e95c1a028d309fcd2b6 (patch)
tree1a96a0da41efad0d18303c4e9323ff32364ef09d
parenteaee8ec4eb031cda0003ec4c893058c54db20ee4 (diff)
parent76baee6c733bfef30fcf86cbd121e336b839e408 (diff)
Merge tag 'amdkfd-fixes-2015-01-06' of git://people.freedesktop.org/~gabbayo/linux into drm-fixes
- Complete overhaul to the main IOCTL function, kfd_ioctl(), according to drm_ioctl() example. This includes changing the IOCTL definitions, so it breaks compatibility with previous versions of the userspace. However, because the kernel was not officialy released yet, and this the first kernel that includes amdkfd, I assume I can still do that at this stage. - A couple of bug fixes for the non-HWS path (used for bring-ups and debugging purposes only). * tag 'amdkfd-fixes-2015-01-06' of git://people.freedesktop.org/~gabbayo/linux: drm/amdkfd: rewrite kfd_ioctl() according to drm_ioctl() drm/amdkfd: reformat IOCTL definitions to drm-style drm/amdkfd: Do copy_to/from_user in general kfd_ioctl() drm/amdkfd: unmap VMID<-->PASID when relesing VMID (non-HWS) drm/radeon: Assign VMID to PASID for IH in non-HWS mode drm/radeon: do not leave queue acquired if timeout happens in kgd_hqd_destroy() drm/amdkfd: Load mqd to hqd in non-HWS mode drm/amd: Fixing typos in kfd<->kgd interface
-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