From patchwork Fri Jul 14 10:40:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Borntraeger X-Patchwork-Id: 9840617 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 30679602BD for ; Fri, 14 Jul 2017 11:16:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2203F28751 for ; Fri, 14 Jul 2017 11:16:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 16E9228763; Fri, 14 Jul 2017 11:16:13 +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 5F82828752 for ; Fri, 14 Jul 2017 11:16:12 +0000 (UTC) Received: from localhost ([::1]:37047 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dVyZv-000163-J3 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 14 Jul 2017 07:16:11 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56609) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dVyP6-0008Kn-Rl for qemu-devel@nongnu.org; Fri, 14 Jul 2017 07:05:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dVyP3-0003xe-NF for qemu-devel@nongnu.org; Fri, 14 Jul 2017 07:05:00 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:35628 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dVyP3-0003xF-Gz for qemu-devel@nongnu.org; Fri, 14 Jul 2017 07:04:57 -0400 Received: from pps.filterd (m0098417.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id v6EB4kNE084193 for ; Fri, 14 Jul 2017 07:04:57 -0400 Received: from e06smtp13.uk.ibm.com (e06smtp13.uk.ibm.com [195.75.94.109]) by mx0a-001b2d01.pphosted.com with ESMTP id 2bpuk7tqwn-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Fri, 14 Jul 2017 07:04:56 -0400 Received: from localhost by e06smtp13.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 14 Jul 2017 12:04:54 +0100 Received: from b06cxnps4075.portsmouth.uk.ibm.com (9.149.109.197) by e06smtp13.uk.ibm.com (192.168.101.143) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 14 Jul 2017 12:04:51 +0100 Received: from d06av21.portsmouth.uk.ibm.com (d06av21.portsmouth.uk.ibm.com [9.149.105.232]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v6EB4oPm35389590; Fri, 14 Jul 2017 11:04:50 GMT Received: from d06av21.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id CD95E52A74; Fri, 14 Jul 2017 10:37:27 +0100 (BST) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.152.85.9]) by d06av21.portsmouth.uk.ibm.com (Postfix) with ESMTPS id B5EA452A73; Fri, 14 Jul 2017 10:37:27 +0100 (BST) Received: by tuxmaker.boeblingen.de.ibm.com (Postfix, from userid 25651) id E988520F69D; Fri, 14 Jul 2017 12:41:09 +0200 (CEST) From: Christian Borntraeger To: Peter Maydell Date: Fri, 14 Jul 2017 12:40:35 +0200 X-Mailer: git-send-email 2.7.4 In-Reply-To: <1500028867-134709-1-git-send-email-borntraeger@de.ibm.com> References: <1500028867-134709-1-git-send-email-borntraeger@de.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 17071411-0012-0000-0000-000005632B96 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17071411-0013-0000-0000-000018D63EB6 Message-Id: <1500028867-134709-9-git-send-email-borntraeger@de.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-07-13_13:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1706020000 definitions=main-1707140183 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.158.5 Subject: [Qemu-devel] [PULL 08/40] s390x/flic: introduce modify_ais_mode callback 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: Thomas Huth , Yi Min Zhao , Cornelia Huck , qemu-devel , Alexander Graf , Christian Borntraeger , Fei Li , Richard Henderson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Fei Li In order to emulate the adapter interruption suppression (AIS) facility properly, the guest needs to be able to modify the AIS mask. Interrupt suppression will be handled via the flic (for kvm, via a recently introduced kernel backend; for !kvm, in the flic code), so let's introduce a method to change the mode via the flic interface. We introduce the 'simm' and 'nimm' fields to QEMUS390FLICState to store interruption modes for each ISC. Each bit in 'simm' and 'nimm' targets one ISC, and collaboratively indicate three modes: ALL-Interruptions, SINGLE-Interruption and NO-Interruptions. This interface can initiate most transitions between the states; transition from SINGLE-Interruption to NO-Interruptions via adapter interrupt injection will be introduced in a following patch. The meaningful combinations are as follows: interruption mode | simm bit | nimm bit ------------------|----------|---------- ALL | 0 | 0 SINGLE | 1 | 0 NO | 1 | 1 Co-authored-by: Yi Min Zhao Signed-off-by: Yi Min Zhao Signed-off-by: Fei Li Signed-off-by: Christian Borntraeger --- hw/intc/s390_flic.c | 37 ++++++++++++++++++++++++++++++++++++- hw/intc/s390_flic_kvm.c | 36 ++++++++++++++++++++++++++++++++++++ include/hw/s390x/s390_flic.h | 9 ++++++++- 3 files changed, 80 insertions(+), 2 deletions(-) diff --git a/hw/intc/s390_flic.c b/hw/intc/s390_flic.c index d3938b3..ce7f355 100644 --- a/hw/intc/s390_flic.c +++ b/hw/intc/s390_flic.c @@ -79,15 +79,47 @@ static int qemu_s390_clear_io_flic(S390FLICState *fs, uint16_t subchannel_id, return -ENOSYS; } +static int qemu_s390_modify_ais_mode(S390FLICState *fs, uint8_t isc, + uint16_t mode) +{ + QEMUS390FLICState *flic = QEMU_S390_FLIC(fs); + + switch (mode) { + case SIC_IRQ_MODE_ALL: + flic->simm &= ~AIS_MODE_MASK(isc); + flic->nimm &= ~AIS_MODE_MASK(isc); + break; + case SIC_IRQ_MODE_SINGLE: + flic->simm |= AIS_MODE_MASK(isc); + flic->nimm &= ~AIS_MODE_MASK(isc); + break; + default: + return -EINVAL; + } + + return 0; +} + +static void qemu_s390_flic_reset(DeviceState *dev) +{ + QEMUS390FLICState *flic = QEMU_S390_FLIC(dev); + + flic->simm = 0; + flic->nimm = 0; +} + static void qemu_s390_flic_class_init(ObjectClass *oc, void *data) { + DeviceClass *dc = DEVICE_CLASS(oc); S390FLICStateClass *fsc = S390_FLIC_COMMON_CLASS(oc); + dc->reset = qemu_s390_flic_reset; fsc->register_io_adapter = qemu_s390_register_io_adapter; fsc->io_adapter_map = qemu_s390_io_adapter_map; fsc->add_adapter_routes = qemu_s390_add_adapter_routes; fsc->release_adapter_routes = qemu_s390_release_adapter_routes; fsc->clear_io_irq = qemu_s390_clear_io_flic; + fsc->modify_ais_mode = qemu_s390_modify_ais_mode; } static Property s390_flic_common_properties[] = { @@ -98,12 +130,15 @@ static Property s390_flic_common_properties[] = { static void s390_flic_common_realize(DeviceState *dev, Error **errp) { - uint32_t max_batch = S390_FLIC_COMMON(dev)->adapter_routes_max_batch; + S390FLICState *fs = S390_FLIC_COMMON(dev); + uint32_t max_batch = fs->adapter_routes_max_batch; if (max_batch > ADAPTER_ROUTES_MAX_GSI) { error_setg(errp, "flic property adapter_routes_max_batch too big" " (%d > %d)", max_batch, ADAPTER_ROUTES_MAX_GSI); } + + fs->ais_supported = true; } static void s390_flic_class_init(ObjectClass *oc, void *data) diff --git a/hw/intc/s390_flic_kvm.c b/hw/intc/s390_flic_kvm.c index 15ff534..55aa35f 100644 --- a/hw/intc/s390_flic_kvm.c +++ b/hw/intc/s390_flic_kvm.c @@ -20,6 +20,7 @@ #include "sysemu/kvm.h" #include "hw/s390x/s390_flic.h" #include "hw/s390x/adapter.h" +#include "hw/s390x/css.h" #include "trace.h" #define FLIC_SAVE_INITIAL_SIZE getpagesize() @@ -149,6 +150,26 @@ static int kvm_s390_clear_io_flic(S390FLICState *fs, uint16_t subchannel_id, return rc ? -errno : 0; } +static int kvm_s390_modify_ais_mode(S390FLICState *fs, uint8_t isc, + uint16_t mode) +{ + KVMS390FLICState *flic = KVM_S390_FLIC(fs); + struct kvm_s390_ais_req req = { + .isc = isc, + .mode = mode, + }; + struct kvm_device_attr attr = { + .group = KVM_DEV_FLIC_AISM, + .addr = (uint64_t)&req, + }; + + if (!fs->ais_supported) { + return -ENOSYS; + } + + return ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr) ? -errno : 0; +} + /** * __get_all_irqs - store all pending irqs in buffer * @flic: pointer to flic device state @@ -406,6 +427,7 @@ typedef struct KVMS390FLICStateClass { static void kvm_s390_flic_realize(DeviceState *dev, Error **errp) { + S390FLICState *fs = S390_FLIC_COMMON(dev); KVMS390FLICState *flic_state = KVM_S390_FLIC(dev); struct kvm_create_device cd = {0}; struct kvm_device_attr test_attr = {0}; @@ -438,6 +460,7 @@ static void kvm_s390_flic_realize(DeviceState *dev, Error **errp) flic_state->clear_io_supported = !ioctl(flic_state->fd, KVM_HAS_DEVICE_ATTR, test_attr); + fs->ais_supported = false; return; fail: error_propagate(errp, errp_local); @@ -446,10 +469,12 @@ fail: static void kvm_s390_flic_reset(DeviceState *dev) { KVMS390FLICState *flic = KVM_S390_FLIC(dev); + S390FLICState *fs = S390_FLIC_COMMON(dev); struct kvm_device_attr attr = { .group = KVM_DEV_FLIC_CLEAR_IRQS, }; int rc = 0; + uint8_t isc; if (flic->fd == -1) { return; @@ -457,6 +482,16 @@ static void kvm_s390_flic_reset(DeviceState *dev) flic_disable_wait_pfault(flic); + if (fs->ais_supported) { + for (isc = 0; isc <= MAX_ISC; isc++) { + rc = kvm_s390_modify_ais_mode(fs, isc, SIC_IRQ_MODE_ALL); + if (rc) { + error_report("Failed to reset ais mode for isc %d: %s", + isc, strerror(-rc)); + } + } + } + rc = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr); if (rc) { trace_flic_reset_failed(errno); @@ -479,6 +514,7 @@ static void kvm_s390_flic_class_init(ObjectClass *oc, void *data) fsc->add_adapter_routes = kvm_s390_add_adapter_routes; fsc->release_adapter_routes = kvm_s390_release_adapter_routes; fsc->clear_io_irq = kvm_s390_clear_io_flic; + fsc->modify_ais_mode = kvm_s390_modify_ais_mode; } static const TypeInfo kvm_s390_flic_info = { diff --git a/include/hw/s390x/s390_flic.h b/include/hw/s390x/s390_flic.h index d4145ad..f500184 100644 --- a/include/hw/s390x/s390_flic.h +++ b/include/hw/s390x/s390_flic.h @@ -44,7 +44,7 @@ typedef struct S390FLICState { SysBusDevice parent_obj; /* to limit AdapterRoutes.num_routes for compat */ uint32_t adapter_routes_max_batch; - + bool ais_supported; } S390FLICState; #define S390_FLIC_COMMON_CLASS(klass) \ @@ -63,6 +63,7 @@ typedef struct S390FLICStateClass { void (*release_adapter_routes)(S390FLICState *fs, AdapterRoutes *routes); int (*clear_io_irq)(S390FLICState *fs, uint16_t subchannel_id, uint16_t subchannel_nr); + int (*modify_ais_mode)(S390FLICState *fs, uint8_t isc, uint16_t mode); } S390FLICStateClass; #define TYPE_KVM_S390_FLIC "s390-flic-kvm" @@ -73,8 +74,14 @@ typedef struct S390FLICStateClass { #define QEMU_S390_FLIC(obj) \ OBJECT_CHECK(QEMUS390FLICState, (obj), TYPE_QEMU_S390_FLIC) +#define SIC_IRQ_MODE_ALL 0 +#define SIC_IRQ_MODE_SINGLE 1 +#define AIS_MODE_MASK(isc) (0x80 >> isc) + typedef struct QEMUS390FLICState { S390FLICState parent_obj; + uint8_t simm; + uint8_t nimm; } QEMUS390FLICState; void s390_flic_init(void);