From 817eb40d7ea1a8321fbf671f36758e897f30dc3d Mon Sep 17 00:00:00 2001 From: Vasantha Balla Date: Wed, 4 Oct 2023 03:50:43 +0530 Subject: [PATCH 1/4] vidc: Skip unsupported session load in load calculation Sometimes client may take time to release unsupported sessions, Skip such unsupported sessions load in load calculation to allow other sessions. Change-Id: I9ec35da0a6bba762311876d41933f4fc3d7e6f3e Signed-off-by: Vasantha Balla --- msm/vidc/msm_vidc.c | 1 + msm/vidc/msm_vidc_common.c | 9 ++++++--- msm/vidc/msm_vidc_common.h | 5 ++++- msm/vidc/msm_vidc_internal.h | 1 + 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index cbb46852cbb9..aff15514f359 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1488,6 +1488,7 @@ void *msm_vidc_open(int core_id, int session_type) inst->entropy_mode = HFI_H264_ENTROPY_CABAC; inst->full_range = COLOR_RANGE_UNSPECIFIED; inst->active = true; + inst->supported = true; for (i = SESSION_MSG_INDEX(SESSION_MSG_START); i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) { diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 3e968fc92def..bf80a5650805 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -817,8 +817,8 @@ int msm_comm_get_inst_load(struct msm_vidc_inst *inst, * | res * max(op, fps)| * ----------------|----------------------------| */ - - if (is_thumbnail_session(inst) || + if (!is_supported_session(inst) || + is_thumbnail_session(inst) || (!is_realtime_session(inst) && quirks == LOAD_ADMISSION_CONTROL)) { load = 0; @@ -858,7 +858,6 @@ int msm_comm_get_device_load(struct msm_vidc_core *core, list_for_each_entry(inst, &core->instances, list) { if (inst->session_type != sess_type) continue; - if (load_type == MSM_VIDC_VIDEO && !is_video_session(inst)) continue; else if (load_type == MSM_VIDC_IMAGE && !is_grid_session(inst)) @@ -3547,6 +3546,7 @@ static int msm_vidc_load_resources(int flipped_state, "H/W is overloaded. needed: %d max: %d\n", video_load, max_video_load); msm_vidc_print_running_insts(inst->core); + inst->supported = false; return -EBUSY; } @@ -3555,6 +3555,7 @@ static int msm_vidc_load_resources(int flipped_state, "H/W is overloaded. needed: [video + image][%d + %d], max: [video + image][%d + %d]\n", video_load, image_load, max_video_load, max_image_load); msm_vidc_print_running_insts(inst->core); + inst->supported = false; return -EBUSY; } @@ -5962,6 +5963,7 @@ static int msm_vidc_check_mbps_supported(struct msm_vidc_inst *inst) "H/W is overloaded. needed: %d max: %d\n", video_load, max_video_load); msm_vidc_print_running_insts(inst->core); + inst->supported = false; return -EBUSY; } @@ -5971,6 +5973,7 @@ static int msm_vidc_check_mbps_supported(struct msm_vidc_inst *inst) video_load, image_load, max_video_load, max_image_load); msm_vidc_print_running_insts(inst->core); + inst->supported = false; return -EBUSY; } } diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index a7e1cc23b50c..70fb65a9fd08 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -157,7 +157,10 @@ static inline bool is_encode_session(struct msm_vidc_inst *inst) { return inst->session_type == MSM_VIDC_ENCODER; } - +static inline bool is_supported_session(struct msm_vidc_inst *inst) +{ + return inst->supported; +} static inline bool is_primary_output_mode(struct msm_vidc_inst *inst) { return inst->stream_output_mode == HAL_VIDEO_DECODER_PRIMARY; diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 55f11e0b1eaf..a9580496ca22 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -577,6 +577,7 @@ struct msm_vidc_inst { int full_range; u64 last_qbuf_time_ns; bool active; + bool supported; }; extern struct msm_vidc_drv *vidc_driver; From f4ebe15f7fef82c3cd5c0f4f77c6ddef900607da Mon Sep 17 00:00:00 2001 From: Vasantha Balla Date: Tue, 19 Dec 2023 14:47:03 +0530 Subject: [PATCH 2/4] vidc: Return EBUSY if mbpf check fails Driver should return EBUSY as HAL checks for this to return insufficient resources error to client. Change-Id: I2392953affc71e8b7e314a51ace349320d81562c Signed-off-by: Vasantha Balla --- msm/vidc/msm_vidc_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 3e968fc92def..4a9b9a14dcda 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5818,7 +5818,7 @@ static int msm_vidc_check_mbpf_supported(struct msm_vidc_inst *inst) if (mbpf > core->resources.max_mbpf) { msm_vidc_print_running_insts(inst->core); - return -ENOMEM; + return -EBUSY; } return 0; From f1b7dbbc6d693f3d887df00c2dc56588ebae896d Mon Sep 17 00:00:00 2001 From: Vasantha Balla Date: Fri, 2 Feb 2024 17:39:43 +0530 Subject: [PATCH 3/4] msm: vidc: Fix possible UAF during buffer unregister call [1] During buffer unregister, CVP buffer lock is released immediately after finding buffer in register buffer list. UAF might happen if two threads execute same unregister command as buffer free happens after unregister done. [2] Hold CVP buffer lock through out in unregister and unregister done calls. Change-Id: I8b6734410369ab990081c558ba846b6dfbfc8588 Signed-off-by: Vasantha Balla --- msm/vidc/msm_cvp_internal.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_cvp_internal.c b/msm/vidc/msm_cvp_internal.c index 82fc710a9644..65523ebec990 100644 --- a/msm/vidc/msm_cvp_internal.c +++ b/msm/vidc/msm_cvp_internal.c @@ -142,7 +142,6 @@ void handle_session_unregister_buffer_done(enum hal_command_response cmd, break; } } - mutex_unlock(&inst->cvpbufs.lock); if (!found) { s_vpr_e(inst->sid, "%s: client_data %x not found\n", __func__, response->data.unregbuf.client_data); @@ -164,12 +163,11 @@ void handle_session_unregister_buffer_done(enum hal_command_response cmd, data[3] = cbuf->buf.offset; v4l2_event_queue_fh(&inst->event_handler, &event); - mutex_lock(&inst->cvpbufs.lock); list_del(&cbuf->list); - mutex_unlock(&inst->cvpbufs.lock); kfree(cbuf); cbuf = NULL; exit: + mutex_unlock(&inst->cvpbufs.lock); s_vpr_l(inst->sid, "handled: SESSION_UNREGISTER_BUFFER_DONE\n"); put_inst(inst); } @@ -432,7 +430,6 @@ static int msm_cvp_unregister_buffer(struct msm_vidc_inst *inst, break; } } - mutex_unlock(&inst->cvpbufs.lock); if (!found) { print_client_buffer(VIDC_ERR, "invalid", inst, buf); return -EINVAL; @@ -450,6 +447,7 @@ static int msm_cvp_unregister_buffer(struct msm_vidc_inst *inst, if (rc) print_cvp_buffer(VIDC_ERR, "unregister failed", inst, cbuf); + mutex_unlock(&inst->cvpbufs.lock); return rc; } From 332abefb4523ca63a1a4751c9b6795b25bd18e2e Mon Sep 17 00:00:00 2001 From: Vasantha Balla Date: Tue, 30 Apr 2024 10:20:35 +0530 Subject: [PATCH 4/4] msm: vidc: Release cvp buffer lock in invalid buffer case If client tries to unregister invalid buffer, release cvp buffer lock before sending error. Change-Id: I968ff15673ae5e72299602f595f794658bb28e2a Signed-off-by: Vasantha Balla --- msm/vidc/msm_cvp_internal.c | 1 + 1 file changed, 1 insertion(+) diff --git a/msm/vidc/msm_cvp_internal.c b/msm/vidc/msm_cvp_internal.c index 65523ebec990..938c2671f41c 100644 --- a/msm/vidc/msm_cvp_internal.c +++ b/msm/vidc/msm_cvp_internal.c @@ -432,6 +432,7 @@ static int msm_cvp_unregister_buffer(struct msm_vidc_inst *inst, } if (!found) { print_client_buffer(VIDC_ERR, "invalid", inst, buf); + mutex_unlock(&inst->cvpbufs.lock); return -EINVAL; }