From aa52019b1b10988afaf210abbf321d41b7803804 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Fri, 1 Jun 2012 11:09:36 +0300 Subject: video: tegra: host: Remove error case panics Remove BUG_ON()s in error cases: * If IOCTL size is too large, return error instead * If sync point id is out of range, return error. Prevents panics in sanity checks nvhost_cdma. Bug 993642 Change-Id: I3cfa7a23dc557c811e20b726885f82666437de7f Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/105866 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Juha Tukkinen --- drivers/video/tegra/host/bus_client.c | 14 ++++++++------ drivers/video/tegra/host/dev.c | 5 ++--- drivers/video/tegra/host/nvhost_acm.c | 12 ++++++++++-- drivers/video/tegra/host/nvhost_syncpt.h | 5 +++++ 4 files changed, 25 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/video/tegra/host/bus_client.c b/drivers/video/tegra/host/bus_client.c index 651a8dec738c..6bfce9a3cb2a 100644 --- a/drivers/video/tegra/host/bus_client.c +++ b/drivers/video/tegra/host/bus_client.c @@ -179,14 +179,17 @@ fail: static int set_submit(struct nvhost_channel_userctx *ctx) { - struct device *device = &ctx->ch->dev->dev; + struct nvhost_device *ndev = ctx->ch->dev; + struct nvhost_master *host = nvhost_get_host(ndev); /* submit should have at least 1 cmdbuf */ - if (!ctx->hdr.num_cmdbufs) + if (!ctx->hdr.num_cmdbufs || + !nvhost_syncpt_is_valid(&host->syncpt, + ctx->hdr.syncpt_id)) return -EIO; if (!ctx->nvmap) { - dev_err(device, "no nvmap context set\n"); + dev_err(&ndev->dev, "no nvmap context set\n"); return -EFAULT; } @@ -402,11 +405,10 @@ static long nvhost_channelctl(struct file *filp, if ((_IOC_TYPE(cmd) != NVHOST_IOCTL_MAGIC) || (_IOC_NR(cmd) == 0) || - (_IOC_NR(cmd) > NVHOST_IOCTL_CHANNEL_LAST)) + (_IOC_NR(cmd) > NVHOST_IOCTL_CHANNEL_LAST) || + (_IOC_SIZE(cmd) > NVHOST_IOCTL_CHANNEL_MAX_ARG_SIZE)) return -EFAULT; - BUG_ON(_IOC_SIZE(cmd) > NVHOST_IOCTL_CHANNEL_MAX_ARG_SIZE); - if (_IOC_DIR(cmd) & _IOC_WRITE) { if (copy_from_user(buf, (void __user *)arg, _IOC_SIZE(cmd))) return -EFAULT; diff --git a/drivers/video/tegra/host/dev.c b/drivers/video/tegra/host/dev.c index 67520a884d3e..2c05fbfb7477 100644 --- a/drivers/video/tegra/host/dev.c +++ b/drivers/video/tegra/host/dev.c @@ -255,11 +255,10 @@ static long nvhost_ctrlctl(struct file *filp, if ((_IOC_TYPE(cmd) != NVHOST_IOCTL_MAGIC) || (_IOC_NR(cmd) == 0) || - (_IOC_NR(cmd) > NVHOST_IOCTL_CTRL_LAST)) + (_IOC_NR(cmd) > NVHOST_IOCTL_CTRL_LAST) || + (_IOC_SIZE(cmd) > NVHOST_IOCTL_CTRL_MAX_ARG_SIZE)) return -EFAULT; - BUG_ON(_IOC_SIZE(cmd) > NVHOST_IOCTL_CTRL_MAX_ARG_SIZE); - if (_IOC_DIR(cmd) & _IOC_WRITE) { if (copy_from_user(buf, (void __user *)arg, _IOC_SIZE(cmd))) return -EFAULT; diff --git a/drivers/video/tegra/host/nvhost_acm.c b/drivers/video/tegra/host/nvhost_acm.c index 6d96bd023d81..dfd84328307b 100644 --- a/drivers/video/tegra/host/nvhost_acm.c +++ b/drivers/video/tegra/host/nvhost_acm.c @@ -134,7 +134,11 @@ static void to_state_running_locked(struct nvhost_device *dev) for (i = 0; i < dev->num_clks; i++) { int err = clk_enable(dev->clk[i]); - BUG_ON(err); + if (err) { + dev_err(&dev->dev, "Cannot turn on clock %s", + dev->clocks[i].name); + return; + } } if (prev_state == NVHOST_POWER_STATE_POWERGATED @@ -369,7 +373,11 @@ int nvhost_module_init(struct nvhost_device *dev) snprintf(devname, MAX_DEVID_LENGTH, "tegra_%s", dev->name); c = clk_get_sys(devname, dev->clocks[i].name); - BUG_ON(IS_ERR_OR_NULL(c)); + if (IS_ERR_OR_NULL(c)) { + dev_err(&dev->dev, "Cannot get clock %s\n", + dev->clocks[i].name); + continue; + } rate = clk_round_rate(c, rate); clk_enable(c); diff --git a/drivers/video/tegra/host/nvhost_syncpt.h b/drivers/video/tegra/host/nvhost_syncpt.h index b58921bffa9c..fcc9fce72071 100644 --- a/drivers/video/tegra/host/nvhost_syncpt.h +++ b/drivers/video/tegra/host/nvhost_syncpt.h @@ -140,6 +140,11 @@ int nvhost_syncpt_patch_wait(struct nvhost_syncpt *sp, void *patch_addr); void nvhost_syncpt_debug(struct nvhost_syncpt *sp); +static inline int nvhost_syncpt_is_valid(struct nvhost_syncpt *sp, u32 id) +{ + return id != NVSYNCPT_INVALID && id < sp->nb_pts; +} + int nvhost_mutex_try_lock(struct nvhost_syncpt *sp, int idx); void nvhost_mutex_unlock(struct nvhost_syncpt *sp, int idx); -- cgit v1.2.3