From 59fe8f5aef60e673005d9f80d88ee70f8b96429a Mon Sep 17 00:00:00 2001 From: Gunjan Mehta Date: Fri, 1 Nov 2019 18:27:12 +0530 Subject: [PATCH] dla: linux: add speculation barrieir in linux driver Bug 200483495 Add speculation barriers for if and for loops to prevent spectre variant 1-S type attacks Change-Id: If44a2c96047899accecf9604f3893daf681656c7 Signed-off-by: Gunjan Mehta Reviewed-on: https://git-master.nvidia.com/r/2230039 Reviewed-by: Arvind M Tested-by: Arvind M Reviewed-by: Bharat Nihalani GVS: Gerrit_Virtual_Submit Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/video/tegra/host/nvdla/dla_queue.c | 3 +++ drivers/video/tegra/host/nvdla/nvdla.c | 1 + drivers/video/tegra/host/nvdla/nvdla_buffer.c | 3 +++ drivers/video/tegra/host/nvdla/nvdla_ioctl.c | 8 ++++++++ drivers/video/tegra/host/nvdla/nvdla_queue.c | 8 ++++++++ 5 files changed, 23 insertions(+) diff --git a/drivers/video/tegra/host/nvdla/dla_queue.c b/drivers/video/tegra/host/nvdla/dla_queue.c index 69f10680..2f31f501 100644 --- a/drivers/video/tegra/host/nvdla/dla_queue.c +++ b/drivers/video/tegra/host/nvdla/dla_queue.c @@ -212,6 +212,7 @@ struct nvdla_queue_pool *nvdla_queue_init(struct platform_device *pdev, queue->task_pool = (void *)&task_pool[i]; nvdla_queue_get_task_size(queue); } + speculation_barrier(); /* break_spec_p#5_1 */ return pool; @@ -302,6 +303,7 @@ struct nvdla_queue *nvdla_queue_alloc(struct nvdla_queue_pool *pool, err = -ENOMEM; goto err_alloc_queue; } + speculation_barrier(); /* break_spec_p#1 */ /* reserve the queue */ queue = &queues[index]; @@ -478,6 +480,7 @@ int nvdla_queue_submit_to_host1x(struct nvdla_queue *queue, job->waitchk[i].thresh = wait_syncpt_thresholds[i]; job->waitchk[i].mem = 0; } + speculation_barrier(); /* break_spec_p#5_1 */ /* Initialize syncpoint increments */ job->sp->id = queue->syncpt_id; diff --git a/drivers/video/tegra/host/nvdla/nvdla.c b/drivers/video/tegra/host/nvdla/nvdla.c index 4f4c9798..0621b62b 100644 --- a/drivers/video/tegra/host/nvdla/nvdla.c +++ b/drivers/video/tegra/host/nvdla/nvdla.c @@ -574,6 +574,7 @@ int nvdla_send_gos_region(struct platform_device *pdev) gos_region->grid_size = MAX_GRID_SIZE; for (i = 0; i < num_grids; i++) gos_region->address[i] = dla_grid[i]; + speculation_barrier(); /* break_spec_p#5_1 */ /* set cmd info */ cmd_data.method_id = DLA_CMD_SET_REGIONS; diff --git a/drivers/video/tegra/host/nvdla/nvdla_buffer.c b/drivers/video/tegra/host/nvdla/nvdla_buffer.c index 1d7fabfb..88e9b5ab 100644 --- a/drivers/video/tegra/host/nvdla/nvdla_buffer.c +++ b/drivers/video/tegra/host/nvdla/nvdla_buffer.c @@ -261,6 +261,7 @@ int nvdla_buffer_submit_pin(struct nvdla_buffers *nvdla_buffers, if (heap != NULL) heap[i] = vm->heap; } + speculation_barrier(); /* break_spec_p#5_1 */ mutex_unlock(&nvdla_buffers->mutex); return 0; @@ -304,6 +305,7 @@ int nvdla_buffer_pin(struct nvdla_buffers *nvdla_buffers, nvdla_buffer_insert_map_buffer(nvdla_buffers, vm); } + speculation_barrier(); /* break_spec_p#5_1 */ mutex_unlock(&nvdla_buffers->mutex); return err; @@ -362,6 +364,7 @@ void nvdla_buffer_unpin(struct nvdla_buffers *nvdla_buffers, vm->user_map_count = 0; nvdla_buffer_unmap(nvdla_buffers, vm); } + speculation_barrier(); /* break_spec_p#5_1 */ mutex_unlock(&nvdla_buffers->mutex); } diff --git a/drivers/video/tegra/host/nvdla/nvdla_ioctl.c b/drivers/video/tegra/host/nvdla/nvdla_ioctl.c index 86f2a721..a9bb63b8 100644 --- a/drivers/video/tegra/host/nvdla/nvdla_ioctl.c +++ b/drivers/video/tegra/host/nvdla/nvdla_ioctl.c @@ -207,6 +207,7 @@ static int nvdla_pin(struct nvdla_private *priv, void *arg) goto fail_to_get_dma_buf; } } + speculation_barrier(); /* break_spec_p#5_1 */ err = nvdla_buffer_pin(priv->buffers, dmabufs, count); @@ -260,6 +261,7 @@ static int nvdla_unpin(struct nvdla_private *priv, void *arg) if (IS_ERR_OR_NULL(dmabufs[i])) continue; } + speculation_barrier(); /* break_spec_p#5_1 */ nvdla_buffer_unpin(priv->buffers, dmabufs, count); @@ -465,6 +467,7 @@ static int nvdla_send_emu_signal_fences(struct nvdla_emu_task *task, } } } + speculation_barrier(); /* break_spec_p#5_1 */ nvdla_dbg_fn(dla_pdev, "copy prefences to user"); /* send pre fences */ @@ -506,6 +509,7 @@ static int nvdla_send_emu_signal_fences(struct nvdla_emu_task *task, } } } + speculation_barrier(); /* break_spec_p#5_1 */ nvdla_dbg_fn(dla_pdev, "copy postfences to user"); /* send post fences */ @@ -567,6 +571,7 @@ static int nvdla_update_signal_fences(struct nvdla_task *task, } } } + speculation_barrier(); /* break_spec_p#5_1 */ nvdla_dbg_fn(dla_pdev, "copy prefences to user"); /* copy pre fences */ @@ -608,6 +613,7 @@ static int nvdla_update_signal_fences(struct nvdla_task *task, } } } + speculation_barrier(); /* break_spec_p#5_1 */ nvdla_dbg_fn(dla_pdev, "copy postfences to user"); /* copy post fences */ @@ -838,6 +844,7 @@ static void nvdla_dump_task(struct nvdla_task *task) i, task->memory_handles[i].handle, task->memory_handles[i].offset); } + speculation_barrier(); /* break_spec_p#5_1 */ } static int nvdla_emu_task_submit(struct nvdla_private *priv, void *arg) @@ -924,6 +931,7 @@ static int nvdla_emu_task_submit(struct nvdla_private *priv, void *arg) } nvdla_dbg_info(pdev, "signal fences of task[%d] sent", i + 1); } + speculation_barrier(); /* break_spec_p#5_1 */ nvdla_dbg_fn(pdev, "Emulator task submitted, done!"); exit: diff --git a/drivers/video/tegra/host/nvdla/nvdla_queue.c b/drivers/video/tegra/host/nvdla/nvdla_queue.c index 10c4b145..fa075ed5 100644 --- a/drivers/video/tegra/host/nvdla/nvdla_queue.c +++ b/drivers/video/tegra/host/nvdla/nvdla_queue.c @@ -78,6 +78,7 @@ static void nvdla_queue_dump_op(struct nvdla_queue *queue, struct seq_file *s) } + speculation_barrier(); /* break_spec_p#5_1 */ mutex_unlock(&queue->list_lock); } @@ -246,6 +247,7 @@ static int nvdla_unmap_task_memory(struct nvdla_task *task) } nvdla_dbg_fn(pdev, "all out timestamps unmaped"); + speculation_barrier(); /* break_spec_p#5_1 */ return 0; } @@ -547,6 +549,7 @@ static int nvdla_map_task_memory(struct nvdla_task *task) next = add_address(next, dma_addr + task->memory_handles[jj].offset); } + speculation_barrier(); /* break_spec_p#5_1 */ fail_to_pin_mem: return err; @@ -1071,6 +1074,7 @@ static int nvdla_fill_postactions(struct nvdla_task *task) postactionl->offset = postactionlist_of; postactionl->size = next - start; + speculation_barrier(); /* break_spec_p#5_1 */ fail: return err; } @@ -1179,6 +1183,7 @@ static int nvdla_fill_preactions(struct nvdla_task *task) preactionl->offset = preactionlist_of; preactionl->size = next - start; + speculation_barrier(); /* break_spec_p#5_1 */ fail: return err; } @@ -1300,6 +1305,7 @@ static int nvdla_send_cmd_channel(struct platform_device *pdev, syncpt_wait_thresh[i] = task->prefences[i].syncpoint_value; } + speculation_barrier(); /* break_spec_p#5_1 */ cmdbuf[0] = nvhost_opcode_incr(NV_DLA_THI_METHOD_ID >> 2, 2); cmdbuf[1] = method_id; @@ -1431,6 +1437,7 @@ int nvdla_emulator_submit(struct nvdla_queue *queue, struct nvdla_emu_task *task } } + speculation_barrier(); /* break_spec_p#5_1 */ return 0; } @@ -1491,6 +1498,7 @@ int nvdla_get_signal_fences(struct nvdla_queue *queue, void *in_task) counter = counter - 1; } } + speculation_barrier(); /* break_spec_p#5_1 */ return 0; }