mirror of
https://github.com/torvalds/linux.git
synced 2026-05-23 14:42:08 +02:00
drm/msm/a6xx: Track current_ctx_seqno per ring
With preemption it is not enough to track the current_ctx_seqno globally as execution might switch between rings. This is especially problematic when current_ctx_seqno is used to determine whether a page table switch is necessary as it might lead to security bugs. Track current context per ring. Tested-by: Rob Clark <robdclark@gmail.com> Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-QRD Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8450-HDK Signed-off-by: Antonino Maniscalco <antomani103@gmail.com> Patchwork: https://patchwork.freedesktop.org/patch/618012/ Signed-off-by: Rob Clark <robdclark@chromium.org>
This commit is contained in:
parent
76a28f4c0c
commit
3241504ea2
|
|
@ -22,7 +22,7 @@ static void a2xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
|
|||
break;
|
||||
case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
|
||||
/* ignore if there has not been a ctx switch: */
|
||||
if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
|
||||
if (ring->cur_ctx_seqno == submit->queue->ctx->seqno)
|
||||
break;
|
||||
fallthrough;
|
||||
case MSM_SUBMIT_CMD_BUF:
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ static void a3xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
|
|||
break;
|
||||
case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
|
||||
/* ignore if there has not been a ctx switch: */
|
||||
if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
|
||||
if (ring->cur_ctx_seqno == submit->queue->ctx->seqno)
|
||||
break;
|
||||
fallthrough;
|
||||
case MSM_SUBMIT_CMD_BUF:
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ static void a4xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
|
|||
break;
|
||||
case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
|
||||
/* ignore if there has not been a ctx switch: */
|
||||
if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
|
||||
if (ring->cur_ctx_seqno == submit->queue->ctx->seqno)
|
||||
break;
|
||||
fallthrough;
|
||||
case MSM_SUBMIT_CMD_BUF:
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit
|
|||
case MSM_SUBMIT_CMD_IB_TARGET_BUF:
|
||||
break;
|
||||
case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
|
||||
if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
|
||||
if (ring->cur_ctx_seqno == submit->queue->ctx->seqno)
|
||||
break;
|
||||
fallthrough;
|
||||
case MSM_SUBMIT_CMD_BUF:
|
||||
|
|
@ -132,7 +132,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
|
|||
unsigned int i, ibs = 0;
|
||||
|
||||
if (IS_ENABLED(CONFIG_DRM_MSM_GPU_SUDO) && submit->in_rb) {
|
||||
gpu->cur_ctx_seqno = 0;
|
||||
ring->cur_ctx_seqno = 0;
|
||||
a5xx_submit_in_rb(gpu, submit);
|
||||
return;
|
||||
}
|
||||
|
|
@ -171,7 +171,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
|
|||
case MSM_SUBMIT_CMD_IB_TARGET_BUF:
|
||||
break;
|
||||
case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
|
||||
if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
|
||||
if (ring->cur_ctx_seqno == submit->queue->ctx->seqno)
|
||||
break;
|
||||
fallthrough;
|
||||
case MSM_SUBMIT_CMD_BUF:
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
|
|||
u32 asid;
|
||||
u64 memptr = rbmemptr(ring, ttbr0);
|
||||
|
||||
if (ctx->seqno == a6xx_gpu->base.base.cur_ctx_seqno)
|
||||
if (ctx->seqno == ring->cur_ctx_seqno)
|
||||
return;
|
||||
|
||||
if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid))
|
||||
|
|
@ -219,7 +219,7 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
|
|||
case MSM_SUBMIT_CMD_IB_TARGET_BUF:
|
||||
break;
|
||||
case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
|
||||
if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
|
||||
if (ring->cur_ctx_seqno == submit->queue->ctx->seqno)
|
||||
break;
|
||||
fallthrough;
|
||||
case MSM_SUBMIT_CMD_BUF:
|
||||
|
|
@ -305,7 +305,7 @@ static void a7xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
|
|||
case MSM_SUBMIT_CMD_IB_TARGET_BUF:
|
||||
break;
|
||||
case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
|
||||
if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
|
||||
if (ring->cur_ctx_seqno == submit->queue->ctx->seqno)
|
||||
break;
|
||||
fallthrough;
|
||||
case MSM_SUBMIT_CMD_BUF:
|
||||
|
|
@ -854,6 +854,7 @@ static int hw_init(struct msm_gpu *gpu)
|
|||
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
|
||||
struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
|
||||
u64 gmem_range_min;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
if (!adreno_has_gmu_wrapper(adreno_gpu)) {
|
||||
|
|
@ -1135,7 +1136,8 @@ static int hw_init(struct msm_gpu *gpu)
|
|||
/* Always come up on rb 0 */
|
||||
a6xx_gpu->cur_ring = gpu->rb[0];
|
||||
|
||||
gpu->cur_ctx_seqno = 0;
|
||||
for (i = 0; i < gpu->nr_rings; i++)
|
||||
gpu->rb[i]->cur_ctx_seqno = 0;
|
||||
|
||||
/* Enable the SQE_to start the CP engine */
|
||||
gpu_write(gpu, REG_A6XX_CP_SQE_CNTL, 1);
|
||||
|
|
|
|||
|
|
@ -783,7 +783,7 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
|
|||
mutex_unlock(&gpu->active_lock);
|
||||
|
||||
gpu->funcs->submit(gpu, submit);
|
||||
gpu->cur_ctx_seqno = submit->queue->ctx->seqno;
|
||||
submit->ring->cur_ctx_seqno = submit->queue->ctx->seqno;
|
||||
|
||||
pm_runtime_put(&gpu->pdev->dev);
|
||||
hangcheck_timer_reset(gpu);
|
||||
|
|
|
|||
|
|
@ -193,17 +193,6 @@ struct msm_gpu {
|
|||
*/
|
||||
refcount_t sysprof_active;
|
||||
|
||||
/**
|
||||
* cur_ctx_seqno:
|
||||
*
|
||||
* The ctx->seqno value of the last context to submit rendering,
|
||||
* and the one with current pgtables installed (for generations
|
||||
* that support per-context pgtables). Tracked by seqno rather
|
||||
* than pointer value to avoid dangling pointers, and cases where
|
||||
* a ctx can be freed and a new one created with the same address.
|
||||
*/
|
||||
int cur_ctx_seqno;
|
||||
|
||||
/**
|
||||
* lock:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -100,6 +100,16 @@ struct msm_ringbuffer {
|
|||
* preemption. Can be aquired from irq context.
|
||||
*/
|
||||
spinlock_t preempt_lock;
|
||||
|
||||
/**
|
||||
* cur_ctx_seqno:
|
||||
*
|
||||
* The ctx->seqno value of the last context to submit to this ring
|
||||
* Tracked by seqno rather than pointer value to avoid dangling
|
||||
* pointers, and cases where a ctx can be freed and a new one created
|
||||
* with the same address.
|
||||
*/
|
||||
int cur_ctx_seqno;
|
||||
};
|
||||
|
||||
struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user