diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1418-drm-amdgpu-Fix-CP_HQD_PQ_WPTR-initialization-on.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1418-drm-amdgpu-Fix-CP_HQD_PQ_WPTR-initialization-on.patch | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1418-drm-amdgpu-Fix-CP_HQD_PQ_WPTR-initialization-on.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1418-drm-amdgpu-Fix-CP_HQD_PQ_WPTR-initialization-on.patch new file mode 100644 index 00000000..fdb2df3e --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1418-drm-amdgpu-Fix-CP_HQD_PQ_WPTR-initialization-on.patch @@ -0,0 +1,92 @@ +From aa29688809e41aec4f2fb49bcdd22efd8cc40c61 Mon Sep 17 00:00:00 2001 +From: Chaudhary Amit Kumar <chaudharyamit.kumar@amd.com> +Date: Thu, 18 Oct 2018 19:12:05 +0530 +Subject: [PATCH 1418/4131] drm/amdgpu: Fix CP_HQD_PQ_WPTR initialization on + KFD HQD load + +The return value from copy_from_user() was interpreted as the opposite +of its intended meaning. This caused PQ_WPTR to be populated with the +uninitialized value from shadow_wptr, causing intermittent HIQ hangs. + +Always initialize PQ_WPTR to zero if a shadow write pointer is not +available. Also check for NULL as this may be mapped in userspace +but has a specific meaning when passed to hqd_load(). + +Change-Id: I3ced7765659a043a53b8123bace0e6288a23b59d +Signed-off-by: Jay Cornwall <jay.cornwall@amd.com> +Reviewed-by: David Ogbeide <davidboyowa.ogbeide@amd.com> + +Signed-off-by: Chaudhary Amit Kumar <chaudharyamit.kumar@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | 8 ++++---- + drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c | 13 ++++++------- + 2 files changed, 10 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c +index 558bf3e..9eca46f 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c +@@ -406,12 +406,13 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, + uint32_t page_table_base) + { + struct amdgpu_device *adev = get_amdgpu_device(kgd); +- uint32_t wptr_shadow, is_wptr_shadow_valid; + struct cik_mqd *m; ++ uint32_t wptr_shadow = 0, is_wptr_shadow_valid = 0; + + m = get_mqd(mqd); + +- is_wptr_shadow_valid = !get_user(wptr_shadow, wptr); ++ if (wptr != NULL) ++ is_wptr_shadow_valid = !get_user(wptr_shadow, wptr); + + acquire_queue(kgd, pipe_id, queue_id); + +@@ -458,8 +459,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, + + WREG32(mmCP_HQD_IQ_RPTR, m->cp_hqd_iq_rptr); + +- if (is_wptr_shadow_valid) +- WREG32(mmCP_HQD_PQ_WPTR, wptr_shadow); ++ WREG32(mmCP_HQD_PQ_WPTR, (is_wptr_shadow_valid ? wptr_shadow : 0)); + + WREG32(mmCP_HQD_ACTIVE, m->cp_hqd_active); + release_queue(kgd); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c +index 34e4a81..41925d3 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c +@@ -322,13 +322,15 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, + uint32_t queue_id, uint32_t __user *wptr, + uint32_t page_table_base) + { +- struct vi_mqd *m; +- uint32_t shadow_wptr, valid_wptr; + struct amdgpu_device *adev = get_amdgpu_device(kgd); ++ struct vi_mqd *m; ++ uint32_t wptr_shadow = 0, is_wptr_shadow_valid = 0; + + m = get_mqd(mqd); + +- valid_wptr = copy_from_user(&shadow_wptr, wptr, sizeof(shadow_wptr)); ++ if (wptr != NULL) ++ is_wptr_shadow_valid = !get_user(wptr_shadow, wptr); ++ + acquire_queue(kgd, pipe_id, queue_id); + + WREG32(mmCP_MQD_CONTROL, m->cp_mqd_control); +@@ -345,10 +347,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, + WREG32(mmCP_HQD_PQ_RPTR_REPORT_ADDR, m->cp_hqd_pq_rptr_report_addr_lo); + WREG32(mmCP_HQD_PQ_RPTR_REPORT_ADDR_HI, + m->cp_hqd_pq_rptr_report_addr_hi); +- +- if (valid_wptr > 0) +- WREG32(mmCP_HQD_PQ_WPTR, shadow_wptr); +- ++ WREG32(mmCP_HQD_PQ_WPTR, (is_wptr_shadow_valid ? wptr_shadow : 0)); + WREG32(mmCP_HQD_PQ_CONTROL, m->cp_hqd_pq_control); + WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, m->cp_hqd_pq_doorbell_control); + +-- +2.7.4 + |