summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/host/bus_client.c
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2012-05-31 08:15:28 +0300
committerSimone Willett <swillett@nvidia.com>2012-06-03 08:01:37 -0700
commitfdf40891983fc3fe1942877dcb07a4eab25f1796 (patch)
treef95b2e3f593cece2d8bd89c7cef8489f9fc42d6e /drivers/video/tegra/host/bus_client.c
parent22049ebd104af134fce3cdf39c813fb993d869e9 (diff)
video: tegra: host: Restrict register access
Register access (read/write) to modules MPE, ISP and VI lack sanity check for the register number. Add checks to ensure only aperture is accessed. Also make sure that the check accounts for wrapping of values of offset and count. Also fixes the register offset for reads which are done in multiple blocks. Bug 992938 Change-Id: I35f30cbd1dda31956286e48c5995b24fd262d1ae Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/105585 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'drivers/video/tegra/host/bus_client.c')
-rw-r--r--drivers/video/tegra/host/bus_client.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/video/tegra/host/bus_client.c b/drivers/video/tegra/host/bus_client.c
index 962de32f359f..651a8dec738c 100644
--- a/drivers/video/tegra/host/bus_client.c
+++ b/drivers/video/tegra/host/bus_client.c
@@ -50,10 +50,28 @@
#include "nvhost_job.h"
#include "nvhost_hwctx.h"
-void nvhost_read_module_regs(struct nvhost_device *ndev,
+static int validate_reg(struct nvhost_device *ndev, u32 offset, int count)
+{
+ struct resource *r = nvhost_get_resource(ndev, IORESOURCE_MEM, 0);
+ int err = 0;
+
+ if (offset + 4 * count > resource_size(r)
+ || (offset + 4 * count < offset))
+ err = -EPERM;
+
+ return err;
+}
+
+int nvhost_read_module_regs(struct nvhost_device *ndev,
u32 offset, int count, u32 *values)
{
void __iomem *p = ndev->aperture + offset;
+ int err;
+
+ /* verify offset */
+ err = validate_reg(ndev, offset, count);
+ if (err)
+ return err;
nvhost_module_busy(ndev);
while (count--) {
@@ -62,12 +80,20 @@ void nvhost_read_module_regs(struct nvhost_device *ndev,
}
rmb();
nvhost_module_idle(ndev);
+
+ return 0;
}
-void nvhost_write_module_regs(struct nvhost_device *ndev,
+int nvhost_write_module_regs(struct nvhost_device *ndev,
u32 offset, int count, const u32 *values)
{
void __iomem *p = ndev->aperture + offset;
+ int err;
+
+ /* verify offset */
+ err = validate_reg(ndev, offset, count);
+ if (err)
+ return err;
nvhost_module_busy(ndev);
while (count--) {
@@ -76,6 +102,8 @@ void nvhost_write_module_regs(struct nvhost_device *ndev,
}
wmb();
nvhost_module_idle(ndev);
+
+ return 0;
}
struct nvhost_channel_userctx {