msm: vidc: restrict non_secure iova usage
check total non_secure memory usage, reject the new non-secure session, if total non-secure memory usage exceeds the non-secure region size. Change-Id: I2b0aaae061e5b022237a4c49c66e92461fb40fca Signed-off-by: Govindaraj Rajagopal <grajagop@codeaurora.org>
This commit is contained in:
parent
9f4d365098
commit
809cf3a2e5
@ -3397,6 +3397,7 @@ static int __protect_cp_mem(struct venus_hfi_device *device)
|
||||
memprot.cp_nonpixel_start = 0x0;
|
||||
memprot.cp_nonpixel_size = 0x0;
|
||||
|
||||
mutex_lock(&device->res->cb_lock);
|
||||
list_for_each_entry(cb, &device->res->context_banks, list) {
|
||||
if (!strcmp(cb->name, "venus_ns")) {
|
||||
memprot.cp_size = cb->addr_range.start;
|
||||
@ -3414,6 +3415,7 @@ static int __protect_cp_mem(struct venus_hfi_device *device)
|
||||
memprot.cp_nonpixel_size);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&device->res->cb_lock);
|
||||
|
||||
rc = qcom_scm_mem_protect_video(memprot.cp_start, memprot.cp_size,
|
||||
memprot.cp_nonpixel_start, memprot.cp_nonpixel_size);
|
||||
|
@ -583,6 +583,7 @@ struct context_bank_info *msm_smem_get_context_bank(u32 session_type,
|
||||
buffer_type = HAL_BUFFER_INTERNAL_PERSIST_1;
|
||||
}
|
||||
|
||||
mutex_lock(&res->cb_lock);
|
||||
list_for_each_entry(cb, &res->context_banks, list) {
|
||||
if (cb->is_secure == is_secure &&
|
||||
cb->buffer_type & buffer_type) {
|
||||
@ -590,6 +591,7 @@ struct context_bank_info *msm_smem_get_context_bank(u32 session_type,
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&res->cb_lock);
|
||||
if (!match)
|
||||
s_vpr_e(sid,
|
||||
"%s: cb not found for buffer_type %x, is_secure %d\n",
|
||||
|
@ -289,6 +289,7 @@ static int msm_vidc_initialize_core(struct platform_device *pdev,
|
||||
|
||||
INIT_LIST_HEAD(&core->instances);
|
||||
mutex_init(&core->lock);
|
||||
mutex_init(&core->resources.cb_lock);
|
||||
|
||||
core->state = VIDC_CORE_UNINIT;
|
||||
for (i = SYS_MSG_INDEX(SYS_MSG_START);
|
||||
@ -644,6 +645,7 @@ static int msm_vidc_remove(struct platform_device *pdev)
|
||||
msm_vidc_free_platform_resources(&core->resources);
|
||||
sysfs_remove_group(&pdev->dev.kobj, &msm_vidc_core_attr_group);
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
mutex_destroy(&core->resources.cb_lock);
|
||||
mutex_destroy(&core->lock);
|
||||
kfree(core);
|
||||
return rc;
|
||||
|
@ -5717,26 +5717,29 @@ int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_inst)
|
||||
struct msm_vidc_format *fmt;
|
||||
struct v4l2_format *f;
|
||||
struct hal_buffer_requirements *req;
|
||||
struct context_bank_info *cb = NULL;
|
||||
u32 i, dpb_cnt = 0, dpb_size = 0, rc = 0;
|
||||
u64 mem_size = 0;
|
||||
u32 inst_mem_size, non_sec_cb_size = 0;
|
||||
u64 total_mem_size = 0, non_sec_mem_size = 0;
|
||||
u32 memory_limit_mbytes;
|
||||
|
||||
core = vidc_inst->core;
|
||||
|
||||
mutex_lock(&core->lock);
|
||||
list_for_each_entry(inst, &core->instances, list) {
|
||||
inst_mem_size = 0;
|
||||
/* input port buffers memory size */
|
||||
fmt = &inst->fmts[INPUT_PORT];
|
||||
f = &fmt->v4l2_fmt;
|
||||
for (i = 0; i < f->fmt.pix_mp.num_planes; i++)
|
||||
mem_size += f->fmt.pix_mp.plane_fmt[i].sizeimage *
|
||||
inst_mem_size += f->fmt.pix_mp.plane_fmt[i].sizeimage *
|
||||
fmt->count_min_host;
|
||||
|
||||
/* output port buffers memory size */
|
||||
fmt = &inst->fmts[OUTPUT_PORT];
|
||||
f = &fmt->v4l2_fmt;
|
||||
for (i = 0; i < f->fmt.pix_mp.num_planes; i++)
|
||||
mem_size += f->fmt.pix_mp.plane_fmt[i].sizeimage *
|
||||
inst_mem_size += f->fmt.pix_mp.plane_fmt[i].sizeimage *
|
||||
fmt->count_min_host;
|
||||
|
||||
/* dpb buffers memory size */
|
||||
@ -5753,29 +5756,49 @@ int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_inst)
|
||||
}
|
||||
dpb_cnt = dpb.buffer_count_actual;
|
||||
dpb_size = dpb.buffer_size;
|
||||
mem_size += dpb_cnt * dpb_size;
|
||||
inst_mem_size += dpb_cnt * dpb_size;
|
||||
}
|
||||
|
||||
/* internal buffers memory size */
|
||||
for (i = 0; i < HAL_BUFFER_MAX; i++) {
|
||||
req = &inst->buff_req.buffer[i];
|
||||
if (is_internal_buffer(req->buffer_type))
|
||||
mem_size += req->buffer_size *
|
||||
inst_mem_size += req->buffer_size *
|
||||
req->buffer_count_actual;
|
||||
}
|
||||
|
||||
if (!is_secure_session(inst))
|
||||
non_sec_mem_size += inst_mem_size;
|
||||
total_mem_size += inst_mem_size;
|
||||
}
|
||||
mutex_unlock(&core->lock);
|
||||
|
||||
memory_limit_mbytes = msm_comm_get_memory_limit(core);
|
||||
|
||||
if ((mem_size >> 20) > memory_limit_mbytes) {
|
||||
if ((total_mem_size >> 20) > memory_limit_mbytes) {
|
||||
s_vpr_e(vidc_inst->sid,
|
||||
"%s: video mem overshoot - reached %llu MB, max_limit %llu MB\n",
|
||||
__func__, mem_size >> 20, memory_limit_mbytes);
|
||||
msm_comm_print_mem_usage(core);
|
||||
__func__, total_mem_size >> 20, memory_limit_mbytes);
|
||||
msm_comm_print_insts_info(core);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (!is_secure_session(vidc_inst)) {
|
||||
mutex_lock(&core->resources.cb_lock);
|
||||
list_for_each_entry(cb, &core->resources.context_banks, list)
|
||||
if (!cb->is_secure)
|
||||
non_sec_cb_size = cb->addr_range.size;
|
||||
mutex_unlock(&core->resources.cb_lock);
|
||||
|
||||
if (non_sec_mem_size > non_sec_cb_size) {
|
||||
s_vpr_e(vidc_inst->sid,
|
||||
"%s: insufficient device addr space, required %llu, available %llu\n",
|
||||
__func__, non_sec_mem_size, non_sec_cb_size);
|
||||
msm_comm_print_insts_info(core);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -6284,6 +6307,23 @@ void msm_comm_print_inst_info(struct msm_vidc_inst *inst)
|
||||
mutex_unlock(&inst->outputbufs.lock);
|
||||
}
|
||||
|
||||
void msm_comm_print_insts_info(struct msm_vidc_core *core)
|
||||
{
|
||||
struct msm_vidc_inst *inst = NULL;
|
||||
|
||||
if (!core) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
msm_comm_print_mem_usage(core);
|
||||
|
||||
mutex_lock(&core->lock);
|
||||
list_for_each_entry(inst, &core->instances, list)
|
||||
msm_comm_print_inst_info(inst);
|
||||
mutex_unlock(&core->lock);
|
||||
}
|
||||
|
||||
int msm_comm_session_continue(void *instance)
|
||||
{
|
||||
struct msm_vidc_inst *inst = instance;
|
||||
|
@ -273,6 +273,7 @@ int msm_comm_ctrl_deinit(struct msm_vidc_inst *inst);
|
||||
void msm_comm_cleanup_internal_buffers(struct msm_vidc_inst *inst);
|
||||
bool msm_comm_turbo_session(struct msm_vidc_inst *inst);
|
||||
void msm_comm_print_inst_info(struct msm_vidc_inst *inst);
|
||||
void msm_comm_print_insts_info(struct msm_vidc_core *core);
|
||||
int msm_comm_v4l2_to_hfi(int id, int value, u32 sid);
|
||||
int msm_comm_hfi_to_v4l2(int id, int value, u32 sid);
|
||||
int msm_comm_get_v4l2_profile(int fourcc, int profile, u32 sid);
|
||||
|
@ -850,7 +850,6 @@ int read_platform_resources_from_dt(
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
||||
INIT_LIST_HEAD(&res->context_banks);
|
||||
|
||||
res->firmware_base = (phys_addr_t)firmware_base;
|
||||
@ -989,7 +988,6 @@ int msm_vidc_smmu_fault_handler(struct iommu_domain *domain,
|
||||
struct device *dev, unsigned long iova, int flags, void *token)
|
||||
{
|
||||
struct msm_vidc_core *core = token;
|
||||
struct msm_vidc_inst *inst;
|
||||
|
||||
if (!domain || !core) {
|
||||
d_vpr_e("%s: invalid params %pK %pK\n",
|
||||
@ -1008,12 +1006,8 @@ int msm_vidc_smmu_fault_handler(struct iommu_domain *domain,
|
||||
|
||||
d_vpr_e("%s: faulting address: %lx\n", __func__, iova);
|
||||
|
||||
mutex_lock(&core->lock);
|
||||
list_for_each_entry(inst, &core->instances, list) {
|
||||
msm_comm_print_inst_info(inst);
|
||||
}
|
||||
core->smmu_fault_handled = true;
|
||||
mutex_unlock(&core->lock);
|
||||
msm_comm_print_insts_info(core);
|
||||
/*
|
||||
* Return -EINVAL to elicit the default behaviour of smmu driver.
|
||||
* If we return -EINVAL, then smmu driver assumes page fault handler
|
||||
@ -1043,7 +1037,10 @@ static int msm_vidc_populate_context_bank(struct device *dev,
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&cb->list);
|
||||
|
||||
mutex_lock(&core->resources.cb_lock);
|
||||
list_add_tail(&cb->list, &core->resources.context_banks);
|
||||
mutex_unlock(&core->resources.cb_lock);
|
||||
|
||||
rc = of_property_read_string(np, "label", &cb->name);
|
||||
if (rc) {
|
||||
@ -1123,7 +1120,10 @@ static int msm_vidc_populate_legacy_context_bank(
|
||||
return -ENOMEM;
|
||||
}
|
||||
INIT_LIST_HEAD(&cb->list);
|
||||
|
||||
mutex_lock(&res->cb_lock);
|
||||
list_add_tail(&cb->list, &res->context_banks);
|
||||
mutex_unlock(&res->cb_lock);
|
||||
|
||||
ctx_node = of_parse_phandle(domains_child_node,
|
||||
"qcom,vidc-domain-phandle", 0);
|
||||
|
@ -167,6 +167,7 @@ struct msm_vidc_platform_resources {
|
||||
bool sw_power_collapsible;
|
||||
bool slave_side_cp;
|
||||
struct list_head context_banks;
|
||||
struct mutex cb_lock;
|
||||
bool thermal_mitigable;
|
||||
const char *fw_name;
|
||||
const char *hfi_version;
|
||||
|
Loading…
Reference in New Issue
Block a user