Commit 7122e505a52a2b1b8a21101cce04bcdf7c28deab

Authored by Dave Airlie

Merge branch 'drm-fixes-4.1' of git://people.freedesktop.org/~agd5f/linux into drm-fixes

Mostly stability fixes for UVD and VCE, plus a few other bug and regression
fixes.

* 'drm-fixes-4.1' of git://people.freedesktop.org/~agd5f/linux:
  drm/radeon: stop trying to suspend UVD sessions
  drm/radeon: more strictly validate the UVD codec
  drm/radeon: make UVD handle checking more strict
  drm/radeon: make VCE handle check more strict
  drm/radeon: fix userptr lockup
  drm/radeon: fix userptr BO unpin bug v3
  drm/radeon: don't setup audio on asics that don't support it
  drm/radeon: disable semaphores for UVD V1 (v2)

Showing 11 changed files Side-by-side Diff

drivers/gpu/drm/radeon/radeon.h
... ... @@ -1673,7 +1673,6 @@
1673 1673 struct radeon_bo *vcpu_bo;
1674 1674 void *cpu_addr;
1675 1675 uint64_t gpu_addr;
1676   - void *saved_bo;
1677 1676 atomic_t handles[RADEON_MAX_UVD_HANDLES];
1678 1677 struct drm_file *filp[RADEON_MAX_UVD_HANDLES];
1679 1678 unsigned img_size[RADEON_MAX_UVD_HANDLES];
drivers/gpu/drm/radeon/radeon_asic.c
... ... @@ -1202,7 +1202,7 @@
1202 1202 static struct radeon_asic_ring rv770_uvd_ring = {
1203 1203 .ib_execute = &uvd_v1_0_ib_execute,
1204 1204 .emit_fence = &uvd_v2_2_fence_emit,
1205   - .emit_semaphore = &uvd_v1_0_semaphore_emit,
  1205 + .emit_semaphore = &uvd_v2_2_semaphore_emit,
1206 1206 .cs_parse = &radeon_uvd_cs_parse,
1207 1207 .ring_test = &uvd_v1_0_ring_test,
1208 1208 .ib_test = &uvd_v1_0_ib_test,
drivers/gpu/drm/radeon/radeon_asic.h
... ... @@ -949,6 +949,10 @@
949 949 int uvd_v2_2_resume(struct radeon_device *rdev);
950 950 void uvd_v2_2_fence_emit(struct radeon_device *rdev,
951 951 struct radeon_fence *fence);
  952 +bool uvd_v2_2_semaphore_emit(struct radeon_device *rdev,
  953 + struct radeon_ring *ring,
  954 + struct radeon_semaphore *semaphore,
  955 + bool emit_wait);
952 956  
953 957 /* uvd v3.1 */
954 958 bool uvd_v3_1_semaphore_emit(struct radeon_device *rdev,
drivers/gpu/drm/radeon/radeon_audio.c
... ... @@ -464,6 +464,10 @@
464 464 return;
465 465  
466 466 rdev = connector->encoder->dev->dev_private;
  467 +
  468 + if (!radeon_audio_chipset_supported(rdev))
  469 + return;
  470 +
467 471 radeon_encoder = to_radeon_encoder(connector->encoder);
468 472 dig = radeon_encoder->enc_priv;
469 473  
drivers/gpu/drm/radeon/radeon_mn.c
... ... @@ -142,6 +142,9 @@
142 142  
143 143 list_for_each_entry(bo, &node->bos, mn_list) {
144 144  
  145 + if (!bo->tbo.ttm || bo->tbo.ttm->state != tt_bound)
  146 + continue;
  147 +
145 148 r = radeon_bo_reserve(bo, true);
146 149 if (r) {
147 150 DRM_ERROR("(%ld) failed to reserve user bo\n", r);
drivers/gpu/drm/radeon/radeon_ttm.c
... ... @@ -591,8 +591,7 @@
591 591 {
592 592 struct radeon_device *rdev = radeon_get_rdev(ttm->bdev);
593 593 struct radeon_ttm_tt *gtt = (void *)ttm;
594   - struct scatterlist *sg;
595   - int i;
  594 + struct sg_page_iter sg_iter;
596 595  
597 596 int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY);
598 597 enum dma_data_direction direction = write ?
... ... @@ -605,9 +604,8 @@
605 604 /* free the sg table and pages again */
606 605 dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
607 606  
608   - for_each_sg(ttm->sg->sgl, sg, ttm->sg->nents, i) {
609   - struct page *page = sg_page(sg);
610   -
  607 + for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) {
  608 + struct page *page = sg_page_iter_page(&sg_iter);
611 609 if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY))
612 610 set_page_dirty(page);
613 611  
drivers/gpu/drm/radeon/radeon_uvd.c
... ... @@ -204,28 +204,32 @@
204 204  
205 205 int radeon_uvd_suspend(struct radeon_device *rdev)
206 206 {
207   - unsigned size;
208   - void *ptr;
209   - int i;
  207 + int i, r;
210 208  
211 209 if (rdev->uvd.vcpu_bo == NULL)
212 210 return 0;
213 211  
214   - for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i)
215   - if (atomic_read(&rdev->uvd.handles[i]))
216   - break;
  212 + for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
  213 + uint32_t handle = atomic_read(&rdev->uvd.handles[i]);
  214 + if (handle != 0) {
  215 + struct radeon_fence *fence;
217 216  
218   - if (i == RADEON_MAX_UVD_HANDLES)
219   - return 0;
  217 + radeon_uvd_note_usage(rdev);
220 218  
221   - size = radeon_bo_size(rdev->uvd.vcpu_bo);
222   - size -= rdev->uvd_fw->size;
  219 + r = radeon_uvd_get_destroy_msg(rdev,
  220 + R600_RING_TYPE_UVD_INDEX, handle, &fence);
  221 + if (r) {
  222 + DRM_ERROR("Error destroying UVD (%d)!\n", r);
  223 + continue;
  224 + }
223 225  
224   - ptr = rdev->uvd.cpu_addr;
225   - ptr += rdev->uvd_fw->size;
  226 + radeon_fence_wait(fence, false);
  227 + radeon_fence_unref(&fence);
226 228  
227   - rdev->uvd.saved_bo = kmalloc(size, GFP_KERNEL);
228   - memcpy(rdev->uvd.saved_bo, ptr, size);
  229 + rdev->uvd.filp[i] = NULL;
  230 + atomic_set(&rdev->uvd.handles[i], 0);
  231 + }
  232 + }
229 233  
230 234 return 0;
231 235 }
... ... @@ -246,12 +250,7 @@
246 250 ptr = rdev->uvd.cpu_addr;
247 251 ptr += rdev->uvd_fw->size;
248 252  
249   - if (rdev->uvd.saved_bo != NULL) {
250   - memcpy(ptr, rdev->uvd.saved_bo, size);
251   - kfree(rdev->uvd.saved_bo);
252   - rdev->uvd.saved_bo = NULL;
253   - } else
254   - memset(ptr, 0, size);
  253 + memset(ptr, 0, size);
255 254  
256 255 return 0;
257 256 }
... ... @@ -396,6 +395,29 @@
396 395 return 0;
397 396 }
398 397  
  398 +static int radeon_uvd_validate_codec(struct radeon_cs_parser *p,
  399 + unsigned stream_type)
  400 +{
  401 + switch (stream_type) {
  402 + case 0: /* H264 */
  403 + case 1: /* VC1 */
  404 + /* always supported */
  405 + return 0;
  406 +
  407 + case 3: /* MPEG2 */
  408 + case 4: /* MPEG4 */
  409 + /* only since UVD 3 */
  410 + if (p->rdev->family >= CHIP_PALM)
  411 + return 0;
  412 +
  413 + /* fall through */
  414 + default:
  415 + DRM_ERROR("UVD codec not supported by hardware %d!\n",
  416 + stream_type);
  417 + return -EINVAL;
  418 + }
  419 +}
  420 +
399 421 static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
400 422 unsigned offset, unsigned buf_sizes[])
401 423 {
402 424  
403 425  
404 426  
405 427  
406 428  
... ... @@ -436,50 +458,70 @@
436 458 return -EINVAL;
437 459 }
438 460  
439   - if (msg_type == 1) {
440   - /* it's a decode msg, calc buffer sizes */
441   - r = radeon_uvd_cs_msg_decode(msg, buf_sizes);
442   - /* calc image size (width * height) */
443   - img_size = msg[6] * msg[7];
  461 + switch (msg_type) {
  462 + case 0:
  463 + /* it's a create msg, calc image size (width * height) */
  464 + img_size = msg[7] * msg[8];
  465 +
  466 + r = radeon_uvd_validate_codec(p, msg[4]);
444 467 radeon_bo_kunmap(bo);
445 468 if (r)
446 469 return r;
447 470  
448   - } else if (msg_type == 2) {
  471 + /* try to alloc a new handle */
  472 + for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
  473 + if (atomic_read(&p->rdev->uvd.handles[i]) == handle) {
  474 + DRM_ERROR("Handle 0x%x already in use!\n", handle);
  475 + return -EINVAL;
  476 + }
  477 +
  478 + if (!atomic_cmpxchg(&p->rdev->uvd.handles[i], 0, handle)) {
  479 + p->rdev->uvd.filp[i] = p->filp;
  480 + p->rdev->uvd.img_size[i] = img_size;
  481 + return 0;
  482 + }
  483 + }
  484 +
  485 + DRM_ERROR("No more free UVD handles!\n");
  486 + return -EINVAL;
  487 +
  488 + case 1:
  489 + /* it's a decode msg, validate codec and calc buffer sizes */
  490 + r = radeon_uvd_validate_codec(p, msg[4]);
  491 + if (!r)
  492 + r = radeon_uvd_cs_msg_decode(msg, buf_sizes);
  493 + radeon_bo_kunmap(bo);
  494 + if (r)
  495 + return r;
  496 +
  497 + /* validate the handle */
  498 + for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
  499 + if (atomic_read(&p->rdev->uvd.handles[i]) == handle) {
  500 + if (p->rdev->uvd.filp[i] != p->filp) {
  501 + DRM_ERROR("UVD handle collision detected!\n");
  502 + return -EINVAL;
  503 + }
  504 + return 0;
  505 + }
  506 + }
  507 +
  508 + DRM_ERROR("Invalid UVD handle 0x%x!\n", handle);
  509 + return -ENOENT;
  510 +
  511 + case 2:
449 512 /* it's a destroy msg, free the handle */
450 513 for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i)
451 514 atomic_cmpxchg(&p->rdev->uvd.handles[i], handle, 0);
452 515 radeon_bo_kunmap(bo);
453 516 return 0;
454   - } else {
455   - /* it's a create msg, calc image size (width * height) */
456   - img_size = msg[7] * msg[8];
457   - radeon_bo_kunmap(bo);
458 517  
459   - if (msg_type != 0) {
460   - DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
461   - return -EINVAL;
462   - }
  518 + default:
463 519  
464   - /* it's a create msg, no special handling needed */
  520 + DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
  521 + return -EINVAL;
465 522 }
466 523  
467   - /* create or decode, validate the handle */
468   - for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
469   - if (atomic_read(&p->rdev->uvd.handles[i]) == handle)
470   - return 0;
471   - }
472   -
473   - /* handle not found try to alloc a new one */
474   - for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
475   - if (!atomic_cmpxchg(&p->rdev->uvd.handles[i], 0, handle)) {
476   - p->rdev->uvd.filp[i] = p->filp;
477   - p->rdev->uvd.img_size[i] = img_size;
478   - return 0;
479   - }
480   - }
481   -
482   - DRM_ERROR("No more free UVD handles!\n");
  524 + BUG();
483 525 return -EINVAL;
484 526 }
485 527  
drivers/gpu/drm/radeon/radeon_vce.c
... ... @@ -493,18 +493,27 @@
493 493 *
494 494 * @p: parser context
495 495 * @handle: handle to validate
  496 + * @allocated: allocated a new handle?
496 497 *
497 498 * Validates the handle and return the found session index or -EINVAL
498 499 * we we don't have another free session index.
499 500 */
500   -int radeon_vce_validate_handle(struct radeon_cs_parser *p, uint32_t handle)
  501 +static int radeon_vce_validate_handle(struct radeon_cs_parser *p,
  502 + uint32_t handle, bool *allocated)
501 503 {
502 504 unsigned i;
503 505  
  506 + *allocated = false;
  507 +
504 508 /* validate the handle */
505 509 for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) {
506   - if (atomic_read(&p->rdev->vce.handles[i]) == handle)
  510 + if (atomic_read(&p->rdev->vce.handles[i]) == handle) {
  511 + if (p->rdev->vce.filp[i] != p->filp) {
  512 + DRM_ERROR("VCE handle collision detected!\n");
  513 + return -EINVAL;
  514 + }
507 515 return i;
  516 + }
508 517 }
509 518  
510 519 /* handle not found try to alloc a new one */
... ... @@ -512,6 +521,7 @@
512 521 if (!atomic_cmpxchg(&p->rdev->vce.handles[i], 0, handle)) {
513 522 p->rdev->vce.filp[i] = p->filp;
514 523 p->rdev->vce.img_size[i] = 0;
  524 + *allocated = true;
515 525 return i;
516 526 }
517 527 }
518 528  
... ... @@ -529,10 +539,10 @@
529 539 int radeon_vce_cs_parse(struct radeon_cs_parser *p)
530 540 {
531 541 int session_idx = -1;
532   - bool destroyed = false;
  542 + bool destroyed = false, created = false, allocated = false;
533 543 uint32_t tmp, handle = 0;
534 544 uint32_t *size = &tmp;
535   - int i, r;
  545 + int i, r = 0;
536 546  
537 547 while (p->idx < p->chunk_ib->length_dw) {
538 548 uint32_t len = radeon_get_ib_value(p, p->idx);
539 549  
540 550  
... ... @@ -540,18 +550,21 @@
540 550  
541 551 if ((len < 8) || (len & 3)) {
542 552 DRM_ERROR("invalid VCE command length (%d)!\n", len);
543   - return -EINVAL;
  553 + r = -EINVAL;
  554 + goto out;
544 555 }
545 556  
546 557 if (destroyed) {
547 558 DRM_ERROR("No other command allowed after destroy!\n");
548   - return -EINVAL;
  559 + r = -EINVAL;
  560 + goto out;
549 561 }
550 562  
551 563 switch (cmd) {
552 564 case 0x00000001: // session
553 565 handle = radeon_get_ib_value(p, p->idx + 2);
554   - session_idx = radeon_vce_validate_handle(p, handle);
  566 + session_idx = radeon_vce_validate_handle(p, handle,
  567 + &allocated);
555 568 if (session_idx < 0)
556 569 return session_idx;
557 570 size = &p->rdev->vce.img_size[session_idx];
... ... @@ -561,6 +574,13 @@
561 574 break;
562 575  
563 576 case 0x01000001: // create
  577 + created = true;
  578 + if (!allocated) {
  579 + DRM_ERROR("Handle already in use!\n");
  580 + r = -EINVAL;
  581 + goto out;
  582 + }
  583 +
564 584 *size = radeon_get_ib_value(p, p->idx + 8) *
565 585 radeon_get_ib_value(p, p->idx + 10) *
566 586 8 * 3 / 2;
567 587  
... ... @@ -578,12 +598,12 @@
578 598 r = radeon_vce_cs_reloc(p, p->idx + 10, p->idx + 9,
579 599 *size);
580 600 if (r)
581   - return r;
  601 + goto out;
582 602  
583 603 r = radeon_vce_cs_reloc(p, p->idx + 12, p->idx + 11,
584 604 *size / 3);
585 605 if (r)
586   - return r;
  606 + goto out;
587 607 break;
588 608  
589 609 case 0x02000001: // destroy
... ... @@ -594,7 +614,7 @@
594 614 r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2,
595 615 *size * 2);
596 616 if (r)
597   - return r;
  617 + goto out;
598 618 break;
599 619  
600 620 case 0x05000004: // video bitstream buffer
601 621  
602 622  
603 623  
604 624  
605 625  
... ... @@ -602,36 +622,47 @@
602 622 r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2,
603 623 tmp);
604 624 if (r)
605   - return r;
  625 + goto out;
606 626 break;
607 627  
608 628 case 0x05000005: // feedback buffer
609 629 r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2,
610 630 4096);
611 631 if (r)
612   - return r;
  632 + goto out;
613 633 break;
614 634  
615 635 default:
616 636 DRM_ERROR("invalid VCE command (0x%x)!\n", cmd);
617   - return -EINVAL;
  637 + r = -EINVAL;
  638 + goto out;
618 639 }
619 640  
620 641 if (session_idx == -1) {
621 642 DRM_ERROR("no session command at start of IB\n");
622   - return -EINVAL;
  643 + r = -EINVAL;
  644 + goto out;
623 645 }
624 646  
625 647 p->idx += len / 4;
626 648 }
627 649  
628   - if (destroyed) {
629   - /* IB contains a destroy msg, free the handle */
  650 + if (allocated && !created) {
  651 + DRM_ERROR("New session without create command!\n");
  652 + r = -ENOENT;
  653 + }
  654 +
  655 +out:
  656 + if ((!r && destroyed) || (r && allocated)) {
  657 + /*
  658 + * IB contains a destroy msg or we have allocated an
  659 + * handle and got an error, anyway free the handle
  660 + */
630 661 for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i)
631 662 atomic_cmpxchg(&p->rdev->vce.handles[i], handle, 0);
632 663 }
633 664  
634   - return 0;
  665 + return r;
635 666 }
636 667  
637 668 /**
drivers/gpu/drm/radeon/rv770d.h
... ... @@ -989,6 +989,9 @@
989 989 ((n) & 0x3FFF) << 16)
990 990  
991 991 /* UVD */
  992 +#define UVD_SEMA_ADDR_LOW 0xef00
  993 +#define UVD_SEMA_ADDR_HIGH 0xef04
  994 +#define UVD_SEMA_CMD 0xef08
992 995 #define UVD_GPCOM_VCPU_CMD 0xef0c
993 996 #define UVD_GPCOM_VCPU_DATA0 0xef10
994 997 #define UVD_GPCOM_VCPU_DATA1 0xef14
drivers/gpu/drm/radeon/uvd_v1_0.c
... ... @@ -466,18 +466,8 @@
466 466 struct radeon_semaphore *semaphore,
467 467 bool emit_wait)
468 468 {
469   - uint64_t addr = semaphore->gpu_addr;
470   -
471   - radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0));
472   - radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
473   -
474   - radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0));
475   - radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
476   -
477   - radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
478   - radeon_ring_write(ring, emit_wait ? 1 : 0);
479   -
480   - return true;
  469 + /* disable semaphores for UVD V1 hardware */
  470 + return false;
481 471 }
482 472  
483 473 /**
drivers/gpu/drm/radeon/uvd_v2_2.c
... ... @@ -60,6 +60,35 @@
60 60 }
61 61  
62 62 /**
  63 + * uvd_v2_2_semaphore_emit - emit semaphore command
  64 + *
  65 + * @rdev: radeon_device pointer
  66 + * @ring: radeon_ring pointer
  67 + * @semaphore: semaphore to emit commands for
  68 + * @emit_wait: true if we should emit a wait command
  69 + *
  70 + * Emit a semaphore command (either wait or signal) to the UVD ring.
  71 + */
  72 +bool uvd_v2_2_semaphore_emit(struct radeon_device *rdev,
  73 + struct radeon_ring *ring,
  74 + struct radeon_semaphore *semaphore,
  75 + bool emit_wait)
  76 +{
  77 + uint64_t addr = semaphore->gpu_addr;
  78 +
  79 + radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0));
  80 + radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
  81 +
  82 + radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0));
  83 + radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
  84 +
  85 + radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
  86 + radeon_ring_write(ring, emit_wait ? 1 : 0);
  87 +
  88 + return true;
  89 +}
  90 +
  91 +/**
63 92 * uvd_v2_2_resume - memory controller programming
64 93 *
65 94 * @rdev: radeon_device pointer