diff --git a/drivers/gpu/nvgpu/common/falcon/falcon.c b/drivers/gpu/nvgpu/common/falcon/falcon.c index a4eff456e..6defee2af 100644 --- a/drivers/gpu/nvgpu/common/falcon/falcon.c +++ b/drivers/gpu/nvgpu/common/falcon/falcon.c @@ -282,7 +282,7 @@ int nvgpu_falcon_copy_to_emem(struct nvgpu_falcon *flcn, } static int falcon_memcpy_params_check(struct nvgpu_falcon *flcn, - u32 offset, u32 size, enum falcon_mem_type mem_type) + u32 offset, u32 size, enum falcon_mem_type mem_type, u8 port) { struct gk20a *g = flcn->g; u32 mem_size = 0; @@ -298,6 +298,11 @@ static int falcon_memcpy_params_check(struct nvgpu_falcon *flcn, goto exit; } + if (port >= flcn->flcn_ops.get_ports_count(flcn, mem_type)) { + nvgpu_err(g, "invalid port %u", (u32) port); + goto exit; + } + ret = nvgpu_falcon_get_mem_size(flcn, mem_type, &mem_size); if (ret != 0) { goto exit; @@ -335,7 +340,7 @@ int nvgpu_falcon_copy_from_dmem(struct nvgpu_falcon *flcn, goto exit; } - if (falcon_memcpy_params_check(flcn, src, size, MEM_DMEM) != 0) { + if (falcon_memcpy_params_check(flcn, src, size, MEM_DMEM, port) != 0) { nvgpu_err(flcn->g, "incorrect parameters"); goto exit; } @@ -366,7 +371,7 @@ int nvgpu_falcon_copy_to_dmem(struct nvgpu_falcon *flcn, goto exit; } - if (falcon_memcpy_params_check(flcn, dst, size, MEM_DMEM) != 0) { + if (falcon_memcpy_params_check(flcn, dst, size, MEM_DMEM, port) != 0) { nvgpu_err(flcn->g, "incorrect parameters"); goto exit; } @@ -397,7 +402,7 @@ int nvgpu_falcon_copy_from_imem(struct nvgpu_falcon *flcn, goto exit; } - if (falcon_memcpy_params_check(flcn, src, size, MEM_IMEM) != 0) { + if (falcon_memcpy_params_check(flcn, src, size, MEM_IMEM, port) != 0) { nvgpu_err(flcn->g, "incorrect parameters"); goto exit; } @@ -428,7 +433,7 @@ int nvgpu_falcon_copy_to_imem(struct nvgpu_falcon *flcn, goto exit; } - if (falcon_memcpy_params_check(flcn, dst, size, MEM_IMEM) != 0) { + if (falcon_memcpy_params_check(flcn, dst, size, MEM_IMEM, port) != 0) { nvgpu_err(flcn->g, "incorrect parameters"); goto exit; } @@ -451,7 +456,7 @@ static void falcon_print_mem(struct nvgpu_falcon *flcn, u32 src, u32 i = 0; int status = 0; - if (falcon_memcpy_params_check(flcn, src, size, mem_type) != 0) { + if (falcon_memcpy_params_check(flcn, src, size, mem_type, 0) != 0) { nvgpu_err(flcn->g, "incorrect parameters"); return; } diff --git a/drivers/gpu/nvgpu/common/falcon/falcon_gk20a.c b/drivers/gpu/nvgpu/common/falcon/falcon_gk20a.c index 725606a0a..4122ba1d4 100644 --- a/drivers/gpu/nvgpu/common/falcon/falcon_gk20a.c +++ b/drivers/gpu/nvgpu/common/falcon/falcon_gk20a.c @@ -147,6 +147,23 @@ static u32 gk20a_falcon_get_mem_size(struct nvgpu_falcon *flcn, return mem_size; } +static u8 gk20a_falcon_get_ports_count(struct nvgpu_falcon *flcn, + enum falcon_mem_type mem_type) +{ + struct gk20a *g = flcn->g; + u8 ports = 0; + u32 hw_cfg_reg1 = gk20a_readl(g, + flcn->flcn_base + falcon_falcon_hwcfg1_r()); + + if (mem_type == MEM_DMEM) { + ports = (u8) falcon_falcon_hwcfg1_dmem_ports_v(hw_cfg_reg1); + } else { + ports = (u8) falcon_falcon_hwcfg1_imem_ports_v(hw_cfg_reg1); + } + + return ports; +} + static int gk20a_falcon_copy_from_dmem(struct nvgpu_falcon *flcn, u32 src, u8 *dst, u32 size, u8 port) { @@ -585,6 +602,7 @@ void gk20a_falcon_ops(struct nvgpu_falcon *flcn) flcn_ops->mailbox_write = gk20a_falcon_mailbox_write; flcn_ops->get_falcon_ctls = gk20a_falcon_get_ctls; flcn_ops->get_mem_size = gk20a_falcon_get_mem_size; + flcn_ops->get_ports_count = gk20a_falcon_get_ports_count; gk20a_falcon_engine_dependency_ops(flcn); } diff --git a/drivers/gpu/nvgpu/common/falcon/falcon_priv.h b/drivers/gpu/nvgpu/common/falcon/falcon_priv.h index 539749805..38b4a9b5e 100644 --- a/drivers/gpu/nvgpu/common/falcon/falcon_priv.h +++ b/drivers/gpu/nvgpu/common/falcon/falcon_priv.h @@ -99,6 +99,8 @@ struct nvgpu_falcon_ops { u32 *cpuctl); u32 (*get_mem_size)(struct nvgpu_falcon *flcn, enum falcon_mem_type mem_type); + u8 (*get_ports_count)(struct nvgpu_falcon *flcn, + enum falcon_mem_type mem_type); }; struct nvgpu_falcon {