From patchwork Wed Sep 13 13:27:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Halil Pasic X-Patchwork-Id: 9951419 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2D4B06038F for ; Wed, 13 Sep 2017 13:39:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1CB6C285F9 for ; Wed, 13 Sep 2017 13:39:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0F2BC286C5; Wed, 13 Sep 2017 13:39:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6268B285F9 for ; Wed, 13 Sep 2017 13:39:55 +0000 (UTC) Received: from localhost ([::1]:42587 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ds7tS-0003EV-N2 for patchwork-qemu-devel@patchwork.kernel.org; Wed, 13 Sep 2017 09:39:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40479) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ds7iE-00005e-Cr for qemu-devel@nongnu.org; Wed, 13 Sep 2017 09:28:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ds7iB-0006NV-4t for qemu-devel@nongnu.org; Wed, 13 Sep 2017 09:28:18 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:41114) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ds7iA-0006Mr-S0 for qemu-devel@nongnu.org; Wed, 13 Sep 2017 09:28:15 -0400 Received: from pps.filterd (m0098409.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id v8DDOp95037844 for ; Wed, 13 Sep 2017 09:28:13 -0400 Received: from e06smtp13.uk.ibm.com (e06smtp13.uk.ibm.com [195.75.94.109]) by mx0a-001b2d01.pphosted.com with ESMTP id 2cy388yywk-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Wed, 13 Sep 2017 09:28:13 -0400 Received: from localhost by e06smtp13.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 13 Sep 2017 14:28:10 +0100 Received: from b06cxnps4076.portsmouth.uk.ibm.com (9.149.109.198) by e06smtp13.uk.ibm.com (192.168.101.143) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 13 Sep 2017 14:28:07 +0100 Received: from d06av23.portsmouth.uk.ibm.com (d06av23.portsmouth.uk.ibm.com [9.149.105.59]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v8DDS7jC6488294; Wed, 13 Sep 2017 13:28:07 GMT Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 51E0BA4051; Wed, 13 Sep 2017 14:24:17 +0100 (BST) Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1CEB3A4040; Wed, 13 Sep 2017 14:24:17 +0100 (BST) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.152.85.9]) by d06av23.portsmouth.uk.ibm.com (Postfix) with ESMTPS; Wed, 13 Sep 2017 14:24:17 +0100 (BST) From: Halil Pasic To: Cornelia Huck Date: Wed, 13 Sep 2017 15:27:51 +0200 X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913132752.8484-1-pasic@linux.vnet.ibm.com> References: <20170913132752.8484-1-pasic@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 17091313-0012-0000-0000-00000578B37A X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17091313-0013-0000-0000-000018F1D015 Message-Id: <20170913132752.8484-2-pasic@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-09-13_04:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=2 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1707230000 definitions=main-1709130210 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.156.1 Subject: [Qemu-devel] [PATCH 1/2] s390x/ccs: add ccw-tester emulated device X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dong Jia Shi , Halil Pasic , Pierre Morel , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add a fake device meant for testing the correctness of our css emulation. What we currently have is writing a Fibonacci sequence of uint32_t to the device via ccw write. The write is going to fail if it ain't a Fibonacci and indicate a device exception in scsw together with the proper residual count. Of course lot's of invalid inputs (besides basic data processing) can be tested with that as well. Usage: 1) fire up a qemu with something like -device ccw-tester,devno=fe.0.0001 on the command line 2) exercise the device from the guest Signed-off-by: Halil Pasic --- Depends on the series 'add CCW indirect data access support' --- hw/s390x/Makefile.objs | 1 + hw/s390x/ccw-tester.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 hw/s390x/ccw-tester.c diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs index 7ee19d3abc..28eb58a3cb 100644 --- a/hw/s390x/Makefile.objs +++ b/hw/s390x/Makefile.objs @@ -18,3 +18,4 @@ obj-y += s390-stattrib.o obj-$(CONFIG_KVM) += s390-skeys-kvm.o obj-$(CONFIG_KVM) += s390-stattrib-kvm.o obj-y += s390-ccw.o +obj-y += ccw-tester.o diff --git a/hw/s390x/ccw-tester.c b/hw/s390x/ccw-tester.c new file mode 100644 index 0000000000..c8017818c4 --- /dev/null +++ b/hw/s390x/ccw-tester.c @@ -0,0 +1,179 @@ +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/module.h" +#include "cpu.h" +#include "hw/s390x/css.h" +#include "hw/s390x/css-bridge.h" +#include "hw/s390x/3270-ccw.h" +#include "exec/address-spaces.h" +#include + +typedef struct CcwTesterDevice { + CcwDevice parent_obj; + uint16_t cu_type; + uint8_t chpid_type; + struct { + uint32_t ring[4]; + unsigned int next; + } fib; +} CcwTesterDevice; + + +typedef struct CcwTesterClass { + CCWDeviceClass parent_class; + DeviceRealize parent_realize; +} CcwTesterClass; + +#define TYPE_CCW_TESTER "ccw-tester" + +#define CCW_TESTER(obj) \ + OBJECT_CHECK(CcwTesterDevice, (obj), TYPE_CCW_TESTER) +#define CCW_TESTER_CLASS(klass) \ + OBJECT_CLASS_CHECK(CcwTesterClass, (klass), TYPE_CCW_TESTER) +#define CCW_TESTER_GET_CLASS(obj) \ + OBJECT_GET_CLASS(CcwTesterClass, (obj), TYPE_CCW_TESTER) + +#define CCW_CMD_READ 0x01U +#define CCW_CMD_WRITE 0x02U + +static unsigned int abs_to_ring(unsigned int i) +{ + return i & 0x3; +} + +static int ccw_tester_write_fib(SubchDev *sch, CCW1 ccw) +{ + CcwTesterDevice *d = sch->driver_data; + bool is_fib = true; + uint32_t sum; + int ret = 0; + + ccw_dstream_init(&sch->cds, &ccw, &sch->orb); + d->fib.next = 0; + while (ccw_dstream_avail(&sch->cds) > 0) { + ret = ccw_dstream_read(&sch->cds, + d->fib.ring[abs_to_ring(d->fib.next)]); + if (ret) { + error(0, -ret, "fib"); + break; + } + if (d->fib.next > 2) { + sum = (d->fib.ring[abs_to_ring(d->fib.next - 1)] + + d->fib.ring[abs_to_ring(d->fib.next - 2)]); + is_fib = sum == d->fib.ring[abs_to_ring(d->fib.next)]; + if (!is_fib) { + break; + } + } + ++(d->fib.next); + } + if (!is_fib) { + sch->curr_status.scsw.ctrl &= ~SCSW_ACTL_START_PEND; + sch->curr_status.scsw.ctrl |= SCSW_STCTL_PRIMARY | + SCSW_STCTL_SECONDARY | + SCSW_STCTL_ALERT | + SCSW_STCTL_STATUS_PEND; + sch->curr_status.scsw.count = ccw_dstream_residual_count(&sch->cds); + sch->curr_status.scsw.cpa = sch->channel_prog + 8; + sch->curr_status.scsw.dstat = SCSW_DSTAT_UNIT_EXCEP; + return -EIO; + } + return ret; +} + +static int ccw_tester_ccw_cb_impl(SubchDev *sch, CCW1 ccw) +{ + switch (ccw.cmd_code) { + case CCW_CMD_READ: + break; + case CCW_CMD_WRITE: + return ccw_tester_write_fib(sch, ccw); + default: + return -EINVAL; + } + return 0; +} + +static void ccw_tester_realize(DeviceState *ds, Error **errp) +{ + uint16_t chpid; + CcwTesterDevice *dev = CCW_TESTER(ds); + CcwTesterClass *ctc = CCW_TESTER_GET_CLASS(dev); + CcwDevice *cdev = CCW_DEVICE(ds); + BusState *qbus = qdev_get_parent_bus(ds); + VirtualCssBus *cbus = VIRTUAL_CSS_BUS(qbus); + SubchDev *sch; + Error *err = NULL; + + sch = css_create_sch(cdev->devno, true, cbus->squash_mcss, errp); + if (!sch) { + return; + } + + sch->driver_data = dev; + cdev->sch = sch; + chpid = css_find_free_chpid(sch->cssid); + + if (chpid > MAX_CHPID) { + error_setg(&err, "No available chpid to use."); + goto out_err; + } + + sch->id.reserved = 0xff; + sch->id.cu_type = dev->cu_type; + css_sch_build_virtual_schib(sch, (uint8_t)chpid, + dev->chpid_type); + sch->ccw_cb = ccw_tester_ccw_cb_impl; + sch->do_subchannel_work = do_subchannel_work_virtual; + + + ctc->parent_realize(ds, &err); + if (err) { + goto out_err; + } + + css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, + ds->hotplugged, 1); + return; + +out_err: + error_propagate(errp, err); + css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL); + cdev->sch = NULL; + g_free(sch); +} + +static Property ccw_tester_properties[] = { + DEFINE_PROP_UINT16("cu_type", CcwTesterDevice, cu_type, + 0x3831), + DEFINE_PROP_UINT8("chpid_type", CcwTesterDevice, chpid_type, + 0x98), + DEFINE_PROP_END_OF_LIST(), +}; + +static void ccw_tester_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + CcwTesterClass *ctc = CCW_TESTER_CLASS(klass); + + dc->props = ccw_tester_properties; + dc->bus_type = TYPE_VIRTUAL_CSS_BUS; + ctc->parent_realize = dc->realize; + dc->realize = ccw_tester_realize; + dc->hotpluggable = false; +} + +static const TypeInfo ccw_tester_info = { + .name = TYPE_CCW_TESTER, + .parent = TYPE_CCW_DEVICE, + .instance_size = sizeof(CcwTesterDevice), + .class_init = ccw_tester_class_init, + .class_size = sizeof(CcwTesterClass), +}; + +static void ccw_tester_register(void) +{ + type_register_static(&ccw_tester_info); +} + +type_init(ccw_tester_register)