/*
 * vfio based subchannel assignment support
 *
 * Copyright 2017 IBM Corp.
 * Copyright 2019 Red Hat, Inc.
 *
 * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
 *            Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
 *            Pierre Morel <pmorel@linux.vnet.ibm.com>
 *            Cornelia Huck <cohuck@redhat.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or (at
 * your option) any later version. See the COPYING file in the top-level
 * directory.
 */

#include "qemu/osdep.h"
#include <linux/vfio.h>
#include <linux/vfio_ccw.h>
#include <sys/ioctl.h>

#include "qapi/error.h"
#include "hw/vfio/vfio.h"
#include "hw/vfio/vfio-common.h"
#include "hw/s390x/s390-ccw.h"
#include "hw/s390x/vfio-ccw.h"
#include "hw/qdev-properties.h"
#include "hw/s390x/ccw-device.h"
#include "exec/address-spaces.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"

struct VFIOCCWDevice {
    S390CCWDevice cdev;
    VFIODevice vdev;
    uint64_t io_region_size;
    uint64_t io_region_offset;
    struct ccw_io_region *io_region;
    uint64_t async_cmd_region_size;
    uint64_t async_cmd_region_offset;
    struct ccw_cmd_region *async_cmd_region;
    uint64_t schib_region_size;
    uint64_t schib_region_offset;
    struct ccw_schib_region *schib_region;
    uint64_t crw_region_size;
    uint64_t crw_region_offset;
    struct ccw_crw_region *crw_region;
    EventNotifier io_notifier;
    EventNotifier crw_notifier;
    EventNotifier req_notifier;
    bool force_orb_pfch;
    bool warned_orb_pfch;
};

static inline void warn_once_pfch(VFIOCCWDevice *vcdev, SubchDev *sch,
                                  const char *msg)
{
    warn_report_once_cond(&vcdev->warned_orb_pfch,
                          "vfio-ccw (devno %x.%x.%04x): %s",
                          sch->cssid, sch->ssid, sch->devno, msg);
}

static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
{
    vdev->needs_reset = false;
}

/*
 * We don't need vfio_hot_reset_multi and vfio_eoi operations for
 * vfio_ccw device now.
 */
struct VFIODeviceOps vfio_ccw_ops = {
    .vfio_compute_needs_reset = vfio_ccw_compute_needs_reset,
};

static IOInstEnding vfio_ccw_handle_request(SubchDev *sch)
{
    S390CCWDevice *cdev = sch->driver_data;
    VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
    struct ccw_io_region *region = vcdev->io_region;
    int ret;

    if (!(sch->orb.ctrl0 & ORB_CTRL0_MASK_PFCH) && vcdev->force_orb_pfch) {
        sch->orb.ctrl0 |= ORB_CTRL0_MASK_PFCH;
        warn_once_pfch(vcdev, sch, "PFCH flag forced");
    }

    QEMU_BUILD_BUG_ON(sizeof(region->orb_area) != sizeof(ORB));
    QEMU_BUILD_BUG_ON(sizeof(region->scsw_area) != sizeof(SCSW));
    QEMU_BUILD_BUG_ON(sizeof(region->irb_area) != sizeof(IRB));

    memset(region, 0, sizeof(*region));

    memcpy(region->orb_area, &sch->orb, sizeof(ORB));
    memcpy(region->scsw_area, &sch->curr_status.scsw, sizeof(SCSW));

again:
    ret = pwrite(vcdev->vdev.fd, region,
                 vcdev->io_region_size, vcdev->io_region_offset);
    if (ret != vcdev->io_region_size) {
        if (errno == EAGAIN) {
            goto again;
        }
        error_report("vfio-ccw: write I/O region failed with errno=%d", errno);
        ret = errno ? -errno : -EFAULT;
    } else {
        ret = 0;
    }
    switch (ret) {
    case 0:
        return IOINST_CC_EXPECTED;
    case -EBUSY:
        return IOINST_CC_BUSY;
    case -ENODEV:
    case -EACCES:
        return IOINST_CC_NOT_OPERATIONAL;
    case -EFAULT:
    default:
        sch_gen_unit_exception(sch);
        css_inject_io_interrupt(sch);
        return IOINST_CC_EXPECTED;
    }
}

static IOInstEnding vfio_ccw_handle_store(SubchDev *sch)
{
    S390CCWDevice *cdev = sch->driver_data;
    VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
    SCHIB *schib = &sch->curr_status;
    struct ccw_schib_region *region = vcdev->schib_region;
    SCHIB *s;
    int ret;

    /* schib region not available so nothing else to do */
    if (!region) {
        return IOINST_CC_EXPECTED;
    }

    memset(region, 0, sizeof(*region));
    ret = pread(vcdev->vdev.fd, region, vcdev->schib_region_size,
                vcdev->schib_region_offset);

    if (ret == -1) {
        /*
         * Device is probably damaged, but store subchannel does not
         * have a nonzero cc defined for this scenario.  Log an error,
         * and presume things are otherwise fine.
         */
        error_report("vfio-ccw: store region read failed with errno=%d", errno);
        return IOINST_CC_EXPECTED;
    }

    /*
     * Selectively copy path-related bits of the SCHIB,
     * rather than copying the entire struct.
     */
    s = (SCHIB *)region->schib_area;
    schib->pmcw.pnom = s->pmcw.pnom;
    schib->pmcw.lpum = s->pmcw.lpum;
    schib->pmcw.pam = s->pmcw.pam;
    schib->pmcw.pom = s->pmcw.pom;

    if (s->scsw.flags & SCSW_FLAGS_MASK_PNO) {
        schib->scsw.flags |= SCSW_FLAGS_MASK_PNO;
    }

    return IOINST_CC_EXPECTED;
}

static int vfio_ccw_handle_clear(SubchDev *sch)
{
    S390CCWDevice *cdev = sch->driver_data;
    VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
    struct ccw_cmd_region *region = vcdev->async_cmd_region;
    int ret;

    if (!vcdev->async_cmd_region) {
        /* Async command region not available, fall back to emulation */
        return -ENOSYS;
    }

    memset(region, 0, sizeof(*region));
    region->command = VFIO_CCW_ASYNC_CMD_CSCH;

again:
    ret = pwrite(vcdev->vdev.fd, region,
                 vcdev->async_cmd_region_size, vcdev->async_cmd_region_offset);
    if (ret != vcdev->async_cmd_region_size) {
        if (errno == EAGAIN) {
            goto again;
        }
        error_report("vfio-ccw: write cmd region failed with errno=%d", errno);
        ret = errno ? -errno : -EFAULT;
    } else {
        ret = 0;
    }
    switch (ret) {
    case 0:
    case -ENODEV:
    case -EACCES:
        return ret;
    case -EFAULT:
    default:
        sch_gen_unit_exception(sch);
        css_inject_io_interrupt(sch);
        return 0;
    }
}

static int vfio_ccw_handle_halt(SubchDev *sch)
{
    S390CCWDevice *cdev = sch->driver_data;
    VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
    struct ccw_cmd_region *region = vcdev->async_cmd_region;
    int ret;

    if (!vcdev->async_cmd_region) {
        /* Async command region not available, fall back to emulation */
        return -ENOSYS;
    }

    memset(region, 0, sizeof(*region));
    region->command = VFIO_CCW_ASYNC_CMD_HSCH;

again:
    ret = pwrite(vcdev->vdev.fd, region,
                 vcdev->async_cmd_region_size, vcdev->async_cmd_region_offset);
    if (ret != vcdev->async_cmd_region_size) {
        if (errno == EAGAIN) {
            goto again;
        }
        error_report("vfio-ccw: write cmd region failed with errno=%d", errno);
        ret = errno ? -errno : -EFAULT;
    } else {
        ret = 0;
    }
    switch (ret) {
    case 0:
    case -EBUSY:
    case -ENODEV:
    case -EACCES:
        return ret;
    case -EFAULT:
    default:
        sch_gen_unit_exception(sch);
        css_inject_io_interrupt(sch);
        return 0;
    }
}

static void vfio_ccw_reset(DeviceState *dev)
{
    CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
    S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
    VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);

    ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET);
}

static void vfio_ccw_crw_read(VFIOCCWDevice *vcdev)
{
    struct ccw_crw_region *region = vcdev->crw_region;
    CRW crw;
    int size;

    /* Keep reading CRWs as long as data is returned */
    do {
        memset(region, 0, sizeof(*region));
        size = pread(vcdev->vdev.fd, region, vcdev->crw_region_size,
                     vcdev->crw_region_offset);

        if (size == -1) {
            error_report("vfio-ccw: Read crw region failed with errno=%d",
                         errno);
            break;
        }

        if (region->crw == 0) {
            /* No more CRWs to queue */
            break;
        }

        memcpy(&crw, &region->crw, sizeof(CRW));

        css_crw_add_to_queue(crw);
    } while (1);
}

static void vfio_ccw_req_notifier_handler(void *opaque)
{
    VFIOCCWDevice *vcdev = opaque;
    Error *err = NULL;

    if (!event_notifier_test_and_clear(&vcdev->req_notifier)) {
        return;
    }

    qdev_unplug(DEVICE(vcdev), &err);
    if (err) {
        warn_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name);
    }
}

static void vfio_ccw_crw_notifier_handler(void *opaque)
{
    VFIOCCWDevice *vcdev = opaque;

    while (event_notifier_test_and_clear(&vcdev->crw_notifier)) {
        vfio_ccw_crw_read(vcdev);
    }
}

static void vfio_ccw_io_notifier_handler(void *opaque)
{
    VFIOCCWDevice *vcdev = opaque;
    struct ccw_io_region *region = vcdev->io_region;
    S390CCWDevice *cdev = S390_CCW_DEVICE(vcdev);
    CcwDevice *ccw_dev = CCW_DEVICE(cdev);
    SubchDev *sch = ccw_dev->sch;
    SCHIB *schib = &sch->curr_status;
    SCSW s;
    IRB irb;
    ESW esw;
    int size;

    if (!event_notifier_test_and_clear(&vcdev->io_notifier)) {
        return;
    }

    size = pread(vcdev->vdev.fd, region, vcdev->io_region_size,
                 vcdev->io_region_offset);
    if (size == -1) {
        switch (errno) {
        case ENODEV:
            /* Generate a deferred cc 3 condition. */
            schib->scsw.flags |= SCSW_FLAGS_MASK_CC;
            schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
            schib->scsw.ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
            goto read_err;
        case EFAULT:
            /* Memory problem, generate channel data check. */
            schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
            schib->scsw.cstat = SCSW_CSTAT_DATA_CHECK;
            schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
            schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
                       SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
            goto read_err;
        default:
            /* Error, generate channel program check. */
            schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
            schib->scsw.cstat = SCSW_CSTAT_PROG_CHECK;
            schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
            schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
                       SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
            goto read_err;
        }
    } else if (size != vcdev->io_region_size) {
        /* Information transfer error, generate channel-control check. */
        schib->scsw.ctrl &= ~SCSW_ACTL_START_PEND;
        schib->scsw.cstat = SCSW_CSTAT_CHN_CTRL_CHK;
        schib->scsw.ctrl &= ~SCSW_CTRL_MASK_STCTL;
        schib->scsw.ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY |
                   SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND;
        goto read_err;
    }

    memcpy(&irb, region->irb_area, sizeof(IRB));

    /* Update control block via irb. */
    s = schib->scsw;
    copy_scsw_to_guest(&s, &irb.scsw);
    schib->scsw = s;

    copy_esw_to_guest(&esw, &irb.esw);
    sch->esw = esw;

    /* If a uint check is pending, copy sense data. */
    if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
        (schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) {
        memcpy(sch->sense_data, irb.ecw, sizeof(irb.ecw));
    }

read_err:
    css_inject_io_interrupt(sch);
}

static void vfio_ccw_register_irq_notifier(VFIOCCWDevice *vcdev,
                                           unsigned int irq,
                                           Error **errp)
{
    VFIODevice *vdev = &vcdev->vdev;
    struct vfio_irq_info *irq_info;
    size_t argsz;
    int fd;
    EventNotifier *notifier;
    IOHandler *fd_read;

    switch (irq) {
    case VFIO_CCW_IO_IRQ_INDEX:
        notifier = &vcdev->io_notifier;
        fd_read = vfio_ccw_io_notifier_handler;
        break;
    case VFIO_CCW_CRW_IRQ_INDEX:
        notifier = &vcdev->crw_notifier;
        fd_read = vfio_ccw_crw_notifier_handler;
        break;
    case VFIO_CCW_REQ_IRQ_INDEX:
        notifier = &vcdev->req_notifier;
        fd_read = vfio_ccw_req_notifier_handler;
        break;
    default:
        error_setg(errp, "vfio: Unsupported device irq(%d)", irq);
        return;
    }

    if (vdev->num_irqs < irq + 1) {
        error_setg(errp, "vfio: IRQ %u not available (number of irqs %u)",
                   irq, vdev->num_irqs);
        return;
    }

    argsz = sizeof(*irq_info);
    irq_info = g_malloc0(argsz);
    irq_info->index = irq;
    irq_info->argsz = argsz;
    if (ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO,
              irq_info) < 0 || irq_info->count < 1) {
        error_setg_errno(errp, errno, "vfio: Error getting irq info");
        goto out_free_info;
    }

    if (event_notifier_init(notifier, 0)) {
        error_setg_errno(errp, errno,
                         "vfio: Unable to init event notifier for irq (%d)",
                         irq);
        goto out_free_info;
    }

    fd = event_notifier_get_fd(notifier);
    qemu_set_fd_handler(fd, fd_read, NULL, vcdev);

    if (vfio_set_irq_signaling(vdev, irq, 0,
                               VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) {
        qemu_set_fd_handler(fd, NULL, NULL, vcdev);
        event_notifier_cleanup(notifier);
    }

out_free_info:
    g_free(irq_info);
}

static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice *vcdev,
                                             unsigned int irq)
{
    Error *err = NULL;
    EventNotifier *notifier;

    switch (irq) {
    case VFIO_CCW_IO_IRQ_INDEX:
        notifier = &vcdev->io_notifier;
        break;
    case VFIO_CCW_CRW_IRQ_INDEX:
        notifier = &vcdev->crw_notifier;
        break;
    case VFIO_CCW_REQ_IRQ_INDEX:
        notifier = &vcdev->req_notifier;
        break;
    default:
        error_report("vfio: Unsupported device irq(%d)", irq);
        return;
    }

    if (vfio_set_irq_signaling(&vcdev->vdev, irq, 0,
                               VFIO_IRQ_SET_ACTION_TRIGGER, -1, &err)) {
        warn_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name);
    }

    qemu_set_fd_handler(event_notifier_get_fd(notifier),
                        NULL, NULL, vcdev);
    event_notifier_cleanup(notifier);
}

static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)
{
    VFIODevice *vdev = &vcdev->vdev;
    struct vfio_region_info *info;
    int ret;

    /* Sanity check device */
    if (!(vdev->flags & VFIO_DEVICE_FLAGS_CCW)) {
        error_setg(errp, "vfio: Um, this isn't a vfio-ccw device");
        return;
    }

    /*
     * We always expect at least the I/O region to be present. We also
     * may have a variable number of regions governed by capabilities.
     */
    if (vdev->num_regions < VFIO_CCW_CONFIG_REGION_INDEX + 1) {
        error_setg(errp, "vfio: too few regions (%u), expected at least %u",
                   vdev->num_regions, VFIO_CCW_CONFIG_REGION_INDEX + 1);
        return;
    }

    ret = vfio_get_region_info(vdev, VFIO_CCW_CONFIG_REGION_INDEX, &info);
    if (ret) {
        error_setg_errno(errp, -ret, "vfio: Error getting config info");
        return;
    }

    vcdev->io_region_size = info->size;
    if (sizeof(*vcdev->io_region) != vcdev->io_region_size) {
        error_setg(errp, "vfio: Unexpected size of the I/O region");
        goto out_err;
    }

    vcdev->io_region_offset = info->offset;
    vcdev->io_region = g_malloc0(info->size);
    g_free(info);

    /* check for the optional async command region */
    ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW,
                                   VFIO_REGION_SUBTYPE_CCW_ASYNC_CMD, &info);
    if (!ret) {
        vcdev->async_cmd_region_size = info->size;
        if (sizeof(*vcdev->async_cmd_region) != vcdev->async_cmd_region_size) {
            error_setg(errp, "vfio: Unexpected size of the async cmd region");
            goto out_err;
        }
        vcdev->async_cmd_region_offset = info->offset;
        vcdev->async_cmd_region = g_malloc0(info->size);
        g_free(info);
    }

    ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW,
                                   VFIO_REGION_SUBTYPE_CCW_SCHIB, &info);
    if (!ret) {
        vcdev->schib_region_size = info->size;
        if (sizeof(*vcdev->schib_region) != vcdev->schib_region_size) {
            error_setg(errp, "vfio: Unexpected size of the schib region");
            goto out_err;
        }
        vcdev->schib_region_offset = info->offset;
        vcdev->schib_region = g_malloc(info->size);
        g_free(info);
    }

    ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW,
                                   VFIO_REGION_SUBTYPE_CCW_CRW, &info);

    if (!ret) {
        vcdev->crw_region_size = info->size;
        if (sizeof(*vcdev->crw_region) != vcdev->crw_region_size) {
            error_setg(errp, "vfio: Unexpected size of the CRW region");
            goto out_err;
        }
        vcdev->crw_region_offset = info->offset;
        vcdev->crw_region = g_malloc(info->size);
        g_free(info);
    }

    return;

out_err:
    g_free(vcdev->crw_region);
    g_free(vcdev->schib_region);
    g_free(vcdev->async_cmd_region);
    g_free(vcdev->io_region);
    g_free(info);
    return;
}

static void vfio_ccw_put_region(VFIOCCWDevice *vcdev)
{
    g_free(vcdev->crw_region);
    g_free(vcdev->schib_region);
    g_free(vcdev->async_cmd_region);
    g_free(vcdev->io_region);
}

static void vfio_ccw_put_device(VFIOCCWDevice *vcdev)
{
    g_free(vcdev->vdev.name);
    vfio_put_base_device(&vcdev->vdev);
}

static void vfio_ccw_get_device(VFIOGroup *group, VFIOCCWDevice *vcdev,
                                Error **errp)
{
    char *name = g_strdup_printf("%x.%x.%04x", vcdev->cdev.hostid.cssid,
                                 vcdev->cdev.hostid.ssid,
                                 vcdev->cdev.hostid.devid);
    VFIODevice *vbasedev;

    QLIST_FOREACH(vbasedev, &group->device_list, next) {
        if (strcmp(vbasedev->name, name) == 0) {
            error_setg(errp, "vfio: subchannel %s has already been attached",
                       name);
            goto out_err;
        }
    }

    /*
     * All vfio-ccw devices are believed to operate in a way compatible with
     * discarding of memory in RAM blocks, ie. pages pinned in the host are
     * in the current working set of the guest driver and therefore never
     * overlap e.g., with pages available to the guest balloon driver.  This
     * needs to be set before vfio_get_device() for vfio common to handle
     * ram_block_discard_disable().
     */
    vcdev->vdev.ram_block_discard_allowed = true;

    if (vfio_get_device(group, vcdev->cdev.mdevid, &vcdev->vdev, errp)) {
        goto out_err;
    }

    vcdev->vdev.ops = &vfio_ccw_ops;
    vcdev->vdev.type = VFIO_DEVICE_TYPE_CCW;
    vcdev->vdev.name = name;
    vcdev->vdev.dev = &vcdev->cdev.parent_obj.parent_obj;

    return;

out_err:
    g_free(name);
}

static VFIOGroup *vfio_ccw_get_group(S390CCWDevice *cdev, Error **errp)
{
    char *tmp, group_path[PATH_MAX];
    ssize_t len;
    int groupid;

    tmp = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x/%s/iommu_group",
                          cdev->hostid.cssid, cdev->hostid.ssid,
                          cdev->hostid.devid, cdev->mdevid);
    len = readlink(tmp, group_path, sizeof(group_path));
    g_free(tmp);

    if (len <= 0 || len >= sizeof(group_path)) {
        error_setg(errp, "vfio: no iommu_group found");
        return NULL;
    }

    group_path[len] = 0;

    if (sscanf(basename(group_path), "%d", &groupid) != 1) {
        error_setg(errp, "vfio: failed to read %s", group_path);
        return NULL;
    }

    return vfio_get_group(groupid, &address_space_memory, errp);
}

static void vfio_ccw_realize(DeviceState *dev, Error **errp)
{
    VFIOGroup *group;
    CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
    S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
    VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
    S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
    Error *err = NULL;

    /* Call the class init function for subchannel. */
    if (cdc->realize) {
        cdc->realize(cdev, vcdev->vdev.sysfsdev, &err);
        if (err) {
            goto out_err_propagate;
        }
    }

    group = vfio_ccw_get_group(cdev, &err);
    if (!group) {
        goto out_group_err;
    }

    vfio_ccw_get_device(group, vcdev, &err);
    if (err) {
        goto out_device_err;
    }

    vfio_ccw_get_region(vcdev, &err);
    if (err) {
        goto out_region_err;
    }

    vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, &err);
    if (err) {
        goto out_io_notifier_err;
    }

    if (vcdev->crw_region) {
        vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX, &err);
        if (err) {
            goto out_irq_notifier_err;
        }
    }

    vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX, &err);
    if (err) {
        /*
         * Report this error, but do not make it a failing condition.
         * Lack of this IRQ in the host does not prevent normal operation.
         */
        error_report_err(err);
    }

    return;

out_irq_notifier_err:
    vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX);
    vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX);
    vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX);
out_io_notifier_err:
    vfio_ccw_put_region(vcdev);
out_region_err:
    vfio_ccw_put_device(vcdev);
out_device_err:
    vfio_put_group(group);
out_group_err:
    if (cdc->unrealize) {
        cdc->unrealize(cdev);
    }
out_err_propagate:
    error_propagate(errp, err);
}

static void vfio_ccw_unrealize(DeviceState *dev)
{
    CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
    S390CCWDevice *cdev = DO_UPCAST(S390CCWDevice, parent_obj, ccw_dev);
    VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
    S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
    VFIOGroup *group = vcdev->vdev.group;

    vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX);
    vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX);
    vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX);
    vfio_ccw_put_region(vcdev);
    vfio_ccw_put_device(vcdev);
    vfio_put_group(group);

    if (cdc->unrealize) {
        cdc->unrealize(cdev);
    }
}

static Property vfio_ccw_properties[] = {
    DEFINE_PROP_STRING("sysfsdev", VFIOCCWDevice, vdev.sysfsdev),
    DEFINE_PROP_BOOL("force-orb-pfch", VFIOCCWDevice, force_orb_pfch, false),
    DEFINE_PROP_END_OF_LIST(),
};

static const VMStateDescription vfio_ccw_vmstate = {
    .name = "vfio-ccw",
    .unmigratable = 1,
};

static void vfio_ccw_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    S390CCWDeviceClass *cdc = S390_CCW_DEVICE_CLASS(klass);

    device_class_set_props(dc, vfio_ccw_properties);
    dc->vmsd = &vfio_ccw_vmstate;
    dc->desc = "VFIO-based subchannel assignment";
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
    dc->realize = vfio_ccw_realize;
    dc->unrealize = vfio_ccw_unrealize;
    dc->reset = vfio_ccw_reset;

    cdc->handle_request = vfio_ccw_handle_request;
    cdc->handle_halt = vfio_ccw_handle_halt;
    cdc->handle_clear = vfio_ccw_handle_clear;
    cdc->handle_store = vfio_ccw_handle_store;
}

static const TypeInfo vfio_ccw_info = {
    .name = TYPE_VFIO_CCW,
    .parent = TYPE_S390_CCW,
    .instance_size = sizeof(VFIOCCWDevice),
    .class_init = vfio_ccw_class_init,
};

static void register_vfio_ccw_type(void)
{
    type_register_static(&vfio_ccw_info);
}

type_init(register_vfio_ccw_type)
