xref: /openbmc/qemu/hw/vfio/ccw.c (revision 7200fb21)
1 /*
2  * vfio based subchannel assignment support
3  *
4  * Copyright 2017 IBM Corp.
5  * Copyright 2019 Red Hat, Inc.
6  *
7  * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
8  *            Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
9  *            Pierre Morel <pmorel@linux.vnet.ibm.com>
10  *            Cornelia Huck <cohuck@redhat.com>
11  *
12  * This work is licensed under the terms of the GNU GPL, version 2 or (at
13  * your option) any later version. See the COPYING file in the top-level
14  * directory.
15  */
16 
17 #include "qemu/osdep.h"
18 #include <linux/vfio.h>
19 #include <linux/vfio_ccw.h>
20 #include <sys/ioctl.h>
21 
22 #include "qapi/error.h"
23 #include "hw/vfio/vfio-common.h"
24 #include "hw/s390x/s390-ccw.h"
25 #include "hw/s390x/vfio-ccw.h"
26 #include "hw/qdev-properties.h"
27 #include "hw/s390x/ccw-device.h"
28 #include "exec/address-spaces.h"
29 #include "qemu/error-report.h"
30 #include "qemu/main-loop.h"
31 #include "qemu/module.h"
32 
33 struct VFIOCCWDevice {
34     S390CCWDevice cdev;
35     VFIODevice vdev;
36     uint64_t io_region_size;
37     uint64_t io_region_offset;
38     struct ccw_io_region *io_region;
39     uint64_t async_cmd_region_size;
40     uint64_t async_cmd_region_offset;
41     struct ccw_cmd_region *async_cmd_region;
42     uint64_t schib_region_size;
43     uint64_t schib_region_offset;
44     struct ccw_schib_region *schib_region;
45     uint64_t crw_region_size;
46     uint64_t crw_region_offset;
47     struct ccw_crw_region *crw_region;
48     EventNotifier io_notifier;
49     EventNotifier crw_notifier;
50     EventNotifier req_notifier;
51     bool force_orb_pfch;
52     bool warned_orb_pfch;
53 };
54 
55 static inline void warn_once_pfch(VFIOCCWDevice *vcdev, SubchDev *sch,
56                                   const char *msg)
57 {
58     warn_report_once_cond(&vcdev->warned_orb_pfch,
59                           "vfio-ccw (devno %x.%x.%04x): %s",
60                           sch->cssid, sch->ssid, sch->devno, msg);
61 }
62 
63 static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
64 {
65     vdev->needs_reset = false;
66 }
67 
68 /*
69  * We don't need vfio_hot_reset_multi and vfio_eoi operations for
70  * vfio_ccw device now.
71  */
72 struct VFIODeviceOps vfio_ccw_ops = {
73     .vfio_compute_needs_reset = vfio_ccw_compute_needs_reset,
74 };
75 
76 static IOInstEnding vfio_ccw_handle_request(SubchDev *sch)
77 {
78     VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data);
79     struct ccw_io_region *region = vcdev->io_region;
80     int ret;
81 
82     if (!(sch->orb.ctrl0 & ORB_CTRL0_MASK_PFCH) && vcdev->force_orb_pfch) {
83         sch->orb.ctrl0 |= ORB_CTRL0_MASK_PFCH;
84         warn_once_pfch(vcdev, sch, "PFCH flag forced");
85     }
86 
87     QEMU_BUILD_BUG_ON(sizeof(region->orb_area) != sizeof(ORB));
88     QEMU_BUILD_BUG_ON(sizeof(region->scsw_area) != sizeof(SCSW));
89     QEMU_BUILD_BUG_ON(sizeof(region->irb_area) != sizeof(IRB));
90 
91     memset(region, 0, sizeof(*region));
92 
93     memcpy(region->orb_area, &sch->orb, sizeof(ORB));
94     memcpy(region->scsw_area, &sch->curr_status.scsw, sizeof(SCSW));
95 
96 again:
97     ret = pwrite(vcdev->vdev.fd, region,
98                  vcdev->io_region_size, vcdev->io_region_offset);
99     if (ret != vcdev->io_region_size) {
100         if (errno == EAGAIN) {
101             goto again;
102         }
103         error_report("vfio-ccw: write I/O region failed with errno=%d", errno);
104         ret = errno ? -errno : -EFAULT;
105     } else {
106         ret = 0;
107     }
108     switch (ret) {
109     case 0:
110         return IOINST_CC_EXPECTED;
111     case -EBUSY:
112         return IOINST_CC_BUSY;
113     case -ENODEV:
114     case -EACCES:
115         return IOINST_CC_NOT_OPERATIONAL;
116     case -EFAULT:
117     default:
118         sch_gen_unit_exception(sch);
119         css_inject_io_interrupt(sch);
120         return IOINST_CC_EXPECTED;
121     }
122 }
123 
124 static IOInstEnding vfio_ccw_handle_store(SubchDev *sch)
125 {
126     VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data);
127     SCHIB *schib = &sch->curr_status;
128     struct ccw_schib_region *region = vcdev->schib_region;
129     SCHIB *s;
130     int ret;
131 
132     /* schib region not available so nothing else to do */
133     if (!region) {
134         return IOINST_CC_EXPECTED;
135     }
136 
137     memset(region, 0, sizeof(*region));
138     ret = pread(vcdev->vdev.fd, region, vcdev->schib_region_size,
139                 vcdev->schib_region_offset);
140 
141     if (ret == -1) {
142         /*
143          * Device is probably damaged, but store subchannel does not
144          * have a nonzero cc defined for this scenario.  Log an error,
145          * and presume things are otherwise fine.
146          */
147         error_report("vfio-ccw: store region read failed with errno=%d", errno);
148         return IOINST_CC_EXPECTED;
149     }
150 
151     /*
152      * Selectively copy path-related bits of the SCHIB,
153      * rather than copying the entire struct.
154      */
155     s = (SCHIB *)region->schib_area;
156     schib->pmcw.pnom = s->pmcw.pnom;
157     schib->pmcw.lpum = s->pmcw.lpum;
158     schib->pmcw.pam = s->pmcw.pam;
159     schib->pmcw.pom = s->pmcw.pom;
160 
161     if (s->scsw.flags & SCSW_FLAGS_MASK_PNO) {
162         schib->scsw.flags |= SCSW_FLAGS_MASK_PNO;
163     }
164 
165     return IOINST_CC_EXPECTED;
166 }
167 
168 static int vfio_ccw_handle_clear(SubchDev *sch)
169 {
170     VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data);
171     struct ccw_cmd_region *region = vcdev->async_cmd_region;
172     int ret;
173 
174     if (!vcdev->async_cmd_region) {
175         /* Async command region not available, fall back to emulation */
176         return -ENOSYS;
177     }
178 
179     memset(region, 0, sizeof(*region));
180     region->command = VFIO_CCW_ASYNC_CMD_CSCH;
181 
182 again:
183     ret = pwrite(vcdev->vdev.fd, region,
184                  vcdev->async_cmd_region_size, vcdev->async_cmd_region_offset);
185     if (ret != vcdev->async_cmd_region_size) {
186         if (errno == EAGAIN) {
187             goto again;
188         }
189         error_report("vfio-ccw: write cmd region failed with errno=%d", errno);
190         ret = errno ? -errno : -EFAULT;
191     } else {
192         ret = 0;
193     }
194     switch (ret) {
195     case 0:
196     case -ENODEV:
197     case -EACCES:
198         return ret;
199     case -EFAULT:
200     default:
201         sch_gen_unit_exception(sch);
202         css_inject_io_interrupt(sch);
203         return 0;
204     }
205 }
206 
207 static int vfio_ccw_handle_halt(SubchDev *sch)
208 {
209     VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data);
210     struct ccw_cmd_region *region = vcdev->async_cmd_region;
211     int ret;
212 
213     if (!vcdev->async_cmd_region) {
214         /* Async command region not available, fall back to emulation */
215         return -ENOSYS;
216     }
217 
218     memset(region, 0, sizeof(*region));
219     region->command = VFIO_CCW_ASYNC_CMD_HSCH;
220 
221 again:
222     ret = pwrite(vcdev->vdev.fd, region,
223                  vcdev->async_cmd_region_size, vcdev->async_cmd_region_offset);
224     if (ret != vcdev->async_cmd_region_size) {
225         if (errno == EAGAIN) {
226             goto again;
227         }
228         error_report("vfio-ccw: write cmd region failed with errno=%d", errno);
229         ret = errno ? -errno : -EFAULT;
230     } else {
231         ret = 0;
232     }
233     switch (ret) {
234     case 0:
235     case -EBUSY:
236     case -ENODEV:
237     case -EACCES:
238         return ret;
239     case -EFAULT:
240     default:
241         sch_gen_unit_exception(sch);
242         css_inject_io_interrupt(sch);
243         return 0;
244     }
245 }
246 
247 static void vfio_ccw_reset(DeviceState *dev)
248 {
249     VFIOCCWDevice *vcdev = VFIO_CCW(dev);
250 
251     ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET);
252 }
253 
254 static void vfio_ccw_crw_read(VFIOCCWDevice *vcdev)
255 {
256     struct ccw_crw_region *region = vcdev->crw_region;
257     CRW crw;
258     int size;
259 
260     /* Keep reading CRWs as long as data is returned */
261     do {
262         memset(region, 0, sizeof(*region));
263         size = pread(vcdev->vdev.fd, region, vcdev->crw_region_size,
264                      vcdev->crw_region_offset);
265 
266         if (size == -1) {
267             error_report("vfio-ccw: Read crw region failed with errno=%d",
268                          errno);
269             break;
270         }
271 
272         if (region->crw == 0) {
273             /* No more CRWs to queue */
274             break;
275         }
276 
277         memcpy(&crw, &region->crw, sizeof(CRW));
278 
279         css_crw_add_to_queue(crw);
280     } while (1);
281 }
282 
283 static void vfio_ccw_req_notifier_handler(void *opaque)
284 {
285     VFIOCCWDevice *vcdev = opaque;
286     Error *err = NULL;
287 
288     if (!event_notifier_test_and_clear(&vcdev->req_notifier)) {
289         return;
290     }
291 
292     qdev_unplug(DEVICE(vcdev), &err);
293     if (err) {
294         warn_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name);
295     }
296 }
297 
298 static void vfio_ccw_crw_notifier_handler(void *opaque)
299 {
300     VFIOCCWDevice *vcdev = opaque;
301 
302     while (event_notifier_test_and_clear(&vcdev->crw_notifier)) {
303         vfio_ccw_crw_read(vcdev);
304     }
305 }
306 
307 static void vfio_ccw_io_notifier_handler(void *opaque)
308 {
309     VFIOCCWDevice *vcdev = opaque;
310     struct ccw_io_region *region = vcdev->io_region;
311     CcwDevice *ccw_dev = CCW_DEVICE(vcdev);
312     SubchDev *sch = ccw_dev->sch;
313     SCHIB *schib = &sch->curr_status;
314     SCSW s;
315     IRB irb;
316     ESW esw;
317     int size;
318 
319     if (!event_notifier_test_and_clear(&vcdev->io_notifier)) {
320         return;
321     }
322 
323     size = pread(vcdev->vdev.fd, region, vcdev->io_region_size,
324                  vcdev->io_region_offset);
325     if (size == -1) {
326         switch (errno) {
327         case ENODEV:
328             /* Generate a deferred cc 3 condition. */
329             schib->scsw.flags |= SCSW_FLAGS_MASK_CC;
330             schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
331             schib->scsw.ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
332             goto read_err;
333         case EFAULT:
334             /* Memory problem, generate channel data check. */
335             schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
336             schib->scsw.cstat = SCSW_CSTAT_DATA_CHECK;
337             schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
338             schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
339                        SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
340             goto read_err;
341         default:
342             /* Error, generate channel program check. */
343             schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
344             schib->scsw.cstat = SCSW_CSTAT_PROG_CHECK;
345             schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
346             schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
347                        SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
348             goto read_err;
349         }
350     } else if (size != vcdev->io_region_size) {
351         /* Information transfer error, generate channel-control check. */
352         schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
353         schib->scsw.cstat = SCSW_CSTAT_CHN_CTRL_CHK;
354         schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
355         schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
356                    SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
357         goto read_err;
358     }
359 
360     memcpy(&irb, region->irb_area, sizeof(IRB));
361 
362     /* Update control block via irb. */
363     s = schib->scsw;
364     copy_scsw_to_guest(&s, &irb.scsw);
365     schib->scsw = s;
366 
367     copy_esw_to_guest(&esw, &irb.esw);
368     sch->esw = esw;
369 
370     /* If a uint check is pending, copy sense data. */
371     if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
372         (schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) {
373         memcpy(sch->sense_data, irb.ecw, sizeof(irb.ecw));
374     }
375 
376 read_err:
377     css_inject_io_interrupt(sch);
378 }
379 
380 static void vfio_ccw_register_irq_notifier(VFIOCCWDevice *vcdev,
381                                            unsigned int irq,
382                                            Error **errp)
383 {
384     VFIODevice *vdev = &vcdev->vdev;
385     struct vfio_irq_info *irq_info;
386     size_t argsz;
387     int fd;
388     EventNotifier *notifier;
389     IOHandler *fd_read;
390 
391     switch (irq) {
392     case VFIO_CCW_IO_IRQ_INDEX:
393         notifier = &vcdev->io_notifier;
394         fd_read = vfio_ccw_io_notifier_handler;
395         break;
396     case VFIO_CCW_CRW_IRQ_INDEX:
397         notifier = &vcdev->crw_notifier;
398         fd_read = vfio_ccw_crw_notifier_handler;
399         break;
400     case VFIO_CCW_REQ_IRQ_INDEX:
401         notifier = &vcdev->req_notifier;
402         fd_read = vfio_ccw_req_notifier_handler;
403         break;
404     default:
405         error_setg(errp, "vfio: Unsupported device irq(%d)", irq);
406         return;
407     }
408 
409     if (vdev->num_irqs < irq + 1) {
410         error_setg(errp, "vfio: IRQ %u not available (number of irqs %u)",
411                    irq, vdev->num_irqs);
412         return;
413     }
414 
415     argsz = sizeof(*irq_info);
416     irq_info = g_malloc0(argsz);
417     irq_info->index = irq;
418     irq_info->argsz = argsz;
419     if (ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO,
420               irq_info) < 0 || irq_info->count < 1) {
421         error_setg_errno(errp, errno, "vfio: Error getting irq info");
422         goto out_free_info;
423     }
424 
425     if (event_notifier_init(notifier, 0)) {
426         error_setg_errno(errp, errno,
427                          "vfio: Unable to init event notifier for irq (%d)",
428                          irq);
429         goto out_free_info;
430     }
431 
432     fd = event_notifier_get_fd(notifier);
433     qemu_set_fd_handler(fd, fd_read, NULL, vcdev);
434 
435     if (vfio_set_irq_signaling(vdev, irq, 0,
436                                VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) {
437         qemu_set_fd_handler(fd, NULL, NULL, vcdev);
438         event_notifier_cleanup(notifier);
439     }
440 
441 out_free_info:
442     g_free(irq_info);
443 }
444 
445 static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice *vcdev,
446                                              unsigned int irq)
447 {
448     Error *err = NULL;
449     EventNotifier *notifier;
450 
451     switch (irq) {
452     case VFIO_CCW_IO_IRQ_INDEX:
453         notifier = &vcdev->io_notifier;
454         break;
455     case VFIO_CCW_CRW_IRQ_INDEX:
456         notifier = &vcdev->crw_notifier;
457         break;
458     case VFIO_CCW_REQ_IRQ_INDEX:
459         notifier = &vcdev->req_notifier;
460         break;
461     default:
462         error_report("vfio: Unsupported device irq(%d)", irq);
463         return;
464     }
465 
466     if (vfio_set_irq_signaling(&vcdev->vdev, irq, 0,
467                                VFIO_IRQ_SET_ACTION_TRIGGER, -1, &err)) {
468         warn_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name);
469     }
470 
471     qemu_set_fd_handler(event_notifier_get_fd(notifier),
472                         NULL, NULL, vcdev);
473     event_notifier_cleanup(notifier);
474 }
475 
476 static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)
477 {
478     VFIODevice *vdev = &vcdev->vdev;
479     struct vfio_region_info *info;
480     int ret;
481 
482     /* Sanity check device */
483     if (!(vdev->flags & VFIO_DEVICE_FLAGS_CCW)) {
484         error_setg(errp, "vfio: Um, this isn't a vfio-ccw device");
485         return;
486     }
487 
488     /*
489      * We always expect at least the I/O region to be present. We also
490      * may have a variable number of regions governed by capabilities.
491      */
492     if (vdev->num_regions < VFIO_CCW_CONFIG_REGION_INDEX + 1) {
493         error_setg(errp, "vfio: too few regions (%u), expected at least %u",
494                    vdev->num_regions, VFIO_CCW_CONFIG_REGION_INDEX + 1);
495         return;
496     }
497 
498     ret = vfio_get_region_info(vdev, VFIO_CCW_CONFIG_REGION_INDEX, &info);
499     if (ret) {
500         error_setg_errno(errp, -ret, "vfio: Error getting config info");
501         return;
502     }
503 
504     vcdev->io_region_size = info->size;
505     if (sizeof(*vcdev->io_region) != vcdev->io_region_size) {
506         error_setg(errp, "vfio: Unexpected size of the I/O region");
507         goto out_err;
508     }
509 
510     vcdev->io_region_offset = info->offset;
511     vcdev->io_region = g_malloc0(info->size);
512     g_free(info);
513 
514     /* check for the optional async command region */
515     ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW,
516                                    VFIO_REGION_SUBTYPE_CCW_ASYNC_CMD, &info);
517     if (!ret) {
518         vcdev->async_cmd_region_size = info->size;
519         if (sizeof(*vcdev->async_cmd_region) != vcdev->async_cmd_region_size) {
520             error_setg(errp, "vfio: Unexpected size of the async cmd region");
521             goto out_err;
522         }
523         vcdev->async_cmd_region_offset = info->offset;
524         vcdev->async_cmd_region = g_malloc0(info->size);
525         g_free(info);
526     }
527 
528     ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW,
529                                    VFIO_REGION_SUBTYPE_CCW_SCHIB, &info);
530     if (!ret) {
531         vcdev->schib_region_size = info->size;
532         if (sizeof(*vcdev->schib_region) != vcdev->schib_region_size) {
533             error_setg(errp, "vfio: Unexpected size of the schib region");
534             goto out_err;
535         }
536         vcdev->schib_region_offset = info->offset;
537         vcdev->schib_region = g_malloc(info->size);
538         g_free(info);
539     }
540 
541     ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW,
542                                    VFIO_REGION_SUBTYPE_CCW_CRW, &info);
543 
544     if (!ret) {
545         vcdev->crw_region_size = info->size;
546         if (sizeof(*vcdev->crw_region) != vcdev->crw_region_size) {
547             error_setg(errp, "vfio: Unexpected size of the CRW region");
548             goto out_err;
549         }
550         vcdev->crw_region_offset = info->offset;
551         vcdev->crw_region = g_malloc(info->size);
552         g_free(info);
553     }
554 
555     return;
556 
557 out_err:
558     g_free(vcdev->crw_region);
559     g_free(vcdev->schib_region);
560     g_free(vcdev->async_cmd_region);
561     g_free(vcdev->io_region);
562     g_free(info);
563     return;
564 }
565 
566 static void vfio_ccw_put_region(VFIOCCWDevice *vcdev)
567 {
568     g_free(vcdev->crw_region);
569     g_free(vcdev->schib_region);
570     g_free(vcdev->async_cmd_region);
571     g_free(vcdev->io_region);
572 }
573 
574 static void vfio_ccw_realize(DeviceState *dev, Error **errp)
575 {
576     S390CCWDevice *cdev = S390_CCW_DEVICE(dev);
577     VFIOCCWDevice *vcdev = VFIO_CCW(cdev);
578     S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
579     VFIODevice *vbasedev = &vcdev->vdev;
580     Error *err = NULL;
581     int ret;
582 
583     /* Call the class init function for subchannel. */
584     if (cdc->realize) {
585         cdc->realize(cdev, vcdev->vdev.sysfsdev, &err);
586         if (err) {
587             goto out_err_propagate;
588         }
589     }
590 
591     vbasedev->ops = &vfio_ccw_ops;
592     vbasedev->type = VFIO_DEVICE_TYPE_CCW;
593     vbasedev->name = g_strdup_printf("%x.%x.%04x", vcdev->cdev.hostid.cssid,
594                            vcdev->cdev.hostid.ssid,
595                            vcdev->cdev.hostid.devid);
596     vbasedev->dev = dev;
597 
598     /*
599      * All vfio-ccw devices are believed to operate in a way compatible with
600      * discarding of memory in RAM blocks, ie. pages pinned in the host are
601      * in the current working set of the guest driver and therefore never
602      * overlap e.g., with pages available to the guest balloon driver.  This
603      * needs to be set before vfio_get_device() for vfio common to handle
604      * ram_block_discard_disable().
605      */
606     vbasedev->ram_block_discard_allowed = true;
607 
608     ret = vfio_attach_device(cdev->mdevid, vbasedev,
609                              &address_space_memory, errp);
610     if (ret) {
611         goto out_attach_dev_err;
612     }
613 
614     vfio_ccw_get_region(vcdev, &err);
615     if (err) {
616         goto out_region_err;
617     }
618 
619     vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, &err);
620     if (err) {
621         goto out_io_notifier_err;
622     }
623 
624     if (vcdev->crw_region) {
625         vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX, &err);
626         if (err) {
627             goto out_irq_notifier_err;
628         }
629     }
630 
631     vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX, &err);
632     if (err) {
633         /*
634          * Report this error, but do not make it a failing condition.
635          * Lack of this IRQ in the host does not prevent normal operation.
636          */
637         error_report_err(err);
638     }
639 
640     return;
641 
642 out_irq_notifier_err:
643     vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX);
644     vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX);
645     vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX);
646 out_io_notifier_err:
647     vfio_ccw_put_region(vcdev);
648 out_region_err:
649     vfio_detach_device(vbasedev);
650 out_attach_dev_err:
651     g_free(vbasedev->name);
652     if (cdc->unrealize) {
653         cdc->unrealize(cdev);
654     }
655 out_err_propagate:
656     error_propagate(errp, err);
657 }
658 
659 static void vfio_ccw_unrealize(DeviceState *dev)
660 {
661     S390CCWDevice *cdev = S390_CCW_DEVICE(dev);
662     VFIOCCWDevice *vcdev = VFIO_CCW(cdev);
663     S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
664 
665     vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX);
666     vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX);
667     vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX);
668     vfio_ccw_put_region(vcdev);
669     vfio_detach_device(&vcdev->vdev);
670     g_free(vcdev->vdev.name);
671 
672     if (cdc->unrealize) {
673         cdc->unrealize(cdev);
674     }
675 }
676 
677 static Property vfio_ccw_properties[] = {
678     DEFINE_PROP_STRING("sysfsdev", VFIOCCWDevice, vdev.sysfsdev),
679     DEFINE_PROP_BOOL("force-orb-pfch", VFIOCCWDevice, force_orb_pfch, false),
680     DEFINE_PROP_END_OF_LIST(),
681 };
682 
683 static const VMStateDescription vfio_ccw_vmstate = {
684     .name = "vfio-ccw",
685     .unmigratable = 1,
686 };
687 
688 static void vfio_ccw_class_init(ObjectClass *klass, void *data)
689 {
690     DeviceClass *dc = DEVICE_CLASS(klass);
691     S390CCWDeviceClass *cdc = S390_CCW_DEVICE_CLASS(klass);
692 
693     device_class_set_props(dc, vfio_ccw_properties);
694     dc->vmsd = &vfio_ccw_vmstate;
695     dc->desc = "VFIO-based subchannel assignment";
696     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
697     dc->realize = vfio_ccw_realize;
698     dc->unrealize = vfio_ccw_unrealize;
699     dc->reset = vfio_ccw_reset;
700 
701     cdc->handle_request = vfio_ccw_handle_request;
702     cdc->handle_halt = vfio_ccw_handle_halt;
703     cdc->handle_clear = vfio_ccw_handle_clear;
704     cdc->handle_store = vfio_ccw_handle_store;
705 }
706 
707 static const TypeInfo vfio_ccw_info = {
708     .name = TYPE_VFIO_CCW,
709     .parent = TYPE_S390_CCW,
710     .instance_size = sizeof(VFIOCCWDevice),
711     .class_init = vfio_ccw_class_init,
712 };
713 
714 static void register_vfio_ccw_type(void)
715 {
716     type_register_static(&vfio_ccw_info);
717 }
718 
719 type_init(register_vfio_ccw_type)
720