platform: tegra: rtcpu: Fix cache sync APIs

For dma mappings done with dma_map_sg() calls, dma_sync_sg* calls are
required in order to make sure that caches for all the scattered
addresses are synced. Using dma_sync_single* call for syncing caches
can access address which is not mapped by dma_sync_sg() and cause kernel
exceptions.
Fix this by using correct cache sync calls for appropriate dma mapping
APIs.

Bug 3879036

Change-Id: I30afcf17806c505d94ff4eb7faefab5fbbf9e7b9
Signed-off-by: Ashish Mhetre <amhetre@nvidia.com>
Signed-off-by: Matti Ryttylainen <mryttylainen@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2839838
Reviewed-by: svcacv <svcacv@nvidia.com>
Reviewed-by: Pekka Pessi <ppessi@nvidia.com>
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Ashish Mhetre
2023-01-09 08:46:35 +00:00
committed by mobile promotions
parent 947f489dac
commit ff7d0cc87c

View File

@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#include "soc/tegra/camrtc-dbg-messages.h"
@@ -840,6 +840,8 @@ static void camrtc_run_rmem_unmap_all(struct camrtc_debug *crd,
}
}
#define INT_MAX ((int)(~0U >> 1))
static int camrtc_run_mem_map(struct tegra_ivc_channel *ch,
struct device *mem_dev,
struct device *dev,
@@ -861,6 +863,8 @@ static int camrtc_run_mem_map(struct tegra_ivc_channel *ch,
if (mem_dev == dev) {
*return_iova = mem->iova;
dma_sync_single_for_device(dev, mem->iova, mem->size,
DMA_BIDIRECTIONAL);
goto done;
}
@@ -872,6 +876,8 @@ static int camrtc_run_mem_map(struct tegra_ivc_channel *ch,
*return_iova = 0ULL;
return -ENOMEM;
}
dma_sync_single_for_device(dev, mem->iova, mem->size,
DMA_BIDIRECTIONAL);
} else {
ret = dma_get_sgtable(dev, sgt, mem->ptr, mem->iova, mem->size);
if (ret < 0) {
@@ -889,6 +895,10 @@ static int camrtc_run_mem_map(struct tegra_ivc_channel *ch,
}
*return_iova = sgt->sgl->dma_address;
if (sgt->nents <= INT_MAX)
dma_sync_sg_for_device(dev, sgt->sgl, (int)sgt->nents, DMA_BIDIRECTIONAL);
else
ret = -EINVAL;
}
done:
@@ -1056,8 +1066,6 @@ static int camrtc_run_mem_test(struct seq_file *file,
if (ret < 0)
goto unmap;
dma_sync_single_for_device(mem_dev, mem->iova, mem->used,
DMA_BIDIRECTIONAL);
}
BUILD_BUG_ON_MISMATCH(
@@ -1080,8 +1088,12 @@ static int camrtc_run_mem_test(struct seq_file *file,
if (!WARN_ON(testmem->size > mem->size))
mem->used = testmem->size;
if (_camdbg_rmem.enabled)
dma_sync_single_for_cpu(mem_dev, mem->iova, mem->used,
DMA_BIDIRECTIONAL);
else
dma_sync_sg_for_cpu(mem_dev, vi_sgt[i].sgl,
vi_sgt[i].nents, DMA_BIDIRECTIONAL);
}
unmap: