aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c80
1 files changed, 47 insertions, 33 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index 2cf6c6b06e3b..d0312364d950 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -156,7 +156,7 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
156 r = amdgpu_bo_create(adev, bo_size, PAGE_SIZE, true, 156 r = amdgpu_bo_create(adev, bo_size, PAGE_SIZE, true,
157 AMDGPU_GEM_DOMAIN_VRAM, 157 AMDGPU_GEM_DOMAIN_VRAM,
158 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, 158 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
159 NULL, &adev->uvd.vcpu_bo); 159 NULL, NULL, &adev->uvd.vcpu_bo);
160 if (r) { 160 if (r) {
161 dev_err(adev->dev, "(%d) failed to allocate UVD bo\n", r); 161 dev_err(adev->dev, "(%d) failed to allocate UVD bo\n", r);
162 return r; 162 return r;
@@ -543,46 +543,60 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx,
543 return -EINVAL; 543 return -EINVAL;
544 } 544 }
545 545
546 if (msg_type == 1) { 546 switch (msg_type) {
547 case 0:
548 /* it's a create msg, calc image size (width * height) */
549 amdgpu_bo_kunmap(bo);
550
551 /* try to alloc a new handle */
552 for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) {
553 if (atomic_read(&adev->uvd.handles[i]) == handle) {
554 DRM_ERROR("Handle 0x%x already in use!\n", handle);
555 return -EINVAL;
556 }
557
558 if (!atomic_cmpxchg(&adev->uvd.handles[i], 0, handle)) {
559 adev->uvd.filp[i] = ctx->parser->filp;
560 return 0;
561 }
562 }
563
564 DRM_ERROR("No more free UVD handles!\n");
565 return -EINVAL;
566
567 case 1:
547 /* it's a decode msg, calc buffer sizes */ 568 /* it's a decode msg, calc buffer sizes */
548 r = amdgpu_uvd_cs_msg_decode(msg, ctx->buf_sizes); 569 r = amdgpu_uvd_cs_msg_decode(msg, ctx->buf_sizes);
549 amdgpu_bo_kunmap(bo); 570 amdgpu_bo_kunmap(bo);
550 if (r) 571 if (r)
551 return r; 572 return r;
552 573
553 } else if (msg_type == 2) { 574 /* validate the handle */
575 for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) {
576 if (atomic_read(&adev->uvd.handles[i]) == handle) {
577 if (adev->uvd.filp[i] != ctx->parser->filp) {
578 DRM_ERROR("UVD handle collision detected!\n");
579 return -EINVAL;
580 }
581 return 0;
582 }
583 }
584
585 DRM_ERROR("Invalid UVD handle 0x%x!\n", handle);
586 return -ENOENT;
587
588 case 2:
554 /* it's a destroy msg, free the handle */ 589 /* it's a destroy msg, free the handle */
555 for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) 590 for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i)
556 atomic_cmpxchg(&adev->uvd.handles[i], handle, 0); 591 atomic_cmpxchg(&adev->uvd.handles[i], handle, 0);
557 amdgpu_bo_kunmap(bo); 592 amdgpu_bo_kunmap(bo);
558 return 0; 593 return 0;
559 } else {
560 /* it's a create msg */
561 amdgpu_bo_kunmap(bo);
562
563 if (msg_type != 0) {
564 DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
565 return -EINVAL;
566 }
567
568 /* it's a create msg, no special handling needed */
569 }
570
571 /* create or decode, validate the handle */
572 for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) {
573 if (atomic_read(&adev->uvd.handles[i]) == handle)
574 return 0;
575 }
576 594
577 /* handle not found try to alloc a new one */ 595 default:
578 for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { 596 DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
579 if (!atomic_cmpxchg(&adev->uvd.handles[i], 0, handle)) { 597 return -EINVAL;
580 adev->uvd.filp[i] = ctx->parser->filp;
581 return 0;
582 }
583 } 598 }
584 599 BUG();
585 DRM_ERROR("No more free UVD handles!\n");
586 return -EINVAL; 600 return -EINVAL;
587} 601}
588 602
@@ -805,10 +819,10 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx)
805} 819}
806 820
807static int amdgpu_uvd_free_job( 821static int amdgpu_uvd_free_job(
808 struct amdgpu_job *sched_job) 822 struct amdgpu_job *job)
809{ 823{
810 amdgpu_ib_free(sched_job->adev, sched_job->ibs); 824 amdgpu_ib_free(job->adev, job->ibs);
811 kfree(sched_job->ibs); 825 kfree(job->ibs);
812 return 0; 826 return 0;
813} 827}
814 828
@@ -905,7 +919,7 @@ int amdgpu_uvd_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
905 r = amdgpu_bo_create(adev, 1024, PAGE_SIZE, true, 919 r = amdgpu_bo_create(adev, 1024, PAGE_SIZE, true,
906 AMDGPU_GEM_DOMAIN_VRAM, 920 AMDGPU_GEM_DOMAIN_VRAM,
907 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, 921 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
908 NULL, &bo); 922 NULL, NULL, &bo);
909 if (r) 923 if (r)
910 return r; 924 return r;
911 925
@@ -954,7 +968,7 @@ int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
954 r = amdgpu_bo_create(adev, 1024, PAGE_SIZE, true, 968 r = amdgpu_bo_create(adev, 1024, PAGE_SIZE, true,
955 AMDGPU_GEM_DOMAIN_VRAM, 969 AMDGPU_GEM_DOMAIN_VRAM,
956 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, 970 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
957 NULL, &bo); 971 NULL, NULL, &bo);
958 if (r) 972 if (r)
959 return r; 973 return r;
960 974