diff options
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 931490b9cfed..87df0b3674fd 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
| @@ -1214,14 +1214,36 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, | |||
| 1214 | SVGA3dCmdSurfaceDMA dma; | 1214 | SVGA3dCmdSurfaceDMA dma; |
| 1215 | } *cmd; | 1215 | } *cmd; |
| 1216 | int ret; | 1216 | int ret; |
| 1217 | SVGA3dCmdSurfaceDMASuffix *suffix; | ||
| 1218 | uint32_t bo_size; | ||
| 1217 | 1219 | ||
| 1218 | cmd = container_of(header, struct vmw_dma_cmd, header); | 1220 | cmd = container_of(header, struct vmw_dma_cmd, header); |
| 1221 | suffix = (SVGA3dCmdSurfaceDMASuffix *)((unsigned long) &cmd->dma + | ||
| 1222 | header->size - sizeof(*suffix)); | ||
| 1223 | |||
| 1224 | /* Make sure device and verifier stays in sync. */ | ||
| 1225 | if (unlikely(suffix->suffixSize != sizeof(*suffix))) { | ||
| 1226 | DRM_ERROR("Invalid DMA suffix size.\n"); | ||
| 1227 | return -EINVAL; | ||
| 1228 | } | ||
| 1229 | |||
| 1219 | ret = vmw_translate_guest_ptr(dev_priv, sw_context, | 1230 | ret = vmw_translate_guest_ptr(dev_priv, sw_context, |
| 1220 | &cmd->dma.guest.ptr, | 1231 | &cmd->dma.guest.ptr, |
| 1221 | &vmw_bo); | 1232 | &vmw_bo); |
| 1222 | if (unlikely(ret != 0)) | 1233 | if (unlikely(ret != 0)) |
| 1223 | return ret; | 1234 | return ret; |
| 1224 | 1235 | ||
| 1236 | /* Make sure DMA doesn't cross BO boundaries. */ | ||
| 1237 | bo_size = vmw_bo->base.num_pages * PAGE_SIZE; | ||
| 1238 | if (unlikely(cmd->dma.guest.ptr.offset > bo_size)) { | ||
| 1239 | DRM_ERROR("Invalid DMA offset.\n"); | ||
| 1240 | return -EINVAL; | ||
| 1241 | } | ||
| 1242 | |||
| 1243 | bo_size -= cmd->dma.guest.ptr.offset; | ||
| 1244 | if (unlikely(suffix->maximumOffset > bo_size)) | ||
| 1245 | suffix->maximumOffset = bo_size; | ||
| 1246 | |||
| 1225 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, | 1247 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, |
| 1226 | user_surface_converter, &cmd->dma.host.sid, | 1248 | user_surface_converter, &cmd->dma.host.sid, |
| 1227 | NULL); | 1249 | NULL); |
