diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 80 |
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 | ||
807 | static int amdgpu_uvd_free_job( | 821 | static 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 | ||