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:
Govindaraj Rajagopal 2020-03-05 20:29:04 +05:30
parent 9f4d365098
commit 809cf3a2e5
7 changed files with 63 additions and 15 deletions

View File

@ -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);

View File

@ -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",

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;