diff --git a/drivers/video/rockchip/mpp/mpp_common.c b/drivers/video/rockchip/mpp/mpp_common.c index d44f1ac720ab..09dda6be23ac 100644 --- a/drivers/video/rockchip/mpp/mpp_common.c +++ b/drivers/video/rockchip/mpp/mpp_common.c @@ -1337,6 +1337,28 @@ int mpp_check_req(struct mpp_request *req, int base, return 0; } +int mpp_extract_reg_offset_info(struct reg_offset_info *off_inf, + struct mpp_request *req) +{ + int max_size = ARRAY_SIZE(off_inf->elem); + int cnt = req->size / sizeof(off_inf->elem[0]); + + if ((cnt + off_inf->cnt) > max_size) { + mpp_err("count %d, total %d, max_size %d\n", + cnt, off_inf->cnt, max_size); + return -EINVAL; + } + if (copy_from_user(&off_inf->elem[off_inf->cnt], + req->data, + req->size)) { + mpp_err("copy_from_user failed\n"); + return -EINVAL; + } + off_inf->cnt += cnt; + + return 0; +} + int mpp_query_reg_offset_info(struct reg_offset_info *off_inf, u32 index) { diff --git a/drivers/video/rockchip/mpp/mpp_common.h b/drivers/video/rockchip/mpp/mpp_common.h index b21bd38219d2..9181947ad4dc 100644 --- a/drivers/video/rockchip/mpp/mpp_common.h +++ b/drivers/video/rockchip/mpp/mpp_common.h @@ -435,6 +435,8 @@ int mpp_translate_reg_address(struct mpp_session *session, int mpp_check_req(struct mpp_request *req, int base, int max_size, u32 off_s, u32 off_e); +int mpp_extract_reg_offset_info(struct reg_offset_info *off_inf, + struct mpp_request *req); int mpp_query_reg_offset_info(struct reg_offset_info *off_inf, u32 index); int mpp_translate_reg_offset_info(struct mpp_task *task, diff --git a/drivers/video/rockchip/mpp/mpp_iep2.c b/drivers/video/rockchip/mpp/mpp_iep2.c index a06c91fd2b1e..03114fa157be 100644 --- a/drivers/video/rockchip/mpp/mpp_iep2.c +++ b/drivers/video/rockchip/mpp/mpp_iep2.c @@ -276,9 +276,7 @@ static int iep2_extract_task_msg(struct iep_task *task, struct mpp_task_msgs *msgs) { u32 i; - int ret; struct mpp_request *req; - struct reg_offset_info *off_inf = &task->off_inf; for (i = 0; i < msgs->req_cnt; i++) { req = &msgs->reqs[i]; @@ -298,19 +296,7 @@ static int iep2_extract_task_msg(struct iep_task *task, req, sizeof(*req)); } break; case MPP_CMD_SET_REG_ADDR_OFFSET: { - int off = off_inf->cnt * sizeof(off_inf->elem[0]); - - ret = mpp_check_req(req, off, sizeof(off_inf->elem), - 0, sizeof(off_inf->elem)); - if (ret) - continue; - if (copy_from_user(&off_inf->elem[off_inf->cnt], - req->data, - req->size)) { - mpp_err("copy_from_user failed\n"); - return -EINVAL; - } - off_inf->cnt += req->size / sizeof(off_inf->elem[0]); + mpp_extract_reg_offset_info(&task->off_inf, req); } break; default: break; diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec.c b/drivers/video/rockchip/mpp/mpp_rkvdec.c index 704b4a8179b7..eff2dba2c76c 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec.c @@ -744,7 +744,6 @@ static int rkvdec_extract_task_msg(struct rkvdec_task *task, u32 i; int ret; struct mpp_request *req; - struct reg_offset_info *off_inf = &task->off_inf; struct mpp_hw_info *hw_info = task->mpp_task.hw_info; for (i = 0; i < msgs->req_cnt; i++) { @@ -781,19 +780,7 @@ static int rkvdec_extract_task_msg(struct rkvdec_task *task, req, sizeof(*req)); } break; case MPP_CMD_SET_REG_ADDR_OFFSET: { - int off = off_inf->cnt * sizeof(off_inf->elem[0]); - - ret = mpp_check_req(req, off, sizeof(off_inf->elem), - 0, sizeof(off_inf->elem)); - if (ret) - continue; - if (copy_from_user(&off_inf->elem[off_inf->cnt], - req->data, - req->size)) { - mpp_err("copy_from_user failed\n"); - return -EINVAL; - } - off_inf->cnt += req->size / sizeof(off_inf->elem[0]); + mpp_extract_reg_offset_info(&task->off_inf, req); } break; default: break; diff --git a/drivers/video/rockchip/mpp/mpp_rkvenc.c b/drivers/video/rockchip/mpp/mpp_rkvenc.c index 5829a158868c..e3503d1e2842 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvenc.c +++ b/drivers/video/rockchip/mpp/mpp_rkvenc.c @@ -233,7 +233,6 @@ static int rkvenc_extract_task_msg(struct rkvenc_task *task, u32 i; int ret; struct mpp_request *req; - struct reg_offset_info *off_inf = &task->off_inf; for (i = 0; i < msgs->req_cnt; i++) { req = &msgs->reqs[i]; @@ -290,18 +289,7 @@ static int rkvenc_extract_task_msg(struct rkvenc_task *task, req, sizeof(*req)); } break; case MPP_CMD_SET_REG_ADDR_OFFSET: { - ret = mpp_check_req(req, req->offset, - sizeof(off_inf->elem), - 0, sizeof(off_inf->elem)); - if (ret) - return ret; - if (copy_from_user(&off_inf->elem[off_inf->cnt], - req->data, - req->size)) { - mpp_err("copy_from_user failed\n"); - return -EINVAL; - } - off_inf->cnt += req->size / sizeof(off_inf->elem[0]); + mpp_extract_reg_offset_info(&task->off_inf, req); } break; default: break; diff --git a/drivers/video/rockchip/mpp/mpp_vdpu1.c b/drivers/video/rockchip/mpp/mpp_vdpu1.c index 6dd1867c7b08..9bb721423edd 100644 --- a/drivers/video/rockchip/mpp/mpp_vdpu1.c +++ b/drivers/video/rockchip/mpp/mpp_vdpu1.c @@ -280,7 +280,6 @@ static int vdpu_extract_task_msg(struct vdpu_task *task, u32 i; int ret; struct mpp_request *req; - struct reg_offset_info *off_inf = &task->off_inf; struct mpp_hw_info *hw_info = task->mpp_task.hw_info; for (i = 0; i < msgs->req_cnt; i++) { @@ -317,19 +316,7 @@ static int vdpu_extract_task_msg(struct vdpu_task *task, req, sizeof(*req)); } break; case MPP_CMD_SET_REG_ADDR_OFFSET: { - int off = off_inf->cnt * sizeof(off_inf->elem[0]); - - ret = mpp_check_req(req, off, sizeof(off_inf->elem), - 0, sizeof(off_inf->elem)); - if (ret) - continue; - if (copy_from_user(&off_inf->elem[off_inf->cnt], - req->data, - req->size)) { - mpp_err("copy_from_user failed\n"); - return -EINVAL; - } - off_inf->cnt += req->size / sizeof(off_inf->elem[0]); + mpp_extract_reg_offset_info(&task->off_inf, req); } break; default: break; diff --git a/drivers/video/rockchip/mpp/mpp_vdpu2.c b/drivers/video/rockchip/mpp/mpp_vdpu2.c index d4246f20a20a..882faf5699f8 100644 --- a/drivers/video/rockchip/mpp/mpp_vdpu2.c +++ b/drivers/video/rockchip/mpp/mpp_vdpu2.c @@ -237,7 +237,6 @@ static int vdpu_extract_task_msg(struct vdpu_task *task, u32 i; int ret; struct mpp_request *req; - struct reg_offset_info *off_inf = &task->off_inf; struct mpp_hw_info *hw_info = task->mpp_task.hw_info; for (i = 0; i < msgs->req_cnt; i++) { @@ -274,19 +273,7 @@ static int vdpu_extract_task_msg(struct vdpu_task *task, req, sizeof(*req)); } break; case MPP_CMD_SET_REG_ADDR_OFFSET: { - int off = off_inf->cnt * sizeof(off_inf->elem[0]); - - ret = mpp_check_req(req, off, sizeof(off_inf->elem), - 0, sizeof(off_inf->elem)); - if (ret) - continue; - if (copy_from_user(&off_inf->elem[off_inf->cnt], - req->data, - req->size)) { - mpp_err("copy_from_user failed\n"); - return -EINVAL; - } - off_inf->cnt += req->size / sizeof(off_inf->elem[0]); + mpp_extract_reg_offset_info(&task->off_inf, req); } break; default: break; diff --git a/drivers/video/rockchip/mpp/mpp_vepu1.c b/drivers/video/rockchip/mpp/mpp_vepu1.c index b24329994d4f..3696898fd10e 100644 --- a/drivers/video/rockchip/mpp/mpp_vepu1.c +++ b/drivers/video/rockchip/mpp/mpp_vepu1.c @@ -155,7 +155,6 @@ static int vepu_extract_task_msg(struct vepu_task *task, u32 i; int ret; struct mpp_request *req; - struct reg_offset_info *off_inf = &task->off_inf; struct mpp_hw_info *hw_info = task->mpp_task.hw_info; for (i = 0; i < msgs->req_cnt; i++) { @@ -192,19 +191,7 @@ static int vepu_extract_task_msg(struct vepu_task *task, req, sizeof(*req)); } break; case MPP_CMD_SET_REG_ADDR_OFFSET: { - int off = off_inf->cnt * sizeof(off_inf->elem[0]); - - ret = mpp_check_req(req, off, sizeof(off_inf->elem), - 0, sizeof(off_inf->elem)); - if (ret) - continue; - if (copy_from_user(&off_inf->elem[off_inf->cnt], - req->data, - req->size)) { - mpp_err("copy_from_user failed\n"); - return -EINVAL; - } - off_inf->cnt += req->size / sizeof(off_inf->elem[0]); + mpp_extract_reg_offset_info(&task->off_inf, req); } break; default: break; diff --git a/drivers/video/rockchip/mpp/mpp_vepu2.c b/drivers/video/rockchip/mpp/mpp_vepu2.c index 47434fdd2c4d..3d8b0c24a880 100644 --- a/drivers/video/rockchip/mpp/mpp_vepu2.c +++ b/drivers/video/rockchip/mpp/mpp_vepu2.c @@ -165,7 +165,6 @@ static int vepu_extract_task_msg(struct vepu_task *task, u32 i; int ret; struct mpp_request *req; - struct reg_offset_info *off_inf = &task->off_inf; struct mpp_hw_info *hw_info = task->mpp_task.hw_info; for (i = 0; i < msgs->req_cnt; i++) { @@ -202,19 +201,7 @@ static int vepu_extract_task_msg(struct vepu_task *task, req, sizeof(*req)); } break; case MPP_CMD_SET_REG_ADDR_OFFSET: { - int off = off_inf->cnt * sizeof(off_inf->elem[0]); - - ret = mpp_check_req(req, off, sizeof(off_inf->elem), - 0, sizeof(off_inf->elem)); - if (ret) - continue; - if (copy_from_user(&off_inf->elem[off_inf->cnt], - req->data, - req->size)) { - mpp_err("copy_from_user failed\n"); - return -EINVAL; - } - off_inf->cnt += req->size / sizeof(off_inf->elem[0]); + mpp_extract_reg_offset_info(&task->off_inf, req); } break; default: break;