From patchwork Tue Oct 7 14:40:05 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cornelia Huck X-Patchwork-Id: 397368 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id E3475140120 for ; Wed, 8 Oct 2014 04:52:55 +1100 (EST) Received: from localhost ([::1]:60121 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XbYwP-0005f1-TQ for incoming@patchwork.ozlabs.org; Tue, 07 Oct 2014 13:52:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35711) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XbYvl-0004pB-Ap for qemu-devel@nongnu.org; Tue, 07 Oct 2014 13:52:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XbYvc-0005Zs-7d for qemu-devel@nongnu.org; Tue, 07 Oct 2014 13:52:13 -0400 Received: from e06smtp17.uk.ibm.com ([195.75.94.113]:51258) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XbYvb-0005Rc-3K for qemu-devel@nongnu.org; Tue, 07 Oct 2014 13:52:04 -0400 Received: from /spool/local by e06smtp17.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 7 Oct 2014 18:51:58 +0100 Received: from d06dlp02.portsmouth.uk.ibm.com (9.149.20.14) by e06smtp17.uk.ibm.com (192.168.101.147) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 7 Oct 2014 18:51:57 +0100 Received: from b06cxnps4075.portsmouth.uk.ibm.com (d06relay12.portsmouth.uk.ibm.com [9.149.109.197]) by d06dlp02.portsmouth.uk.ibm.com (Postfix) with ESMTP id DB9DC3988F7 for ; Tue, 7 Oct 2014 15:40:29 +0100 (BST) Received: from d06av08.portsmouth.uk.ibm.com (d06av08.portsmouth.uk.ibm.com [9.149.37.249]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id s97EeSFe43974870 for ; Tue, 7 Oct 2014 14:40:33 GMT Received: from d06av08.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av08.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id s97EeJBu001143 for ; Tue, 7 Oct 2014 08:40:20 -0600 Received: from gondolin.boeblingen.de.ibm.com (dyn-9-152-224-210.boeblingen.de.ibm.com [9.152.224.210]) by d06av08.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id s97EeC4E000717; Tue, 7 Oct 2014 08:40:19 -0600 From: Cornelia Huck To: virtualization@lists.linux-foundation.org, qemu-devel@nongnu.org, kvm@vger.kernel.org Date: Tue, 7 Oct 2014 16:40:05 +0200 Message-Id: <1412692807-12398-10-git-send-email-cornelia.huck@de.ibm.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1412692807-12398-1-git-send-email-cornelia.huck@de.ibm.com> References: <1412692807-12398-1-git-send-email-cornelia.huck@de.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 14100717-0542-0000-0000-00000117BFE1 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.75.94.113 Cc: Cornelia Huck , rusty@rustcorp.com.au, thuth@linux.vnet.ibm.com Subject: [Qemu-devel] [PATCH RFC 09/11] s390x/virtio-ccw: add virtio set-revision call X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Thomas Huth 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; but we still extend the feature bit size to be able to handle the VERSION_1 bit. Signed-off-by: Thomas Huth Signed-off-by: Cornelia Huck --- hw/s390x/virtio-ccw.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ hw/s390x/virtio-ccw.h | 7 ++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 69add47..0d414f6 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -20,9 +20,11 @@ #include "hw/virtio/virtio-net.h" #include "hw/sysbus.h" #include "qemu/bitops.h" +#include "hw/virtio/virtio-access.h" #include "hw/virtio/virtio-bus.h" #include "hw/s390x/adapter.h" #include "hw/s390x/s390_flic.h" +#include "linux/virtio_config.h" #include "ioinst.h" #include "css.h" @@ -260,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) @@ -299,6 +307,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) { int ret; VqInfoBlock info; + VirtioRevInfo revinfo; uint8_t status; VirtioFeatDesc features; void *config; @@ -373,6 +382,13 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) ccw.cda + sizeof(features.features)); if (features.index < ARRAY_SIZE(dev->host_features)) { features.features = dev->host_features[features.index]; + /* + * Don't offer version 1 to the guest if it did not + * negotiate at least revision 1. + */ + if (features.index == 1 && dev->revision <= 0) { + features.features &= ~(1 << (VIRTIO_F_VERSION_1 - 32)); + } } else { /* Return zeroes if the guest supports more feature bits. */ features.features = 0; @@ -400,6 +416,13 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) ccw.cda + sizeof(features.features)); features.features = ldl_le_phys(&address_space_memory, ccw.cda); if (features.index < ARRAY_SIZE(vdev->guest_features)) { + /* + * The guest should not set version 1 if it didn't + * negotiate a revision >= 1. + */ + if (features.index == 1 && dev->revision <= 0) { + features.features &= ~(1 << (VIRTIO_F_VERSION_1 - 32)); + } virtio_set_features(vdev, features.index, features.features); } else { /* @@ -600,6 +623,25 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) } } break; + case CCW_CMD_SET_VIRTIO_REV: + len = sizeof(revinfo); + if (ccw.count < len || (check_len && ccw.count > len)) { + ret = -EINVAL; + break; + } + if (!ccw.cda) { + ret = -EFAULT; + break; + } + cpu_physical_memory_read(ccw.cda, &revinfo, len); + if (dev->revision >= 0 || + revinfo.revision > VIRTIO_CCW_REV_MAX) { + ret = -ENOSYS; + break; + } + ret = 0; + dev->revision = revinfo.revision; + break; default: ret = -ENOSYS; break; @@ -607,6 +649,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 int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev) { unsigned int cssid = 0; @@ -733,6 +782,7 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev) 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)); @@ -740,6 +790,8 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev) sch->id.cu_type = VIRTIO_CCW_CU_TYPE; sch->id.cu_model = vdev->device_id; + dev->revision = -1; + /* Set default feature bits that are offered by the host. */ for (i = 0; i < ARRAY_SIZE(dev->host_features); i++) { dev->host_features[i] = @@ -749,6 +801,8 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev) dev->host_features[0] |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY; dev->host_features[0] |= 0x1 << VIRTIO_F_BAD_FEATURE; + dev->host_features[1] = 1 << (VIRTIO_F_VERSION_1 - 32); + css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, parent->hotplugged, 1); return 0; diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h index 5a1f16e..03d5955 100644 --- a/hw/s390x/virtio-ccw.h +++ b/hw/s390x/virtio-ccw.h @@ -40,6 +40,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) \ @@ -69,7 +70,10 @@ typedef struct VirtIOCCWDeviceClass { } VirtIOCCWDeviceClass; /* Change here if we want to support more feature bits. */ -#define VIRTIO_CCW_FEATURE_SIZE 1 +#define VIRTIO_CCW_FEATURE_SIZE NR_VIRTIO_FEATURE_WORDS + +/* The maximum virtio revision we support. */ +#define VIRTIO_CCW_REV_MAX 0 /* Performance improves when virtqueue kick processing is decoupled from the * vcpu thread using ioeventfd for some devices. */ @@ -89,6 +93,7 @@ struct VirtioCcwDevice { SubchDev *sch; char *bus_id; uint32_t host_features[VIRTIO_CCW_FEATURE_SIZE]; + int revision; VirtioBusState bus; bool ioeventfd_started; bool ioeventfd_disabled;