summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
diff options
context:
space:
mode:
authorKerwin Wan <kerwinw@nvidia.com>2014-04-10 23:24:10 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:09:11 -0400
commit875d12c7a06bc6906bb072feb15227addec22276 (patch)
tree0c3755b00c06d24bd0549a28f8b6bd7cda44af06 /drivers/gpu/nvgpu/gk20a/channel_gk20a.c
parent0389835edbb9687fdd28bc25668f7cd23974b7c3 (diff)
gpu: nvgpu: gk20a: check the return value of gk20a_channel_busy
gk20a_channel_busy is called to host gpu so that gk20a can be accessed. But it may return error like if gpu fails to be powered on. Always check the return value of gk20a_channel_busy to avoid illegal access to gk20a. Bug 1488409 Change-Id: Ie22da9e436ee5ea711003530419f546a73791b73 Signed-off-by: Kerwin Wan <kerwinw@nvidia.com> Reviewed-on: http://git-master/r/395180 Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/channel_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c80
1 files changed, 69 insertions, 11 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index 1cc0f154..90b7489c 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -697,10 +697,16 @@ int gk20a_channel_release(struct inode *inode, struct file *filp)
697{ 697{
698 struct channel_gk20a *ch = (struct channel_gk20a *)filp->private_data; 698 struct channel_gk20a *ch = (struct channel_gk20a *)filp->private_data;
699 struct gk20a *g = ch->g; 699 struct gk20a *g = ch->g;
700 int err;
700 701
701 trace_gk20a_channel_release(dev_name(&g->dev->dev)); 702 trace_gk20a_channel_release(dev_name(&g->dev->dev));
702 703
703 gk20a_channel_busy(ch->g->dev); 704 err = gk20a_channel_busy(ch->g->dev);
705 if (err) {
706 gk20a_err(dev_from_gk20a(g), "failed to release channel %d",
707 ch->hw_chid);
708 return err;
709 }
704 gk20a_free_channel(ch, true); 710 gk20a_free_channel(ch, true);
705 gk20a_channel_idle(ch->g->dev); 711 gk20a_channel_idle(ch->g->dev);
706 712
@@ -1422,7 +1428,7 @@ static int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
1422{ 1428{
1423 struct gk20a *g = c->g; 1429 struct gk20a *g = c->g;
1424 struct device *d = dev_from_gk20a(g); 1430 struct device *d = dev_from_gk20a(g);
1425 u32 err = 0; 1431 int err = 0;
1426 int i; 1432 int i;
1427 struct priv_cmd_entry *wait_cmd = NULL; 1433 struct priv_cmd_entry *wait_cmd = NULL;
1428 struct priv_cmd_entry *incr_cmd = NULL; 1434 struct priv_cmd_entry *incr_cmd = NULL;
@@ -1453,7 +1459,11 @@ static int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
1453 gk20a_dbg_info("channel %d", c->hw_chid); 1459 gk20a_dbg_info("channel %d", c->hw_chid);
1454 1460
1455 /* gk20a_channel_update releases this ref. */ 1461 /* gk20a_channel_update releases this ref. */
1456 gk20a_channel_busy(g->dev); 1462 err = gk20a_channel_busy(g->dev);
1463 if (err) {
1464 gk20a_err(d, "failed to host gk20a to submit gpfifo");
1465 return err;
1466 }
1457 1467
1458 trace_gk20a_channel_submit_gpfifo(c->g->dev->name, 1468 trace_gk20a_channel_submit_gpfifo(c->g->dev->name,
1459 c->hw_chid, 1469 c->hw_chid,
@@ -2031,19 +2041,37 @@ long gk20a_channel_ioctl(struct file *filp,
2031 case NVHOST_IOCTL_CHANNEL_SET_NVMAP_FD: 2041 case NVHOST_IOCTL_CHANNEL_SET_NVMAP_FD:
2032 break; 2042 break;
2033 case NVHOST_IOCTL_CHANNEL_ALLOC_OBJ_CTX: 2043 case NVHOST_IOCTL_CHANNEL_ALLOC_OBJ_CTX:
2034 gk20a_channel_busy(dev); 2044 err = gk20a_channel_busy(dev);
2045 if (err) {
2046 dev_err(&dev->dev,
2047 "%s: failed to host gk20a for ioctl cmd: 0x%x",
2048 __func__, cmd);
2049 return err;
2050 }
2035 err = gk20a_alloc_obj_ctx(ch, 2051 err = gk20a_alloc_obj_ctx(ch,
2036 (struct nvhost_alloc_obj_ctx_args *)buf); 2052 (struct nvhost_alloc_obj_ctx_args *)buf);
2037 gk20a_channel_idle(dev); 2053 gk20a_channel_idle(dev);
2038 break; 2054 break;
2039 case NVHOST_IOCTL_CHANNEL_FREE_OBJ_CTX: 2055 case NVHOST_IOCTL_CHANNEL_FREE_OBJ_CTX:
2040 gk20a_channel_busy(dev); 2056 err = gk20a_channel_busy(dev);
2057 if (err) {
2058 dev_err(&dev->dev,
2059 "%s: failed to host gk20a for ioctl cmd: 0x%x",
2060 __func__, cmd);
2061 return err;
2062 }
2041 err = gk20a_free_obj_ctx(ch, 2063 err = gk20a_free_obj_ctx(ch,
2042 (struct nvhost_free_obj_ctx_args *)buf); 2064 (struct nvhost_free_obj_ctx_args *)buf);
2043 gk20a_channel_idle(dev); 2065 gk20a_channel_idle(dev);
2044 break; 2066 break;
2045 case NVHOST_IOCTL_CHANNEL_ALLOC_GPFIFO: 2067 case NVHOST_IOCTL_CHANNEL_ALLOC_GPFIFO:
2046 gk20a_channel_busy(dev); 2068 err = gk20a_channel_busy(dev);
2069 if (err) {
2070 dev_err(&dev->dev,
2071 "%s: failed to host gk20a for ioctl cmd: 0x%x",
2072 __func__, cmd);
2073 return err;
2074 }
2047 err = gk20a_alloc_channel_gpfifo(ch, 2075 err = gk20a_alloc_channel_gpfifo(ch,
2048 (struct nvhost_alloc_gpfifo_args *)buf); 2076 (struct nvhost_alloc_gpfifo_args *)buf);
2049 gk20a_channel_idle(dev); 2077 gk20a_channel_idle(dev);
@@ -2053,26 +2081,50 @@ long gk20a_channel_ioctl(struct file *filp,
2053 (struct nvhost_submit_gpfifo_args *)buf); 2081 (struct nvhost_submit_gpfifo_args *)buf);
2054 break; 2082 break;
2055 case NVHOST_IOCTL_CHANNEL_WAIT: 2083 case NVHOST_IOCTL_CHANNEL_WAIT:
2056 gk20a_channel_busy(dev); 2084 err = gk20a_channel_busy(dev);
2085 if (err) {
2086 dev_err(&dev->dev,
2087 "%s: failed to host gk20a for ioctl cmd: 0x%x",
2088 __func__, cmd);
2089 return err;
2090 }
2057 err = gk20a_channel_wait(ch, 2091 err = gk20a_channel_wait(ch,
2058 (struct nvhost_wait_args *)buf); 2092 (struct nvhost_wait_args *)buf);
2059 gk20a_channel_idle(dev); 2093 gk20a_channel_idle(dev);
2060 break; 2094 break;
2061 case NVHOST_IOCTL_CHANNEL_ZCULL_BIND: 2095 case NVHOST_IOCTL_CHANNEL_ZCULL_BIND:
2062 gk20a_channel_busy(dev); 2096 err = gk20a_channel_busy(dev);
2097 if (err) {
2098 dev_err(&dev->dev,
2099 "%s: failed to host gk20a for ioctl cmd: 0x%x",
2100 __func__, cmd);
2101 return err;
2102 }
2063 err = gk20a_channel_zcull_bind(ch, 2103 err = gk20a_channel_zcull_bind(ch,
2064 (struct nvhost_zcull_bind_args *)buf); 2104 (struct nvhost_zcull_bind_args *)buf);
2065 gk20a_channel_idle(dev); 2105 gk20a_channel_idle(dev);
2066 break; 2106 break;
2067 case NVHOST_IOCTL_CHANNEL_SET_ERROR_NOTIFIER: 2107 case NVHOST_IOCTL_CHANNEL_SET_ERROR_NOTIFIER:
2068 gk20a_channel_busy(dev); 2108 err = gk20a_channel_busy(dev);
2109 if (err) {
2110 dev_err(&dev->dev,
2111 "%s: failed to host gk20a for ioctl cmd: 0x%x",
2112 __func__, cmd);
2113 return err;
2114 }
2069 err = gk20a_init_error_notifier(ch, 2115 err = gk20a_init_error_notifier(ch,
2070 (struct nvhost_set_error_notifier *)buf); 2116 (struct nvhost_set_error_notifier *)buf);
2071 gk20a_channel_idle(dev); 2117 gk20a_channel_idle(dev);
2072 break; 2118 break;
2073#ifdef CONFIG_GK20A_CYCLE_STATS 2119#ifdef CONFIG_GK20A_CYCLE_STATS
2074 case NVHOST_IOCTL_CHANNEL_CYCLE_STATS: 2120 case NVHOST_IOCTL_CHANNEL_CYCLE_STATS:
2075 gk20a_channel_busy(dev); 2121 err = gk20a_channel_busy(dev);
2122 if (err) {
2123 dev_err(&dev->dev,
2124 "%s: failed to host gk20a for ioctl cmd: 0x%x",
2125 __func__, cmd);
2126 return err;
2127 }
2076 err = gk20a_channel_cycle_stats(ch, 2128 err = gk20a_channel_cycle_stats(ch,
2077 (struct nvhost_cycle_stats_args *)buf); 2129 (struct nvhost_cycle_stats_args *)buf);
2078 gk20a_channel_idle(dev); 2130 gk20a_channel_idle(dev);
@@ -2105,7 +2157,13 @@ long gk20a_channel_ioctl(struct file *filp,
2105 ch->has_timedout; 2157 ch->has_timedout;
2106 break; 2158 break;
2107 case NVHOST_IOCTL_CHANNEL_SET_PRIORITY: 2159 case NVHOST_IOCTL_CHANNEL_SET_PRIORITY:
2108 gk20a_channel_busy(dev); 2160 err = gk20a_channel_busy(dev);
2161 if (err) {
2162 dev_err(&dev->dev,
2163 "%s: failed to host gk20a for ioctl cmd: 0x%x",
2164 __func__, cmd);
2165 return err;
2166 }
2109 gk20a_channel_set_priority(ch, 2167 gk20a_channel_set_priority(ch,
2110 ((struct nvhost_set_priority_args *)buf)->priority); 2168 ((struct nvhost_set_priority_args *)buf)->priority);
2111 gk20a_channel_idle(dev); 2169 gk20a_channel_idle(dev);