mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-23 17:55:05 +03:00
nvdla: Fix build for CONFIG_FRAME_WARN=1024
Some 3rd party Linux distributions, set the kernel configuration option "CONFIG_FRAME_WARN=1024" which will causes the compiler to generate compilation errors when a functions stack frame size exceeds 1024 bytes. When compiling the DLA driver on Fedora the compilation fails with the following errors. drivers/video/tegra/host/nvdla/nvdla.o] Error 1 drivers/video/tegra/host/nvdla/nvdla_ioctl.c: In function ‘nvdla_emu_task_submit’: build/drivers/video/tegra/host/nvdla/nvdla_ioctl.c:918:1: error: the frame size of 1456 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] drivers/video/tegra/host/nvdla/nvdla_ioctl.c: In function ‘nvdla_submit’: drivers/video/tegra/host/nvdla/nvdla_ioctl.c:1118:1: error: the frame size of 1440 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] Fix this by copying the user tasks from userspace one at a time and allocating the structure nvdla_emu_task dynamically so that is it not allocated on the stack. Bug 3524939 Change-Id: If752423a170c46efd9b6cffc458a7c1db1984afe Signed-off-by: Jon Hunter <jonathanh@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2694097 Tested-by: Amit Sharma (SW-TEGRA) <amisharma@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Amit Sharma (SW-TEGRA) <amisharma@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Arvind M <am@nvidia.com> Reviewed-by: Praveen K <kpraveen@nvidia.com> GVS: Gerrit_Virtual_Submit
This commit is contained in:
committed by
Laxman Dewangan
parent
0b7fd59dca
commit
b67df49181
@@ -832,10 +832,10 @@ static int nvdla_emu_task_submit(struct nvdla_private *priv, void *arg)
|
|||||||
struct nvdla_submit_args *args =
|
struct nvdla_submit_args *args =
|
||||||
(struct nvdla_submit_args *)arg;
|
(struct nvdla_submit_args *)arg;
|
||||||
struct nvdla_ioctl_emu_submit_task __user *user_tasks;
|
struct nvdla_ioctl_emu_submit_task __user *user_tasks;
|
||||||
struct nvdla_ioctl_emu_submit_task local_tasks[MAX_NVDLA_TASKS_PER_SUBMIT];
|
struct nvdla_ioctl_emu_submit_task local_task;
|
||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
struct nvdla_queue *queue;
|
struct nvdla_queue *queue;
|
||||||
struct nvdla_emu_task task;
|
struct nvdla_emu_task *task;
|
||||||
int err = 0, i = 0;
|
int err = 0, i = 0;
|
||||||
u32 num_tasks;
|
u32 num_tasks;
|
||||||
|
|
||||||
@@ -849,8 +849,6 @@ static int nvdla_emu_task_submit(struct nvdla_private *priv, void *arg)
|
|||||||
|
|
||||||
nvdla_dbg_fn(pdev, "inside emulator task submit");
|
nvdla_dbg_fn(pdev, "inside emulator task submit");
|
||||||
|
|
||||||
task.queue = queue;
|
|
||||||
|
|
||||||
user_tasks = (struct nvdla_ioctl_emu_submit_task __user *)
|
user_tasks = (struct nvdla_ioctl_emu_submit_task __user *)
|
||||||
(uintptr_t)args->tasks;
|
(uintptr_t)args->tasks;
|
||||||
if (!user_tasks)
|
if (!user_tasks)
|
||||||
@@ -862,40 +860,44 @@ static int nvdla_emu_task_submit(struct nvdla_private *priv, void *arg)
|
|||||||
|
|
||||||
nvdla_dbg_info(pdev, "num of emulator tasks [%d]", num_tasks);
|
nvdla_dbg_info(pdev, "num of emulator tasks [%d]", num_tasks);
|
||||||
|
|
||||||
/* IOCTL copy descriptors*/
|
task = kmalloc(sizeof(*task), GFP_KERNEL);
|
||||||
if (copy_from_user(local_tasks, (void __user *)user_tasks,
|
if (!task)
|
||||||
(num_tasks * sizeof(*user_tasks)))) {
|
return -ENOMEM;
|
||||||
|
|
||||||
|
task->queue = queue;
|
||||||
|
|
||||||
|
for (i = 0; i < num_tasks; i++) {
|
||||||
|
/* IOCTL copy descriptor */
|
||||||
|
if (copy_from_user(&local_task, (void __user *)&user_tasks[i],
|
||||||
|
sizeof(*user_tasks))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
nvdla_dbg_info(pdev, "copy of user tasks done");
|
|
||||||
|
|
||||||
for (i = 0; i < num_tasks; i++) {
|
|
||||||
|
|
||||||
nvdla_dbg_info(pdev, "submit [%d]th task", i + 1);
|
nvdla_dbg_info(pdev, "submit [%d]th task", i + 1);
|
||||||
|
|
||||||
task.num_prefences = local_tasks[i].num_prefences;
|
task->num_prefences = local_task.num_prefences;
|
||||||
task.num_postfences = local_tasks[i].num_postfences;
|
task->num_postfences = local_task.num_postfences;
|
||||||
|
|
||||||
/* get pre fences */
|
/* get pre fences */
|
||||||
if (copy_from_user(task.prefences,
|
if (copy_from_user(task->prefences,
|
||||||
(void __user *)local_tasks[i].prefences,
|
(void __user *)local_task.prefences,
|
||||||
(task.num_prefences * sizeof(struct nvdev_fence)))) {
|
(task->num_prefences * sizeof(struct nvdev_fence)))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
nvdla_dbg_err(pdev, "failed to copy prefences");
|
nvdla_dbg_err(pdev, "failed to copy prefences");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get post fences */
|
/* get post fences */
|
||||||
if (copy_from_user(task.postfences,
|
if (copy_from_user(task->postfences,
|
||||||
(void __user *)local_tasks[i].postfences,
|
(void __user *)local_task.postfences,
|
||||||
(task.num_postfences * sizeof(struct nvdev_fence)))) {
|
(task->num_postfences * sizeof(struct nvdev_fence)))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
nvdla_dbg_err(pdev, "failed to copy postfences");
|
nvdla_dbg_err(pdev, "failed to copy postfences");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = nvdla_emulator_submit(queue, &task);
|
err = nvdla_emulator_submit(queue, task);
|
||||||
if (err) {
|
if (err) {
|
||||||
nvdla_dbg_err(pdev, "fail to submit task: %d", i + 1);
|
nvdla_dbg_err(pdev, "fail to submit task: %d", i + 1);
|
||||||
goto exit;
|
goto exit;
|
||||||
@@ -903,7 +905,7 @@ static int nvdla_emu_task_submit(struct nvdla_private *priv, void *arg)
|
|||||||
nvdla_dbg_info(pdev, "task[%d] submitted", i + 1);
|
nvdla_dbg_info(pdev, "task[%d] submitted", i + 1);
|
||||||
|
|
||||||
/* send signal fences to user */
|
/* send signal fences to user */
|
||||||
err = nvdla_send_emu_signal_fences(&task, local_tasks + i);
|
err = nvdla_send_emu_signal_fences(task, &local_task);
|
||||||
if (err) {
|
if (err) {
|
||||||
nvdla_dbg_err(pdev, "fail to send sig fence%d", i + 1);
|
nvdla_dbg_err(pdev, "fail to send sig fence%d", i + 1);
|
||||||
goto exit;
|
goto exit;
|
||||||
@@ -914,6 +916,8 @@ static int nvdla_emu_task_submit(struct nvdla_private *priv, void *arg)
|
|||||||
nvdla_dbg_fn(pdev, "Emulator task submitted, done!");
|
nvdla_dbg_fn(pdev, "Emulator task submitted, done!");
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
kfree(task);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -986,7 +990,7 @@ static int nvdla_submit(struct nvdla_private *priv, void *arg)
|
|||||||
struct nvdla_submit_args *args =
|
struct nvdla_submit_args *args =
|
||||||
(struct nvdla_submit_args *)arg;
|
(struct nvdla_submit_args *)arg;
|
||||||
struct nvdla_ioctl_submit_task __user *user_tasks;
|
struct nvdla_ioctl_submit_task __user *user_tasks;
|
||||||
struct nvdla_ioctl_submit_task local_tasks[MAX_NVDLA_TASKS_PER_SUBMIT];
|
struct nvdla_ioctl_submit_task local_task;
|
||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
struct nvdla_queue *queue;
|
struct nvdla_queue *queue;
|
||||||
struct nvdla_buffers *buffers;
|
struct nvdla_buffers *buffers;
|
||||||
@@ -1020,15 +1024,14 @@ static int nvdla_submit(struct nvdla_private *priv, void *arg)
|
|||||||
bypass_exec = ((args->flags & NVDLA_SUBMIT_FLAGS_BYPASS_EXEC) != 0U);
|
bypass_exec = ((args->flags & NVDLA_SUBMIT_FLAGS_BYPASS_EXEC) != 0U);
|
||||||
nvdla_dbg_info(pdev, "submit flags [%u]", args->flags);
|
nvdla_dbg_info(pdev, "submit flags [%u]", args->flags);
|
||||||
|
|
||||||
/* IOCTL copy descriptors*/
|
for (i = 0; i < num_tasks; i++) {
|
||||||
if (copy_from_user(local_tasks, (void __user *)user_tasks,
|
/* IOCTL copy descriptor */
|
||||||
(num_tasks * sizeof(*user_tasks)))) {
|
if (copy_from_user(&local_task, (void __user *)&user_tasks[i],
|
||||||
|
sizeof(*user_tasks))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
goto fail_to_copy_task;
|
goto fail_to_copy_task;
|
||||||
}
|
}
|
||||||
nvdla_dbg_info(pdev, "copy of user tasks done");
|
|
||||||
|
|
||||||
for (i = 0; i < num_tasks; i++) {
|
|
||||||
nvdla_dbg_info(pdev, "submit [%d]th task", i + 1);
|
nvdla_dbg_info(pdev, "submit [%d]th task", i + 1);
|
||||||
|
|
||||||
err = nvdla_get_task_mem(queue, &task);
|
err = nvdla_get_task_mem(queue, &task);
|
||||||
@@ -1042,7 +1045,7 @@ static int nvdla_submit(struct nvdla_private *priv, void *arg)
|
|||||||
kref_init(&task->ref);
|
kref_init(&task->ref);
|
||||||
|
|
||||||
/* fill local task param from user args */
|
/* fill local task param from user args */
|
||||||
err = nvdla_fill_task(queue, buffers, local_tasks + i, task);
|
err = nvdla_fill_task(queue, buffers, &local_task, task);
|
||||||
if (err) {
|
if (err) {
|
||||||
nvdla_dbg_err(pdev, "failed to fill task[%d]", i + 1);
|
nvdla_dbg_err(pdev, "failed to fill task[%d]", i + 1);
|
||||||
goto fail_to_fill_task;
|
goto fail_to_fill_task;
|
||||||
@@ -1075,7 +1078,7 @@ static int nvdla_submit(struct nvdla_private *priv, void *arg)
|
|||||||
nvdla_dbg_info(pdev, "task[%d] got fences", i + 1);
|
nvdla_dbg_info(pdev, "task[%d] got fences", i + 1);
|
||||||
|
|
||||||
/* update fences to user */
|
/* update fences to user */
|
||||||
err = nvdla_update_signal_fences(task, local_tasks + i);
|
err = nvdla_update_signal_fences(task, &local_task);
|
||||||
if (err) {
|
if (err) {
|
||||||
nvdla_dbg_err(pdev, "fail update postfence%d", i + 1);
|
nvdla_dbg_err(pdev, "fail update postfence%d", i + 1);
|
||||||
goto fail_to_update_postfences;
|
goto fail_to_update_postfences;
|
||||||
|
|||||||
Reference in New Issue
Block a user