qemu/hw/s390x/virtio-ccw.c
<<
>>
Prefs
   1/*
   2 * virtio ccw target implementation
   3 *
   4 * Copyright 2012,2015 IBM Corp.
   5 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
   6 *            Pierre Morel <pmorel@linux.vnet.ibm.com>
   7 *
   8 * This work is licensed under the terms of the GNU GPL, version 2 or (at
   9 * your option) any later version. See the COPYING file in the top-level
  10 * directory.
  11 */
  12
  13#include "qemu/osdep.h"
  14#include "qapi/error.h"
  15#include "sysemu/kvm.h"
  16#include "net/net.h"
  17#include "hw/virtio/virtio.h"
  18#include "migration/qemu-file-types.h"
  19#include "hw/virtio/virtio-net.h"
  20#include "qemu/bitops.h"
  21#include "qemu/error-report.h"
  22#include "qemu/module.h"
  23#include "hw/virtio/virtio-access.h"
  24#include "hw/virtio/virtio-bus.h"
  25#include "hw/s390x/adapter.h"
  26#include "hw/s390x/s390_flic.h"
  27
  28#include "hw/s390x/ioinst.h"
  29#include "hw/s390x/css.h"
  30#include "virtio-ccw.h"
  31#include "trace.h"
  32#include "hw/s390x/css-bridge.h"
  33#include "hw/s390x/s390-virtio-ccw.h"
  34#include "sysemu/replay.h"
  35
  36#define NR_CLASSIC_INDICATOR_BITS 64
  37
  38bool have_virtio_ccw = true;
  39
  40static int virtio_ccw_dev_post_load(void *opaque, int version_id)
  41{
  42    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(opaque);
  43    CcwDevice *ccw_dev = CCW_DEVICE(dev);
  44    CCWDeviceClass *ck = CCW_DEVICE_GET_CLASS(ccw_dev);
  45
  46    ccw_dev->sch->driver_data = dev;
  47    if (ccw_dev->sch->thinint_active) {
  48        dev->routes.adapter.adapter_id = css_get_adapter_id(
  49                                         CSS_IO_ADAPTER_VIRTIO,
  50                                         dev->thinint_isc);
  51    }
  52    /* Re-fill subch_id after loading the subchannel states.*/
  53    if (ck->refill_ids) {
  54        ck->refill_ids(ccw_dev);
  55    }
  56    return 0;
  57}
  58
  59typedef struct VirtioCcwDeviceTmp {
  60    VirtioCcwDevice *parent;
  61    uint16_t config_vector;
  62} VirtioCcwDeviceTmp;
  63
  64static int virtio_ccw_dev_tmp_pre_save(void *opaque)
  65{
  66    VirtioCcwDeviceTmp *tmp = opaque;
  67    VirtioCcwDevice *dev = tmp->parent;
  68    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
  69
  70    tmp->config_vector = vdev->config_vector;
  71
  72    return 0;
  73}
  74
  75static int virtio_ccw_dev_tmp_post_load(void *opaque, int version_id)
  76{
  77    VirtioCcwDeviceTmp *tmp = opaque;
  78    VirtioCcwDevice *dev = tmp->parent;
  79    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
  80
  81    vdev->config_vector = tmp->config_vector;
  82    return 0;
  83}
  84
  85const VMStateDescription vmstate_virtio_ccw_dev_tmp = {
  86    .name = "s390_virtio_ccw_dev_tmp",
  87    .pre_save = virtio_ccw_dev_tmp_pre_save,
  88    .post_load = virtio_ccw_dev_tmp_post_load,
  89    .fields = (VMStateField[]) {
  90        VMSTATE_UINT16(config_vector, VirtioCcwDeviceTmp),
  91        VMSTATE_END_OF_LIST()
  92    }
  93};
  94
  95const VMStateDescription vmstate_virtio_ccw_dev = {
  96    .name = "s390_virtio_ccw_dev",
  97    .version_id = 1,
  98    .minimum_version_id = 1,
  99    .post_load = virtio_ccw_dev_post_load,
 100    .fields = (VMStateField[]) {
 101        VMSTATE_CCW_DEVICE(parent_obj, VirtioCcwDevice),
 102        VMSTATE_PTR_TO_IND_ADDR(indicators, VirtioCcwDevice),
 103        VMSTATE_PTR_TO_IND_ADDR(indicators2, VirtioCcwDevice),
 104        VMSTATE_PTR_TO_IND_ADDR(summary_indicator, VirtioCcwDevice),
 105        /*
 106         * Ugly hack because VirtIODevice does not migrate itself.
 107         * This also makes legacy via vmstate_save_state possible.
 108         */
 109        VMSTATE_WITH_TMP(VirtioCcwDevice, VirtioCcwDeviceTmp,
 110                         vmstate_virtio_ccw_dev_tmp),
 111        VMSTATE_STRUCT(routes, VirtioCcwDevice, 1, vmstate_adapter_routes,
 112                       AdapterRoutes),
 113        VMSTATE_UINT8(thinint_isc, VirtioCcwDevice),
 114        VMSTATE_INT32(revision, VirtioCcwDevice),
 115        VMSTATE_END_OF_LIST()
 116    }
 117};
 118
 119static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size,
 120                               VirtioCcwDevice *dev);
 121
 122VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch)
 123{
 124    VirtIODevice *vdev = NULL;
 125    VirtioCcwDevice *dev = sch->driver_data;
 126
 127    if (dev) {
 128        vdev = virtio_bus_get_device(&dev->bus);
 129    }
 130    return vdev;
 131}
 132
 133static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev)
 134{
 135    virtio_bus_start_ioeventfd(&dev->bus);
 136}
 137
 138static void virtio_ccw_stop_ioeventfd(VirtioCcwDevice *dev)
 139{
 140    virtio_bus_stop_ioeventfd(&dev->bus);
 141}
 142
 143static bool virtio_ccw_ioeventfd_enabled(DeviceState *d)
 144{
 145    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
 146
 147    return (dev->flags & VIRTIO_CCW_FLAG_USE_IOEVENTFD) != 0;
 148}
 149
 150static int virtio_ccw_ioeventfd_assign(DeviceState *d, EventNotifier *notifier,
 151                                       int n, bool assign)
 152{
 153    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
 154    CcwDevice *ccw_dev = CCW_DEVICE(dev);
 155    SubchDev *sch = ccw_dev->sch;
 156    uint32_t sch_id = (css_build_subchannel_id(sch) << 16) | sch->schid;
 157
 158    return s390_assign_subch_ioeventfd(notifier, sch_id, n, assign);
 159}
 160
 161/* Communication blocks used by several channel commands. */
 162typedef struct VqInfoBlockLegacy {
 163    uint64_t queue;
 164    uint32_t align;
 165    uint16_t index;
 166    uint16_t num;
 167} QEMU_PACKED VqInfoBlockLegacy;
 168
 169typedef struct VqInfoBlock {
 170    uint64_t desc;
 171    uint32_t res0;
 172    uint16_t index;
 173    uint16_t num;
 174    uint64_t avail;
 175    uint64_t used;
 176} QEMU_PACKED VqInfoBlock;
 177
 178typedef struct VqConfigBlock {
 179    uint16_t index;
 180    uint16_t num_max;
 181} QEMU_PACKED VqConfigBlock;
 182
 183typedef struct VirtioFeatDesc {
 184    uint32_t features;
 185    uint8_t index;
 186} QEMU_PACKED VirtioFeatDesc;
 187
 188typedef struct VirtioThinintInfo {
 189    hwaddr summary_indicator;
 190    hwaddr device_indicator;
 191    uint64_t ind_bit;
 192    uint8_t isc;
 193} QEMU_PACKED VirtioThinintInfo;
 194
 195typedef struct VirtioRevInfo {
 196    uint16_t revision;
 197    uint16_t length;
 198    uint8_t data[];
 199} QEMU_PACKED VirtioRevInfo;
 200
 201/* Specify where the virtqueues for the subchannel are in guest memory. */
 202static int virtio_ccw_set_vqs(SubchDev *sch, VqInfoBlock *info,
 203                              VqInfoBlockLegacy *linfo)
 204{
 205    VirtIODevice *vdev = virtio_ccw_get_vdev(sch);
 206    uint16_t index = info ? info->index : linfo->index;
 207    uint16_t num = info ? info->num : linfo->num;
 208    uint64_t desc = info ? info->desc : linfo->queue;
 209
 210    if (index >= VIRTIO_QUEUE_MAX) {
 211        return -EINVAL;
 212    }
 213
 214    /* Current code in virtio.c relies on 4K alignment. */
 215    if (linfo && desc && (linfo->align != 4096)) {
 216        return -EINVAL;
 217    }
 218
 219    if (!vdev) {
 220        return -EINVAL;
 221    }
 222
 223    if (info) {
 224        virtio_queue_set_rings(vdev, index, desc, info->avail, info->used);
 225    } else {
 226        virtio_queue_set_addr(vdev, index, desc);
 227    }
 228    if (!desc) {
 229        virtio_queue_set_vector(vdev, index, VIRTIO_NO_VECTOR);
 230    } else {
 231        if (info) {
 232            /* virtio-1 allows changing the ring size. */
 233            if (virtio_queue_get_max_num(vdev, index) < num) {
 234                /* Fail if we exceed the maximum number. */
 235                return -EINVAL;
 236            }
 237            virtio_queue_set_num(vdev, index, num);
 238        } else if (virtio_queue_get_num(vdev, index) > num) {
 239            /* Fail if we don't have a big enough queue. */
 240            return -EINVAL;
 241        }
 242        /* We ignore possible increased num for legacy for compatibility. */
 243        virtio_queue_set_vector(vdev, index, index);
 244    }
 245    /* tell notify handler in case of config change */
 246    vdev->config_vector = VIRTIO_QUEUE_MAX;
 247    return 0;
 248}
 249
 250static void virtio_ccw_reset_virtio(VirtioCcwDevice *dev, VirtIODevice *vdev)
 251{
 252    CcwDevice *ccw_dev = CCW_DEVICE(dev);
 253
 254    virtio_ccw_stop_ioeventfd(dev);
 255    virtio_reset(vdev);
 256    if (dev->indicators) {
 257        release_indicator(&dev->routes.adapter, dev->indicators);
 258        dev->indicators = NULL;
 259    }
 260    if (dev->indicators2) {
 261        release_indicator(&dev->routes.adapter, dev->indicators2);
 262        dev->indicators2 = NULL;
 263    }
 264    if (dev->summary_indicator) {
 265        release_indicator(&dev->routes.adapter, dev->summary_indicator);
 266        dev->summary_indicator = NULL;
 267    }
 268    ccw_dev->sch->thinint_active = false;
 269}
 270
 271static int virtio_ccw_handle_set_vq(SubchDev *sch, CCW1 ccw, bool check_len,
 272                                    bool is_legacy)
 273{
 274    int ret;
 275    VqInfoBlock info;
 276    VqInfoBlockLegacy linfo;
 277    size_t info_len = is_legacy ? sizeof(linfo) : sizeof(info);
 278
 279    if (check_len) {
 280        if (ccw.count != info_len) {
 281            return -EINVAL;
 282        }
 283    } else if (ccw.count < info_len) {
 284        /* Can't execute command. */
 285        return -EINVAL;
 286    }
 287    if (!ccw.cda) {
 288        return -EFAULT;
 289    }
 290    if (is_legacy) {
 291        ret = ccw_dstream_read(&sch->cds, linfo);
 292        if (ret) {
 293            return ret;
 294        }
 295        linfo.queue = be64_to_cpu(linfo.queue);
 296        linfo.align = be32_to_cpu(linfo.align);
 297        linfo.index = be16_to_cpu(linfo.index);
 298        linfo.num = be16_to_cpu(linfo.num);
 299        ret = virtio_ccw_set_vqs(sch, NULL, &linfo);
 300    } else {
 301        ret = ccw_dstream_read(&sch->cds, info);
 302        if (ret) {
 303            return ret;
 304        }
 305        info.desc = be64_to_cpu(info.desc);
 306        info.index = be16_to_cpu(info.index);
 307        info.num = be16_to_cpu(info.num);
 308        info.avail = be64_to_cpu(info.avail);
 309        info.used = be64_to_cpu(info.used);
 310        ret = virtio_ccw_set_vqs(sch, &info, NULL);
 311    }
 312    sch->curr_status.scsw.count = 0;
 313    return ret;
 314}
 315
 316static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
 317{
 318    int ret;
 319    VirtioRevInfo revinfo;
 320    uint8_t status;
 321    VirtioFeatDesc features;
 322    hwaddr indicators;
 323    VqConfigBlock vq_config;
 324    VirtioCcwDevice *dev = sch->driver_data;
 325    VirtIODevice *vdev = virtio_ccw_get_vdev(sch);
 326    bool check_len;
 327    int len;
 328    VirtioThinintInfo thinint;
 329
 330    if (!dev) {
 331        return -EINVAL;
 332    }
 333
 334    trace_virtio_ccw_interpret_ccw(sch->cssid, sch->ssid, sch->schid,
 335                                   ccw.cmd_code);
 336    check_len = !((ccw.flags & CCW_FLAG_SLI) && !(ccw.flags & CCW_FLAG_DC));
 337
 338    if (dev->revision < 0 && ccw.cmd_code != CCW_CMD_SET_VIRTIO_REV) {
 339        if (dev->force_revision_1) {
 340            /*
 341             * virtio-1 drivers must start with negotiating to a revision >= 1,
 342             * so post a command reject for all other commands
 343             */
 344            return -ENOSYS;
 345        } else {
 346            /*
 347             * If the driver issues any command that is not SET_VIRTIO_REV,
 348             * we'll have to operate the device in legacy mode.
 349             */
 350            dev->revision = 0;
 351        }
 352    }
 353
 354    /* Look at the command. */
 355    switch (ccw.cmd_code) {
 356    case CCW_CMD_SET_VQ:
 357        ret = virtio_ccw_handle_set_vq(sch, ccw, check_len, dev->revision < 1);
 358        break;
 359    case CCW_CMD_VDEV_RESET:
 360        virtio_ccw_reset_virtio(dev, vdev);
 361        ret = 0;
 362        break;
 363    case CCW_CMD_READ_FEAT:
 364        if (check_len) {
 365            if (ccw.count != sizeof(features)) {
 366                ret = -EINVAL;
 367                break;
 368            }
 369        } else if (ccw.count < sizeof(features)) {
 370            /* Can't execute command. */
 371            ret = -EINVAL;
 372            break;
 373        }
 374        if (!ccw.cda) {
 375            ret = -EFAULT;
 376        } else {
 377            VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
 378
 379            ccw_dstream_advance(&sch->cds, sizeof(features.features));
 380            ret = ccw_dstream_read(&sch->cds, features.index);
 381            if (ret) {
 382                break;
 383            }
 384            if (features.index == 0) {
 385                if (dev->revision >= 1) {
 386                    /* Don't offer legacy features for modern devices. */
 387                    features.features = (uint32_t)
 388                        (vdev->host_features & ~vdc->legacy_features);
 389                } else {
 390                    features.features = (uint32_t)vdev->host_features;
 391                }
 392            } else if ((features.index == 1) && (dev->revision >= 1)) {
 393                /*
 394                 * Only offer feature bits beyond 31 if the guest has
 395                 * negotiated at least revision 1.
 396                 */
 397                features.features = (uint32_t)(vdev->host_features >> 32);
 398            } else {
 399                /* Return zeroes if the guest supports more feature bits. */
 400                features.features = 0;
 401            }
 402            ccw_dstream_rewind(&sch->cds);
 403            features.features = cpu_to_le32(features.features);
 404            ret = ccw_dstream_write(&sch->cds, features.features);
 405            if (!ret) {
 406                sch->curr_status.scsw.count = ccw.count - sizeof(features);
 407            }
 408        }
 409        break;
 410    case CCW_CMD_WRITE_FEAT:
 411        if (check_len) {
 412            if (ccw.count != sizeof(features)) {
 413                ret = -EINVAL;
 414                break;
 415            }
 416        } else if (ccw.count < sizeof(features)) {
 417            /* Can't execute command. */
 418            ret = -EINVAL;
 419            break;
 420        }
 421        if (!ccw.cda) {
 422            ret = -EFAULT;
 423        } else {
 424            ret = ccw_dstream_read(&sch->cds, features);
 425            if (ret) {
 426                break;
 427            }
 428            features.features = le32_to_cpu(features.features);
 429            if (features.index == 0) {
 430                virtio_set_features(vdev,
 431                                    (vdev->guest_features & 0xffffffff00000000ULL) |
 432                                    features.features);
 433            } else if ((features.index == 1) && (dev->revision >= 1)) {
 434                /*
 435                 * If the guest did not negotiate at least revision 1,
 436                 * we did not offer it any feature bits beyond 31. Such a
 437                 * guest passing us any bit here is therefore buggy.
 438                 */
 439                virtio_set_features(vdev,
 440                                    (vdev->guest_features & 0x00000000ffffffffULL) |
 441                                    ((uint64_t)features.features << 32));
 442            } else {
 443                /*
 444                 * If the guest supports more feature bits, assert that it
 445                 * passes us zeroes for those we don't support.
 446                 */
 447                if (features.features) {
 448                    qemu_log_mask(LOG_GUEST_ERROR,
 449                                  "Guest bug: features[%i]=%x (expected 0)",
 450                                  features.index, features.features);
 451                    /* XXX: do a unit check here? */
 452                }
 453            }
 454            sch->curr_status.scsw.count = ccw.count - sizeof(features);
 455            ret = 0;
 456        }
 457        break;
 458    case CCW_CMD_READ_CONF:
 459        if (check_len) {
 460            if (ccw.count > vdev->config_len) {
 461                ret = -EINVAL;
 462                break;
 463            }
 464        }
 465        len = MIN(ccw.count, vdev->config_len);
 466        if (!ccw.cda) {
 467            ret = -EFAULT;
 468        } else {
 469            virtio_bus_get_vdev_config(&dev->bus, vdev->config);
 470            ret = ccw_dstream_write_buf(&sch->cds, vdev->config, len);
 471            if (ret) {
 472                sch->curr_status.scsw.count = ccw.count - len;
 473            }
 474        }
 475        break;
 476    case CCW_CMD_WRITE_CONF:
 477        if (check_len) {
 478            if (ccw.count > vdev->config_len) {
 479                ret = -EINVAL;
 480                break;
 481            }
 482        }
 483        len = MIN(ccw.count, vdev->config_len);
 484        if (!ccw.cda) {
 485            ret = -EFAULT;
 486        } else {
 487            ret = ccw_dstream_read_buf(&sch->cds, vdev->config, len);
 488            if (!ret) {
 489                virtio_bus_set_vdev_config(&dev->bus, vdev->config);
 490                sch->curr_status.scsw.count = ccw.count - len;
 491            }
 492        }
 493        break;
 494    case CCW_CMD_READ_STATUS:
 495        if (check_len) {
 496            if (ccw.count != sizeof(status)) {
 497                ret = -EINVAL;
 498                break;
 499            }
 500        } else if (ccw.count < sizeof(status)) {
 501            /* Can't execute command. */
 502            ret = -EINVAL;
 503            break;
 504        }
 505        if (!ccw.cda) {
 506            ret = -EFAULT;
 507        } else {
 508            address_space_stb(&address_space_memory, ccw.cda, vdev->status,
 509                                        MEMTXATTRS_UNSPECIFIED, NULL);
 510            sch->curr_status.scsw.count = ccw.count - sizeof(vdev->status);
 511            ret = 0;
 512        }
 513        break;
 514    case CCW_CMD_WRITE_STATUS:
 515        if (check_len) {
 516            if (ccw.count != sizeof(status)) {
 517                ret = -EINVAL;
 518                break;
 519            }
 520        } else if (ccw.count < sizeof(status)) {
 521            /* Can't execute command. */
 522            ret = -EINVAL;
 523            break;
 524        }
 525        if (!ccw.cda) {
 526            ret = -EFAULT;
 527        } else {
 528            ret = ccw_dstream_read(&sch->cds, status);
 529            if (ret) {
 530                break;
 531            }
 532            if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
 533                virtio_ccw_stop_ioeventfd(dev);
 534            }
 535            if (virtio_set_status(vdev, status) == 0) {
 536                if (vdev->status == 0) {
 537                    virtio_ccw_reset_virtio(dev, vdev);
 538                }
 539                if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
 540                    virtio_ccw_start_ioeventfd(dev);
 541                }
 542                sch->curr_status.scsw.count = ccw.count - sizeof(status);
 543                ret = 0;
 544            } else {
 545                /* Trigger a command reject. */
 546                ret = -ENOSYS;
 547            }
 548        }
 549        break;
 550    case CCW_CMD_SET_IND:
 551        if (check_len) {
 552            if (ccw.count != sizeof(indicators)) {
 553                ret = -EINVAL;
 554                break;
 555            }
 556        } else if (ccw.count < sizeof(indicators)) {
 557            /* Can't execute command. */
 558            ret = -EINVAL;
 559            break;
 560        }
 561        if (sch->thinint_active) {
 562            /* Trigger a command reject. */
 563            ret = -ENOSYS;
 564            break;
 565        }
 566        if (virtio_get_num_queues(vdev) > NR_CLASSIC_INDICATOR_BITS) {
 567            /* More queues than indicator bits --> trigger a reject */
 568            ret = -ENOSYS;
 569            break;
 570        }
 571        if (!ccw.cda) {
 572            ret = -EFAULT;
 573        } else {
 574            ret = ccw_dstream_read(&sch->cds, indicators);
 575            if (ret) {
 576                break;
 577            }
 578            indicators = be64_to_cpu(indicators);
 579            dev->indicators = get_indicator(indicators, sizeof(uint64_t));
 580            sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
 581            ret = 0;
 582        }
 583        break;
 584    case CCW_CMD_SET_CONF_IND:
 585        if (check_len) {
 586            if (ccw.count != sizeof(indicators)) {
 587                ret = -EINVAL;
 588                break;
 589            }
 590        } else if (ccw.count < sizeof(indicators)) {
 591            /* Can't execute command. */
 592            ret = -EINVAL;
 593            break;
 594        }
 595        if (!ccw.cda) {
 596            ret = -EFAULT;
 597        } else {
 598            ret = ccw_dstream_read(&sch->cds, indicators);
 599            if (ret) {
 600                break;
 601            }
 602            indicators = be64_to_cpu(indicators);
 603            dev->indicators2 = get_indicator(indicators, sizeof(uint64_t));
 604            sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
 605            ret = 0;
 606        }
 607        break;
 608    case CCW_CMD_READ_VQ_CONF:
 609        if (check_len) {
 610            if (ccw.count != sizeof(vq_config)) {
 611                ret = -EINVAL;
 612                break;
 613            }
 614        } else if (ccw.count < sizeof(vq_config)) {
 615            /* Can't execute command. */
 616            ret = -EINVAL;
 617            break;
 618        }
 619        if (!ccw.cda) {
 620            ret = -EFAULT;
 621        } else {
 622            ret = ccw_dstream_read(&sch->cds, vq_config.index);
 623            if (ret) {
 624                break;
 625            }
 626            vq_config.index = be16_to_cpu(vq_config.index);
 627            if (vq_config.index >= VIRTIO_QUEUE_MAX) {
 628                ret = -EINVAL;
 629                break;
 630            }
 631            vq_config.num_max = virtio_queue_get_num(vdev,
 632                                                     vq_config.index);
 633            vq_config.num_max = cpu_to_be16(vq_config.num_max);
 634            ret = ccw_dstream_write(&sch->cds, vq_config.num_max);
 635            if (!ret) {
 636                sch->curr_status.scsw.count = ccw.count - sizeof(vq_config);
 637            }
 638        }
 639        break;
 640    case CCW_CMD_SET_IND_ADAPTER:
 641        if (check_len) {
 642            if (ccw.count != sizeof(thinint)) {
 643                ret = -EINVAL;
 644                break;
 645            }
 646        } else if (ccw.count < sizeof(thinint)) {
 647            /* Can't execute command. */
 648            ret = -EINVAL;
 649            break;
 650        }
 651        if (!ccw.cda) {
 652            ret = -EFAULT;
 653        } else if (dev->indicators && !sch->thinint_active) {
 654            /* Trigger a command reject. */
 655            ret = -ENOSYS;
 656        } else {
 657            if (ccw_dstream_read(&sch->cds, thinint)) {
 658                ret = -EFAULT;
 659            } else {
 660                thinint.ind_bit = be64_to_cpu(thinint.ind_bit);
 661                thinint.summary_indicator =
 662                    be64_to_cpu(thinint.summary_indicator);
 663                thinint.device_indicator =
 664                    be64_to_cpu(thinint.device_indicator);
 665
 666                dev->summary_indicator =
 667                    get_indicator(thinint.summary_indicator, sizeof(uint8_t));
 668                dev->indicators =
 669                    get_indicator(thinint.device_indicator,
 670                                  thinint.ind_bit / 8 + 1);
 671                dev->thinint_isc = thinint.isc;
 672                dev->routes.adapter.ind_offset = thinint.ind_bit;
 673                dev->routes.adapter.summary_offset = 7;
 674                dev->routes.adapter.adapter_id = css_get_adapter_id(
 675                                                 CSS_IO_ADAPTER_VIRTIO,
 676                                                 dev->thinint_isc);
 677                sch->thinint_active = ((dev->indicators != NULL) &&
 678                                       (dev->summary_indicator != NULL));
 679                sch->curr_status.scsw.count = ccw.count - sizeof(thinint);
 680                ret = 0;
 681            }
 682        }
 683        break;
 684    case CCW_CMD_SET_VIRTIO_REV:
 685        len = sizeof(revinfo);
 686        if (ccw.count < len) {
 687            ret = -EINVAL;
 688            break;
 689        }
 690        if (!ccw.cda) {
 691            ret = -EFAULT;
 692            break;
 693        }
 694        ret = ccw_dstream_read_buf(&sch->cds, &revinfo, 4);
 695        if (ret < 0) {
 696            break;
 697        }
 698        revinfo.revision = be16_to_cpu(revinfo.revision);
 699        revinfo.length = be16_to_cpu(revinfo.length);
 700        if (ccw.count < len + revinfo.length ||
 701            (check_len && ccw.count > len + revinfo.length)) {
 702            ret = -EINVAL;
 703            break;
 704        }
 705        /*
 706         * Once we start to support revisions with additional data, we'll
 707         * need to fetch it here. Nothing to do for now, though.
 708         */
 709        if (dev->revision >= 0 ||
 710            revinfo.revision > virtio_ccw_rev_max(dev) ||
 711            (dev->force_revision_1 && !revinfo.revision)) {
 712            ret = -ENOSYS;
 713            break;
 714        }
 715        ret = 0;
 716        dev->revision = revinfo.revision;
 717        break;
 718    default:
 719        ret = -ENOSYS;
 720        break;
 721    }
 722    return ret;
 723}
 724
 725static void virtio_sch_disable_cb(SubchDev *sch)
 726{
 727    VirtioCcwDevice *dev = sch->driver_data;
 728
 729    dev->revision = -1;
 730}
 731
 732static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
 733{
 734    VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
 735    CcwDevice *ccw_dev = CCW_DEVICE(dev);
 736    CCWDeviceClass *ck = CCW_DEVICE_GET_CLASS(ccw_dev);
 737    SubchDev *sch;
 738    Error *err = NULL;
 739    int i;
 740
 741    sch = css_create_sch(ccw_dev->devno, errp);
 742    if (!sch) {
 743        return;
 744    }
 745    if (!virtio_ccw_rev_max(dev) && dev->force_revision_1) {
 746        error_setg(&err, "Invalid value of property max_rev "
 747                   "(is %d expected >= 1)", virtio_ccw_rev_max(dev));
 748        goto out_err;
 749    }
 750
 751    sch->driver_data = dev;
 752    sch->ccw_cb = virtio_ccw_cb;
 753    sch->disable_cb = virtio_sch_disable_cb;
 754    sch->id.reserved = 0xff;
 755    sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
 756    sch->do_subchannel_work = do_subchannel_work_virtual;
 757    sch->irb_cb = build_irb_virtual;
 758    ccw_dev->sch = sch;
 759    dev->indicators = NULL;
 760    dev->revision = -1;
 761    for (i = 0; i < ADAPTER_ROUTES_MAX_GSI; i++) {
 762        dev->routes.gsi[i] = -1;
 763    }
 764    css_sch_build_virtual_schib(sch, 0, VIRTIO_CCW_CHPID_TYPE);
 765
 766    trace_virtio_ccw_new_device(
 767        sch->cssid, sch->ssid, sch->schid, sch->devno,
 768        ccw_dev->devno.valid ? "user-configured" : "auto-configured");
 769
 770    if (kvm_enabled() && !kvm_eventfds_enabled()) {
 771        dev->flags &= ~VIRTIO_CCW_FLAG_USE_IOEVENTFD;
 772    }
 773
 774    /* fd-based ioevents can't be synchronized in record/replay */
 775    if (replay_mode != REPLAY_MODE_NONE) {
 776        dev->flags &= ~VIRTIO_CCW_FLAG_USE_IOEVENTFD;
 777    }
 778
 779    if (k->realize) {
 780        k->realize(dev, &err);
 781        if (err) {
 782            goto out_err;
 783        }
 784    }
 785
 786    ck->realize(ccw_dev, &err);
 787    if (err) {
 788        goto out_err;
 789    }
 790
 791    return;
 792
 793out_err:
 794    error_propagate(errp, err);
 795    css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
 796    ccw_dev->sch = NULL;
 797    g_free(sch);
 798}
 799
 800static void virtio_ccw_device_unrealize(VirtioCcwDevice *dev)
 801{
 802    VirtIOCCWDeviceClass *dc = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
 803    CcwDevice *ccw_dev = CCW_DEVICE(dev);
 804    SubchDev *sch = ccw_dev->sch;
 805
 806    if (dc->unrealize) {
 807        dc->unrealize(dev);
 808    }
 809
 810    if (sch) {
 811        css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
 812        g_free(sch);
 813        ccw_dev->sch = NULL;
 814    }
 815    if (dev->indicators) {
 816        release_indicator(&dev->routes.adapter, dev->indicators);
 817        dev->indicators = NULL;
 818    }
 819}
 820
 821/* DeviceState to VirtioCcwDevice. Note: used on datapath,
 822 * be careful and test performance if you change this.
 823 */
 824static inline VirtioCcwDevice *to_virtio_ccw_dev_fast(DeviceState *d)
 825{
 826    CcwDevice *ccw_dev = to_ccw_dev_fast(d);
 827
 828    return container_of(ccw_dev, VirtioCcwDevice, parent_obj);
 829}
 830
 831static uint8_t virtio_set_ind_atomic(SubchDev *sch, uint64_t ind_loc,
 832                                     uint8_t to_be_set)
 833{
 834    uint8_t expected, actual;
 835    hwaddr len = 1;
 836    /* avoid  multiple fetches */
 837    uint8_t volatile *ind_addr;
 838
 839    ind_addr = cpu_physical_memory_map(ind_loc, &len, true);
 840    if (!ind_addr) {
 841        error_report("%s(%x.%x.%04x): unable to access indicator",
 842                     __func__, sch->cssid, sch->ssid, sch->schid);
 843        return -1;
 844    }
 845    actual = *ind_addr;
 846    do {
 847        expected = actual;
 848        actual = qatomic_cmpxchg(ind_addr, expected, expected | to_be_set);
 849    } while (actual != expected);
 850    trace_virtio_ccw_set_ind(ind_loc, actual, actual | to_be_set);
 851    cpu_physical_memory_unmap((void *)ind_addr, len, 1, len);
 852
 853    return actual;
 854}
 855
 856static void virtio_ccw_notify(DeviceState *d, uint16_t vector)
 857{
 858    VirtioCcwDevice *dev = to_virtio_ccw_dev_fast(d);
 859    CcwDevice *ccw_dev = to_ccw_dev_fast(d);
 860    SubchDev *sch = ccw_dev->sch;
 861    uint64_t indicators;
 862
 863    if (vector == VIRTIO_NO_VECTOR) {
 864        return;
 865    }
 866    /*
 867     * vector < VIRTIO_QUEUE_MAX: notification for a virtqueue
 868     * vector == VIRTIO_QUEUE_MAX: configuration change notification
 869     * bits beyond that are unused and should never be notified for
 870     */
 871    assert(vector <= VIRTIO_QUEUE_MAX);
 872
 873    if (vector < VIRTIO_QUEUE_MAX) {
 874        if (!dev->indicators) {
 875            return;
 876        }
 877        if (sch->thinint_active) {
 878            /*
 879             * In the adapter interrupt case, indicators points to a
 880             * memory area that may be (way) larger than 64 bit and
 881             * ind_bit indicates the start of the indicators in a big
 882             * endian notation.
 883             */
 884            uint64_t ind_bit = dev->routes.adapter.ind_offset;
 885
 886            virtio_set_ind_atomic(sch, dev->indicators->addr +
 887                                  (ind_bit + vector) / 8,
 888                                  0x80 >> ((ind_bit + vector) % 8));
 889            if (!virtio_set_ind_atomic(sch, dev->summary_indicator->addr,
 890                                       0x01)) {
 891                css_adapter_interrupt(CSS_IO_ADAPTER_VIRTIO, dev->thinint_isc);
 892            }
 893        } else {
 894            assert(vector < NR_CLASSIC_INDICATOR_BITS);
 895            indicators = address_space_ldq(&address_space_memory,
 896                                           dev->indicators->addr,
 897                                           MEMTXATTRS_UNSPECIFIED,
 898                                           NULL);
 899            indicators |= 1ULL << vector;
 900            address_space_stq(&address_space_memory, dev->indicators->addr,
 901                              indicators, MEMTXATTRS_UNSPECIFIED, NULL);
 902            css_conditional_io_interrupt(sch);
 903        }
 904    } else {
 905        if (!dev->indicators2) {
 906            return;
 907        }
 908        indicators = address_space_ldq(&address_space_memory,
 909                                       dev->indicators2->addr,
 910                                       MEMTXATTRS_UNSPECIFIED,
 911                                       NULL);
 912        indicators |= 1ULL;
 913        address_space_stq(&address_space_memory, dev->indicators2->addr,
 914                          indicators, MEMTXATTRS_UNSPECIFIED, NULL);
 915        css_conditional_io_interrupt(sch);
 916    }
 917}
 918
 919static void virtio_ccw_reset(DeviceState *d)
 920{
 921    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
 922    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
 923    VirtIOCCWDeviceClass *vdc = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
 924
 925    virtio_ccw_reset_virtio(dev, vdev);
 926    if (vdc->parent_reset) {
 927        vdc->parent_reset(d);
 928    }
 929}
 930
 931static void virtio_ccw_vmstate_change(DeviceState *d, bool running)
 932{
 933    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
 934
 935    if (running) {
 936        virtio_ccw_start_ioeventfd(dev);
 937    } else {
 938        virtio_ccw_stop_ioeventfd(dev);
 939    }
 940}
 941
 942static bool virtio_ccw_query_guest_notifiers(DeviceState *d)
 943{
 944    CcwDevice *dev = CCW_DEVICE(d);
 945
 946    return !!(dev->sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ENA);
 947}
 948
 949static int virtio_ccw_get_mappings(VirtioCcwDevice *dev)
 950{
 951    int r;
 952    CcwDevice *ccw_dev = CCW_DEVICE(dev);
 953
 954    if (!ccw_dev->sch->thinint_active) {
 955        return -EINVAL;
 956    }
 957
 958    r = map_indicator(&dev->routes.adapter, dev->summary_indicator);
 959    if (r) {
 960        return r;
 961    }
 962    r = map_indicator(&dev->routes.adapter, dev->indicators);
 963    if (r) {
 964        return r;
 965    }
 966    dev->routes.adapter.summary_addr = dev->summary_indicator->map;
 967    dev->routes.adapter.ind_addr = dev->indicators->map;
 968
 969    return 0;
 970}
 971
 972static int virtio_ccw_setup_irqroutes(VirtioCcwDevice *dev, int nvqs)
 973{
 974    int i;
 975    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
 976    int ret;
 977    S390FLICState *fs = s390_get_flic();
 978    S390FLICStateClass *fsc = s390_get_flic_class(fs);
 979
 980    ret = virtio_ccw_get_mappings(dev);
 981    if (ret) {
 982        return ret;
 983    }
 984    for (i = 0; i < nvqs; i++) {
 985        if (!virtio_queue_get_num(vdev, i)) {
 986            break;
 987        }
 988    }
 989    dev->routes.num_routes = i;
 990    return fsc->add_adapter_routes(fs, &dev->routes);
 991}
 992
 993static void virtio_ccw_release_irqroutes(VirtioCcwDevice *dev, int nvqs)
 994{
 995    S390FLICState *fs = s390_get_flic();
 996    S390FLICStateClass *fsc = s390_get_flic_class(fs);
 997
 998    fsc->release_adapter_routes(fs, &dev->routes);
 999}
1000
1001static int virtio_ccw_add_irqfd(VirtioCcwDevice *dev, int n)
1002{
1003    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
1004    VirtQueue *vq = virtio_get_queue(vdev, n);
1005    EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
1006
1007    return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, notifier, NULL,
1008                                              dev->routes.gsi[n]);
1009}
1010
1011static void virtio_ccw_remove_irqfd(VirtioCcwDevice *dev, int n)
1012{
1013    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
1014    VirtQueue *vq = virtio_get_queue(vdev, n);
1015    EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
1016    int ret;
1017
1018    ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, notifier,
1019                                                dev->routes.gsi[n]);
1020    assert(ret == 0);
1021}
1022
1023static int virtio_ccw_set_guest_notifier(VirtioCcwDevice *dev, int n,
1024                                         bool assign, bool with_irqfd)
1025{
1026    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
1027    VirtQueue *vq = virtio_get_queue(vdev, n);
1028    EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
1029    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
1030
1031    if (assign) {
1032        int r = event_notifier_init(notifier, 0);
1033
1034        if (r < 0) {
1035            return r;
1036        }
1037        virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd);
1038        if (with_irqfd) {
1039            r = virtio_ccw_add_irqfd(dev, n);
1040            if (r) {
1041                virtio_queue_set_guest_notifier_fd_handler(vq, false,
1042                                                           with_irqfd);
1043                return r;
1044            }
1045        }
1046        /*
1047         * We do not support individual masking for channel devices, so we
1048         * need to manually trigger any guest masking callbacks here.
1049         */
1050        if (k->guest_notifier_mask && vdev->use_guest_notifier_mask) {
1051            k->guest_notifier_mask(vdev, n, false);
1052        }
1053        /* get lost events and re-inject */
1054        if (k->guest_notifier_pending &&
1055            k->guest_notifier_pending(vdev, n)) {
1056            event_notifier_set(notifier);
1057        }
1058    } else {
1059        if (k->guest_notifier_mask && vdev->use_guest_notifier_mask) {
1060            k->guest_notifier_mask(vdev, n, true);
1061        }
1062        if (with_irqfd) {
1063            virtio_ccw_remove_irqfd(dev, n);
1064        }
1065        virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd);
1066        event_notifier_cleanup(notifier);
1067    }
1068    return 0;
1069}
1070
1071static int virtio_ccw_set_guest_notifiers(DeviceState *d, int nvqs,
1072                                          bool assigned)
1073{
1074    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
1075    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
1076    CcwDevice *ccw_dev = CCW_DEVICE(d);
1077    bool with_irqfd = ccw_dev->sch->thinint_active && kvm_irqfds_enabled();
1078    int r, n;
1079
1080    if (with_irqfd && assigned) {
1081        /* irq routes need to be set up before assigning irqfds */
1082        r = virtio_ccw_setup_irqroutes(dev, nvqs);
1083        if (r < 0) {
1084            goto irqroute_error;
1085        }
1086    }
1087    for (n = 0; n < nvqs; n++) {
1088        if (!virtio_queue_get_num(vdev, n)) {
1089            break;
1090        }
1091        r = virtio_ccw_set_guest_notifier(dev, n, assigned, with_irqfd);
1092        if (r < 0) {
1093            goto assign_error;
1094        }
1095    }
1096    if (with_irqfd && !assigned) {
1097        /* release irq routes after irqfds have been released */
1098        virtio_ccw_release_irqroutes(dev, nvqs);
1099    }
1100    return 0;
1101
1102assign_error:
1103    while (--n >= 0) {
1104        virtio_ccw_set_guest_notifier(dev, n, !assigned, false);
1105    }
1106irqroute_error:
1107    if (with_irqfd && assigned) {
1108        virtio_ccw_release_irqroutes(dev, nvqs);
1109    }
1110    return r;
1111}
1112
1113static void virtio_ccw_save_queue(DeviceState *d, int n, QEMUFile *f)
1114{
1115    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
1116    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
1117
1118    qemu_put_be16(f, virtio_queue_vector(vdev, n));
1119}
1120
1121static int virtio_ccw_load_queue(DeviceState *d, int n, QEMUFile *f)
1122{
1123    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
1124    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
1125    uint16_t vector;
1126
1127    qemu_get_be16s(f, &vector);
1128    virtio_queue_set_vector(vdev, n , vector);
1129
1130    return 0;
1131}
1132
1133static void virtio_ccw_save_config(DeviceState *d, QEMUFile *f)
1134{
1135    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
1136    vmstate_save_state(f, &vmstate_virtio_ccw_dev, dev, NULL);
1137}
1138
1139static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f)
1140{
1141    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
1142    return vmstate_load_state(f, &vmstate_virtio_ccw_dev, dev, 1);
1143}
1144
1145static void virtio_ccw_pre_plugged(DeviceState *d, Error **errp)
1146{
1147   VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
1148   VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
1149
1150    if (dev->max_rev >= 1) {
1151        virtio_add_feature(&vdev->host_features, VIRTIO_F_VERSION_1);
1152    }
1153}
1154
1155/* This is called by virtio-bus just after the device is plugged. */
1156static void virtio_ccw_device_plugged(DeviceState *d, Error **errp)
1157{
1158    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
1159    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
1160    CcwDevice *ccw_dev = CCW_DEVICE(d);
1161    SubchDev *sch = ccw_dev->sch;
1162    int n = virtio_get_num_queues(vdev);
1163    S390FLICState *flic = s390_get_flic();
1164
1165    if (!virtio_has_feature(vdev->host_features, VIRTIO_F_VERSION_1)) {
1166        dev->max_rev = 0;
1167    }
1168
1169    if (!virtio_ccw_rev_max(dev) && !virtio_legacy_allowed(vdev)) {
1170        /*
1171         * To avoid migration issues, we allow legacy mode when legacy
1172         * check is disabled in the old machine types (< 5.1).
1173         */
1174        if (virtio_legacy_check_disabled(vdev)) {
1175            warn_report("device requires revision >= 1, but for backward "
1176                        "compatibility max_revision=0 is allowed");
1177        } else {
1178            error_setg(errp, "Invalid value of property max_rev "
1179                       "(is %d expected >= 1)", virtio_ccw_rev_max(dev));
1180            return;
1181        }
1182    }
1183
1184    if (virtio_get_num_queues(vdev) > VIRTIO_QUEUE_MAX) {
1185        error_setg(errp, "The number of virtqueues %d "
1186                   "exceeds virtio limit %d", n,
1187                   VIRTIO_QUEUE_MAX);
1188        return;
1189    }
1190    if (virtio_get_num_queues(vdev) > flic->adapter_routes_max_batch) {
1191        error_setg(errp, "The number of virtqueues %d "
1192                   "exceeds flic adapter route limit %d", n,
1193                   flic->adapter_routes_max_batch);
1194        return;
1195    }
1196
1197    sch->id.cu_model = virtio_bus_get_vdev_id(&dev->bus);
1198
1199
1200    css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
1201                          d->hotplugged, 1);
1202}
1203
1204static void virtio_ccw_device_unplugged(DeviceState *d)
1205{
1206    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
1207
1208    virtio_ccw_stop_ioeventfd(dev);
1209}
1210/**************** Virtio-ccw Bus Device Descriptions *******************/
1211
1212static void virtio_ccw_busdev_realize(DeviceState *dev, Error **errp)
1213{
1214    VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
1215
1216    virtio_ccw_bus_new(&_dev->bus, sizeof(_dev->bus), _dev);
1217    virtio_ccw_device_realize(_dev, errp);
1218}
1219
1220static void virtio_ccw_busdev_unrealize(DeviceState *dev)
1221{
1222    VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
1223
1224    virtio_ccw_device_unrealize(_dev);
1225}
1226
1227static void virtio_ccw_busdev_unplug(HotplugHandler *hotplug_dev,
1228                                     DeviceState *dev, Error **errp)
1229{
1230    VirtioCcwDevice *_dev = to_virtio_ccw_dev_fast(dev);
1231
1232    virtio_ccw_stop_ioeventfd(_dev);
1233}
1234
1235static void virtio_ccw_device_class_init(ObjectClass *klass, void *data)
1236{
1237    DeviceClass *dc = DEVICE_CLASS(klass);
1238    CCWDeviceClass *k = CCW_DEVICE_CLASS(dc);
1239    VirtIOCCWDeviceClass *vdc = VIRTIO_CCW_DEVICE_CLASS(klass);
1240
1241    k->unplug = virtio_ccw_busdev_unplug;
1242    dc->realize = virtio_ccw_busdev_realize;
1243    dc->unrealize = virtio_ccw_busdev_unrealize;
1244    device_class_set_parent_reset(dc, virtio_ccw_reset, &vdc->parent_reset);
1245}
1246
1247static const TypeInfo virtio_ccw_device_info = {
1248    .name = TYPE_VIRTIO_CCW_DEVICE,
1249    .parent = TYPE_CCW_DEVICE,
1250    .instance_size = sizeof(VirtioCcwDevice),
1251    .class_init = virtio_ccw_device_class_init,
1252    .class_size = sizeof(VirtIOCCWDeviceClass),
1253    .abstract = true,
1254};
1255
1256/* virtio-ccw-bus */
1257
1258static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size,
1259                               VirtioCcwDevice *dev)
1260{
1261    DeviceState *qdev = DEVICE(dev);
1262    char virtio_bus_name[] = "virtio-bus";
1263
1264    qbus_init(bus, bus_size, TYPE_VIRTIO_CCW_BUS, qdev, virtio_bus_name);
1265}
1266
1267static void virtio_ccw_bus_class_init(ObjectClass *klass, void *data)
1268{
1269    VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
1270    BusClass *bus_class = BUS_CLASS(klass);
1271
1272    bus_class->max_dev = 1;
1273    k->notify = virtio_ccw_notify;
1274    k->vmstate_change = virtio_ccw_vmstate_change;
1275    k->query_guest_notifiers = virtio_ccw_query_guest_notifiers;
1276    k->set_guest_notifiers = virtio_ccw_set_guest_notifiers;
1277    k->save_queue = virtio_ccw_save_queue;
1278    k->load_queue = virtio_ccw_load_queue;
1279    k->save_config = virtio_ccw_save_config;
1280    k->load_config = virtio_ccw_load_config;
1281    k->pre_plugged = virtio_ccw_pre_plugged;
1282    k->device_plugged = virtio_ccw_device_plugged;
1283    k->device_unplugged = virtio_ccw_device_unplugged;
1284    k->ioeventfd_enabled = virtio_ccw_ioeventfd_enabled;
1285    k->ioeventfd_assign = virtio_ccw_ioeventfd_assign;
1286}
1287
1288static const TypeInfo virtio_ccw_bus_info = {
1289    .name = TYPE_VIRTIO_CCW_BUS,
1290    .parent = TYPE_VIRTIO_BUS,
1291    .instance_size = sizeof(VirtioCcwBusState),
1292    .class_size = sizeof(VirtioCcwBusClass),
1293    .class_init = virtio_ccw_bus_class_init,
1294};
1295
1296static void virtio_ccw_register(void)
1297{
1298    type_register_static(&virtio_ccw_bus_info);
1299    type_register_static(&virtio_ccw_device_info);
1300}
1301
1302type_init(virtio_ccw_register)
1303