17
#include "qemu/osdep.h"
18
#include CONFIG_DEVICES
19
#include <linux/vfio.h>
20
#include <linux/vfio_ccw.h>
23
#include "qapi/error.h"
24
#include "hw/vfio/vfio-common.h"
25
#include "sysemu/iommufd.h"
26
#include "hw/s390x/s390-ccw.h"
27
#include "hw/s390x/vfio-ccw.h"
28
#include "hw/qdev-properties.h"
29
#include "hw/s390x/ccw-device.h"
30
#include "exec/address-spaces.h"
31
#include "qemu/error-report.h"
32
#include "qemu/main-loop.h"
33
#include "qemu/module.h"
38
uint64_t io_region_size;
39
uint64_t io_region_offset;
40
struct ccw_io_region *io_region;
41
uint64_t async_cmd_region_size;
42
uint64_t async_cmd_region_offset;
43
struct ccw_cmd_region *async_cmd_region;
44
uint64_t schib_region_size;
45
uint64_t schib_region_offset;
46
struct ccw_schib_region *schib_region;
47
uint64_t crw_region_size;
48
uint64_t crw_region_offset;
49
struct ccw_crw_region *crw_region;
50
EventNotifier io_notifier;
51
EventNotifier crw_notifier;
52
EventNotifier req_notifier;
57
static inline void warn_once_pfch(VFIOCCWDevice *vcdev, SubchDev *sch,
60
warn_report_once_cond(&vcdev->warned_orb_pfch,
61
"vfio-ccw (devno %x.%x.%04x): %s",
62
sch->cssid, sch->ssid, sch->devno, msg);
65
static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
67
vdev->needs_reset = false;
74
struct VFIODeviceOps vfio_ccw_ops = {
75
.vfio_compute_needs_reset = vfio_ccw_compute_needs_reset,
78
static IOInstEnding vfio_ccw_handle_request(SubchDev *sch)
80
VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data);
81
struct ccw_io_region *region = vcdev->io_region;
84
if (!(sch->orb.ctrl0 & ORB_CTRL0_MASK_PFCH) && vcdev->force_orb_pfch) {
85
sch->orb.ctrl0 |= ORB_CTRL0_MASK_PFCH;
86
warn_once_pfch(vcdev, sch, "PFCH flag forced");
89
QEMU_BUILD_BUG_ON(sizeof(region->orb_area) != sizeof(ORB));
90
QEMU_BUILD_BUG_ON(sizeof(region->scsw_area) != sizeof(SCSW));
91
QEMU_BUILD_BUG_ON(sizeof(region->irb_area) != sizeof(IRB));
93
memset(region, 0, sizeof(*region));
95
memcpy(region->orb_area, &sch->orb, sizeof(ORB));
96
memcpy(region->scsw_area, &sch->curr_status.scsw, sizeof(SCSW));
99
ret = pwrite(vcdev->vdev.fd, region,
100
vcdev->io_region_size, vcdev->io_region_offset);
101
if (ret != vcdev->io_region_size) {
102
if (errno == EAGAIN) {
105
error_report("vfio-ccw: write I/O region failed with errno=%d", errno);
106
ret = errno ? -errno : -EFAULT;
112
return IOINST_CC_EXPECTED;
114
return IOINST_CC_BUSY;
117
return IOINST_CC_NOT_OPERATIONAL;
120
sch_gen_unit_exception(sch);
121
css_inject_io_interrupt(sch);
122
return IOINST_CC_EXPECTED;
126
static IOInstEnding vfio_ccw_handle_store(SubchDev *sch)
128
VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data);
129
SCHIB *schib = &sch->curr_status;
130
struct ccw_schib_region *region = vcdev->schib_region;
136
return IOINST_CC_EXPECTED;
139
memset(region, 0, sizeof(*region));
140
ret = pread(vcdev->vdev.fd, region, vcdev->schib_region_size,
141
vcdev->schib_region_offset);
149
error_report("vfio-ccw: store region read failed with errno=%d", errno);
150
return IOINST_CC_EXPECTED;
157
s = (SCHIB *)region->schib_area;
158
schib->pmcw.pnom = s->pmcw.pnom;
159
schib->pmcw.lpum = s->pmcw.lpum;
160
schib->pmcw.pam = s->pmcw.pam;
161
schib->pmcw.pom = s->pmcw.pom;
163
if (s->scsw.flags & SCSW_FLAGS_MASK_PNO) {
164
schib->scsw.flags |= SCSW_FLAGS_MASK_PNO;
167
return IOINST_CC_EXPECTED;
170
static int vfio_ccw_handle_clear(SubchDev *sch)
172
VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data);
173
struct ccw_cmd_region *region = vcdev->async_cmd_region;
176
if (!vcdev->async_cmd_region) {
181
memset(region, 0, sizeof(*region));
182
region->command = VFIO_CCW_ASYNC_CMD_CSCH;
185
ret = pwrite(vcdev->vdev.fd, region,
186
vcdev->async_cmd_region_size, vcdev->async_cmd_region_offset);
187
if (ret != vcdev->async_cmd_region_size) {
188
if (errno == EAGAIN) {
191
error_report("vfio-ccw: write cmd region failed with errno=%d", errno);
192
ret = errno ? -errno : -EFAULT;
203
sch_gen_unit_exception(sch);
204
css_inject_io_interrupt(sch);
209
static int vfio_ccw_handle_halt(SubchDev *sch)
211
VFIOCCWDevice *vcdev = VFIO_CCW(sch->driver_data);
212
struct ccw_cmd_region *region = vcdev->async_cmd_region;
215
if (!vcdev->async_cmd_region) {
220
memset(region, 0, sizeof(*region));
221
region->command = VFIO_CCW_ASYNC_CMD_HSCH;
224
ret = pwrite(vcdev->vdev.fd, region,
225
vcdev->async_cmd_region_size, vcdev->async_cmd_region_offset);
226
if (ret != vcdev->async_cmd_region_size) {
227
if (errno == EAGAIN) {
230
error_report("vfio-ccw: write cmd region failed with errno=%d", errno);
231
ret = errno ? -errno : -EFAULT;
243
sch_gen_unit_exception(sch);
244
css_inject_io_interrupt(sch);
249
static void vfio_ccw_reset(DeviceState *dev)
251
VFIOCCWDevice *vcdev = VFIO_CCW(dev);
253
ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET);
256
static void vfio_ccw_crw_read(VFIOCCWDevice *vcdev)
258
struct ccw_crw_region *region = vcdev->crw_region;
264
memset(region, 0, sizeof(*region));
265
size = pread(vcdev->vdev.fd, region, vcdev->crw_region_size,
266
vcdev->crw_region_offset);
269
error_report("vfio-ccw: Read crw region failed with errno=%d",
274
if (region->crw == 0) {
279
memcpy(&crw, ®ion->crw, sizeof(CRW));
281
css_crw_add_to_queue(crw);
285
static void vfio_ccw_req_notifier_handler(void *opaque)
287
VFIOCCWDevice *vcdev = opaque;
290
if (!event_notifier_test_and_clear(&vcdev->req_notifier)) {
294
qdev_unplug(DEVICE(vcdev), &err);
296
warn_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name);
300
static void vfio_ccw_crw_notifier_handler(void *opaque)
302
VFIOCCWDevice *vcdev = opaque;
304
while (event_notifier_test_and_clear(&vcdev->crw_notifier)) {
305
vfio_ccw_crw_read(vcdev);
309
static void vfio_ccw_io_notifier_handler(void *opaque)
311
VFIOCCWDevice *vcdev = opaque;
312
struct ccw_io_region *region = vcdev->io_region;
313
CcwDevice *ccw_dev = CCW_DEVICE(vcdev);
314
SubchDev *sch = ccw_dev->sch;
315
SCHIB *schib = &sch->curr_status;
321
if (!event_notifier_test_and_clear(&vcdev->io_notifier)) {
325
size = pread(vcdev->vdev.fd, region, vcdev->io_region_size,
326
vcdev->io_region_offset);
331
schib->scsw.flags |= SCSW_FLAGS_MASK_CC;
332
schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
333
schib->scsw.ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
337
schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
338
schib->scsw.cstat = SCSW_CSTAT_DATA_CHECK;
339
schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
340
schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
341
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
345
schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
346
schib->scsw.cstat = SCSW_CSTAT_PROG_CHECK;
347
schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
348
schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
349
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
352
} else if (size != vcdev->io_region_size) {
354
schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
355
schib->scsw.cstat = SCSW_CSTAT_CHN_CTRL_CHK;
356
schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
357
schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
358
SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
362
memcpy(&irb, region->irb_area, sizeof(IRB));
366
copy_scsw_to_guest(&s, &irb.scsw);
369
copy_esw_to_guest(&esw, &irb.esw);
373
if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
374
(schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) {
375
memcpy(sch->sense_data, irb.ecw, sizeof(irb.ecw));
379
css_inject_io_interrupt(sch);
382
static bool vfio_ccw_register_irq_notifier(VFIOCCWDevice *vcdev,
386
VFIODevice *vdev = &vcdev->vdev;
387
g_autofree struct vfio_irq_info *irq_info = NULL;
390
EventNotifier *notifier;
394
case VFIO_CCW_IO_IRQ_INDEX:
395
notifier = &vcdev->io_notifier;
396
fd_read = vfio_ccw_io_notifier_handler;
398
case VFIO_CCW_CRW_IRQ_INDEX:
399
notifier = &vcdev->crw_notifier;
400
fd_read = vfio_ccw_crw_notifier_handler;
402
case VFIO_CCW_REQ_IRQ_INDEX:
403
notifier = &vcdev->req_notifier;
404
fd_read = vfio_ccw_req_notifier_handler;
407
error_setg(errp, "vfio: Unsupported device irq(%d)", irq);
411
if (vdev->num_irqs < irq + 1) {
412
error_setg(errp, "vfio: IRQ %u not available (number of irqs %u)",
413
irq, vdev->num_irqs);
417
argsz = sizeof(*irq_info);
418
irq_info = g_malloc0(argsz);
419
irq_info->index = irq;
420
irq_info->argsz = argsz;
421
if (ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO,
422
irq_info) < 0 || irq_info->count < 1) {
423
error_setg_errno(errp, errno, "vfio: Error getting irq info");
427
if (event_notifier_init(notifier, 0)) {
428
error_setg_errno(errp, errno,
429
"vfio: Unable to init event notifier for irq (%d)",
434
fd = event_notifier_get_fd(notifier);
435
qemu_set_fd_handler(fd, fd_read, NULL, vcdev);
437
if (!vfio_set_irq_signaling(vdev, irq, 0,
438
VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) {
439
qemu_set_fd_handler(fd, NULL, NULL, vcdev);
440
event_notifier_cleanup(notifier);
446
static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice *vcdev,
450
EventNotifier *notifier;
453
case VFIO_CCW_IO_IRQ_INDEX:
454
notifier = &vcdev->io_notifier;
456
case VFIO_CCW_CRW_IRQ_INDEX:
457
notifier = &vcdev->crw_notifier;
459
case VFIO_CCW_REQ_IRQ_INDEX:
460
notifier = &vcdev->req_notifier;
463
error_report("vfio: Unsupported device irq(%d)", irq);
467
if (!vfio_set_irq_signaling(&vcdev->vdev, irq, 0,
468
VFIO_IRQ_SET_ACTION_TRIGGER, -1, &err)) {
469
warn_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name);
472
qemu_set_fd_handler(event_notifier_get_fd(notifier),
474
event_notifier_cleanup(notifier);
477
static bool vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)
479
VFIODevice *vdev = &vcdev->vdev;
480
struct vfio_region_info *info;
484
if (!(vdev->flags & VFIO_DEVICE_FLAGS_CCW)) {
485
error_setg(errp, "vfio: Um, this isn't a vfio-ccw device");
493
if (vdev->num_regions < VFIO_CCW_CONFIG_REGION_INDEX + 1) {
494
error_setg(errp, "vfio: too few regions (%u), expected at least %u",
495
vdev->num_regions, VFIO_CCW_CONFIG_REGION_INDEX + 1);
499
ret = vfio_get_region_info(vdev, VFIO_CCW_CONFIG_REGION_INDEX, &info);
501
error_setg_errno(errp, -ret, "vfio: Error getting config info");
505
vcdev->io_region_size = info->size;
506
if (sizeof(*vcdev->io_region) != vcdev->io_region_size) {
507
error_setg(errp, "vfio: Unexpected size of the I/O region");
511
vcdev->io_region_offset = info->offset;
512
vcdev->io_region = g_malloc0(info->size);
516
ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW,
517
VFIO_REGION_SUBTYPE_CCW_ASYNC_CMD, &info);
519
vcdev->async_cmd_region_size = info->size;
520
if (sizeof(*vcdev->async_cmd_region) != vcdev->async_cmd_region_size) {
521
error_setg(errp, "vfio: Unexpected size of the async cmd region");
524
vcdev->async_cmd_region_offset = info->offset;
525
vcdev->async_cmd_region = g_malloc0(info->size);
529
ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW,
530
VFIO_REGION_SUBTYPE_CCW_SCHIB, &info);
532
vcdev->schib_region_size = info->size;
533
if (sizeof(*vcdev->schib_region) != vcdev->schib_region_size) {
534
error_setg(errp, "vfio: Unexpected size of the schib region");
537
vcdev->schib_region_offset = info->offset;
538
vcdev->schib_region = g_malloc(info->size);
542
ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW,
543
VFIO_REGION_SUBTYPE_CCW_CRW, &info);
546
vcdev->crw_region_size = info->size;
547
if (sizeof(*vcdev->crw_region) != vcdev->crw_region_size) {
548
error_setg(errp, "vfio: Unexpected size of the CRW region");
551
vcdev->crw_region_offset = info->offset;
552
vcdev->crw_region = g_malloc(info->size);
559
g_free(vcdev->crw_region);
560
g_free(vcdev->schib_region);
561
g_free(vcdev->async_cmd_region);
562
g_free(vcdev->io_region);
567
static void vfio_ccw_put_region(VFIOCCWDevice *vcdev)
569
g_free(vcdev->crw_region);
570
g_free(vcdev->schib_region);
571
g_free(vcdev->async_cmd_region);
572
g_free(vcdev->io_region);
575
static void vfio_ccw_realize(DeviceState *dev, Error **errp)
577
S390CCWDevice *cdev = S390_CCW_DEVICE(dev);
578
VFIOCCWDevice *vcdev = VFIO_CCW(cdev);
579
S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
580
VFIODevice *vbasedev = &vcdev->vdev;
585
if (!cdc->realize(cdev, vcdev->vdev.sysfsdev, errp)) {
590
if (!vfio_device_get_name(vbasedev, errp)) {
594
if (!vfio_attach_device(cdev->mdevid, vbasedev,
595
&address_space_memory, errp)) {
596
goto out_attach_dev_err;
599
if (!vfio_ccw_get_region(vcdev, errp)) {
603
if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, errp)) {
604
goto out_io_notifier_err;
607
if (vcdev->crw_region) {
608
if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX,
610
goto out_irq_notifier_err;
614
if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX, &err)) {
619
warn_report_err(err);
625
vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX);
626
vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX);
627
vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX);
629
vfio_ccw_put_region(vcdev);
631
vfio_detach_device(vbasedev);
633
g_free(vbasedev->name);
635
if (cdc->unrealize) {
636
cdc->unrealize(cdev);
640
static void vfio_ccw_unrealize(DeviceState *dev)
642
S390CCWDevice *cdev = S390_CCW_DEVICE(dev);
643
VFIOCCWDevice *vcdev = VFIO_CCW(cdev);
644
S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
646
vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX);
647
vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX);
648
vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX);
649
vfio_ccw_put_region(vcdev);
650
vfio_detach_device(&vcdev->vdev);
651
g_free(vcdev->vdev.name);
653
if (cdc->unrealize) {
654
cdc->unrealize(cdev);
658
static Property vfio_ccw_properties[] = {
659
DEFINE_PROP_STRING("sysfsdev", VFIOCCWDevice, vdev.sysfsdev),
660
DEFINE_PROP_BOOL("force-orb-pfch", VFIOCCWDevice, force_orb_pfch, false),
662
DEFINE_PROP_LINK("iommufd", VFIOCCWDevice, vdev.iommufd,
663
TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *),
665
DEFINE_PROP_END_OF_LIST(),
668
static const VMStateDescription vfio_ccw_vmstate = {
673
static void vfio_ccw_instance_init(Object *obj)
675
VFIOCCWDevice *vcdev = VFIO_CCW(obj);
676
VFIODevice *vbasedev = &vcdev->vdev;
679
vbasedev->mdev = true;
689
vfio_device_init(vbasedev, VFIO_DEVICE_TYPE_CCW, &vfio_ccw_ops,
690
DEVICE(vcdev), true);
694
static void vfio_ccw_set_fd(Object *obj, const char *str, Error **errp)
696
vfio_device_set_fd(&VFIO_CCW(obj)->vdev, str, errp);
700
static void vfio_ccw_class_init(ObjectClass *klass, void *data)
702
DeviceClass *dc = DEVICE_CLASS(klass);
703
S390CCWDeviceClass *cdc = S390_CCW_DEVICE_CLASS(klass);
705
device_class_set_props(dc, vfio_ccw_properties);
707
object_class_property_add_str(klass, "fd", NULL, vfio_ccw_set_fd);
709
dc->vmsd = &vfio_ccw_vmstate;
710
dc->desc = "VFIO-based subchannel assignment";
711
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
712
dc->realize = vfio_ccw_realize;
713
dc->unrealize = vfio_ccw_unrealize;
714
dc->reset = vfio_ccw_reset;
716
cdc->handle_request = vfio_ccw_handle_request;
717
cdc->handle_halt = vfio_ccw_handle_halt;
718
cdc->handle_clear = vfio_ccw_handle_clear;
719
cdc->handle_store = vfio_ccw_handle_store;
722
static const TypeInfo vfio_ccw_info = {
723
.name = TYPE_VFIO_CCW,
724
.parent = TYPE_S390_CCW,
725
.instance_size = sizeof(VFIOCCWDevice),
726
.instance_init = vfio_ccw_instance_init,
727
.class_init = vfio_ccw_class_init,
730
static void register_vfio_ccw_type(void)
732
type_register_static(&vfio_ccw_info);
735
type_init(register_vfio_ccw_type)