Christian König (4): drm/ttm: add ttm_bo_pin()/ttm_bo_unpin() v2 drm/ttm: never consider pinned BOs for eviction&swap drm/vmwgfx: stop using ttm_bo_create v2 drm/vmwgfx: switch over to the new pin interface v2
Lee Jones (1): drm/vmwgfx/vmwgfx_cmdbuf_res: Remove unused variable 'ret'
Wang Hai (1): drm/ttm: Fix kabi breakage in struct ttm_buffer_object
Zack Rusin (2): drm/vmwgfx: Fix some static checker warnings drm/vmwgfx: Fix possible null pointer derefence with invalid contexts
drivers/gpu/drm/ttm/ttm_bo.c | 15 +++- drivers/gpu/drm/ttm/ttm_bo_util.c | 2 +- drivers/gpu/drm/ttm/ttm_memory.c | 2 + drivers/gpu/drm/vmwgfx/vmwgfx_binding.c | 20 ++--- drivers/gpu/drm/vmwgfx/vmwgfx_blit.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 92 ++++++++++++++++------ drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c | 8 +- drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 11 ++- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 12 ++- drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_mob.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 6 +- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 12 ++- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_shader.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_so.c | 3 +- drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 50 +----------- drivers/gpu/drm/vmwgfx/vmwgfx_validation.c | 6 +- include/drm/ttm/ttm_bo_api.h | 26 ++++++ 22 files changed, 172 insertions(+), 121 deletions(-)
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/10285 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/O...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/10285 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/O...
From: Christian König christian.koenig@amd.com
stable inclusion from stable-v5.10.190 commit 5f6d5b58c59e6ded30f60e899b8c8bae80b1c5a8 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IAEV5X
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit deb0814b43f370a448a498409d949e38c9d8f02e ]
As an alternative to the placement flag add a pin count to the ttm buffer object.
v2: add dma_resv_assert_help() calls
Signed-off-by: Christian König christian.koenig@amd.com Reviewed-by: Dave Airlie airlied@redhat.com Reviewed-by: Huang Rui ray.huang@amd.com Link: https://patchwork.freedesktop.org/patch/391596/?series=81973&rev=1 Stable-dep-of: a2848d08742c ("drm/ttm: never consider pinned BOs for eviction&swap") Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Wang Hai wanghai38@huawei.com Signed-off-by: Pu Lehui pulehui@huawei.com --- drivers/gpu/drm/ttm/ttm_bo.c | 9 ++++++--- drivers/gpu/drm/ttm/ttm_bo_util.c | 2 +- include/drm/ttm/ttm_bo_api.h | 26 ++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index f673292eec9d..9a05caec3c99 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -115,7 +115,7 @@ static void ttm_bo_add_mem_to_lru(struct ttm_buffer_object *bo, struct ttm_bo_device *bdev = bo->bdev; struct ttm_resource_manager *man;
- if (!list_empty(&bo->lru)) + if (!list_empty(&bo->lru) || bo->pin_count) return;
if (mem->placement & TTM_PL_FLAG_NO_EVICT) @@ -165,7 +165,8 @@ void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo, ttm_bo_del_from_lru(bo); ttm_bo_add_mem_to_lru(bo, &bo->mem);
- if (bulk && !(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) { + if (bulk && !(bo->mem.placement & TTM_PL_FLAG_NO_EVICT) && + !bo->pin_count) { switch (bo->mem.mem_type) { case TTM_PL_TT: ttm_bo_bulk_move_set_pos(&bulk->tt[bo->priority], bo); @@ -544,8 +545,9 @@ static void ttm_bo_release(struct kref *kref) * shrinkers, now that they are queued for * destruction. */ - if (bo->mem.placement & TTM_PL_FLAG_NO_EVICT) { + if (bo->mem.placement & TTM_PL_FLAG_NO_EVICT || bo->pin_count) { bo->mem.placement &= ~TTM_PL_FLAG_NO_EVICT; + bo->pin_count = 0; ttm_bo_del_from_lru(bo); ttm_bo_add_mem_to_lru(bo, &bo->mem); } @@ -1174,6 +1176,7 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, bo->moving = NULL; bo->mem.placement = TTM_PL_FLAG_CACHED; bo->acc_size = acc_size; + bo->pin_count = 0; bo->sg = sg; if (resv) { bo->base.resv = resv; diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 20a5434c6853..0e364897107f 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -352,7 +352,6 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, return -ENOMEM;
fbo->base = *bo; - fbo->base.mem.placement |= TTM_PL_FLAG_NO_EVICT;
ttm_bo_get(bo); fbo->bo = bo; @@ -372,6 +371,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, kref_init(&fbo->base.kref); fbo->base.destroy = &ttm_transfered_destroy; fbo->base.acc_size = 0; + fbo->base.pin_count = 1; if (bo->type != ttm_bo_type_sg) fbo->base.base.resv = &fbo->base.base._resv;
diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 0f7cd21d6d74..33aca60870e2 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -157,6 +157,7 @@ struct ttm_buffer_object {
struct dma_fence *moving; unsigned priority; + unsigned pin_count;
/** * Special members that are protected by the reserve lock @@ -606,6 +607,31 @@ static inline bool ttm_bo_uses_embedded_gem_object(struct ttm_buffer_object *bo) return bo->base.dev != NULL; }
+/** + * ttm_bo_pin - Pin the buffer object. + * @bo: The buffer object to pin + * + * Make sure the buffer is not evicted any more during memory pressure. + */ +static inline void ttm_bo_pin(struct ttm_buffer_object *bo) +{ + dma_resv_assert_held(bo->base.resv); + ++bo->pin_count; +} + +/** + * ttm_bo_unpin - Unpin the buffer object. + * @bo: The buffer object to unpin + * + * Allows the buffer object to be evicted again during memory pressure. + */ +static inline void ttm_bo_unpin(struct ttm_buffer_object *bo) +{ + dma_resv_assert_held(bo->base.resv); + WARN_ON_ONCE(!bo->pin_count); + --bo->pin_count; +} + int ttm_mem_evict_first(struct ttm_bo_device *bdev, struct ttm_resource_manager *man, const struct ttm_place *place,
From: Christian König christian.koenig@amd.com
stable inclusion from stable-v5.10.190 commit 8996b13051f0c211aaaf243dfd270003f1b67431 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IAEV5X
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit a2848d08742c8e8494675892c02c0d22acbe3cf8 ]
There is a small window where we have already incremented the pin count but not yet moved the bo from the lru to the pinned list.
Signed-off-by: Christian König christian.koenig@amd.com Reported-by: Pelloux-Prayer, Pierre-Eric Pierre-eric.Pelloux-prayer@amd.com Tested-by: Pelloux-Prayer, Pierre-Eric Pierre-eric.Pelloux-prayer@amd.com Acked-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230707120826.3701-1-christia... Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Wang Hai wanghai38@huawei.com Signed-off-by: Pu Lehui pulehui@huawei.com --- drivers/gpu/drm/ttm/ttm_bo.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 9a05caec3c99..dca4dfdd332d 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -672,6 +672,12 @@ static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo, { bool ret = false;
+ if (bo->pin_count) { + *locked = false; + *busy = false; + return false; + } + if (bo->base.resv == ctx->resv) { dma_resv_assert_held(bo->base.resv); if (ctx->flags & TTM_OPT_FLAG_ALLOW_RES_EVICT)
From: Wang Hai wanghai38@huawei.com
Offering: HULK hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IAEV5X
--------------------------------
Fix kabi breakage in commit deb0814b43f3 ("[Backport] drm/ttm: add ttm_bo_pin()/ttm_bo_unpin() v2")
Signed-off-by: Wang Hai wanghai38@huawei.com Signed-off-by: Pu Lehui pulehui@huawei.com --- include/drm/ttm/ttm_bo_api.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 33aca60870e2..13e5dfdf1727 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -157,7 +157,7 @@ struct ttm_buffer_object {
struct dma_fence *moving; unsigned priority; - unsigned pin_count; + KABI_FILL_HOLE(unsigned pin_count)
/** * Special members that are protected by the reserve lock
From: Christian König christian.koenig@amd.com
stable inclusion from stable-v5.10.215 commit 1502b87c652a644e48023584ac36cef333b3df60 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9L4RT CVE: CVE-2024-26979
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit b254557cb244e2c18e59ee1cc2293128c52d2473 ]
Implement in the driver instead since it is the only user of that function.
v2: fix usage of ttm_bo_init_reserved
Signed-off-by: Christian König christian.koenig@amd.com Reviewed-by: Dave Airlie airlied@redhat.com Reviewed-by: Huang Rui ray.huang@amd.com Link: https://patchwork.freedesktop.org/patch/391614/?series=81973&rev=1 Stable-dep-of: 517621b70600 ("drm/vmwgfx: Fix possible null pointer derefence with invalid contexts") Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Pu Lehui pulehui@huawei.com --- drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 43 ++++++++++++++++++++++ drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c | 6 +-- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 4 ++ drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 8 ++-- 4 files changed, 53 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c index 813f1b148094..c8ca09f0e627 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c @@ -487,6 +487,49 @@ static void vmw_user_bo_destroy(struct ttm_buffer_object *bo) ttm_prime_object_kfree(vmw_user_bo, prime); }
+/** + * vmw_bo_create_kernel - Create a pinned BO for internal kernel use. + * + * @dev_priv: Pointer to the device private struct + * @size: size of the BO we need + * @placement: where to put it + * @p_bo: resulting BO + * + * Creates and pin a simple BO for in kernel use. + */ +int vmw_bo_create_kernel(struct vmw_private *dev_priv, unsigned long size, + struct ttm_placement *placement, + struct ttm_buffer_object **p_bo) +{ + unsigned npages = PAGE_ALIGN(size) >> PAGE_SHIFT; + struct ttm_operation_ctx ctx = { false, false }; + struct ttm_buffer_object *bo; + size_t acc_size; + int ret; + + bo = kzalloc(sizeof(*bo), GFP_KERNEL); + if (unlikely(!bo)) + return -ENOMEM; + + acc_size = ttm_round_pot(sizeof(*bo)); + acc_size += ttm_round_pot(npages * sizeof(void *)); + acc_size += ttm_round_pot(sizeof(struct ttm_tt)); + ret = ttm_bo_init_reserved(&dev_priv->bdev, bo, size, + ttm_bo_type_device, placement, 0, + &ctx, acc_size, NULL, NULL, NULL); + if (unlikely(ret)) + goto error_free; + + ttm_bo_pin(bo); + ttm_bo_unreserve(bo); + *p_bo = bo; + + return 0; + +error_free: + kfree(bo); + return ret; +}
/** * vmw_bo_init - Initialize a vmw buffer object diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c index 3b41cf63110a..9a9fe10d829b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c @@ -1245,9 +1245,9 @@ int vmw_cmdbuf_set_pool_size(struct vmw_cmdbuf_man *man, !dev_priv->has_mob) return -ENOMEM;
- ret = ttm_bo_create(&dev_priv->bdev, size, ttm_bo_type_device, - &vmw_mob_ne_placement, 0, false, - &man->cmd_space); + ret = vmw_bo_create_kernel(dev_priv, size, + &vmw_mob_placement, + &man->cmd_space); if (ret) return ret;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 0a79c57c7db6..e6af950c4037 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -845,6 +845,10 @@ extern void vmw_bo_get_guest_ptr(const struct ttm_buffer_object *buf, SVGAGuestPtr *ptr); extern void vmw_bo_pin_reserved(struct vmw_buffer_object *bo, bool pin); extern void vmw_bo_bo_free(struct ttm_buffer_object *bo); +extern int vmw_bo_create_kernel(struct vmw_private *dev_priv, + unsigned long size, + struct ttm_placement *placement, + struct ttm_buffer_object **p_bo); extern int vmw_bo_init(struct vmw_private *dev_priv, struct vmw_buffer_object *vmw_bo, size_t size, struct ttm_placement *placement, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c index 73116ec70ba5..8abeef691ad2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c @@ -817,11 +817,9 @@ int vmw_bo_create_and_populate(struct vmw_private *dev_priv, struct ttm_buffer_object *bo; int ret;
- ret = ttm_bo_create(&dev_priv->bdev, bo_size, - ttm_bo_type_device, - &vmw_sys_ne_placement, - 0, false, &bo); - + ret = vmw_bo_create_kernel(dev_priv, bo_size, + &vmw_sys_placement, + &bo); if (unlikely(ret != 0)) return ret;
From: Christian König christian.koenig@amd.com
stable inclusion from stable-v5.10.215 commit b6fc792bf8f25fe1b0019e63d017f3a0363c4761 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9L4RT CVE: CVE-2024-26979
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit fbe86ca567919b22bbba1220ce55020b1868879f ]
Stop using TTM_PL_FLAG_NO_EVICT.
v2: fix unconditional pinning
Signed-off-by: Christian König christian.koenig@amd.com Reviewed-by: Dave Airlie airlied@redhat.com Reviewed-by: Huang Rui ray.huang@amd.com Link: https://patchwork.freedesktop.org/patch/391601/?series=81973&rev=1 Stable-dep-of: 517621b70600 ("drm/vmwgfx: Fix possible null pointer derefence with invalid contexts") Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Pu Lehui pulehui@huawei.com --- drivers/gpu/drm/vmwgfx/vmwgfx_blit.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 49 +++++++++++----------- drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 7 +--- drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_shader.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 42 ------------------- drivers/gpu/drm/vmwgfx/vmwgfx_validation.c | 2 +- 11 files changed, 39 insertions(+), 85 deletions(-)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c b/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c index e8d66182cd7b..ea2f2f937eb3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c @@ -459,9 +459,9 @@ int vmw_bo_cpu_blit(struct ttm_buffer_object *dst, int ret = 0;
/* Buffer objects need to be either pinned or reserved: */ - if (!(dst->mem.placement & TTM_PL_FLAG_NO_EVICT)) + if (!(dst->pin_count)) dma_resv_assert_held(dst->base.resv); - if (!(src->mem.placement & TTM_PL_FLAG_NO_EVICT)) + if (!(src->pin_count)) dma_resv_assert_held(src->base.resv);
if (!ttm_tt_is_populated(dst->ttm)) { diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c index c8ca09f0e627..9a66ba254326 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c @@ -106,7 +106,7 @@ int vmw_bo_pin_in_placement(struct vmw_private *dev_priv, if (unlikely(ret != 0)) goto err;
- if (buf->pin_count > 0) + if (buf->base.pin_count > 0) ret = ttm_bo_mem_compat(placement, &bo->mem, &new_flags) == true ? 0 : -EINVAL; else @@ -155,7 +155,7 @@ int vmw_bo_pin_in_vram_or_gmr(struct vmw_private *dev_priv, if (unlikely(ret != 0)) goto err;
- if (buf->pin_count > 0) { + if (buf->base.pin_count > 0) { ret = ttm_bo_mem_compat(&vmw_vram_gmr_placement, &bo->mem, &new_flags) == true ? 0 : -EINVAL; goto out_unreserve; @@ -246,12 +246,12 @@ int vmw_bo_pin_in_start_of_vram(struct vmw_private *dev_priv, if (bo->mem.mem_type == TTM_PL_VRAM && bo->mem.start < bo->num_pages && bo->mem.start > 0 && - buf->pin_count == 0) { + buf->base.pin_count == 0) { ctx.interruptible = false; (void) ttm_bo_validate(bo, &vmw_sys_placement, &ctx); }
- if (buf->pin_count > 0) + if (buf->base.pin_count > 0) ret = ttm_bo_mem_compat(&placement, &bo->mem, &new_flags) == true ? 0 : -EINVAL; else @@ -343,23 +343,13 @@ void vmw_bo_pin_reserved(struct vmw_buffer_object *vbo, bool pin)
dma_resv_assert_held(bo->base.resv);
- if (pin) { - if (vbo->pin_count++ > 0) - return; - } else { - WARN_ON(vbo->pin_count <= 0); - if (--vbo->pin_count > 0) - return; - } + if (pin == !!bo->pin_count) + return;
pl.fpfn = 0; pl.lpfn = 0; pl.mem_type = bo->mem.mem_type; pl.flags = bo->mem.placement; - if (pin) - pl.flags |= TTM_PL_FLAG_NO_EVICT; - else - pl.flags &= ~TTM_PL_FLAG_NO_EVICT;
memset(&placement, 0, sizeof(placement)); placement.num_placement = 1; @@ -368,8 +358,12 @@ void vmw_bo_pin_reserved(struct vmw_buffer_object *vbo, bool pin) ret = ttm_bo_validate(bo, &placement, &ctx);
BUG_ON(ret != 0 || bo->mem.mem_type != old_mem_type); -}
+ if (pin) + ttm_bo_pin(bo); + else + ttm_bo_unpin(bo); +}
/** * vmw_bo_map_and_cache - Map a buffer object and cache the map @@ -539,6 +533,7 @@ int vmw_bo_create_kernel(struct vmw_private *dev_priv, unsigned long size, * @size: Buffer object size in bytes. * @placement: Initial placement. * @interruptible: Whether waits should be performed interruptible. + * @pin: If the BO should be created pinned at a fixed location. * @bo_free: The buffer object destructor. * Returns: Zero on success, negative error code on error. * @@ -547,9 +542,10 @@ int vmw_bo_create_kernel(struct vmw_private *dev_priv, unsigned long size, int vmw_bo_init(struct vmw_private *dev_priv, struct vmw_buffer_object *vmw_bo, size_t size, struct ttm_placement *placement, - bool interruptible, + bool interruptible, bool pin, void (*bo_free)(struct ttm_buffer_object *bo)) { + struct ttm_operation_ctx ctx = { interruptible, false }; struct ttm_bo_device *bdev = &dev_priv->bdev; size_t acc_size; int ret; @@ -563,11 +559,16 @@ int vmw_bo_init(struct vmw_private *dev_priv, vmw_bo->base.priority = 3; vmw_bo->res_tree = RB_ROOT;
- ret = ttm_bo_init(bdev, &vmw_bo->base, size, - ttm_bo_type_device, placement, - 0, interruptible, acc_size, - NULL, NULL, bo_free); - return ret; + ret = ttm_bo_init_reserved(bdev, &vmw_bo->base, size, + ttm_bo_type_device, placement, + 0, &ctx, acc_size, NULL, NULL, bo_free); + if (unlikely(ret)) + return ret; + + if (pin) + ttm_bo_pin(&vmw_bo->base); + ttm_bo_unreserve(&vmw_bo->base); + return 0; }
@@ -656,7 +657,7 @@ int vmw_user_bo_alloc(struct vmw_private *dev_priv, ret = vmw_bo_init(dev_priv, &user_bo->vbo, size, (dev_priv->has_mob) ? &vmw_sys_placement : - &vmw_vram_sys_placement, true, + &vmw_vram_sys_placement, true, false, &vmw_user_bo_destroy); if (unlikely(ret != 0)) return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c index 65e8e7a97724..984d8884357d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c @@ -410,8 +410,8 @@ static int vmw_cotable_resize(struct vmw_resource *res, size_t new_size) if (!buf) return -ENOMEM;
- ret = vmw_bo_init(dev_priv, buf, new_size, &vmw_mob_ne_placement, - true, vmw_bo_bo_free); + ret = vmw_bo_init(dev_priv, buf, new_size, &vmw_mob_placement, + true, true, vmw_bo_bo_free); if (ret) { DRM_ERROR("Failed initializing new cotable MOB.\n"); return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 31e3e5c9f362..bdb7a5e96560 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -372,7 +372,7 @@ static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv) return -ENOMEM;
ret = vmw_bo_init(dev_priv, vbo, PAGE_SIZE, - &vmw_sys_ne_placement, false, + &vmw_sys_placement, false, true, &vmw_bo_bo_free); if (unlikely(ret != 0)) return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index e6af950c4037..fa285c20d6da 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -99,7 +99,6 @@ struct vmw_fpriv { * struct vmw_buffer_object - TTM buffer object with vmwgfx additions * @base: The TTM buffer object * @res_tree: RB tree of resources using this buffer object as a backing MOB - * @pin_count: pin depth * @cpu_writers: Number of synccpu write grabs. Protected by reservation when * increased. May be decreased without reservation. * @dx_query_ctx: DX context if this buffer object is used as a DX query MOB @@ -110,7 +109,6 @@ struct vmw_fpriv { struct vmw_buffer_object { struct ttm_buffer_object base; struct rb_root res_tree; - s32 pin_count; atomic_t cpu_writers; /* Not ref-counted. Protected by binding_mutex */ struct vmw_resource *dx_query_ctx; @@ -852,7 +850,7 @@ extern int vmw_bo_create_kernel(struct vmw_private *dev_priv, extern int vmw_bo_init(struct vmw_private *dev_priv, struct vmw_buffer_object *vmw_bo, size_t size, struct ttm_placement *placement, - bool interruptible, + bool interruptible, bool pin, void (*bo_free)(struct ttm_buffer_object *bo)); extern int vmw_user_bo_verify_access(struct ttm_buffer_object *bo, struct ttm_object_file *tfile); @@ -1009,16 +1007,13 @@ extern void vmw_validation_mem_init_ttm(struct vmw_private *dev_priv,
extern const size_t vmw_tt_size; extern struct ttm_placement vmw_vram_placement; -extern struct ttm_placement vmw_vram_ne_placement; extern struct ttm_placement vmw_vram_sys_placement; extern struct ttm_placement vmw_vram_gmr_placement; extern struct ttm_placement vmw_vram_gmr_ne_placement; extern struct ttm_placement vmw_sys_placement; -extern struct ttm_placement vmw_sys_ne_placement; extern struct ttm_placement vmw_evictable_placement; extern struct ttm_placement vmw_srf_placement; extern struct ttm_placement vmw_mob_placement; -extern struct ttm_placement vmw_mob_ne_placement; extern struct ttm_placement vmw_nonfixed_placement; extern struct ttm_bo_driver vmw_bo_driver; extern const struct vmw_sg_table * diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 97d9d2557447..3923acc3ab1e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -406,7 +406,7 @@ static int vmw_fb_create_bo(struct vmw_private *vmw_priv,
ret = vmw_bo_init(vmw_priv, vmw_bo, size, &vmw_sys_placement, - false, + false, false, &vmw_bo_bo_free); if (unlikely(ret != 0)) goto err_unlock; /* init frees the buffer on failure */ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index c0f156078dda..5e922d9d5f2c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -370,7 +370,7 @@ static int vmw_resource_buf_alloc(struct vmw_resource *res,
ret = vmw_bo_init(res->dev_priv, backup, res->backup_size, res->func->backup_placement, - interruptible, + interruptible, false, &vmw_bo_bo_free); if (unlikely(ret != 0)) goto out_no_bo; @@ -1002,7 +1002,7 @@ int vmw_resource_pin(struct vmw_resource *res, bool interruptible) vbo = res->backup;
ttm_bo_reserve(&vbo->base, interruptible, false, NULL); - if (!vbo->pin_count) { + if (!vbo->base.pin_count) { ret = ttm_bo_validate (&vbo->base, res->func->backup_placement, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 2b6590344468..9c8109efefbd 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -451,8 +451,8 @@ vmw_sou_primary_plane_prepare_fb(struct drm_plane *plane, */ vmw_overlay_pause_all(dev_priv); ret = vmw_bo_init(dev_priv, vps->bo, size, - &vmw_vram_ne_placement, - false, &vmw_bo_bo_free); + &vmw_vram_placement, + false, true, &vmw_bo_bo_free); vmw_overlay_resume_all(dev_priv); if (ret) { vps->bo = NULL; /* vmw_bo_init frees on error */ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c index e139fdfd1635..f328aa5839a2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c @@ -978,8 +978,8 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv, if (unlikely(!buf)) return -ENOMEM;
- ret = vmw_bo_init(dev_priv, buf, size, &vmw_sys_ne_placement, - true, vmw_bo_bo_free); + ret = vmw_bo_init(dev_priv, buf, size, &vmw_sys_placement, + true, true, vmw_bo_bo_free); if (unlikely(ret != 0)) goto out;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c index 8abeef691ad2..89b3356ec27f 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c @@ -37,13 +37,6 @@ static const struct ttm_place vram_placement_flags = { .flags = TTM_PL_FLAG_CACHED };
-static const struct ttm_place vram_ne_placement_flags = { - .fpfn = 0, - .lpfn = 0, - .mem_type = TTM_PL_VRAM, - .flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_NO_EVICT -}; - static const struct ttm_place sys_placement_flags = { .fpfn = 0, .lpfn = 0, @@ -51,13 +44,6 @@ static const struct ttm_place sys_placement_flags = { .flags = TTM_PL_FLAG_CACHED };
-static const struct ttm_place sys_ne_placement_flags = { - .fpfn = 0, - .lpfn = 0, - .mem_type = TTM_PL_SYSTEM, - .flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_NO_EVICT -}; - static const struct ttm_place gmr_placement_flags = { .fpfn = 0, .lpfn = 0, @@ -79,13 +65,6 @@ static const struct ttm_place mob_placement_flags = { .flags = TTM_PL_FLAG_CACHED };
-static const struct ttm_place mob_ne_placement_flags = { - .fpfn = 0, - .lpfn = 0, - .mem_type = VMW_PL_MOB, - .flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_NO_EVICT -}; - struct ttm_placement vmw_vram_placement = { .num_placement = 1, .placement = &vram_placement_flags, @@ -158,13 +137,6 @@ struct ttm_placement vmw_vram_sys_placement = { .busy_placement = &sys_placement_flags };
-struct ttm_placement vmw_vram_ne_placement = { - .num_placement = 1, - .placement = &vram_ne_placement_flags, - .num_busy_placement = 1, - .busy_placement = &vram_ne_placement_flags -}; - struct ttm_placement vmw_sys_placement = { .num_placement = 1, .placement = &sys_placement_flags, @@ -172,13 +144,6 @@ struct ttm_placement vmw_sys_placement = { .busy_placement = &sys_placement_flags };
-struct ttm_placement vmw_sys_ne_placement = { - .num_placement = 1, - .placement = &sys_ne_placement_flags, - .num_busy_placement = 1, - .busy_placement = &sys_ne_placement_flags -}; - static const struct ttm_place evictable_placement_flags[] = { { .fpfn = 0, @@ -243,13 +208,6 @@ struct ttm_placement vmw_mob_placement = { .busy_placement = &mob_placement_flags };
-struct ttm_placement vmw_mob_ne_placement = { - .num_placement = 1, - .num_busy_placement = 1, - .placement = &mob_ne_placement_flags, - .busy_placement = &mob_ne_placement_flags -}; - struct ttm_placement vmw_nonfixed_placement = { .num_placement = 3, .placement = nonfixed_placement_flags, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c index e69bc373ae2e..f2e2bf6d1421 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c @@ -540,7 +540,7 @@ int vmw_validation_bo_validate_single(struct ttm_buffer_object *bo, if (atomic_read(&vbo->cpu_writers)) return -EBUSY;
- if (vbo->pin_count > 0) + if (vbo->base.pin_count > 0) return 0;
if (validate_as_mob)
From: Lee Jones lee.jones@linaro.org
stable inclusion from stable-v5.10.215 commit dc7cd107cef32cb5c194040a8ce88b880936a8a7 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9L4RT CVE: CVE-2024-26979
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit 43ebfe61c3928573a5ef8d80c2f5300aa5c904c0 ]
Fixes the following W=1 kernel build warning(s):
drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c: In function ‘vmw_cmdbuf_res_revert’: drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c:162:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable]
Cc: VMware Graphics linux-graphics-maintainer@vmware.com Cc: Roland Scheidegger sroland@vmware.com Cc: Zack Rusin zackr@vmware.com Cc: David Airlie airlied@linux.ie Cc: Daniel Vetter daniel@ffwll.ch Cc: dri-devel@lists.freedesktop.org Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Zack Rusin zackr@vmware.com Link: https://patchwork.freedesktop.org/patch/msgid/20210115181313.3431493-40-lee.... Stable-dep-of: 517621b70600 ("drm/vmwgfx: Fix possible null pointer derefence with invalid contexts") Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Pu Lehui pulehui@huawei.com --- drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c index 44d858ce4ce7..47b92d0c898a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c @@ -160,7 +160,6 @@ void vmw_cmdbuf_res_commit(struct list_head *list) void vmw_cmdbuf_res_revert(struct list_head *list) { struct vmw_cmdbuf_res *entry, *next; - int ret;
list_for_each_entry_safe(entry, next, list, head) { switch (entry->state) { @@ -168,8 +167,7 @@ void vmw_cmdbuf_res_revert(struct list_head *list) vmw_cmdbuf_res_free(entry->man, entry); break; case VMW_CMDBUF_RES_DEL: - ret = drm_ht_insert_item(&entry->man->resources, - &entry->hash); + drm_ht_insert_item(&entry->man->resources, &entry->hash); list_del(&entry->head); list_add_tail(&entry->head, &entry->man->list); entry->state = VMW_CMDBUF_RES_COMMITTED;
From: Zack Rusin zackr@vmware.com
stable inclusion from stable-v5.10.215 commit 675ebda69c5a03c894eb7482023ffba53d57b9e1 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9L4RT CVE: CVE-2024-26979
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit 74231041d14030f1ae6582b9233bfe782ac23e33 ]
Fix some minor issues that Coverity spotted in the code. None of that are serious but they're all valid concerns so fixing them makes sense.
Signed-off-by: Zack Rusin zackr@vmware.com Reviewed-by: Roland Scheidegger sroland@vmware.com Reviewed-by: Martin Krastev krastevm@vmware.com Link: https://patchwork.freedesktop.org/patch/msgid/20210609172307.131929-5-zackr@... Stable-dep-of: 517621b70600 ("drm/vmwgfx: Fix possible null pointer derefence with invalid contexts") Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Pu Lehui pulehui@huawei.com --- drivers/gpu/drm/ttm/ttm_memory.c | 2 ++ drivers/gpu/drm/vmwgfx/vmwgfx_binding.c | 20 ++++++++------------ drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c | 4 +++- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 2 ++ drivers/gpu/drm/vmwgfx/vmwgfx_mob.c | 4 +++- drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 6 ++++-- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 8 ++++++-- drivers/gpu/drm/vmwgfx/vmwgfx_so.c | 3 ++- drivers/gpu/drm/vmwgfx/vmwgfx_validation.c | 4 ++-- 10 files changed, 33 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c index 89d50f38c0f2..5af52012fc5c 100644 --- a/drivers/gpu/drm/ttm/ttm_memory.c +++ b/drivers/gpu/drm/ttm/ttm_memory.c @@ -431,8 +431,10 @@ int ttm_mem_global_init(struct ttm_mem_global *glob)
si_meminfo(&si);
+ spin_lock(&glob->lock); /* set it as 0 by default to keep original behavior of OOM */ glob->lower_mem_limit = 0; + spin_unlock(&glob->lock);
ret = ttm_mem_init_kernel_zone(glob, &si); if (unlikely(ret != 0)) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c index f41550797970..4da4bf3b7f0b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c @@ -713,7 +713,7 @@ static int vmw_binding_scrub_cb(struct vmw_ctx_bindinfo *bi, bool rebind) * without checking which bindings actually need to be emitted * * @cbs: Pointer to the context's struct vmw_ctx_binding_state - * @bi: Pointer to where the binding info array is stored in @cbs + * @biv: Pointer to where the binding info array is stored in @cbs * @max_num: Maximum number of entries in the @bi array. * * Scans the @bi array for bindings and builds a buffer of view id data. @@ -723,11 +723,9 @@ static int vmw_binding_scrub_cb(struct vmw_ctx_bindinfo *bi, bool rebind) * contains the command data. */ static void vmw_collect_view_ids(struct vmw_ctx_binding_state *cbs, - const struct vmw_ctx_bindinfo *bi, + const struct vmw_ctx_bindinfo_view *biv, u32 max_num) { - const struct vmw_ctx_bindinfo_view *biv = - container_of(bi, struct vmw_ctx_bindinfo_view, bi); unsigned long i;
cbs->bind_cmd_count = 0; @@ -835,7 +833,7 @@ static int vmw_emit_set_sr(struct vmw_ctx_binding_state *cbs, */ static int vmw_emit_set_rt(struct vmw_ctx_binding_state *cbs) { - const struct vmw_ctx_bindinfo *loc = &cbs->render_targets[0].bi; + const struct vmw_ctx_bindinfo_view *loc = &cbs->render_targets[0]; struct { SVGA3dCmdHeader header; SVGA3dCmdDXSetRenderTargets body; @@ -871,7 +869,7 @@ static int vmw_emit_set_rt(struct vmw_ctx_binding_state *cbs) * without checking which bindings actually need to be emitted * * @cbs: Pointer to the context's struct vmw_ctx_binding_state - * @bi: Pointer to where the binding info array is stored in @cbs + * @biso: Pointer to where the binding info array is stored in @cbs * @max_num: Maximum number of entries in the @bi array. * * Scans the @bi array for bindings and builds a buffer of SVGA3dSoTarget data. @@ -881,11 +879,9 @@ static int vmw_emit_set_rt(struct vmw_ctx_binding_state *cbs) * contains the command data. */ static void vmw_collect_so_targets(struct vmw_ctx_binding_state *cbs, - const struct vmw_ctx_bindinfo *bi, + const struct vmw_ctx_bindinfo_so_target *biso, u32 max_num) { - const struct vmw_ctx_bindinfo_so_target *biso = - container_of(bi, struct vmw_ctx_bindinfo_so_target, bi); unsigned long i; SVGA3dSoTarget *so_buffer = (SVGA3dSoTarget *) cbs->bind_cmd_buffer;
@@ -916,7 +912,7 @@ static void vmw_collect_so_targets(struct vmw_ctx_binding_state *cbs, */ static int vmw_emit_set_so_target(struct vmw_ctx_binding_state *cbs) { - const struct vmw_ctx_bindinfo *loc = &cbs->so_targets[0].bi; + const struct vmw_ctx_bindinfo_so_target *loc = &cbs->so_targets[0]; struct { SVGA3dCmdHeader header; SVGA3dCmdDXSetSOTargets body; @@ -1063,7 +1059,7 @@ static int vmw_emit_set_vb(struct vmw_ctx_binding_state *cbs)
static int vmw_emit_set_uav(struct vmw_ctx_binding_state *cbs) { - const struct vmw_ctx_bindinfo *loc = &cbs->ua_views[0].views[0].bi; + const struct vmw_ctx_bindinfo_view *loc = &cbs->ua_views[0].views[0]; struct { SVGA3dCmdHeader header; SVGA3dCmdDXSetUAViews body; @@ -1093,7 +1089,7 @@ static int vmw_emit_set_uav(struct vmw_ctx_binding_state *cbs)
static int vmw_emit_set_cs_uav(struct vmw_ctx_binding_state *cbs) { - const struct vmw_ctx_bindinfo *loc = &cbs->ua_views[1].views[0].bi; + const struct vmw_ctx_bindinfo_view *loc = &cbs->ua_views[1].views[0]; struct { SVGA3dCmdHeader header; SVGA3dCmdDXSetCSUAViews body; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c index 9a9fe10d829b..87a39721e5bc 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c @@ -514,7 +514,7 @@ static void vmw_cmdbuf_work_func(struct work_struct *work) struct vmw_cmdbuf_man *man = container_of(work, struct vmw_cmdbuf_man, work); struct vmw_cmdbuf_header *entry, *next; - uint32_t dummy; + uint32_t dummy = 0; bool send_fence = false; struct list_head restart_head[SVGA_CB_CONTEXT_MAX]; int i; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c index 47b92d0c898a..f212368c0312 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c @@ -160,6 +160,7 @@ void vmw_cmdbuf_res_commit(struct list_head *list) void vmw_cmdbuf_res_revert(struct list_head *list) { struct vmw_cmdbuf_res *entry, *next; + int ret;
list_for_each_entry_safe(entry, next, list, head) { switch (entry->state) { @@ -167,7 +168,8 @@ void vmw_cmdbuf_res_revert(struct list_head *list) vmw_cmdbuf_res_free(entry->man, entry); break; case VMW_CMDBUF_RES_DEL: - drm_ht_insert_item(&entry->man->resources, &entry->hash); + ret = drm_ht_insert_item(&entry->man->resources, &entry->hash); + BUG_ON(ret); list_del(&entry->head); list_add_tail(&entry->head, &entry->man->list); entry->state = VMW_CMDBUF_RES_COMMITTED; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 00082c679170..831291b5d1a0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -2535,6 +2535,8 @@ static int vmw_cmd_dx_so_define(struct vmw_private *dev_priv,
so_type = vmw_so_cmd_to_type(header->id); res = vmw_context_cotable(ctx_node->ctx, vmw_so_cotables[so_type]); + if (IS_ERR(res)) + return PTR_ERR(res); cmd = container_of(header, typeof(*cmd), header); ret = vmw_cotable_notify(res, cmd->defined_id);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c index 7f95ed6aa224..fb0797b380dd 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c @@ -494,11 +494,13 @@ static void vmw_mob_pt_setup(struct vmw_mob *mob, { unsigned long num_pt_pages = 0; struct ttm_buffer_object *bo = mob->pt_bo; - struct vmw_piter save_pt_iter; + struct vmw_piter save_pt_iter = {0}; struct vmw_piter pt_iter; const struct vmw_sg_table *vsgt; int ret;
+ BUG_ON(num_data_pages == 0); + ret = ttm_bo_reserve(bo, false, true, NULL); BUG_ON(ret != 0);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c index 15b5bde69324..751582f5ab0b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c @@ -154,6 +154,7 @@ static unsigned long vmw_port_hb_out(struct rpc_channel *channel, /* HB port can't access encrypted memory. */ if (hb && !mem_encrypt_active()) { unsigned long bp = channel->cookie_high; + u32 channel_id = (channel->channel_id << 16);
si = (uintptr_t) msg; di = channel->cookie_low; @@ -161,7 +162,7 @@ static unsigned long vmw_port_hb_out(struct rpc_channel *channel, VMW_PORT_HB_OUT( (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, msg_len, si, di, - VMWARE_HYPERVISOR_HB | (channel->channel_id << 16) | + VMWARE_HYPERVISOR_HB | channel_id | VMWARE_HYPERVISOR_OUT, VMW_HYPERVISOR_MAGIC, bp, eax, ebx, ecx, edx, si, di); @@ -209,6 +210,7 @@ static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply, /* HB port can't access encrypted memory */ if (hb && !mem_encrypt_active()) { unsigned long bp = channel->cookie_low; + u32 channel_id = (channel->channel_id << 16);
si = channel->cookie_high; di = (uintptr_t) reply; @@ -216,7 +218,7 @@ static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply, VMW_PORT_HB_IN( (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, reply_len, si, di, - VMWARE_HYPERVISOR_HB | (channel->channel_id << 16), + VMWARE_HYPERVISOR_HB | channel_id, VMW_HYPERVISOR_MAGIC, bp, eax, ebx, ecx, edx, si, di);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 5e922d9d5f2c..26f88d64879f 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -114,6 +114,7 @@ static void vmw_resource_release(struct kref *kref) container_of(kref, struct vmw_resource, kref); struct vmw_private *dev_priv = res->dev_priv; int id; + int ret; struct idr *idr = &dev_priv->res_idr[res->func->res_type];
spin_lock(&dev_priv->resource_lock); @@ -122,7 +123,8 @@ static void vmw_resource_release(struct kref *kref) if (res->backup) { struct ttm_buffer_object *bo = &res->backup->base;
- ttm_bo_reserve(bo, false, false, NULL); + ret = ttm_bo_reserve(bo, false, false, NULL); + BUG_ON(ret); if (vmw_resource_mob_attached(res) && res->func->unbind != NULL) { struct ttm_validate_buffer val_buf; @@ -1001,7 +1003,9 @@ int vmw_resource_pin(struct vmw_resource *res, bool interruptible) if (res->backup) { vbo = res->backup;
- ttm_bo_reserve(&vbo->base, interruptible, false, NULL); + ret = ttm_bo_reserve(&vbo->base, interruptible, false, NULL); + if (ret) + goto out_no_validate; if (!vbo->base.pin_count) { ret = ttm_bo_validate (&vbo->base, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_so.c b/drivers/gpu/drm/vmwgfx/vmwgfx_so.c index 3f97b61dd5d8..9330f1a0f174 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_so.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_so.c @@ -538,7 +538,8 @@ const SVGACOTableType vmw_so_cotables[] = { [vmw_so_ds] = SVGA_COTABLE_DEPTHSTENCIL, [vmw_so_rs] = SVGA_COTABLE_RASTERIZERSTATE, [vmw_so_ss] = SVGA_COTABLE_SAMPLER, - [vmw_so_so] = SVGA_COTABLE_STREAMOUTPUT + [vmw_so_so] = SVGA_COTABLE_STREAMOUTPUT, + [vmw_so_max]= SVGA_COTABLE_MAX };
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c index f2e2bf6d1421..cc1cfc827bb9 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c @@ -585,13 +585,13 @@ int vmw_validation_bo_validate(struct vmw_validation_context *ctx, bool intr) container_of(entry->base.bo, typeof(*vbo), base);
if (entry->cpu_blit) { - struct ttm_operation_ctx ctx = { + struct ttm_operation_ctx ttm_ctx = { .interruptible = intr, .no_wait_gpu = false };
ret = ttm_bo_validate(entry->base.bo, - &vmw_nonfixed_placement, &ctx); + &vmw_nonfixed_placement, &ttm_ctx); } else { ret = vmw_validation_bo_validate_single (entry->base.bo, intr, entry->as_mob);
From: Zack Rusin zack.rusin@broadcom.com
stable inclusion from stable-v5.10.215 commit c560327d900bab968c2e1b4cd7fa2d46cd429e3d category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9L4RT CVE: CVE-2024-26979
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit 517621b7060096e48e42f545fa6646fc00252eac ]
vmw_context_cotable can return either an error or a null pointer and its usage sometimes went unchecked. Subsequent code would then try to access either a null pointer or an error value.
The invalid dereferences were only possible with malformed userspace apps which never properly initialized the rendering contexts.
Check the results of vmw_context_cotable to fix the invalid derefs.
Thanks: ziming zhang(@ezrak1e) from Ant Group Light-Year Security Lab who was the first person to discover it. Niels De Graef who reported it and helped to track down the poc.
Fixes: 9c079b8ce8bf ("drm/vmwgfx: Adapt execbuf to the new validation api") Cc: stable@vger.kernel.org # v4.20+ Reported-by: Niels De Graef ndegraef@redhat.com Signed-off-by: Zack Rusin zack.rusin@broadcom.com Cc: Martin Krastev martin.krastev@broadcom.com Cc: Maaz Mombasawala maaz.mombasawala@broadcom.com Cc: Ian Forbes ian.forbes@broadcom.com Cc: Broadcom internal kernel review list bcm-kernel-feedback-list@broadcom.com Cc: dri-devel@lists.freedesktop.org Reviewed-by: Maaz Mombasawala maaz.mombasawala@broadcom.com Reviewed-by: Martin Krastev martin.krastev@broadcom.com Link: https://patchwork.freedesktop.org/patch/msgid/20240110200305.94086-1-zack.ru... Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Pu Lehui pulehui@huawei.com --- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 831291b5d1a0..616f6cb62278 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -467,7 +467,7 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, vmw_res_type(ctx) == vmw_res_dx_context) { for (i = 0; i < cotable_max; ++i) { res = vmw_context_cotable(ctx, i); - if (IS_ERR(res)) + if (IS_ERR_OR_NULL(res)) continue;
ret = vmw_execbuf_res_noctx_val_add(sw_context, res, @@ -1272,6 +1272,8 @@ static int vmw_cmd_dx_define_query(struct vmw_private *dev_priv, return -EINVAL;
cotable_res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_DXQUERY); + if (IS_ERR_OR_NULL(cotable_res)) + return cotable_res ? PTR_ERR(cotable_res) : -EINVAL; ret = vmw_cotable_notify(cotable_res, cmd->body.queryId);
return ret; @@ -2450,6 +2452,8 @@ static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv, return ret;
res = vmw_context_cotable(ctx_node->ctx, vmw_view_cotables[view_type]); + if (IS_ERR_OR_NULL(res)) + return res ? PTR_ERR(res) : -EINVAL; ret = vmw_cotable_notify(res, cmd->defined_id); if (unlikely(ret != 0)) return ret; @@ -2535,8 +2539,8 @@ static int vmw_cmd_dx_so_define(struct vmw_private *dev_priv,
so_type = vmw_so_cmd_to_type(header->id); res = vmw_context_cotable(ctx_node->ctx, vmw_so_cotables[so_type]); - if (IS_ERR(res)) - return PTR_ERR(res); + if (IS_ERR_OR_NULL(res)) + return res ? PTR_ERR(res) : -EINVAL; cmd = container_of(header, typeof(*cmd), header); ret = vmw_cotable_notify(res, cmd->defined_id);
@@ -2655,6 +2659,8 @@ static int vmw_cmd_dx_define_shader(struct vmw_private *dev_priv, return -EINVAL;
res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_DXSHADER); + if (IS_ERR_OR_NULL(res)) + return res ? PTR_ERR(res) : -EINVAL; ret = vmw_cotable_notify(res, cmd->body.shaderId); if (ret) return ret; @@ -2976,6 +2982,8 @@ static int vmw_cmd_dx_define_streamoutput(struct vmw_private *dev_priv, }
res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_STREAMOUTPUT); + if (IS_ERR_OR_NULL(res)) + return res ? PTR_ERR(res) : -EINVAL; ret = vmw_cotable_notify(res, cmd->body.soid); if (ret) return ret;