From fa8b0ca5d1b69975b715a259d3586cadf7a5280f Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Tue, 23 Jun 2015 15:46:31 +0200 Subject: [PATCH 01/11] 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(-) 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) From ec7353a146bb39c3bb3e5ccc50ca585aed97b7cf Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Wed, 24 Jun 2015 10:57:23 +0200 Subject: [PATCH 02/11] 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(+) 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; } From bdc7fe3638fa7693eed5886b5b2afe0858d875fc Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Fri, 19 Jun 2015 15:40:45 +0200 Subject: [PATCH 03/11] s390-ccw.img: Consume service interrupts We have to consume the outstanding service interrupt after each service call, otherwise a correct implementation will return CC=2 on subsequent service calls. Signed-off-by: Christian Borntraeger Reviewed-by: David Hildenbrand Signed-off-by: Cornelia Huck --- pc-bios/s390-ccw/s390-ccw.h | 1 + pc-bios/s390-ccw/sclp-ascii.c | 1 + pc-bios/s390-ccw/start.S | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h index 9b3868bd6e..5484c2a45c 100644 --- a/pc-bios/s390-ccw/s390-ccw.h +++ b/pc-bios/s390-ccw/s390-ccw.h @@ -47,6 +47,7 @@ typedef unsigned long long __u64; /* start.s */ void disabled_wait(void); +void consume_sclp_int(void); /* main.c */ void virtio_panic(const char *string); diff --git a/pc-bios/s390-ccw/sclp-ascii.c b/pc-bios/s390-ccw/sclp-ascii.c index 761fb44ff5..dc1c3e4f4d 100644 --- a/pc-bios/s390-ccw/sclp-ascii.c +++ b/pc-bios/s390-ccw/sclp-ascii.c @@ -24,6 +24,7 @@ static int sclp_service_call(unsigned int command, void *sccb) " srl %0,28" : "=&d" (cc) : "d" (command), "a" (__pa(sccb)) : "cc", "memory"); + consume_sclp_int(); if (cc == 3) return -EIO; if (cc == 2) diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S index 5d5df0d616..b6dd8c2fbe 100644 --- a/pc-bios/s390-ccw/start.S +++ b/pc-bios/s390-ccw/start.S @@ -28,6 +28,38 @@ disabled_wait: larl %r1,disabled_wait_psw lpswe 0(%r1) + +/* + * void consume_sclp_int(void) + * + * eats one sclp interrupt + */ + .globl consume_sclp_int +consume_sclp_int: + /* enable service interrupts in cr0 */ + stctg 0,0,0(15) + oi 6(15), 0x2 + lctlg 0,0,0(15) + /* prepare external call handler */ + larl %r1, external_new_code + stg %r1, 0x1b8 + larl %r1, external_new_mask + mvc 0x1b0(8),0(%r1) + /* load enabled wait PSW */ + larl %r1, enabled_wait_psw + lpswe 0(%r1) + +external_new_code: + /* disable service interrupts in cr0 */ + stctg 0,0,0(15) + ni 6(15), 0xfd + lctlg 0,0,0(15) + br 14 + .align 8 disabled_wait_psw: .quad 0x0002000180000000,0x0000000000000000 +enabled_wait_psw: + .quad 0x0302000180000000,0x0000000000000000 +external_new_mask: + .quad 0x0000000180000000 From 6e7cd94462d65405037c993fc4401d6fceed6660 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Thu, 25 Jun 2015 13:48:58 +0200 Subject: [PATCH 04/11] s390-ccw.img: update Update for "s390-ccw.img: Consume service interrupts". Signed-off-by: Cornelia Huck --- pc-bios/s390-ccw.img | Bin 13616 -> 13784 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/pc-bios/s390-ccw.img b/pc-bios/s390-ccw.img index 3c6b01fc8ef792bde7f84ec4cd9676fe4ed9811f..f64380a972f280d66a4df03f029e4e1d42da292d 100644 GIT binary patch literal 13784 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 literal 13616 zcmeHOdw5jUwO?mul1v`pNr*TRl#>uKfP~>u1wolSKtRyprNPpYK!zj|GGQ{|)s&{n zhiLVRDY5oyH7Yt3A5C+qB~?hQxvg&_^+7EvIAYO^I-yZfG3Wl)I_FFt;&=Pqd;hq9 z^nBmUT6^vF+H0@9_C9-(pUhq`$7WL~_Sk7SaFgKZH0d4#x}yR;G>sC;L#d>q9gk0( z(GQyO41&rjgKR-^qHV{=VbE>U&J5`+gC2wI7k?~!X7^w)zTTi%klhqH_7%@WArQ?P z1eKA}t#n2O%J9er{J)VSlRpM|d^|R5d~*$bwn31x4SEbZN`uF}eR3B(YV;3=N{T_Z zAhFyc&=L&#KmF~5++uK>etuV6V&k&LsZ6Y_ST(V-^x~O zivR4n%n8ZA*l}O;jSW3zt|9#7$fEU! zpSk?VkROh_;U&<&^Fbo9E<9EqNkdVIh6qNUiwr2=>7Wl4%m%FQamMHa`NyPM{8Vgm z*E7sWi^V(6Wp<3DmA=xFUJF?IbUI*qc!Q9Var-+r9P`9{YkqA{Z)o2Xo`>o||-{0Utb zB5_k9X%li&mvxK+CEN98NTv8tkXD3tkkZ;nKhA54?hYL$3f-ma4;>^$Bvseg$a(Hr zWJo2pOl_i;EYfypG%}Jy>GrL6DA8Yswo!6q2MwdGVKus!8YAb>kopaww@3*+p}*4( zkB97G�th0?~ONFh0Z{$d~+s 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 Date: Thu, 11 Dec 2014 14:25:11 +0100 Subject: [PATCH 05/11] 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(+) 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; }; From c42767f2bbd18d4ec895395c01c64bbec16b5b84 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 11 Dec 2014 14:25:12 +0100 Subject: [PATCH 06/11] 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(-) 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; From 0db87e0d1763d3fb4039c2cffb0f3264da88ab30 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Thu, 11 Dec 2014 14:25:13 +0100 Subject: [PATCH 07/11] 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(-) 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); From 213941d73baf8ba7ec5381c8402fed7925d613d4 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Thu, 25 Jun 2015 12:20:08 +0200 Subject: [PATCH 08/11] 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(+) 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; } From 6efd2c2a125b4369b8def585b0dac35c849b5eb3 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Thu, 18 Jun 2015 16:37:39 +0200 Subject: [PATCH 09/11] 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(-) 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) From 55b1b753dff022dcc95123bed35946b4977d31fa Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Tue, 23 Jun 2015 09:10:51 +0200 Subject: [PATCH 10/11] s390x/gdb: synchronize cpu state after modifying acrs Whenever we touch the access control registers, we have to make sure that the values will make it into kvm. Otherwise the change will simply be lost. When synchronizing qemu and kvm, a normal KVM_PUT_RUNTIME_STATE does not take care of these registers. Let's simply trigger a KVM_PUT_FULL_STATE sync, so the values will directly be written to kvm. The performance overhead can be ignored and this is much cleaner than manually writing these registers to kvm via our two supported ways. Reviewed-by: Christian Borntraeger Signed-off-by: David Hildenbrand Signed-off-by: Cornelia Huck --- target-s390x/gdbstub.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target-s390x/gdbstub.c b/target-s390x/gdbstub.c index ddc14a6cd4..31f204964f 100644 --- a/target-s390x/gdbstub.c +++ b/target-s390x/gdbstub.c @@ -92,6 +92,7 @@ static int cpu_write_ac_reg(CPUS390XState *env, uint8_t *mem_buf, int n) switch (n) { case S390_A0_REGNUM ... S390_A15_REGNUM: env->aregs[n] = ldl_p(mem_buf); + cpu_synchronize_post_init(ENV_GET_CPU(env)); return 4; default: return 0; From c4d3c0a2696c09a884b680d15b03325e46656a6c Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Wed, 1 Jul 2015 11:16:57 +0200 Subject: [PATCH 11/11] 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(-) 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)