GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / s390 / cio / vfio_ccw_ops.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Physical device callbacks for vfio_ccw
4  *
5  * Copyright IBM Corp. 2017
6  *
7  * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
8  *            Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
9  */
10
11 #include <linux/vfio.h>
12 #include <linux/mdev.h>
13
14 #include "vfio_ccw_private.h"
15
16 static int vfio_ccw_mdev_reset(struct mdev_device *mdev)
17 {
18         struct vfio_ccw_private *private;
19         struct subchannel *sch;
20         int ret;
21
22         private = dev_get_drvdata(mdev_parent_dev(mdev));
23         sch = private->sch;
24         /*
25          * TODO:
26          * In the cureent stage, some things like "no I/O running" and "no
27          * interrupt pending" are clear, but we are not sure what other state
28          * we need to care about.
29          * There are still a lot more instructions need to be handled. We
30          * should come back here later.
31          */
32         ret = vfio_ccw_sch_quiesce(sch);
33         if (ret)
34                 return ret;
35
36         ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch);
37         if (!ret)
38                 private->state = VFIO_CCW_STATE_IDLE;
39
40         return ret;
41 }
42
43 static int vfio_ccw_mdev_notifier(struct notifier_block *nb,
44                                   unsigned long action,
45                                   void *data)
46 {
47         struct vfio_ccw_private *private =
48                 container_of(nb, struct vfio_ccw_private, nb);
49
50         /*
51          * Vendor drivers MUST unpin pages in response to an
52          * invalidation.
53          */
54         if (action == VFIO_IOMMU_NOTIFY_DMA_UNMAP) {
55                 struct vfio_iommu_type1_dma_unmap *unmap = data;
56
57                 if (!cp_iova_pinned(&private->cp, unmap->iova))
58                         return NOTIFY_OK;
59
60                 if (vfio_ccw_mdev_reset(private->mdev))
61                         return NOTIFY_BAD;
62
63                 cp_free(&private->cp);
64                 return NOTIFY_OK;
65         }
66
67         return NOTIFY_DONE;
68 }
69
70 static ssize_t name_show(struct kobject *kobj, struct device *dev, char *buf)
71 {
72         return sprintf(buf, "I/O subchannel (Non-QDIO)\n");
73 }
74 static MDEV_TYPE_ATTR_RO(name);
75
76 static ssize_t device_api_show(struct kobject *kobj, struct device *dev,
77                                char *buf)
78 {
79         return sprintf(buf, "%s\n", VFIO_DEVICE_API_CCW_STRING);
80 }
81 static MDEV_TYPE_ATTR_RO(device_api);
82
83 static ssize_t available_instances_show(struct kobject *kobj,
84                                         struct device *dev, char *buf)
85 {
86         struct vfio_ccw_private *private = dev_get_drvdata(dev);
87
88         return sprintf(buf, "%d\n", atomic_read(&private->avail));
89 }
90 static MDEV_TYPE_ATTR_RO(available_instances);
91
92 static struct attribute *mdev_types_attrs[] = {
93         &mdev_type_attr_name.attr,
94         &mdev_type_attr_device_api.attr,
95         &mdev_type_attr_available_instances.attr,
96         NULL,
97 };
98
99 static struct attribute_group mdev_type_group = {
100         .name  = "io",
101         .attrs = mdev_types_attrs,
102 };
103
104 static struct attribute_group *mdev_type_groups[] = {
105         &mdev_type_group,
106         NULL,
107 };
108
109 static int vfio_ccw_mdev_create(struct kobject *kobj, struct mdev_device *mdev)
110 {
111         struct vfio_ccw_private *private =
112                 dev_get_drvdata(mdev_parent_dev(mdev));
113
114         if (private->state == VFIO_CCW_STATE_NOT_OPER)
115                 return -ENODEV;
116
117         if (atomic_dec_if_positive(&private->avail) < 0)
118                 return -EPERM;
119
120         private->mdev = mdev;
121         private->state = VFIO_CCW_STATE_IDLE;
122
123         return 0;
124 }
125
126 static int vfio_ccw_mdev_remove(struct mdev_device *mdev)
127 {
128         struct vfio_ccw_private *private =
129                 dev_get_drvdata(mdev_parent_dev(mdev));
130
131         if ((private->state != VFIO_CCW_STATE_NOT_OPER) &&
132             (private->state != VFIO_CCW_STATE_STANDBY)) {
133                 if (!vfio_ccw_sch_quiesce(private->sch))
134                         private->state = VFIO_CCW_STATE_STANDBY;
135                 /* The state will be NOT_OPER on error. */
136         }
137
138         cp_free(&private->cp);
139         private->mdev = NULL;
140         atomic_inc(&private->avail);
141
142         return 0;
143 }
144
145 static int vfio_ccw_mdev_open(struct mdev_device *mdev)
146 {
147         struct vfio_ccw_private *private =
148                 dev_get_drvdata(mdev_parent_dev(mdev));
149         unsigned long events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;
150
151         private->nb.notifier_call = vfio_ccw_mdev_notifier;
152
153         return vfio_register_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
154                                       &events, &private->nb);
155 }
156
157 static void vfio_ccw_mdev_release(struct mdev_device *mdev)
158 {
159         struct vfio_ccw_private *private =
160                 dev_get_drvdata(mdev_parent_dev(mdev));
161
162         if ((private->state != VFIO_CCW_STATE_NOT_OPER) &&
163             (private->state != VFIO_CCW_STATE_STANDBY)) {
164                 if (!vfio_ccw_mdev_reset(mdev))
165                         private->state = VFIO_CCW_STATE_STANDBY;
166                 /* The state will be NOT_OPER on error. */
167         }
168
169         cp_free(&private->cp);
170         vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
171                                  &private->nb);
172 }
173
174 static ssize_t vfio_ccw_mdev_read(struct mdev_device *mdev,
175                                   char __user *buf,
176                                   size_t count,
177                                   loff_t *ppos)
178 {
179         struct vfio_ccw_private *private;
180         struct ccw_io_region *region;
181
182         if (*ppos + count > sizeof(*region))
183                 return -EINVAL;
184
185         private = dev_get_drvdata(mdev_parent_dev(mdev));
186         region = private->io_region;
187         if (copy_to_user(buf, (void *)region + *ppos, count))
188                 return -EFAULT;
189
190         return count;
191 }
192
193 static ssize_t vfio_ccw_mdev_write(struct mdev_device *mdev,
194                                    const char __user *buf,
195                                    size_t count,
196                                    loff_t *ppos)
197 {
198         struct vfio_ccw_private *private;
199         struct ccw_io_region *region;
200
201         if (*ppos + count > sizeof(*region))
202                 return -EINVAL;
203
204         private = dev_get_drvdata(mdev_parent_dev(mdev));
205         if (private->state != VFIO_CCW_STATE_IDLE)
206                 return -EACCES;
207
208         region = private->io_region;
209         if (copy_from_user((void *)region + *ppos, buf, count))
210                 return -EFAULT;
211
212         vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_IO_REQ);
213         if (region->ret_code != 0) {
214                 private->state = VFIO_CCW_STATE_IDLE;
215                 return region->ret_code;
216         }
217
218         return count;
219 }
220
221 static int vfio_ccw_mdev_get_device_info(struct vfio_device_info *info)
222 {
223         info->flags = VFIO_DEVICE_FLAGS_CCW | VFIO_DEVICE_FLAGS_RESET;
224         info->num_regions = VFIO_CCW_NUM_REGIONS;
225         info->num_irqs = VFIO_CCW_NUM_IRQS;
226
227         return 0;
228 }
229
230 static int vfio_ccw_mdev_get_region_info(struct vfio_region_info *info,
231                                          u16 *cap_type_id,
232                                          void **cap_type)
233 {
234         switch (info->index) {
235         case VFIO_CCW_CONFIG_REGION_INDEX:
236                 info->offset = 0;
237                 info->size = sizeof(struct ccw_io_region);
238                 info->flags = VFIO_REGION_INFO_FLAG_READ
239                               | VFIO_REGION_INFO_FLAG_WRITE;
240                 return 0;
241         default:
242                 return -EINVAL;
243         }
244 }
245
246 static int vfio_ccw_mdev_get_irq_info(struct vfio_irq_info *info)
247 {
248         if (info->index != VFIO_CCW_IO_IRQ_INDEX)
249                 return -EINVAL;
250
251         info->count = 1;
252         info->flags = VFIO_IRQ_INFO_EVENTFD;
253
254         return 0;
255 }
256
257 static int vfio_ccw_mdev_set_irqs(struct mdev_device *mdev,
258                                   uint32_t flags,
259                                   void __user *data)
260 {
261         struct vfio_ccw_private *private;
262         struct eventfd_ctx **ctx;
263
264         if (!(flags & VFIO_IRQ_SET_ACTION_TRIGGER))
265                 return -EINVAL;
266
267         private = dev_get_drvdata(mdev_parent_dev(mdev));
268         ctx = &private->io_trigger;
269
270         switch (flags & VFIO_IRQ_SET_DATA_TYPE_MASK) {
271         case VFIO_IRQ_SET_DATA_NONE:
272         {
273                 if (*ctx)
274                         eventfd_signal(*ctx, 1);
275                 return 0;
276         }
277         case VFIO_IRQ_SET_DATA_BOOL:
278         {
279                 uint8_t trigger;
280
281                 if (get_user(trigger, (uint8_t __user *)data))
282                         return -EFAULT;
283
284                 if (trigger && *ctx)
285                         eventfd_signal(*ctx, 1);
286                 return 0;
287         }
288         case VFIO_IRQ_SET_DATA_EVENTFD:
289         {
290                 int32_t fd;
291
292                 if (get_user(fd, (int32_t __user *)data))
293                         return -EFAULT;
294
295                 if (fd == -1) {
296                         if (*ctx)
297                                 eventfd_ctx_put(*ctx);
298                         *ctx = NULL;
299                 } else if (fd >= 0) {
300                         struct eventfd_ctx *efdctx;
301
302                         efdctx = eventfd_ctx_fdget(fd);
303                         if (IS_ERR(efdctx))
304                                 return PTR_ERR(efdctx);
305
306                         if (*ctx)
307                                 eventfd_ctx_put(*ctx);
308
309                         *ctx = efdctx;
310                 } else
311                         return -EINVAL;
312
313                 return 0;
314         }
315         default:
316                 return -EINVAL;
317         }
318 }
319
320 static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
321                                    unsigned int cmd,
322                                    unsigned long arg)
323 {
324         int ret = 0;
325         unsigned long minsz;
326
327         switch (cmd) {
328         case VFIO_DEVICE_GET_INFO:
329         {
330                 struct vfio_device_info info;
331
332                 minsz = offsetofend(struct vfio_device_info, num_irqs);
333
334                 if (copy_from_user(&info, (void __user *)arg, minsz))
335                         return -EFAULT;
336
337                 if (info.argsz < minsz)
338                         return -EINVAL;
339
340                 ret = vfio_ccw_mdev_get_device_info(&info);
341                 if (ret)
342                         return ret;
343
344                 return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0;
345         }
346         case VFIO_DEVICE_GET_REGION_INFO:
347         {
348                 struct vfio_region_info info;
349                 u16 cap_type_id = 0;
350                 void *cap_type = NULL;
351
352                 minsz = offsetofend(struct vfio_region_info, offset);
353
354                 if (copy_from_user(&info, (void __user *)arg, minsz))
355                         return -EFAULT;
356
357                 if (info.argsz < minsz)
358                         return -EINVAL;
359
360                 ret = vfio_ccw_mdev_get_region_info(&info, &cap_type_id,
361                                                     &cap_type);
362                 if (ret)
363                         return ret;
364
365                 return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0;
366         }
367         case VFIO_DEVICE_GET_IRQ_INFO:
368         {
369                 struct vfio_irq_info info;
370
371                 minsz = offsetofend(struct vfio_irq_info, count);
372
373                 if (copy_from_user(&info, (void __user *)arg, minsz))
374                         return -EFAULT;
375
376                 if (info.argsz < minsz || info.index >= VFIO_CCW_NUM_IRQS)
377                         return -EINVAL;
378
379                 ret = vfio_ccw_mdev_get_irq_info(&info);
380                 if (ret)
381                         return ret;
382
383                 if (info.count == -1)
384                         return -EINVAL;
385
386                 return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0;
387         }
388         case VFIO_DEVICE_SET_IRQS:
389         {
390                 struct vfio_irq_set hdr;
391                 size_t data_size;
392                 void __user *data;
393
394                 minsz = offsetofend(struct vfio_irq_set, count);
395
396                 if (copy_from_user(&hdr, (void __user *)arg, minsz))
397                         return -EFAULT;
398
399                 ret = vfio_set_irqs_validate_and_prepare(&hdr, 1,
400                                                          VFIO_CCW_NUM_IRQS,
401                                                          &data_size);
402                 if (ret)
403                         return ret;
404
405                 data = (void __user *)(arg + minsz);
406                 return vfio_ccw_mdev_set_irqs(mdev, hdr.flags, data);
407         }
408         case VFIO_DEVICE_RESET:
409                 return vfio_ccw_mdev_reset(mdev);
410         default:
411                 return -ENOTTY;
412         }
413 }
414
415 static const struct mdev_parent_ops vfio_ccw_mdev_ops = {
416         .owner                  = THIS_MODULE,
417         .supported_type_groups  = mdev_type_groups,
418         .create                 = vfio_ccw_mdev_create,
419         .remove                 = vfio_ccw_mdev_remove,
420         .open                   = vfio_ccw_mdev_open,
421         .release                = vfio_ccw_mdev_release,
422         .read                   = vfio_ccw_mdev_read,
423         .write                  = vfio_ccw_mdev_write,
424         .ioctl                  = vfio_ccw_mdev_ioctl,
425 };
426
427 int vfio_ccw_mdev_reg(struct subchannel *sch)
428 {
429         return mdev_register_device(&sch->dev, &vfio_ccw_mdev_ops);
430 }
431
432 void vfio_ccw_mdev_unreg(struct subchannel *sch)
433 {
434         mdev_unregister_device(&sch->dev);
435 }