--- /dev/null
+From 54c12bc374408faddbff75dbf1a6167c19af39c4 Mon Sep 17 00:00:00 2001
+From: Thomas Hellstrom <thellstrom@vmware.com>
+Date: Mon, 14 Sep 2015 01:13:11 -0700
+Subject: drm/vmwgfx: Fix up user_dmabuf refcounting
+
+From: Thomas Hellstrom <thellstrom@vmware.com>
+
+commit 54c12bc374408faddbff75dbf1a6167c19af39c4 upstream.
+
+If user space calls unreference on a user_dmabuf it will typically
+kill the struct ttm_base_object member which is responsible for the
+user-space visibility. However the dmabuf part may still be alive and
+refcounted. In some situations, like for shared guest-backed surface
+referencing/opening, the driver may try to reference the
+struct ttm_base_object member again, causing an immediate kernel warning
+and a later kernel NULL pointer dereference.
+
+Fix this by always maintaining a reference on the struct
+ttm_base_object member, in situations where it might subsequently be
+referenced.
+
+Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
+Reviewed-by: Brian Paul <brianp@vmware.com>
+Reviewed-by: Sinclair Yeh <syeh@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 3 +++
+ drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 6 ++++--
+ drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 6 ++++--
+ drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c | 2 +-
+ drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 29 +++++++++++++++++++++--------
+ drivers/gpu/drm/vmwgfx/vmwgfx_shader.c | 2 +-
+ drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 12 +++++++++---
+ 7 files changed, 43 insertions(+), 17 deletions(-)
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+@@ -1458,6 +1458,9 @@ static void __exit vmwgfx_exit(void)
+ drm_pci_exit(&driver, &vmw_pci_driver);
+ }
+
++MODULE_INFO(vmw_patch, "ed7d78b2");
++MODULE_INFO(vmw_patch, "54c12bc3");
++
+ module_init(vmwgfx_init);
+ module_exit(vmwgfx_exit);
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+@@ -636,7 +636,8 @@ extern int vmw_user_dmabuf_alloc(struct
+ uint32_t size,
+ bool shareable,
+ uint32_t *handle,
+- struct vmw_dma_buffer **p_dma_buf);
++ struct vmw_dma_buffer **p_dma_buf,
++ struct ttm_base_object **p_base);
+ extern int vmw_user_dmabuf_reference(struct ttm_object_file *tfile,
+ struct vmw_dma_buffer *dma_buf,
+ uint32_t *handle);
+@@ -650,7 +651,8 @@ extern uint32_t vmw_dmabuf_validate_node
+ uint32_t cur_validate_node);
+ extern void vmw_dmabuf_validate_clear(struct ttm_buffer_object *bo);
+ extern int vmw_user_dmabuf_lookup(struct ttm_object_file *tfile,
+- uint32_t id, struct vmw_dma_buffer **out);
++ uint32_t id, struct vmw_dma_buffer **out,
++ struct ttm_base_object **base);
+ extern int vmw_stream_claim_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int vmw_stream_unref_ioctl(struct drm_device *dev, void *data,
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+@@ -887,7 +887,8 @@ static int vmw_translate_mob_ptr(struct
+ struct vmw_relocation *reloc;
+ int ret;
+
+- ret = vmw_user_dmabuf_lookup(sw_context->fp->tfile, handle, &vmw_bo);
++ ret = vmw_user_dmabuf_lookup(sw_context->fp->tfile, handle, &vmw_bo,
++ NULL);
+ if (unlikely(ret != 0)) {
+ DRM_ERROR("Could not find or use MOB buffer.\n");
+ ret = -EINVAL;
+@@ -949,7 +950,8 @@ static int vmw_translate_guest_ptr(struc
+ struct vmw_relocation *reloc;
+ int ret;
+
+- ret = vmw_user_dmabuf_lookup(sw_context->fp->tfile, handle, &vmw_bo);
++ ret = vmw_user_dmabuf_lookup(sw_context->fp->tfile, handle, &vmw_bo,
++ NULL);
+ if (unlikely(ret != 0)) {
+ DRM_ERROR("Could not find or use GMR region.\n");
+ ret = -EINVAL;
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
+@@ -484,7 +484,7 @@ int vmw_overlay_ioctl(struct drm_device
+ goto out_unlock;
+ }
+
+- ret = vmw_user_dmabuf_lookup(tfile, arg->handle, &buf);
++ ret = vmw_user_dmabuf_lookup(tfile, arg->handle, &buf, NULL);
+ if (ret)
+ goto out_unlock;
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+@@ -356,7 +356,7 @@ int vmw_user_lookup_handle(struct vmw_pr
+ }
+
+ *out_surf = NULL;
+- ret = vmw_user_dmabuf_lookup(tfile, handle, out_buf);
++ ret = vmw_user_dmabuf_lookup(tfile, handle, out_buf, NULL);
+ return ret;
+ }
+
+@@ -483,7 +483,8 @@ int vmw_user_dmabuf_alloc(struct vmw_pri
+ uint32_t size,
+ bool shareable,
+ uint32_t *handle,
+- struct vmw_dma_buffer **p_dma_buf)
++ struct vmw_dma_buffer **p_dma_buf,
++ struct ttm_base_object **p_base)
+ {
+ struct vmw_user_dma_buffer *user_bo;
+ struct ttm_buffer_object *tmp;
+@@ -517,6 +518,10 @@ int vmw_user_dmabuf_alloc(struct vmw_pri
+ }
+
+ *p_dma_buf = &user_bo->dma;
++ if (p_base) {
++ *p_base = &user_bo->prime.base;
++ kref_get(&(*p_base)->refcount);
++ }
+ *handle = user_bo->prime.base.hash.key;
+
+ out_no_base_object:
+@@ -633,6 +638,7 @@ int vmw_user_dmabuf_synccpu_ioctl(struct
+ struct vmw_dma_buffer *dma_buf;
+ struct vmw_user_dma_buffer *user_bo;
+ struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
++ struct ttm_base_object *buffer_base;
+ int ret;
+
+ if ((arg->flags & (drm_vmw_synccpu_read | drm_vmw_synccpu_write)) == 0
+@@ -645,7 +651,8 @@ int vmw_user_dmabuf_synccpu_ioctl(struct
+
+ switch (arg->op) {
+ case drm_vmw_synccpu_grab:
+- ret = vmw_user_dmabuf_lookup(tfile, arg->handle, &dma_buf);
++ ret = vmw_user_dmabuf_lookup(tfile, arg->handle, &dma_buf,
++ &buffer_base);
+ if (unlikely(ret != 0))
+ return ret;
+
+@@ -653,6 +660,7 @@ int vmw_user_dmabuf_synccpu_ioctl(struct
+ dma);
+ ret = vmw_user_dmabuf_synccpu_grab(user_bo, tfile, arg->flags);
+ vmw_dmabuf_unreference(&dma_buf);
++ ttm_base_object_unref(&buffer_base);
+ if (unlikely(ret != 0 && ret != -ERESTARTSYS &&
+ ret != -EBUSY)) {
+ DRM_ERROR("Failed synccpu grab on handle 0x%08x.\n",
+@@ -694,7 +702,8 @@ int vmw_dmabuf_alloc_ioctl(struct drm_de
+ return ret;
+
+ ret = vmw_user_dmabuf_alloc(dev_priv, vmw_fpriv(file_priv)->tfile,
+- req->size, false, &handle, &dma_buf);
++ req->size, false, &handle, &dma_buf,
++ NULL);
+ if (unlikely(ret != 0))
+ goto out_no_dmabuf;
+
+@@ -723,7 +732,8 @@ int vmw_dmabuf_unref_ioctl(struct drm_de
+ }
+
+ int vmw_user_dmabuf_lookup(struct ttm_object_file *tfile,
+- uint32_t handle, struct vmw_dma_buffer **out)
++ uint32_t handle, struct vmw_dma_buffer **out,
++ struct ttm_base_object **p_base)
+ {
+ struct vmw_user_dma_buffer *vmw_user_bo;
+ struct ttm_base_object *base;
+@@ -745,7 +755,10 @@ int vmw_user_dmabuf_lookup(struct ttm_ob
+ vmw_user_bo = container_of(base, struct vmw_user_dma_buffer,
+ prime.base);
+ (void)ttm_bo_reference(&vmw_user_bo->dma.base);
+- ttm_base_object_unref(&base);
++ if (p_base)
++ *p_base = base;
++ else
++ ttm_base_object_unref(&base);
+ *out = &vmw_user_bo->dma;
+
+ return 0;
+@@ -1006,7 +1019,7 @@ int vmw_dumb_create(struct drm_file *fil
+
+ ret = vmw_user_dmabuf_alloc(dev_priv, vmw_fpriv(file_priv)->tfile,
+ args->size, false, &args->handle,
+- &dma_buf);
++ &dma_buf, NULL);
+ if (unlikely(ret != 0))
+ goto out_no_dmabuf;
+
+@@ -1034,7 +1047,7 @@ int vmw_dumb_map_offset(struct drm_file
+ struct vmw_dma_buffer *out_buf;
+ int ret;
+
+- ret = vmw_user_dmabuf_lookup(tfile, handle, &out_buf);
++ ret = vmw_user_dmabuf_lookup(tfile, handle, &out_buf, NULL);
+ if (ret != 0)
+ return -EINVAL;
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
+@@ -470,7 +470,7 @@ int vmw_shader_define_ioctl(struct drm_d
+
+ if (arg->buffer_handle != SVGA3D_INVALID_ID) {
+ ret = vmw_user_dmabuf_lookup(tfile, arg->buffer_handle,
+- &buffer);
++ &buffer, NULL);
+ if (unlikely(ret != 0)) {
+ DRM_ERROR("Could not find buffer for shader "
+ "creation.\n");
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+@@ -43,6 +43,7 @@ struct vmw_user_surface {
+ struct vmw_surface srf;
+ uint32_t size;
+ struct drm_master *master;
++ struct ttm_base_object *backup_base;
+ };
+
+ /**
+@@ -652,6 +653,8 @@ static void vmw_user_surface_base_releas
+ struct vmw_resource *res = &user_srf->srf.res;
+
+ *p_base = NULL;
++ if (user_srf->backup_base)
++ ttm_base_object_unref(&user_srf->backup_base);
+ vmw_resource_unreference(&res);
+ }
+
+@@ -846,7 +849,8 @@ int vmw_surface_define_ioctl(struct drm_
+ res->backup_size,
+ true,
+ &backup_handle,
+- &res->backup);
++ &res->backup,
++ &user_srf->backup_base);
+ if (unlikely(ret != 0)) {
+ vmw_resource_unreference(&res);
+ goto out_unlock;
+@@ -1309,7 +1313,8 @@ int vmw_gb_surface_define_ioctl(struct d
+
+ if (req->buffer_handle != SVGA3D_INVALID_ID) {
+ ret = vmw_user_dmabuf_lookup(tfile, req->buffer_handle,
+- &res->backup);
++ &res->backup,
++ &user_srf->backup_base);
+ } else if (req->drm_surface_flags &
+ drm_vmw_surface_flag_create_buffer)
+ ret = vmw_user_dmabuf_alloc(dev_priv, tfile,
+@@ -1317,7 +1322,8 @@ int vmw_gb_surface_define_ioctl(struct d
+ req->drm_surface_flags &
+ drm_vmw_surface_flag_shareable,
+ &backup_handle,
+- &res->backup);
++ &res->backup,
++ &user_srf->backup_base);
+
+ if (unlikely(ret != 0)) {
+ vmw_resource_unreference(&res);
--- /dev/null
+From 0dfc70c33409afc232ef0b9ec210535dfbf9bc61 Mon Sep 17 00:00:00 2001
+From: Keith Busch <keith.busch@intel.com>
+Date: Thu, 15 Oct 2015 13:38:48 -0600
+Subject: NVMe: Fix memory leak on retried commands
+
+From: Keith Busch <keith.busch@intel.com>
+
+commit 0dfc70c33409afc232ef0b9ec210535dfbf9bc61 upstream.
+
+Resources are reallocated for requeued commands, so unmap and release
+the iod for the failed command.
+
+It's a pretty bad memory leak and causes a kernel hang if you remove a
+drive because of a busy dma pool. You'll get messages spewing like this:
+
+ nvme 0000:xx:xx.x: dma_pool_destroy prp list 256, ffff880420dec000 busy
+
+and lock up pci and the driver since removal never completes while
+holding a lock.
+
+Signed-off-by: Keith Busch <keith.busch@intel.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Jens Axboe <axboe@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/block/nvme-core.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/block/nvme-core.c
++++ b/drivers/block/nvme-core.c
+@@ -597,6 +597,7 @@ static void req_completion(struct nvme_q
+ struct nvme_iod *iod = ctx;
+ struct request *req = iod_get_private(iod);
+ struct nvme_cmd_info *cmd_rq = blk_mq_rq_to_pdu(req);
++ bool requeue = false;
+
+ u16 status = le16_to_cpup(&cqe->status) >> 1;
+
+@@ -605,12 +606,13 @@ static void req_completion(struct nvme_q
+ && (jiffies - req->start_time) < req->timeout) {
+ unsigned long flags;
+
++ requeue = true;
+ blk_mq_requeue_request(req);
+ spin_lock_irqsave(req->q->queue_lock, flags);
+ if (!blk_queue_stopped(req->q))
+ blk_mq_kick_requeue_list(req->q);
+ spin_unlock_irqrestore(req->q->queue_lock, flags);
+- return;
++ goto release_iod;
+ }
+ if (req->cmd_type == REQ_TYPE_DRV_PRIV) {
+ if (cmd_rq->ctx == CMD_CTX_CANCELLED)
+@@ -631,7 +633,7 @@ static void req_completion(struct nvme_q
+ dev_warn(nvmeq->dev->dev,
+ "completing aborted command with status:%04x\n",
+ status);
+-
++ release_iod:
+ if (iod->nents) {
+ dma_unmap_sg(nvmeq->dev->dev, iod->sg, iod->nents,
+ rq_data_dir(req) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+@@ -644,7 +646,8 @@ static void req_completion(struct nvme_q
+ }
+ nvme_free_iod(nvmeq->dev, iod);
+
+- blk_mq_complete_request(req);
++ if (likely(!requeue))
++ blk_mq_complete_request(req);
+ }
+
+ /* length is in bytes. gfp flags indicates whether we may sleep. */