]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/xen-gntdev-do-not-destroy-context-while-dma-bufs-are.patch
Linux 4.14.111
[thirdparty/kernel/stable-queue.git] / queue-4.19 / xen-gntdev-do-not-destroy-context-while-dma-bufs-are.patch
1 From 0d017faeb25b5fae49ea89459c85dbb7ca40abfc Mon Sep 17 00:00:00 2001
2 From: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
3 Date: Thu, 14 Feb 2019 16:23:20 +0200
4 Subject: xen/gntdev: Do not destroy context while dma-bufs are in use
5
6 [ Upstream commit fa13e665e02874c0a5f4d06d6967ae34a6cb3d6a ]
7
8 If there are exported DMA buffers which are still in use and
9 grant device is closed by either normal user-space close or by
10 a signal this leads to the grant device context to be destroyed,
11 thus making it not possible to correctly destroy those exported
12 buffers when they are returned back to gntdev and makes the module
13 crash:
14
15 [ 339.617540] [<ffff00000854c0d8>] dmabuf_exp_ops_release+0x40/0xa8
16 [ 339.617560] [<ffff00000867a6e8>] dma_buf_release+0x60/0x190
17 [ 339.617577] [<ffff0000082211f0>] __fput+0x88/0x1d0
18 [ 339.617589] [<ffff000008221394>] ____fput+0xc/0x18
19 [ 339.617607] [<ffff0000080ed4e4>] task_work_run+0x9c/0xc0
20 [ 339.617622] [<ffff000008089714>] do_notify_resume+0xfc/0x108
21
22 Fix this by referencing gntdev on each DMA buffer export and
23 unreferencing on buffer release.
24
25 Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
26 Reviewed-by: Boris Ostrovsky@oracle.com>
27 Signed-off-by: Juergen Gross <jgross@suse.com>
28 Signed-off-by: Sasha Levin <sashal@kernel.org>
29 ---
30 drivers/xen/gntdev-dmabuf.c | 12 +++++++++++-
31 drivers/xen/gntdev-dmabuf.h | 2 +-
32 drivers/xen/gntdev.c | 2 +-
33 3 files changed, 13 insertions(+), 3 deletions(-)
34
35 diff --git a/drivers/xen/gntdev-dmabuf.c b/drivers/xen/gntdev-dmabuf.c
36 index cba6b586bfbd..d97fcfc5e558 100644
37 --- a/drivers/xen/gntdev-dmabuf.c
38 +++ b/drivers/xen/gntdev-dmabuf.c
39 @@ -80,6 +80,12 @@ struct gntdev_dmabuf_priv {
40 struct list_head imp_list;
41 /* This is the lock which protects dma_buf_xxx lists. */
42 struct mutex lock;
43 + /*
44 + * We reference this file while exporting dma-bufs, so
45 + * the grant device context is not destroyed while there are
46 + * external users alive.
47 + */
48 + struct file *filp;
49 };
50
51 /* DMA buffer export support. */
52 @@ -311,6 +317,7 @@ static void dmabuf_exp_release(struct kref *kref)
53
54 dmabuf_exp_wait_obj_signal(gntdev_dmabuf->priv, gntdev_dmabuf);
55 list_del(&gntdev_dmabuf->next);
56 + fput(gntdev_dmabuf->priv->filp);
57 kfree(gntdev_dmabuf);
58 }
59
60 @@ -423,6 +430,7 @@ static int dmabuf_exp_from_pages(struct gntdev_dmabuf_export_args *args)
61 mutex_lock(&args->dmabuf_priv->lock);
62 list_add(&gntdev_dmabuf->next, &args->dmabuf_priv->exp_list);
63 mutex_unlock(&args->dmabuf_priv->lock);
64 + get_file(gntdev_dmabuf->priv->filp);
65 return 0;
66
67 fail:
68 @@ -834,7 +842,7 @@ long gntdev_ioctl_dmabuf_imp_release(struct gntdev_priv *priv,
69 return dmabuf_imp_release(priv->dmabuf_priv, op.fd);
70 }
71
72 -struct gntdev_dmabuf_priv *gntdev_dmabuf_init(void)
73 +struct gntdev_dmabuf_priv *gntdev_dmabuf_init(struct file *filp)
74 {
75 struct gntdev_dmabuf_priv *priv;
76
77 @@ -847,6 +855,8 @@ struct gntdev_dmabuf_priv *gntdev_dmabuf_init(void)
78 INIT_LIST_HEAD(&priv->exp_wait_list);
79 INIT_LIST_HEAD(&priv->imp_list);
80
81 + priv->filp = filp;
82 +
83 return priv;
84 }
85
86 diff --git a/drivers/xen/gntdev-dmabuf.h b/drivers/xen/gntdev-dmabuf.h
87 index 7220a53d0fc5..3d9b9cf9d5a1 100644
88 --- a/drivers/xen/gntdev-dmabuf.h
89 +++ b/drivers/xen/gntdev-dmabuf.h
90 @@ -14,7 +14,7 @@
91 struct gntdev_dmabuf_priv;
92 struct gntdev_priv;
93
94 -struct gntdev_dmabuf_priv *gntdev_dmabuf_init(void);
95 +struct gntdev_dmabuf_priv *gntdev_dmabuf_init(struct file *filp);
96
97 void gntdev_dmabuf_fini(struct gntdev_dmabuf_priv *priv);
98
99 diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
100 index b0b02a501167..9d8e02cfd480 100644
101 --- a/drivers/xen/gntdev.c
102 +++ b/drivers/xen/gntdev.c
103 @@ -600,7 +600,7 @@ static int gntdev_open(struct inode *inode, struct file *flip)
104 mutex_init(&priv->lock);
105
106 #ifdef CONFIG_XEN_GNTDEV_DMABUF
107 - priv->dmabuf_priv = gntdev_dmabuf_init();
108 + priv->dmabuf_priv = gntdev_dmabuf_init(flip);
109 if (IS_ERR(priv->dmabuf_priv)) {
110 ret = PTR_ERR(priv->dmabuf_priv);
111 kfree(priv);
112 --
113 2.19.1
114