cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

virtio-ccw.c (41402B)


      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)