Commit b4c963fa authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20170421' into staging



The first batch of s390x changes for 2.10:
- the new compat machine
- several cleanups and optimizations
- introspection for css ids

# gpg: Signature made Fri 21 Apr 2017 08:36:25 BST
# gpg:                using RSA key 0xDECF6B93C6F02FAF
# gpg: Good signature from "Cornelia Huck <huckc@linux.vnet.ibm.com>"
# gpg:                 aka "Cornelia Huck <cornelia.huck@de.ibm.com>"
# Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0  18CE DECF 6B93 C6F0 2FAF

* remotes/cohuck/tags/s390x-20170421:
  s390x: Drop useless casts
  s390x: register I/O adapters per ISC during init
  s390x/flic: cache flic in s390_get_flic
  s390x: initialize flic before I/O subsystems
  s390x: use enum for adapter type and standardize its naming
  s390x/css: consolidate the devno property for ccw devices
  s390x/css: provide introspection for virtual subchannel and device busid
  s390x/css: introduce read-only property type for device ids
  s390x/pci: make printf always compile in debug output
  s390x/kvm: make printf always compile in debug output
  s390x: introduce 2.10 compat machine

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents bfec359a cb55c19a
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -21,11 +21,14 @@

S390FLICState *s390_get_flic(void)
{
    S390FLICState *fs;
    static S390FLICState *fs;

    if (!fs) {
        fs = S390_FLIC_COMMON(object_resolve_path(TYPE_KVM_S390_FLIC, NULL));
        if (!fs) {
        fs = S390_FLIC_COMMON(object_resolve_path(TYPE_QEMU_S390_FLIC, NULL));
            fs = S390_FLIC_COMMON(object_resolve_path(TYPE_QEMU_S390_FLIC,
                                                      NULL));
        }
    }
    return fs;
}
+40 −0
Original line number Diff line number Diff line
@@ -11,11 +11,51 @@
#include "qemu/osdep.h"
#include "ccw-device.h"

static void ccw_device_refill_ids(CcwDevice *dev)
{
    SubchDev *sch = dev->sch;

    assert(sch);

    dev->dev_id.cssid = sch->cssid;
    dev->dev_id.ssid = sch->ssid;
    dev->dev_id.devid = sch->devno;
    dev->dev_id.valid = true;

    dev->subch_id.cssid = sch->cssid;
    dev->subch_id.ssid = sch->ssid;
    dev->subch_id.devid = sch->schid;
    dev->subch_id.valid = true;
}

static void ccw_device_realize(CcwDevice *dev, Error **errp)
{
    ccw_device_refill_ids(dev);
}

static Property ccw_device_properties[] = {
    DEFINE_PROP_CSS_DEV_ID("devno", CcwDevice, devno),
    DEFINE_PROP_CSS_DEV_ID_RO("dev_id", CcwDevice, dev_id),
    DEFINE_PROP_CSS_DEV_ID_RO("subch_id", CcwDevice, subch_id),
    DEFINE_PROP_END_OF_LIST(),
};

static void ccw_device_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    CCWDeviceClass *k = CCW_DEVICE_CLASS(klass);

    k->realize = ccw_device_realize;
    k->refill_ids = ccw_device_refill_ids;
    dc->props = ccw_device_properties;
}

static const TypeInfo ccw_device_info = {
    .name = TYPE_CCW_DEVICE,
    .parent = TYPE_DEVICE,
    .instance_size = sizeof(CcwDevice),
    .class_size = sizeof(CCWDeviceClass),
    .class_init = ccw_device_class_init,
    .abstract = true,
};

+8 −1
Original line number Diff line number Diff line
@@ -19,12 +19,19 @@ typedef struct CcwDevice {
    DeviceState parent_obj;
    SubchDev *sch;
    /* <cssid>.<ssid>.<device number> */
    CssDevId bus_id;
    /* The user-set busid of the virtual ccw device. */
    CssDevId devno;
    /* The actual busid of the virtual ccw device. */
    CssDevId dev_id;
    /* The actual busid of the virtual subchannel. */
    CssDevId subch_id;
} CcwDevice;

typedef struct CCWDeviceClass {
    DeviceClass parent_class;
    void (*unplug)(HotplugHandler *, DeviceState *, Error **);
    void (*realize)(CcwDevice *, Error **);
    void (*refill_ids)(CcwDevice *);
} CCWDeviceClass;

static inline CcwDevice *to_ccw_dev_fast(DeviceState *d)
+3 −0
Original line number Diff line number Diff line
@@ -107,6 +107,9 @@ VirtualCssBus *virtual_css_bus_init(void)
    /* Enable hotplugging */
    qbus_set_hotplug_handler(bus, dev, &error_abort);

    css_register_io_adapters(CSS_IO_ADAPTER_VIRTIO, true, false,
                             &error_abort);

    return cbus;
 }

+60 −32
Original line number Diff line number Diff line
@@ -47,7 +47,6 @@ typedef struct IoAdapter {
    uint32_t id;
    uint8_t type;
    uint8_t isc;
    QTAILQ_ENTRY(IoAdapter) sibling;
} IoAdapter;

typedef struct ChannelSubSys {
@@ -61,7 +60,7 @@ typedef struct ChannelSubSys {
    uint64_t chnmon_area;
    CssImage *css[MAX_CSSID + 1];
    uint8_t default_cssid;
    QTAILQ_HEAD(, IoAdapter) io_adapters;
    IoAdapter *io_adapters[CSS_IO_ADAPTER_TYPE_NUMS][MAX_ISC + 1];
    QTAILQ_HEAD(, IndAddr) indicator_addresses;
} ChannelSubSys;

@@ -72,7 +71,6 @@ static ChannelSubSys channel_subsys = {
    .do_crw_mchk = true,
    .crws_lost = false,
    .chnmon_active = false,
    .io_adapters = QTAILQ_HEAD_INITIALIZER(channel_subsys.io_adapters),
    .indicator_addresses =
        QTAILQ_HEAD_INITIALIZER(channel_subsys.indicator_addresses),
};
@@ -155,44 +153,67 @@ int css_create_css_image(uint8_t cssid, bool default_image)
    return 0;
}

int css_register_io_adapter(uint8_t type, uint8_t isc, bool swap,
                            bool maskable, uint32_t *id)
uint32_t css_get_adapter_id(CssIoAdapterType type, uint8_t isc)
{
    if (type >= CSS_IO_ADAPTER_TYPE_NUMS || isc > MAX_ISC ||
        !channel_subsys.io_adapters[type][isc]) {
        return -1;
    }

    return channel_subsys.io_adapters[type][isc]->id;
}

/**
 * css_register_io_adapters: Register I/O adapters per ISC during init
 *
 * @swap: an indication if byte swap is needed.
 * @maskable: an indication if the adapter is subject to the mask operation.
 * @errp: location to store error information.
 */
void css_register_io_adapters(CssIoAdapterType type, bool swap, bool maskable,
                              Error **errp)
{
    uint32_t id;
    int ret, isc;
    IoAdapter *adapter;
    bool found = false;
    int ret;
    S390FLICState *fs = s390_get_flic();
    S390FLICStateClass *fsc = S390_FLIC_COMMON_GET_CLASS(fs);

    *id = 0;
    QTAILQ_FOREACH(adapter, &channel_subsys.io_adapters, sibling) {
        if ((adapter->type == type) && (adapter->isc == isc)) {
            *id = adapter->id;
            found = true;
            ret = 0;
            break;
        }
        if (adapter->id >= *id) {
            *id = adapter->id + 1;
        }
    }
    if (found) {
        goto out;
    /*
     * Disallow multiple registrations for the same device type.
     * Report an error if registering for an already registered type.
     */
    if (channel_subsys.io_adapters[type][0]) {
        error_setg(errp, "Adapters for type %d already registered", type);
    }
    adapter = g_new0(IoAdapter, 1);
    ret = fsc->register_io_adapter(fs, *id, isc, swap, maskable);

    for (isc = 0; isc <= MAX_ISC; isc++) {
        id = (type << 3) | isc;
        ret = fsc->register_io_adapter(fs, id, isc, swap, maskable);
        if (ret == 0) {
        adapter->id = *id;
            adapter = g_new0(IoAdapter, 1);
            adapter->id = id;
            adapter->isc = isc;
            adapter->type = type;
        QTAILQ_INSERT_TAIL(&channel_subsys.io_adapters, adapter, sibling);
            channel_subsys.io_adapters[type][isc] = adapter;
        } else {
        g_free(adapter);
        fprintf(stderr, "Unexpected error %d when registering adapter %d\n",
                ret, *id);
            error_setg_errno(errp, -ret, "Unexpected error %d when "
                             "registering adapter %d", ret, id);
            break;
        }
    }

    /*
     * No need to free registered adapters in kvm: kvm will clean up
     * when the machine goes away.
     */
    if (ret) {
        for (isc--; isc >= 0; isc--) {
            g_free(channel_subsys.io_adapters[type][isc]);
            channel_subsys.io_adapters[type][isc] = NULL;
        }
out:
    return ret;
    }

}

static void css_clear_io_interrupt(uint16_t subchannel_id,
@@ -1894,6 +1915,13 @@ PropertyInfo css_devid_propinfo = {
    .set = set_css_devid,
};

PropertyInfo css_devid_ro_propinfo = {
    .name = "str",
    .description = "Read-only identifier of an I/O device in the channel "
                   "subsystem, example: fe.1.23ab",
    .get = get_css_devid,
};

SubchDev *css_create_virtual_sch(CssDevId bus_id, Error **errp)
{
    uint16_t schid = 0;
Loading