From: Greg Kroah-Hartman Date: Fri, 15 May 2015 18:14:05 +0000 (-0700) Subject: 4.0-stable patches X-Git-Tag: v3.10.79~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e9980dc2804e0e9bbab7bb7835180ad12bb271e5;p=thirdparty%2Fkernel%2Fstable-queue.git 4.0-stable patches added patches: drm-radeon-disable-semaphores-for-uvd-v1-v2.patch drm-radeon-don-t-setup-audio-on-asics-that-don-t-support-it.patch drm-radeon-fix-userptr-bo-unpin-bug-v3.patch drm-radeon-make-uvd-handle-checking-more-strict.patch drm-radeon-make-vce-handle-check-more-strict.patch drm-radeon-more-strictly-validate-the-uvd-codec.patch mmc-card-don-t-access-rpmb-partitions-for-normal-read-write.patch mmc-core-add-missing-pm-event-in-mmc_pm_notify-to-fix-hib-restore.patch mmc-sh_mmcif-fix-timeout-value-for-command-request.patch pinctrl-don-t-just-pretend-to-protect-pinctrl_maps-do-it-for-real.patch --- diff --git a/queue-4.0/drm-radeon-disable-semaphores-for-uvd-v1-v2.patch b/queue-4.0/drm-radeon-disable-semaphores-for-uvd-v1-v2.patch new file mode 100644 index 00000000000..f525b3be131 --- /dev/null +++ b/queue-4.0/drm-radeon-disable-semaphores-for-uvd-v1-v2.patch @@ -0,0 +1,127 @@ +From 013ead48a843442e63b9426e3bd5df18ca5d054a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Fri, 1 May 2015 12:34:12 +0200 +Subject: drm/radeon: disable semaphores for UVD V1 (v2) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: =?UTF-8?q?Christian=20K=C3=B6nig?= + +commit 013ead48a843442e63b9426e3bd5df18ca5d054a upstream. + +Hardware doesn't seem to work correctly, just block userspace in this case. + +v2: add missing defines + +Bugs: https://bugs.freedesktop.org/show_bug.cgi?id=85320 + +Signed-off-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_asic.c | 2 +- + drivers/gpu/drm/radeon/radeon_asic.h | 4 ++++ + drivers/gpu/drm/radeon/rv770d.h | 3 +++ + drivers/gpu/drm/radeon/uvd_v1_0.c | 14 ++------------ + drivers/gpu/drm/radeon/uvd_v2_2.c | 29 +++++++++++++++++++++++++++++ + 5 files changed, 39 insertions(+), 13 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_asic.c ++++ b/drivers/gpu/drm/radeon/radeon_asic.c +@@ -1180,7 +1180,7 @@ static struct radeon_asic rs780_asic = { + static struct radeon_asic_ring rv770_uvd_ring = { + .ib_execute = &uvd_v1_0_ib_execute, + .emit_fence = &uvd_v2_2_fence_emit, +- .emit_semaphore = &uvd_v1_0_semaphore_emit, ++ .emit_semaphore = &uvd_v2_2_semaphore_emit, + .cs_parse = &radeon_uvd_cs_parse, + .ring_test = &uvd_v1_0_ring_test, + .ib_test = &uvd_v1_0_ib_test, +--- a/drivers/gpu/drm/radeon/radeon_asic.h ++++ b/drivers/gpu/drm/radeon/radeon_asic.h +@@ -919,6 +919,10 @@ void uvd_v1_0_ib_execute(struct radeon_d + int uvd_v2_2_resume(struct radeon_device *rdev); + void uvd_v2_2_fence_emit(struct radeon_device *rdev, + struct radeon_fence *fence); ++bool uvd_v2_2_semaphore_emit(struct radeon_device *rdev, ++ struct radeon_ring *ring, ++ struct radeon_semaphore *semaphore, ++ bool emit_wait); + + /* uvd v3.1 */ + bool uvd_v3_1_semaphore_emit(struct radeon_device *rdev, +--- a/drivers/gpu/drm/radeon/rv770d.h ++++ b/drivers/gpu/drm/radeon/rv770d.h +@@ -989,6 +989,9 @@ + ((n) & 0x3FFF) << 16) + + /* UVD */ ++#define UVD_SEMA_ADDR_LOW 0xef00 ++#define UVD_SEMA_ADDR_HIGH 0xef04 ++#define UVD_SEMA_CMD 0xef08 + #define UVD_GPCOM_VCPU_CMD 0xef0c + #define UVD_GPCOM_VCPU_DATA0 0xef10 + #define UVD_GPCOM_VCPU_DATA1 0xef14 +--- a/drivers/gpu/drm/radeon/uvd_v1_0.c ++++ b/drivers/gpu/drm/radeon/uvd_v1_0.c +@@ -466,18 +466,8 @@ bool uvd_v1_0_semaphore_emit(struct rade + struct radeon_semaphore *semaphore, + bool emit_wait) + { +- uint64_t addr = semaphore->gpu_addr; +- +- radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0)); +- radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF); +- +- radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0)); +- radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF); +- +- radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0)); +- radeon_ring_write(ring, emit_wait ? 1 : 0); +- +- return true; ++ /* disable semaphores for UVD V1 hardware */ ++ return false; + } + + /** +--- a/drivers/gpu/drm/radeon/uvd_v2_2.c ++++ b/drivers/gpu/drm/radeon/uvd_v2_2.c +@@ -60,6 +60,35 @@ void uvd_v2_2_fence_emit(struct radeon_d + } + + /** ++ * uvd_v2_2_semaphore_emit - emit semaphore command ++ * ++ * @rdev: radeon_device pointer ++ * @ring: radeon_ring pointer ++ * @semaphore: semaphore to emit commands for ++ * @emit_wait: true if we should emit a wait command ++ * ++ * Emit a semaphore command (either wait or signal) to the UVD ring. ++ */ ++bool uvd_v2_2_semaphore_emit(struct radeon_device *rdev, ++ struct radeon_ring *ring, ++ struct radeon_semaphore *semaphore, ++ bool emit_wait) ++{ ++ uint64_t addr = semaphore->gpu_addr; ++ ++ radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0)); ++ radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF); ++ ++ radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0)); ++ radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF); ++ ++ radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0)); ++ radeon_ring_write(ring, emit_wait ? 1 : 0); ++ ++ return true; ++} ++ ++/** + * uvd_v2_2_resume - memory controller programming + * + * @rdev: radeon_device pointer diff --git a/queue-4.0/drm-radeon-don-t-setup-audio-on-asics-that-don-t-support-it.patch b/queue-4.0/drm-radeon-don-t-setup-audio-on-asics-that-don-t-support-it.patch new file mode 100644 index 00000000000..c4fd8a25165 --- /dev/null +++ b/queue-4.0/drm-radeon-don-t-setup-audio-on-asics-that-don-t-support-it.patch @@ -0,0 +1,33 @@ +From d73a824acc705571c0f47596326d7967fba9a1d9 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Mon, 4 May 2015 14:35:01 -0400 +Subject: drm/radeon: don't setup audio on asics that don't support it + +From: Alex Deucher + +commit d73a824acc705571c0f47596326d7967fba9a1d9 upstream. + +bug: https://bugzilla.kernel.org/show_bug.cgi?id=97701 + +Reported-by: Mikael Pettersson +Tested-by: Mikael Pettersson +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_audio.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/gpu/drm/radeon/radeon_audio.c ++++ b/drivers/gpu/drm/radeon/radeon_audio.c +@@ -464,6 +464,10 @@ void radeon_audio_detect(struct drm_conn + return; + + rdev = connector->encoder->dev->dev_private; ++ ++ if (!radeon_audio_chipset_supported(rdev)) ++ return; ++ + radeon_encoder = to_radeon_encoder(connector->encoder); + dig = radeon_encoder->enc_priv; + diff --git a/queue-4.0/drm-radeon-fix-userptr-bo-unpin-bug-v3.patch b/queue-4.0/drm-radeon-fix-userptr-bo-unpin-bug-v3.patch new file mode 100644 index 00000000000..fa27565d732 --- /dev/null +++ b/queue-4.0/drm-radeon-fix-userptr-bo-unpin-bug-v3.patch @@ -0,0 +1,50 @@ +From db12973cd581d4e79f4aadd0960948f268d15af7 Mon Sep 17 00:00:00 2001 +From: "monk.liu" +Date: Tue, 5 May 2015 09:24:17 +0200 +Subject: drm/radeon: fix userptr BO unpin bug v3 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: "monk.liu" + +commit db12973cd581d4e79f4aadd0960948f268d15af7 upstream. + +Fixing a memory leak with userptrs. + +v2: clean up the loop, use an iterator instead +v3: remove unused variable + +Signed-off-by: monk.liu +Signed-off-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_ttm.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_ttm.c ++++ b/drivers/gpu/drm/radeon/radeon_ttm.c +@@ -591,8 +591,7 @@ static void radeon_ttm_tt_unpin_userptr( + { + struct radeon_device *rdev = radeon_get_rdev(ttm->bdev); + struct radeon_ttm_tt *gtt = (void *)ttm; +- struct scatterlist *sg; +- int i; ++ struct sg_page_iter sg_iter; + + int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY); + enum dma_data_direction direction = write ? +@@ -605,9 +604,8 @@ static void radeon_ttm_tt_unpin_userptr( + /* free the sg table and pages again */ + dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction); + +- for_each_sg(ttm->sg->sgl, sg, ttm->sg->nents, i) { +- struct page *page = sg_page(sg); +- ++ for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) { ++ struct page *page = sg_page_iter_page(&sg_iter); + if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY)) + set_page_dirty(page); + diff --git a/queue-4.0/drm-radeon-make-uvd-handle-checking-more-strict.patch b/queue-4.0/drm-radeon-make-uvd-handle-checking-more-strict.patch new file mode 100644 index 00000000000..50c89549405 --- /dev/null +++ b/queue-4.0/drm-radeon-make-uvd-handle-checking-more-strict.patch @@ -0,0 +1,118 @@ +From a1b403da70e038ca6c6c6fe434d1d873546873a3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Thu, 7 May 2015 15:19:23 +0200 +Subject: drm/radeon: make UVD handle checking more strict +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: =?UTF-8?q?Christian=20K=C3=B6nig?= + +commit a1b403da70e038ca6c6c6fe434d1d873546873a3 upstream. + +Invalid messages can crash the hw otherwise. + +Signed-off-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_uvd.c | 72 +++++++++++++++++++++--------------- + 1 file changed, 43 insertions(+), 29 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_uvd.c ++++ b/drivers/gpu/drm/radeon/radeon_uvd.c +@@ -436,50 +436,64 @@ static int radeon_uvd_cs_msg(struct rade + return -EINVAL; + } + +- if (msg_type == 1) { ++ switch (msg_type) { ++ case 0: ++ /* it's a create msg, calc image size (width * height) */ ++ img_size = msg[7] * msg[8]; ++ radeon_bo_kunmap(bo); ++ ++ /* try to alloc a new handle */ ++ for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { ++ if (atomic_read(&p->rdev->uvd.handles[i]) == handle) { ++ DRM_ERROR("Handle 0x%x already in use!\n", handle); ++ return -EINVAL; ++ } ++ ++ if (!atomic_cmpxchg(&p->rdev->uvd.handles[i], 0, handle)) { ++ p->rdev->uvd.filp[i] = p->filp; ++ p->rdev->uvd.img_size[i] = img_size; ++ return 0; ++ } ++ } ++ ++ DRM_ERROR("No more free UVD handles!\n"); ++ return -EINVAL; ++ ++ case 1: + /* it's a decode msg, calc buffer sizes */ + r = radeon_uvd_cs_msg_decode(msg, buf_sizes); +- /* calc image size (width * height) */ +- img_size = msg[6] * msg[7]; + radeon_bo_kunmap(bo); + if (r) + return r; + +- } else if (msg_type == 2) { ++ /* validate the handle */ ++ for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { ++ if (atomic_read(&p->rdev->uvd.handles[i]) == handle) { ++ if (p->rdev->uvd.filp[i] != p->filp) { ++ DRM_ERROR("UVD handle collision detected!\n"); ++ return -EINVAL; ++ } ++ return 0; ++ } ++ } ++ ++ DRM_ERROR("Invalid UVD handle 0x%x!\n", handle); ++ return -ENOENT; ++ ++ case 2: + /* it's a destroy msg, free the handle */ + for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) + atomic_cmpxchg(&p->rdev->uvd.handles[i], handle, 0); + radeon_bo_kunmap(bo); + return 0; +- } else { +- /* it's a create msg, calc image size (width * height) */ +- img_size = msg[7] * msg[8]; +- radeon_bo_kunmap(bo); +- +- if (msg_type != 0) { +- DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type); +- return -EINVAL; +- } + +- /* it's a create msg, no special handling needed */ +- } +- +- /* create or decode, validate the handle */ +- for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { +- if (atomic_read(&p->rdev->uvd.handles[i]) == handle) +- return 0; +- } ++ default: + +- /* handle not found try to alloc a new one */ +- for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { +- if (!atomic_cmpxchg(&p->rdev->uvd.handles[i], 0, handle)) { +- p->rdev->uvd.filp[i] = p->filp; +- p->rdev->uvd.img_size[i] = img_size; +- return 0; +- } ++ DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type); ++ return -EINVAL; + } + +- DRM_ERROR("No more free UVD handles!\n"); ++ BUG(); + return -EINVAL; + } + diff --git a/queue-4.0/drm-radeon-make-vce-handle-check-more-strict.patch b/queue-4.0/drm-radeon-make-vce-handle-check-more-strict.patch new file mode 100644 index 00000000000..64c553bfcfa --- /dev/null +++ b/queue-4.0/drm-radeon-make-vce-handle-check-more-strict.patch @@ -0,0 +1,193 @@ +From 29c63fe22a17c64e54016040cd882481bd45ee5a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Thu, 7 May 2015 15:19:22 +0200 +Subject: drm/radeon: make VCE handle check more strict +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: =?UTF-8?q?Christian=20K=C3=B6nig?= + +commit 29c63fe22a17c64e54016040cd882481bd45ee5a upstream. + +Invalid handles can crash the hw. + +Signed-off-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_vce.c | 65 ++++++++++++++++++++++++++---------- + 1 file changed, 48 insertions(+), 17 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_vce.c ++++ b/drivers/gpu/drm/radeon/radeon_vce.c +@@ -493,18 +493,27 @@ int radeon_vce_cs_reloc(struct radeon_cs + * + * @p: parser context + * @handle: handle to validate ++ * @allocated: allocated a new handle? + * + * Validates the handle and return the found session index or -EINVAL + * we we don't have another free session index. + */ +-int radeon_vce_validate_handle(struct radeon_cs_parser *p, uint32_t handle) ++static int radeon_vce_validate_handle(struct radeon_cs_parser *p, ++ uint32_t handle, bool *allocated) + { + unsigned i; + ++ *allocated = false; ++ + /* validate the handle */ + for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) { +- if (atomic_read(&p->rdev->vce.handles[i]) == handle) ++ if (atomic_read(&p->rdev->vce.handles[i]) == handle) { ++ if (p->rdev->vce.filp[i] != p->filp) { ++ DRM_ERROR("VCE handle collision detected!\n"); ++ return -EINVAL; ++ } + return i; ++ } + } + + /* handle not found try to alloc a new one */ +@@ -512,6 +521,7 @@ int radeon_vce_validate_handle(struct ra + if (!atomic_cmpxchg(&p->rdev->vce.handles[i], 0, handle)) { + p->rdev->vce.filp[i] = p->filp; + p->rdev->vce.img_size[i] = 0; ++ *allocated = true; + return i; + } + } +@@ -529,10 +539,10 @@ int radeon_vce_validate_handle(struct ra + int radeon_vce_cs_parse(struct radeon_cs_parser *p) + { + int session_idx = -1; +- bool destroyed = false; ++ bool destroyed = false, created = false, allocated = false; + uint32_t tmp, handle = 0; + uint32_t *size = &tmp; +- int i, r; ++ int i, r = 0; + + while (p->idx < p->chunk_ib->length_dw) { + uint32_t len = radeon_get_ib_value(p, p->idx); +@@ -540,18 +550,21 @@ int radeon_vce_cs_parse(struct radeon_cs + + if ((len < 8) || (len & 3)) { + DRM_ERROR("invalid VCE command length (%d)!\n", len); +- return -EINVAL; ++ r = -EINVAL; ++ goto out; + } + + if (destroyed) { + DRM_ERROR("No other command allowed after destroy!\n"); +- return -EINVAL; ++ r = -EINVAL; ++ goto out; + } + + switch (cmd) { + case 0x00000001: // session + handle = radeon_get_ib_value(p, p->idx + 2); +- session_idx = radeon_vce_validate_handle(p, handle); ++ session_idx = radeon_vce_validate_handle(p, handle, ++ &allocated); + if (session_idx < 0) + return session_idx; + size = &p->rdev->vce.img_size[session_idx]; +@@ -561,6 +574,13 @@ int radeon_vce_cs_parse(struct radeon_cs + break; + + case 0x01000001: // create ++ created = true; ++ if (!allocated) { ++ DRM_ERROR("Handle already in use!\n"); ++ r = -EINVAL; ++ goto out; ++ } ++ + *size = radeon_get_ib_value(p, p->idx + 8) * + radeon_get_ib_value(p, p->idx + 10) * + 8 * 3 / 2; +@@ -577,12 +597,12 @@ int radeon_vce_cs_parse(struct radeon_cs + r = radeon_vce_cs_reloc(p, p->idx + 10, p->idx + 9, + *size); + if (r) +- return r; ++ goto out; + + r = radeon_vce_cs_reloc(p, p->idx + 12, p->idx + 11, + *size / 3); + if (r) +- return r; ++ goto out; + break; + + case 0x02000001: // destroy +@@ -593,7 +613,7 @@ int radeon_vce_cs_parse(struct radeon_cs + r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2, + *size * 2); + if (r) +- return r; ++ goto out; + break; + + case 0x05000004: // video bitstream buffer +@@ -601,36 +621,47 @@ int radeon_vce_cs_parse(struct radeon_cs + r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2, + tmp); + if (r) +- return r; ++ goto out; + break; + + case 0x05000005: // feedback buffer + r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2, + 4096); + if (r) +- return r; ++ goto out; + break; + + default: + DRM_ERROR("invalid VCE command (0x%x)!\n", cmd); +- return -EINVAL; ++ r = -EINVAL; ++ goto out; + } + + if (session_idx == -1) { + DRM_ERROR("no session command at start of IB\n"); +- return -EINVAL; ++ r = -EINVAL; ++ goto out; + } + + p->idx += len / 4; + } + +- if (destroyed) { +- /* IB contains a destroy msg, free the handle */ ++ if (allocated && !created) { ++ DRM_ERROR("New session without create command!\n"); ++ r = -ENOENT; ++ } ++ ++out: ++ if ((!r && destroyed) || (r && allocated)) { ++ /* ++ * IB contains a destroy msg or we have allocated an ++ * handle and got an error, anyway free the handle ++ */ + for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) + atomic_cmpxchg(&p->rdev->vce.handles[i], handle, 0); + } + +- return 0; ++ return r; + } + + /** diff --git a/queue-4.0/drm-radeon-more-strictly-validate-the-uvd-codec.patch b/queue-4.0/drm-radeon-more-strictly-validate-the-uvd-codec.patch new file mode 100644 index 00000000000..3b698daa419 --- /dev/null +++ b/queue-4.0/drm-radeon-more-strictly-validate-the-uvd-codec.patch @@ -0,0 +1,79 @@ +From d52cdfa4a0c6406bbfb33206341eaf1fb1555994 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Thu, 7 May 2015 15:19:24 +0200 +Subject: drm/radeon: more strictly validate the UVD codec +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: =?UTF-8?q?Christian=20K=C3=B6nig?= + +commit d52cdfa4a0c6406bbfb33206341eaf1fb1555994 upstream. + +MPEG 2/4 are only supported since UVD3. + +Signed-off-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_uvd.c | 33 +++++++++++++++++++++++++++++++-- + 1 file changed, 31 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_uvd.c ++++ b/drivers/gpu/drm/radeon/radeon_uvd.c +@@ -396,6 +396,29 @@ static int radeon_uvd_cs_msg_decode(uint + return 0; + } + ++static int radeon_uvd_validate_codec(struct radeon_cs_parser *p, ++ unsigned stream_type) ++{ ++ switch (stream_type) { ++ case 0: /* H264 */ ++ case 1: /* VC1 */ ++ /* always supported */ ++ return 0; ++ ++ case 3: /* MPEG2 */ ++ case 4: /* MPEG4 */ ++ /* only since UVD 3 */ ++ if (p->rdev->family >= CHIP_PALM) ++ return 0; ++ ++ /* fall through */ ++ default: ++ DRM_ERROR("UVD codec not supported by hardware %d!\n", ++ stream_type); ++ return -EINVAL; ++ } ++} ++ + static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, + unsigned offset, unsigned buf_sizes[]) + { +@@ -440,7 +463,11 @@ static int radeon_uvd_cs_msg(struct rade + case 0: + /* it's a create msg, calc image size (width * height) */ + img_size = msg[7] * msg[8]; ++ ++ r = radeon_uvd_validate_codec(p, msg[4]); + radeon_bo_kunmap(bo); ++ if (r) ++ return r; + + /* try to alloc a new handle */ + for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { +@@ -460,8 +487,10 @@ static int radeon_uvd_cs_msg(struct rade + return -EINVAL; + + case 1: +- /* it's a decode msg, calc buffer sizes */ +- r = radeon_uvd_cs_msg_decode(msg, buf_sizes); ++ /* it's a decode msg, validate codec and calc buffer sizes */ ++ r = radeon_uvd_validate_codec(p, msg[4]); ++ if (!r) ++ r = radeon_uvd_cs_msg_decode(msg, buf_sizes); + radeon_bo_kunmap(bo); + if (r) + return r; diff --git a/queue-4.0/mmc-card-don-t-access-rpmb-partitions-for-normal-read-write.patch b/queue-4.0/mmc-card-don-t-access-rpmb-partitions-for-normal-read-write.patch new file mode 100644 index 00000000000..5d520343b81 --- /dev/null +++ b/queue-4.0/mmc-card-don-t-access-rpmb-partitions-for-normal-read-write.patch @@ -0,0 +1,93 @@ +From 4e93b9a6abc0d028daf3c8a00cb77b679d8a4df4 Mon Sep 17 00:00:00 2001 +From: Chuanxiao Dong +Date: Tue, 12 Aug 2014 12:01:30 +0800 +Subject: mmc: card: Don't access RPMB partitions for normal read/write + +From: Chuanxiao Dong + +commit 4e93b9a6abc0d028daf3c8a00cb77b679d8a4df4 upstream. + +During kernel boot, it will try to read some logical sectors +of each block device node for the possible partition table. + +But since RPMB partition is special and can not be accessed +by normal eMMC read / write CMDs, it will cause below error +messages during kernel boot: +... + mmc0: Got data interrupt 0x00000002 even though no data operation was in progress. + mmcblk0rpmb: error -110 transferring data, sector 0, nr 32, cmd response 0x900, card status 0xb00 + mmcblk0rpmb: retrying using single block read + mmcblk0rpmb: timed out sending r/w cmd command, card status 0x400900 + mmcblk0rpmb: timed out sending r/w cmd command, card status 0x400900 + mmcblk0rpmb: timed out sending r/w cmd command, card status 0x400900 + mmcblk0rpmb: timed out sending r/w cmd command, card status 0x400900 + mmcblk0rpmb: timed out sending r/w cmd command, card status 0x400900 + mmcblk0rpmb: timed out sending r/w cmd command, card status 0x400900 + end_request: I/O error, dev mmcblk0rpmb, sector 0 + Buffer I/O error on device mmcblk0rpmb, logical block 0 + end_request: I/O error, dev mmcblk0rpmb, sector 8 + Buffer I/O error on device mmcblk0rpmb, logical block 1 + end_request: I/O error, dev mmcblk0rpmb, sector 16 + Buffer I/O error on device mmcblk0rpmb, logical block 2 + end_request: I/O error, dev mmcblk0rpmb, sector 24 + Buffer I/O error on device mmcblk0rpmb, logical block 3 +... + +This patch will discard the access request in eMMC queue if +it is RPMB partition access request. By this way, it avoids +trigger above error messages. + +Fixes: 090d25fe224c ("mmc: core: Expose access to RPMB partition") +Signed-off-by: Yunpeng Gao +Signed-off-by: Chuanxiao Dong +Tested-by: Michael Shigorin +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/card/block.c | 12 ++++++++++++ + drivers/mmc/card/queue.c | 2 +- + drivers/mmc/card/queue.h | 2 ++ + 3 files changed, 15 insertions(+), 1 deletion(-) + +--- a/drivers/mmc/card/block.c ++++ b/drivers/mmc/card/block.c +@@ -1029,6 +1029,18 @@ static inline void mmc_blk_reset_success + md->reset_done &= ~type; + } + ++int mmc_access_rpmb(struct mmc_queue *mq) ++{ ++ struct mmc_blk_data *md = mq->data; ++ /* ++ * If this is a RPMB partition access, return ture ++ */ ++ if (md && md->part_type == EXT_CSD_PART_CONFIG_ACC_RPMB) ++ return true; ++ ++ return false; ++} ++ + static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) + { + struct mmc_blk_data *md = mq->data; +--- a/drivers/mmc/card/queue.c ++++ b/drivers/mmc/card/queue.c +@@ -38,7 +38,7 @@ static int mmc_prep_request(struct reque + return BLKPREP_KILL; + } + +- if (mq && mmc_card_removed(mq->card)) ++ if (mq && (mmc_card_removed(mq->card) || mmc_access_rpmb(mq))) + return BLKPREP_KILL; + + req->cmd_flags |= REQ_DONTPREP; +--- a/drivers/mmc/card/queue.h ++++ b/drivers/mmc/card/queue.h +@@ -73,4 +73,6 @@ extern void mmc_queue_bounce_post(struct + extern int mmc_packed_init(struct mmc_queue *, struct mmc_card *); + extern void mmc_packed_clean(struct mmc_queue *); + ++extern int mmc_access_rpmb(struct mmc_queue *); ++ + #endif diff --git a/queue-4.0/mmc-core-add-missing-pm-event-in-mmc_pm_notify-to-fix-hib-restore.patch b/queue-4.0/mmc-core-add-missing-pm-event-in-mmc_pm_notify-to-fix-hib-restore.patch new file mode 100644 index 00000000000..1ab5f94dd6b --- /dev/null +++ b/queue-4.0/mmc-core-add-missing-pm-event-in-mmc_pm_notify-to-fix-hib-restore.patch @@ -0,0 +1,38 @@ +From 184af16b09360d6273fd6160e6ff7f8e2482ef23 Mon Sep 17 00:00:00 2001 +From: Grygorii Strashko +Date: Thu, 23 Apr 2015 13:43:43 +0300 +Subject: mmc: core: add missing pm event in mmc_pm_notify to fix hib restore + +From: Grygorii Strashko + +commit 184af16b09360d6273fd6160e6ff7f8e2482ef23 upstream. + +The PM_RESTORE_PREPARE is not handled now in mmc_pm_notify(), +as result mmc_rescan() could be scheduled and executed at +late hibernation restore stages when MMC device is suspended +already - which, in turn, will lead to system crash on TI dra7-evm board: + +WARNING: CPU: 0 PID: 3188 at drivers/bus/omap_l3_noc.c:148 l3_interrupt_handler+0x258/0x374() +44000000.ocp:L3 Custom Error: MASTER MPU TARGET L4_PER1_P3 (Idle): Data Access in User mode during Functional access + +Hence, add missed PM_RESTORE_PREPARE PM event in mmc_pm_notify(). + +Fixes: 4c2ef25fe0b8 (mmc: fix all hangs related to mmc/sd card...) +Signed-off-by: Grygorii Strashko +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/core/core.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/mmc/core/core.c ++++ b/drivers/mmc/core/core.c +@@ -2648,6 +2648,7 @@ int mmc_pm_notify(struct notifier_block + switch (mode) { + case PM_HIBERNATION_PREPARE: + case PM_SUSPEND_PREPARE: ++ case PM_RESTORE_PREPARE: + spin_lock_irqsave(&host->lock, flags); + host->rescan_disable = 1; + spin_unlock_irqrestore(&host->lock, flags); diff --git a/queue-4.0/mmc-sh_mmcif-fix-timeout-value-for-command-request.patch b/queue-4.0/mmc-sh_mmcif-fix-timeout-value-for-command-request.patch new file mode 100644 index 00000000000..0435cbe84f5 --- /dev/null +++ b/queue-4.0/mmc-sh_mmcif-fix-timeout-value-for-command-request.patch @@ -0,0 +1,42 @@ +From bad4371d87d1d1ed1aecd9c9cc21c41ac3f289c8 Mon Sep 17 00:00:00 2001 +From: Takeshi Kihara +Date: Thu, 30 Apr 2015 02:03:51 +0900 +Subject: mmc: sh_mmcif: Fix timeout value for command request + +From: Takeshi Kihara + +commit bad4371d87d1d1ed1aecd9c9cc21c41ac3f289c8 upstream. + +f9fd54f22e ("mmc: sh_mmcif: Use msecs_to_jiffies() for host->timeout") +changed the timeout value from 1000 jiffies to 1s. In the case where +HZ is 1000 the values are the same. However, for smaller HZ values the +timeout is now smaller, 1s instead of 10s in the case of HZ=100. + +Since the timeout occurs in spite of a normal data transfer a timeout of +10s seems more appropriate. This restores the previous timeout in the +case where HZ=100 and results in an increase over the previous timeout +for larger values of HZ. + +Fixes: f9fd54f22e ("mmc: sh_mmcif: Use msecs_to_jiffies() for host->timeout") +Signed-off-by: Takeshi Kihara +[horms: rewrote changelog to refer to HZ] +Signed-off-by: Simon Horman +Signed-off-by: Yoshihiro Kaneko +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/host/sh_mmcif.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mmc/host/sh_mmcif.c ++++ b/drivers/mmc/host/sh_mmcif.c +@@ -1402,7 +1402,7 @@ static int sh_mmcif_probe(struct platfor + host = mmc_priv(mmc); + host->mmc = mmc; + host->addr = reg; +- host->timeout = msecs_to_jiffies(1000); ++ host->timeout = msecs_to_jiffies(10000); + host->ccs_enable = !pd || !pd->ccs_unsupported; + host->clk_ctrl2_enable = pd && pd->clk_ctrl2_present; + diff --git a/queue-4.0/pinctrl-don-t-just-pretend-to-protect-pinctrl_maps-do-it-for-real.patch b/queue-4.0/pinctrl-don-t-just-pretend-to-protect-pinctrl_maps-do-it-for-real.patch new file mode 100644 index 00000000000..bca5b08c3a5 --- /dev/null +++ b/queue-4.0/pinctrl-don-t-just-pretend-to-protect-pinctrl_maps-do-it-for-real.patch @@ -0,0 +1,103 @@ +From c5272a28566b00cce79127ad382406e0a8650690 Mon Sep 17 00:00:00 2001 +From: Doug Anderson +Date: Fri, 1 May 2015 09:01:27 -0700 +Subject: pinctrl: Don't just pretend to protect pinctrl_maps, do it for real + +From: Doug Anderson + +commit c5272a28566b00cce79127ad382406e0a8650690 upstream. + +Way back, when the world was a simpler place and there was no war, no +evil, and no kernel bugs, there was just a single pinctrl lock. That +was how the world was when (57291ce pinctrl: core device tree mapping +table parsing support) was written. In that case, there were +instances where the pinctrl mutex was already held when +pinctrl_register_map() was called, hence a "locked" parameter was +passed to the function to indicate that the mutex was already locked +(so we shouldn't lock it again). + +A few years ago in (42fed7b pinctrl: move subsystem mutex to +pinctrl_dev struct), we switched to a separate pinctrl_maps_mutex. +...but (oops) we forgot to re-think about the whole "locked" parameter +for pinctrl_register_map(). Basically the "locked" parameter appears +to still refer to whether the bigger pinctrl_dev mutex is locked, but +we're using it to skip locks of our (now separate) pinctrl_maps_mutex. + +That's kind of a bad thing(TM). Probably nobody noticed because most +of the calls to pinctrl_register_map happen at boot time and we've got +synchronous device probing. ...and even cases where we're +asynchronous don't end up actually hitting the race too often. ...but +after banging my head against the wall for a bug that reproduced 1 out +of 1000 reboots and lots of looking through kgdb, I finally noticed +this. + +Anyway, we can now safely remove the "locked" parameter and go back to +a war-free, evil-free, and kernel-bug-free world. + +Fixes: 42fed7ba44e4 ("pinctrl: move subsystem mutex to pinctrl_dev struct") +Signed-off-by: Doug Anderson +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pinctrl/core.c | 10 ++++------ + drivers/pinctrl/core.h | 2 +- + drivers/pinctrl/devicetree.c | 2 +- + 3 files changed, 6 insertions(+), 8 deletions(-) + +--- a/drivers/pinctrl/core.c ++++ b/drivers/pinctrl/core.c +@@ -1110,7 +1110,7 @@ void devm_pinctrl_put(struct pinctrl *p) + EXPORT_SYMBOL_GPL(devm_pinctrl_put); + + int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, +- bool dup, bool locked) ++ bool dup) + { + int i, ret; + struct pinctrl_maps *maps_node; +@@ -1178,11 +1178,9 @@ int pinctrl_register_map(struct pinctrl_ + maps_node->maps = maps; + } + +- if (!locked) +- mutex_lock(&pinctrl_maps_mutex); ++ mutex_lock(&pinctrl_maps_mutex); + list_add_tail(&maps_node->node, &pinctrl_maps); +- if (!locked) +- mutex_unlock(&pinctrl_maps_mutex); ++ mutex_unlock(&pinctrl_maps_mutex); + + return 0; + } +@@ -1197,7 +1195,7 @@ int pinctrl_register_map(struct pinctrl_ + int pinctrl_register_mappings(struct pinctrl_map const *maps, + unsigned num_maps) + { +- return pinctrl_register_map(maps, num_maps, true, false); ++ return pinctrl_register_map(maps, num_maps, true); + } + + void pinctrl_unregister_map(struct pinctrl_map const *map) +--- a/drivers/pinctrl/core.h ++++ b/drivers/pinctrl/core.h +@@ -183,7 +183,7 @@ static inline struct pin_desc *pin_desc_ + } + + int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, +- bool dup, bool locked); ++ bool dup); + void pinctrl_unregister_map(struct pinctrl_map const *map); + + extern int pinctrl_force_sleep(struct pinctrl_dev *pctldev); +--- a/drivers/pinctrl/devicetree.c ++++ b/drivers/pinctrl/devicetree.c +@@ -92,7 +92,7 @@ static int dt_remember_or_free_map(struc + dt_map->num_maps = num_maps; + list_add_tail(&dt_map->node, &p->dt_maps); + +- return pinctrl_register_map(map, num_maps, false, true); ++ return pinctrl_register_map(map, num_maps, false); + } + + struct pinctrl_dev *of_pinctrl_get(struct device_node *np) diff --git a/queue-4.0/series b/queue-4.0/series index 94950d22c48..ccc9e26a68c 100644 --- a/queue-4.0/series +++ b/queue-4.0/series @@ -41,3 +41,13 @@ drm-i915-add-missing-macbook-pro-models-with-dual-channel-lvds.patch drm-i915-dp-there-is-no-audio-on-port-a.patch drm-amdkfd-allow-unregister-process-with-queues.patch drm-amdkfd-initialize-sdma-vm-when-creating-sdma-queue.patch +drm-radeon-disable-semaphores-for-uvd-v1-v2.patch +drm-radeon-don-t-setup-audio-on-asics-that-don-t-support-it.patch +drm-radeon-fix-userptr-bo-unpin-bug-v3.patch +drm-radeon-make-vce-handle-check-more-strict.patch +drm-radeon-make-uvd-handle-checking-more-strict.patch +drm-radeon-more-strictly-validate-the-uvd-codec.patch +pinctrl-don-t-just-pretend-to-protect-pinctrl_maps-do-it-for-real.patch +mmc-card-don-t-access-rpmb-partitions-for-normal-read-write.patch +mmc-core-add-missing-pm-event-in-mmc_pm_notify-to-fix-hib-restore.patch +mmc-sh_mmcif-fix-timeout-value-for-command-request.patch