fbdev: imsttfb: Fix use after free bug in imsttfb_probe
[linux-block.git] / drivers / vfio / iommufd.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES
4  */
5 #include <linux/vfio.h>
6 #include <linux/iommufd.h>
7
8 #include "vfio.h"
9
10 MODULE_IMPORT_NS(IOMMUFD);
11 MODULE_IMPORT_NS(IOMMUFD_VFIO);
12
13 int vfio_iommufd_bind(struct vfio_device *vdev, struct iommufd_ctx *ictx)
14 {
15         u32 ioas_id;
16         u32 device_id;
17         int ret;
18
19         lockdep_assert_held(&vdev->dev_set->lock);
20
21         if (vfio_device_is_noiommu(vdev)) {
22                 if (!capable(CAP_SYS_RAWIO))
23                         return -EPERM;
24
25                 /*
26                  * Require no compat ioas to be assigned to proceed. The basic
27                  * statement is that the user cannot have done something that
28                  * implies they expected translation to exist
29                  */
30                 if (!iommufd_vfio_compat_ioas_get_id(ictx, &ioas_id))
31                         return -EPERM;
32                 return 0;
33         }
34
35         ret = vdev->ops->bind_iommufd(vdev, ictx, &device_id);
36         if (ret)
37                 return ret;
38
39         ret = iommufd_vfio_compat_ioas_get_id(ictx, &ioas_id);
40         if (ret)
41                 goto err_unbind;
42         ret = vdev->ops->attach_ioas(vdev, &ioas_id);
43         if (ret)
44                 goto err_unbind;
45
46         /*
47          * The legacy path has no way to return the device id or the selected
48          * pt_id
49          */
50         return 0;
51
52 err_unbind:
53         if (vdev->ops->unbind_iommufd)
54                 vdev->ops->unbind_iommufd(vdev);
55         return ret;
56 }
57
58 void vfio_iommufd_unbind(struct vfio_device *vdev)
59 {
60         lockdep_assert_held(&vdev->dev_set->lock);
61
62         if (vfio_device_is_noiommu(vdev))
63                 return;
64
65         if (vdev->ops->unbind_iommufd)
66                 vdev->ops->unbind_iommufd(vdev);
67 }
68
69 /*
70  * The physical standard ops mean that the iommufd_device is bound to the
71  * physical device vdev->dev that was provided to vfio_init_group_dev(). Drivers
72  * using this ops set should call vfio_register_group_dev()
73  */
74 int vfio_iommufd_physical_bind(struct vfio_device *vdev,
75                                struct iommufd_ctx *ictx, u32 *out_device_id)
76 {
77         struct iommufd_device *idev;
78
79         idev = iommufd_device_bind(ictx, vdev->dev, out_device_id);
80         if (IS_ERR(idev))
81                 return PTR_ERR(idev);
82         vdev->iommufd_device = idev;
83         return 0;
84 }
85 EXPORT_SYMBOL_GPL(vfio_iommufd_physical_bind);
86
87 void vfio_iommufd_physical_unbind(struct vfio_device *vdev)
88 {
89         lockdep_assert_held(&vdev->dev_set->lock);
90
91         if (vdev->iommufd_attached) {
92                 iommufd_device_detach(vdev->iommufd_device);
93                 vdev->iommufd_attached = false;
94         }
95         iommufd_device_unbind(vdev->iommufd_device);
96         vdev->iommufd_device = NULL;
97 }
98 EXPORT_SYMBOL_GPL(vfio_iommufd_physical_unbind);
99
100 int vfio_iommufd_physical_attach_ioas(struct vfio_device *vdev, u32 *pt_id)
101 {
102         int rc;
103
104         rc = iommufd_device_attach(vdev->iommufd_device, pt_id);
105         if (rc)
106                 return rc;
107         vdev->iommufd_attached = true;
108         return 0;
109 }
110 EXPORT_SYMBOL_GPL(vfio_iommufd_physical_attach_ioas);
111
112 /*
113  * The emulated standard ops mean that vfio_device is going to use the
114  * "mdev path" and will call vfio_pin_pages()/vfio_dma_rw(). Drivers using this
115  * ops set should call vfio_register_emulated_iommu_dev(). Drivers that do
116  * not call vfio_pin_pages()/vfio_dma_rw() have no need to provide dma_unmap.
117  */
118
119 static void vfio_emulated_unmap(void *data, unsigned long iova,
120                                 unsigned long length)
121 {
122         struct vfio_device *vdev = data;
123
124         if (vdev->ops->dma_unmap)
125                 vdev->ops->dma_unmap(vdev, iova, length);
126 }
127
128 static const struct iommufd_access_ops vfio_user_ops = {
129         .needs_pin_pages = 1,
130         .unmap = vfio_emulated_unmap,
131 };
132
133 int vfio_iommufd_emulated_bind(struct vfio_device *vdev,
134                                struct iommufd_ctx *ictx, u32 *out_device_id)
135 {
136         struct iommufd_access *user;
137
138         lockdep_assert_held(&vdev->dev_set->lock);
139
140         user = iommufd_access_create(ictx, &vfio_user_ops, vdev, out_device_id);
141         if (IS_ERR(user))
142                 return PTR_ERR(user);
143         vdev->iommufd_access = user;
144         return 0;
145 }
146 EXPORT_SYMBOL_GPL(vfio_iommufd_emulated_bind);
147
148 void vfio_iommufd_emulated_unbind(struct vfio_device *vdev)
149 {
150         lockdep_assert_held(&vdev->dev_set->lock);
151
152         if (vdev->iommufd_access) {
153                 iommufd_access_destroy(vdev->iommufd_access);
154                 vdev->iommufd_attached = false;
155                 vdev->iommufd_access = NULL;
156         }
157 }
158 EXPORT_SYMBOL_GPL(vfio_iommufd_emulated_unbind);
159
160 int vfio_iommufd_emulated_attach_ioas(struct vfio_device *vdev, u32 *pt_id)
161 {
162         int rc;
163
164         lockdep_assert_held(&vdev->dev_set->lock);
165
166         if (vdev->iommufd_attached)
167                 return -EBUSY;
168         rc = iommufd_access_attach(vdev->iommufd_access, *pt_id);
169         if (rc)
170                 return rc;
171         vdev->iommufd_attached = true;
172         return 0;
173 }
174 EXPORT_SYMBOL_GPL(vfio_iommufd_emulated_attach_ioas);