From fa8b0ca5d1b69975b715a259d3586cadf7a5280f Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Tue, 23 Jun 2015 15:46:31 +0200 Subject: virtio-ccw: complete handling of guest-initiated resets For a guest-initiated reset, we need to not only reset the virtio device, but also reset the VirtioCcwDevice into a clean state. This includes resetting the indicators, or else a guest will not be able to e.g. switch from classic interrupts to adapter interrupts. Split off this routine into a new function virtio_ccw_reset_virtio() to make the distinction between resetting the virtio-related devices and the base subchannel device clear. CC: qemu-stable@nongnu.org Signed-off-by: Cornelia Huck Reviewed-by: Christian Borntraeger --- hw/s390x/virtio-ccw.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) (limited to 'hw') diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 9605bf40b9..2c817719d6 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -296,6 +296,25 @@ static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align, return 0; } +static void virtio_ccw_reset_virtio(VirtioCcwDevice *dev, VirtIODevice *vdev) +{ + virtio_ccw_stop_ioeventfd(dev); + virtio_reset(vdev); + if (dev->indicators) { + release_indicator(&dev->routes.adapter, dev->indicators); + dev->indicators = NULL; + } + if (dev->indicators2) { + release_indicator(&dev->routes.adapter, dev->indicators2); + dev->indicators2 = NULL; + } + if (dev->summary_indicator) { + release_indicator(&dev->routes.adapter, dev->summary_indicator); + dev->summary_indicator = NULL; + } + dev->sch->thinint_active = false; +} + static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) { int ret; @@ -359,8 +378,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) } break; case CCW_CMD_VDEV_RESET: - virtio_ccw_stop_ioeventfd(dev); - virtio_reset(vdev); + virtio_ccw_reset_virtio(dev, vdev); ret = 0; break; case CCW_CMD_READ_FEAT: @@ -500,7 +518,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) } if (virtio_set_status(vdev, status) == 0) { if (vdev->status == 0) { - virtio_reset(vdev); + virtio_ccw_reset_virtio(dev, vdev); } if (status & VIRTIO_CONFIG_S_DRIVER_OK) { virtio_ccw_start_ioeventfd(dev); @@ -1081,21 +1099,8 @@ static void virtio_ccw_reset(DeviceState *d) VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d); VirtIODevice *vdev = virtio_bus_get_device(&dev->bus); - virtio_ccw_stop_ioeventfd(dev); - virtio_reset(vdev); + virtio_ccw_reset_virtio(dev, vdev); css_reset_sch(dev->sch); - if (dev->indicators) { - release_indicator(&dev->routes.adapter, dev->indicators); - dev->indicators = NULL; - } - if (dev->indicators2) { - release_indicator(&dev->routes.adapter, dev->indicators2); - dev->indicators2 = NULL; - } - if (dev->summary_indicator) { - release_indicator(&dev->routes.adapter, dev->summary_indicator); - dev->summary_indicator = NULL; - } } static void virtio_ccw_vmstate_change(DeviceState *d, bool running) -- cgit v1.2.3 From ec7353a146bb39c3bb3e5ccc50ca585aed97b7cf Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Wed, 24 Jun 2015 10:57:23 +0200 Subject: css: mss/mcss-e vs. migration Our main channel_subsys structure is not a device (yet), but we need to setup mss/mcss-e again if the guest had enabled it before. Use a hack that should catch most configurations (assuming that the guest will have enabled at least one device in higher subchannel sets or channel subsystems if it enabled the functionality.) Signed-off-by: Cornelia Huck --- hw/s390x/css.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'hw') diff --git a/hw/s390x/css.c b/hw/s390x/css.c index 5561d807dc..a9cf3d7f97 100644 --- a/hw/s390x/css.c +++ b/hw/s390x/css.c @@ -1464,6 +1464,21 @@ int subch_device_load(SubchDev *s, QEMUFile *f) } s->ccw_fmt_1 = qemu_get_byte(f); s->ccw_no_data_cnt = qemu_get_byte(f); + /* + * Hack alert. We don't migrate the channel subsystem status (no + * device!), but we need to find out if the guest enabled mss/mcss-e. + * If the subchannel is enabled, it certainly was able to access it, + * so adjust the max_ssid/max_cssid values for relevant ssid/cssid + * values. This is not watertight, but better than nothing. + */ + if (s->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ENA) { + if (s->ssid) { + channel_subsys->max_ssid = MAX_SSID; + } + if (s->cssid != channel_subsys->default_cssid) { + channel_subsys->max_cssid = MAX_CSSID; + } + } return 0; } -- cgit v1.2.3 From 62ac4a52e27c706c860403fd1d8535a9a1073a19 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 11 Dec 2014 14:25:11 +0100 Subject: s390x/css: Add a callback for when subchannel gets disabled We need a possibility to run code when a subchannel gets disabled. This patch adds the necessary infrastructure. Signed-off-by: Thomas Huth Signed-off-by: Cornelia Huck Reviewed-by: Michael S. Tsirkin --- hw/s390x/css.c | 12 ++++++++++++ hw/s390x/css.h | 1 + 2 files changed, 13 insertions(+) (limited to 'hw') diff --git a/hw/s390x/css.c b/hw/s390x/css.c index a9cf3d7f97..5df450e00b 100644 --- a/hw/s390x/css.c +++ b/hw/s390x/css.c @@ -588,6 +588,7 @@ int css_do_msch(SubchDev *sch, const SCHIB *orig_schib) { SCSW *s = &sch->curr_status.scsw; PMCW *p = &sch->curr_status.pmcw; + uint16_t oldflags; int ret; SCHIB schib; @@ -610,6 +611,7 @@ int css_do_msch(SubchDev *sch, const SCHIB *orig_schib) copy_schib_from_guest(&schib, orig_schib); /* Only update the program-modifiable fields. */ p->intparm = schib.pmcw.intparm; + oldflags = p->flags; p->flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA | PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME | PMCW_FLAGS_MASK_MP); @@ -625,6 +627,12 @@ int css_do_msch(SubchDev *sch, const SCHIB *orig_schib) (PMCW_CHARS_MASK_MBFC | PMCW_CHARS_MASK_CSENSE); sch->curr_status.mba = schib.mba; + /* Has the channel been disabled? */ + if (sch->disable_cb && (oldflags & PMCW_FLAGS_MASK_ENA) != 0 + && (p->flags & PMCW_FLAGS_MASK_ENA) == 0) { + sch->disable_cb(sch); + } + ret = 0; out: @@ -1498,6 +1506,10 @@ void css_reset_sch(SubchDev *sch) { PMCW *p = &sch->curr_status.pmcw; + if ((p->flags & PMCW_FLAGS_MASK_ENA) != 0 && sch->disable_cb) { + sch->disable_cb(sch); + } + p->intparm = 0; p->flags &= ~(PMCW_FLAGS_MASK_ISC | PMCW_FLAGS_MASK_ENA | PMCW_FLAGS_MASK_LM | PMCW_FLAGS_MASK_MME | diff --git a/hw/s390x/css.h b/hw/s390x/css.h index 7e53148700..a09bb1f87c 100644 --- a/hw/s390x/css.h +++ b/hw/s390x/css.h @@ -81,6 +81,7 @@ struct SubchDev { uint8_t ccw_no_data_cnt; /* transport-provided data: */ int (*ccw_cb) (SubchDev *, CCW1); + void (*disable_cb)(SubchDev *); SenseId id; void *driver_data; }; -- cgit v1.2.3 From c42767f2bbd18d4ec895395c01c64bbec16b5b84 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 11 Dec 2014 14:25:12 +0100 Subject: s390x/virtio-ccw: add virtio set-revision call Handle the virtio-ccw revision according to what the guest sets. When revision 1 is selected, we have a virtio-1 standard device with byteswapping for the virtio rings. When a channel gets disabled, we have to revert to the legacy behavior in case the next user of the device does not negotiate the revision 1 anymore (e.g. the boot firmware uses revision 1, but the operating system only uses the legacy mode). Note that revisions > 0 are still disabled. [CH: assure memory accesses are always BE] Signed-off-by: Thomas Huth Signed-off-by: Cornelia Huck Acked-by: Michael S. Tsirkin --- hw/s390x/virtio-ccw.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++-- hw/s390x/virtio-ccw.h | 8 ++++++ 2 files changed, 84 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 2c817719d6..0b3a0e7657 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -21,6 +21,7 @@ #include "hw/sysbus.h" #include "qemu/bitops.h" #include "qemu/error-report.h" +#include "hw/virtio/virtio-access.h" #include "hw/virtio/virtio-bus.h" #include "hw/s390x/adapter.h" #include "hw/s390x/s390_flic.h" @@ -261,6 +262,12 @@ typedef struct VirtioThinintInfo { uint8_t isc; } QEMU_PACKED VirtioThinintInfo; +typedef struct VirtioRevInfo { + uint16_t revision; + uint16_t length; + uint8_t data[0]; +} QEMU_PACKED VirtioRevInfo; + /* Specify where the virtqueues for the subchannel are in guest memory. */ static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align, uint16_t index, uint16_t num) @@ -319,6 +326,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) { int ret; VqInfoBlock info; + VirtioRevInfo revinfo; uint8_t status; VirtioFeatDesc features; void *config; @@ -401,7 +409,16 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) MEMTXATTRS_UNSPECIFIED, NULL); if (features.index == 0) { - features.features = vdev->host_features; + features.features = (uint32_t)vdev->host_features; + } else if (features.index == 1) { + features.features = (uint32_t)(vdev->host_features >> 32); + /* + * Don't offer version 1 to the guest if it did not + * negotiate at least revision 1. + */ + if (dev->revision <= 0) { + features.features &= ~(1 << (VIRTIO_F_VERSION_1 - 32)); + } } else { /* Return zeroes if the guest supports more feature bits. */ features.features = 0; @@ -437,7 +454,20 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) MEMTXATTRS_UNSPECIFIED, NULL); if (features.index == 0) { - virtio_set_features(vdev, features.features); + virtio_set_features(vdev, + (vdev->guest_features & 0xffffffff00000000ULL) | + features.features); + } else if (features.index == 1) { + /* + * The guest should not set version 1 if it didn't + * negotiate a revision >= 1. + */ + if (dev->revision <= 0) { + features.features &= ~(1 << (VIRTIO_F_VERSION_1 - 32)); + } + virtio_set_features(vdev, + (vdev->guest_features & 0x00000000ffffffffULL) | + ((uint64_t)features.features << 32)); } else { /* * If the guest supports more feature bits, assert that it @@ -658,6 +688,40 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) } } break; + case CCW_CMD_SET_VIRTIO_REV: + len = sizeof(revinfo); + if (ccw.count < len) { + ret = -EINVAL; + break; + } + if (!ccw.cda) { + ret = -EFAULT; + break; + } + revinfo.revision = + address_space_lduw_be(&address_space_memory, ccw.cda, + MEMTXATTRS_UNSPECIFIED, NULL); + revinfo.length = + address_space_lduw_be(&address_space_memory, + ccw.cda + sizeof(revinfo.revision), + MEMTXATTRS_UNSPECIFIED, NULL); + if (ccw.count < len + revinfo.length || + (check_len && ccw.count > len + revinfo.length)) { + ret = -EINVAL; + break; + } + /* + * Once we start to support revisions with additional data, we'll + * need to fetch it here. Nothing to do for now, though. + */ + if (dev->revision >= 0 || + revinfo.revision > virtio_ccw_rev_max(vdev)) { + ret = -ENOSYS; + break; + } + ret = 0; + dev->revision = revinfo.revision; + break; default: ret = -ENOSYS; break; @@ -665,6 +729,13 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) return ret; } +static void virtio_sch_disable_cb(SubchDev *sch) +{ + VirtioCcwDevice *dev = sch->driver_data; + + dev->revision = -1; +} + static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp) { unsigned int cssid = 0; @@ -784,12 +855,15 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp) css_sch_build_virtual_schib(sch, 0, VIRTIO_CCW_CHPID_TYPE); sch->ccw_cb = virtio_ccw_cb; + sch->disable_cb = virtio_sch_disable_cb; /* Build senseid data. */ memset(&sch->id, 0, sizeof(SenseId)); sch->id.reserved = 0xff; sch->id.cu_type = VIRTIO_CCW_CU_TYPE; + dev->revision = -1; + if (k->realize) { k->realize(dev, &err); } diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h index d729263960..692ddd7318 100644 --- a/hw/s390x/virtio-ccw.h +++ b/hw/s390x/virtio-ccw.h @@ -41,6 +41,7 @@ #define CCW_CMD_SET_CONF_IND 0x53 #define CCW_CMD_READ_VQ_CONF 0x32 #define CCW_CMD_SET_IND_ADAPTER 0x73 +#define CCW_CMD_SET_VIRTIO_REV 0x83 #define TYPE_VIRTIO_CCW_DEVICE "virtio-ccw-device" #define VIRTIO_CCW_DEVICE(obj) \ @@ -86,6 +87,7 @@ struct VirtioCcwDevice { DeviceState parent_obj; SubchDev *sch; char *bus_id; + int revision; VirtioBusState bus; bool ioeventfd_started; bool ioeventfd_disabled; @@ -99,6 +101,12 @@ struct VirtioCcwDevice { uint64_t ind_bit; }; +/* The maximum virtio revision we support. */ +static inline int virtio_ccw_rev_max(VirtIODevice *vdev) +{ + return 0; +} + /* virtual css bus type */ typedef struct VirtualCssBus { BusState parent_obj; -- cgit v1.2.3 From 0db87e0d1763d3fb4039c2cffb0f3264da88ab30 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Thu, 11 Dec 2014 14:25:13 +0100 Subject: s390x/virtio-ccw: support virtio-1 set_vq format Support the new CCW_CMD_SET_VQ format for virtio-1 devices. While we're at it, refactor the code a bit and enforce big endian fields (which had always been required, even for legacy). Reviewed-by: Thomas Huth Signed-off-by: Cornelia Huck Reviewed-by: Michael S. Tsirkin --- hw/s390x/virtio-ccw.c | 133 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 92 insertions(+), 41 deletions(-) (limited to 'hw') diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 0b3a0e7657..8597ac479f 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -238,11 +238,20 @@ VirtualCssBus *virtual_css_bus_init(void) } /* Communication blocks used by several channel commands. */ -typedef struct VqInfoBlock { +typedef struct VqInfoBlockLegacy { uint64_t queue; uint32_t align; uint16_t index; uint16_t num; +} QEMU_PACKED VqInfoBlockLegacy; + +typedef struct VqInfoBlock { + uint64_t desc; + uint32_t res0; + uint16_t index; + uint16_t num; + uint64_t avail; + uint64_t used; } QEMU_PACKED VqInfoBlock; typedef struct VqConfigBlock { @@ -269,17 +278,20 @@ typedef struct VirtioRevInfo { } QEMU_PACKED VirtioRevInfo; /* Specify where the virtqueues for the subchannel are in guest memory. */ -static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align, - uint16_t index, uint16_t num) +static int virtio_ccw_set_vqs(SubchDev *sch, VqInfoBlock *info, + VqInfoBlockLegacy *linfo) { VirtIODevice *vdev = virtio_ccw_get_vdev(sch); + uint16_t index = info ? info->index : linfo->index; + uint16_t num = info ? info->num : linfo->num; + uint64_t desc = info ? info->desc : linfo->queue; if (index >= VIRTIO_CCW_QUEUE_MAX) { return -EINVAL; } /* Current code in virtio.c relies on 4K alignment. */ - if (addr && (align != 4096)) { + if (linfo && desc && (linfo->align != 4096)) { return -EINVAL; } @@ -287,8 +299,12 @@ static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align, return -EINVAL; } - virtio_queue_set_addr(vdev, index, addr); - if (!addr) { + if (info) { + virtio_queue_set_rings(vdev, index, desc, info->avail, info->used); + } else { + virtio_queue_set_addr(vdev, index, desc); + } + if (!desc) { virtio_queue_set_vector(vdev, index, VIRTIO_NO_VECTOR); } else { /* Fail if we don't have a big enough queue. */ @@ -322,10 +338,78 @@ static void virtio_ccw_reset_virtio(VirtioCcwDevice *dev, VirtIODevice *vdev) dev->sch->thinint_active = false; } -static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) +static int virtio_ccw_handle_set_vq(SubchDev *sch, CCW1 ccw, bool check_len, + bool is_legacy) { int ret; VqInfoBlock info; + VqInfoBlockLegacy linfo; + size_t info_len = is_legacy ? sizeof(linfo) : sizeof(info); + + if (check_len) { + if (ccw.count != info_len) { + return -EINVAL; + } + } else if (ccw.count < info_len) { + /* Can't execute command. */ + return -EINVAL; + } + if (!ccw.cda) { + return -EFAULT; + } + if (is_legacy) { + linfo.queue = address_space_ldq_be(&address_space_memory, ccw.cda, + MEMTXATTRS_UNSPECIFIED, NULL); + linfo.align = address_space_ldl_be(&address_space_memory, + ccw.cda + sizeof(linfo.queue), + MEMTXATTRS_UNSPECIFIED, + NULL); + linfo.index = address_space_lduw_be(&address_space_memory, + ccw.cda + sizeof(linfo.queue) + + sizeof(linfo.align), + MEMTXATTRS_UNSPECIFIED, + NULL); + linfo.num = address_space_lduw_be(&address_space_memory, + ccw.cda + sizeof(linfo.queue) + + sizeof(linfo.align) + + sizeof(linfo.index), + MEMTXATTRS_UNSPECIFIED, + NULL); + ret = virtio_ccw_set_vqs(sch, NULL, &linfo); + } else { + info.desc = address_space_ldq_be(&address_space_memory, ccw.cda, + MEMTXATTRS_UNSPECIFIED, NULL); + info.index = address_space_lduw_be(&address_space_memory, + ccw.cda + sizeof(info.desc) + + sizeof(info.res0), + MEMTXATTRS_UNSPECIFIED, NULL); + info.num = address_space_lduw_be(&address_space_memory, + ccw.cda + sizeof(info.desc) + + sizeof(info.res0) + + sizeof(info.index), + MEMTXATTRS_UNSPECIFIED, NULL); + info.avail = address_space_ldq_be(&address_space_memory, + ccw.cda + sizeof(info.desc) + + sizeof(info.res0) + + sizeof(info.index) + + sizeof(info.num), + MEMTXATTRS_UNSPECIFIED, NULL); + info.used = address_space_ldq_be(&address_space_memory, + ccw.cda + sizeof(info.desc) + + sizeof(info.res0) + + sizeof(info.index) + + sizeof(info.num) + + sizeof(info.avail), + MEMTXATTRS_UNSPECIFIED, NULL); + ret = virtio_ccw_set_vqs(sch, &info, NULL); + } + sch->curr_status.scsw.count = 0; + return ret; +} + +static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) +{ + int ret; VirtioRevInfo revinfo; uint8_t status; VirtioFeatDesc features; @@ -350,40 +434,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) /* Look at the command. */ switch (ccw.cmd_code) { case CCW_CMD_SET_VQ: - if (check_len) { - if (ccw.count != sizeof(info)) { - ret = -EINVAL; - break; - } - } else if (ccw.count < sizeof(info)) { - /* Can't execute command. */ - ret = -EINVAL; - break; - } - if (!ccw.cda) { - ret = -EFAULT; - } else { - info.queue = address_space_ldq(&address_space_memory, ccw.cda, - MEMTXATTRS_UNSPECIFIED, NULL); - info.align = address_space_ldl(&address_space_memory, - ccw.cda + sizeof(info.queue), - MEMTXATTRS_UNSPECIFIED, - NULL); - info.index = address_space_lduw(&address_space_memory, - ccw.cda + sizeof(info.queue) - + sizeof(info.align), - MEMTXATTRS_UNSPECIFIED, - NULL); - info.num = address_space_lduw(&address_space_memory, - ccw.cda + sizeof(info.queue) - + sizeof(info.align) - + sizeof(info.index), - MEMTXATTRS_UNSPECIFIED, - NULL); - ret = virtio_ccw_set_vqs(sch, info.queue, info.align, info.index, - info.num); - sch->curr_status.scsw.count = 0; - } + ret = virtio_ccw_handle_set_vq(sch, ccw, check_len, dev->revision < 1); break; case CCW_CMD_VDEV_RESET: virtio_ccw_reset_virtio(dev, vdev); -- cgit v1.2.3 From 213941d73baf8ba7ec5381c8402fed7925d613d4 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Thu, 25 Jun 2015 12:20:08 +0200 Subject: virtio-ccw: migrate ->revision We need to migrate the revision field as well. No compatibility concerns as we already introduced migration of ->config_vector in this release. Signed-off-by: Cornelia Huck --- hw/s390x/virtio-ccw.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'hw') diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 8597ac479f..d631337e11 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -1472,6 +1472,7 @@ static void virtio_ccw_save_config(DeviceState *d, QEMUFile *f) qemu_put_be16(f, vdev->config_vector); qemu_put_be64(f, dev->routes.adapter.ind_offset); qemu_put_byte(f, dev->thinint_isc); + qemu_put_be32(f, dev->revision); } static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f) @@ -1512,6 +1513,7 @@ static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f) dev->thinint_isc, true, false, &dev->routes.adapter.adapter_id); } + dev->revision = qemu_get_be32(f); return 0; } -- cgit v1.2.3 From 6efd2c2a125b4369b8def585b0dac35c849b5eb3 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Thu, 18 Jun 2015 16:37:39 +0200 Subject: s390x/ipl: Fix boot if no bootindex was specified commit fa92e218df1d ("s390x/ipl: avoid sign extension") introduced a regression: qemu-system-s390x -drive file=image.qcow,format=qcow2 does not boot, the bios states "No virtio-blk device found!" adding bootindex=1 does boot. The reason is that the uint32_t as return value will not do the right thing for the return -1 (default without bootindex). The bios itself, will interpret a 64bit -1 as autodetect (but it will interpret 32bit -1 as ccw device address ff.ff.ffff) Signed-off-by: Christian Borntraeger Cc: Paolo Bonzini Cc: Cornelia Huck Cc: qemu-stable@nongnu.org # v2.3.0 Tested-by: Aurelien Jarno Reviewed-by: Aurelien Jarno Signed-off-by: Cornelia Huck --- hw/s390x/ipl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 132004ae4f..2e0a8b6e0c 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -218,7 +218,7 @@ static Property s390_ipl_properties[] = { * - -1 if no valid boot device was found * - ccw id of the boot device otherwise */ -static uint32_t s390_update_iplstate(CPUS390XState *env, S390IPLState *ipl) +static uint64_t s390_update_iplstate(CPUS390XState *env, S390IPLState *ipl) { DeviceState *dev_st; @@ -248,7 +248,7 @@ static uint32_t s390_update_iplstate(CPUS390XState *env, S390IPLState *ipl) return -1; out: - return ipl->cssid << 24 | ipl->ssid << 16 | ipl->devno; + return (uint32_t) (ipl->cssid << 24 | ipl->ssid << 16 | ipl->devno); } int s390_ipl_update_diag308(IplParameterBlock *iplb) -- cgit v1.2.3 From c4d3c0a2696c09a884b680d15b03325e46656a6c Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Wed, 1 Jul 2015 11:16:57 +0200 Subject: s390x/migration: Introduce 2.4 machine The section footer changes commit f68945d42bab ("Add a protective section footer") and commit 37fb569c0198 ("Disable section footers on older machine types") broke migration for any non-versioned machines. This pinpoints a problem of s390-ccw machines: it needs to be versioned to be compatible with future changes in common code data structures such as section footers. Let's introduce a version scheme for s390-ccw-virtio machines. We will use the old s390-ccw-virtio name as alias to the latest version as all existing libvirt XML for the ccw type were expanded by libvirt to that name. The only downside of this patch is, that the old alias s390-ccw will no longer be available as machines can have only one alias, but it should not really matter. Cc: Dr. David Alan Gilbert Cc: Juan Quintela Cc: Boris Fiuczynski Cc: Jason J. Herne Signed-off-by: Christian Borntraeger Message-Id: <1435742217-62246-1-git-send-email-borntraeger@de.ibm.com> Reviewed-by: Juan Quintela Signed-off-by: Cornelia Huck --- hw/s390x/s390-virtio-ccw.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'hw') diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index c574988c36..3d20d6a0f7 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -204,9 +204,6 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data) MachineClass *mc = MACHINE_CLASS(oc); NMIClass *nc = NMI_CLASS(oc); - mc->name = "s390-ccw-virtio"; - mc->alias = "s390-ccw"; - mc->desc = "VirtIO-ccw based S390 machine"; mc->init = ccw_init; mc->block_default_type = IF_VIRTIO; mc->no_cdrom = 1; @@ -216,7 +213,6 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data) mc->no_sdcard = 1; mc->use_sclp = 1; mc->max_cpus = 255; - mc->is_default = 1; nc->nmi_monitor_handler = s390_nmi; } @@ -272,6 +268,7 @@ static inline void s390_machine_initfn(Object *obj) static const TypeInfo ccw_machine_info = { .name = TYPE_S390_CCW_MACHINE, .parent = TYPE_MACHINE, + .abstract = true, .instance_size = sizeof(S390CcwMachineState), .instance_init = s390_machine_initfn, .class_init = ccw_machine_class_init, @@ -281,9 +278,26 @@ static const TypeInfo ccw_machine_info = { }, }; +static void ccw_machine_2_4_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->name = "s390-ccw-virtio-2.4"; + mc->alias = "s390-ccw-virtio"; + mc->desc = "VirtIO-ccw based S390 machine v2.4"; + mc->is_default = 1; +} + +static const TypeInfo ccw_machine_2_4_info = { + .name = TYPE_S390_CCW_MACHINE "2.4", + .parent = TYPE_S390_CCW_MACHINE, + .class_init = ccw_machine_2_4_class_init, +}; + static void ccw_machine_register_types(void) { type_register_static(&ccw_machine_info); + type_register_static(&ccw_machine_2_4_info); } type_init(ccw_machine_register_types) -- cgit v1.2.3