From nobody Wed Nov 5 16:56:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linux.ibm.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 153605264763542.96038426545317; Tue, 4 Sep 2018 02:17:27 -0700 (PDT) Received: from localhost ([::1]:49771 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fx7SY-00078K-Au for importer@patchew.org; Tue, 04 Sep 2018 05:17:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46117) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fx7RN-0006S0-Ty for qemu-devel@nongnu.org; Tue, 04 Sep 2018 05:16:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fx7RJ-0001el-TV for qemu-devel@nongnu.org; Tue, 04 Sep 2018 05:16:05 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:46784 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 1fx7RJ-0001eD-N1 for qemu-devel@nongnu.org; Tue, 04 Sep 2018 05:16:01 -0400 Received: from pps.filterd (m0098421.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w849ERON096791 for ; Tue, 4 Sep 2018 05:16:00 -0400 Received: from e33.co.us.ibm.com (e33.co.us.ibm.com [32.97.110.151]) by mx0a-001b2d01.pphosted.com with ESMTP id 2m9mfhfddm-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 04 Sep 2018 05:15:59 -0400 Received: from localhost by e33.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 4 Sep 2018 03:15:58 -0600 Received: from b03cxnp08028.gho.boulder.ibm.com (9.17.130.20) by e33.co.us.ibm.com (192.168.1.133) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Tue, 4 Sep 2018 03:15:56 -0600 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp08028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w849FrKX26083414 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 4 Sep 2018 02:15:53 -0700 Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 520BCBE054; Tue, 4 Sep 2018 03:15:53 -0600 (MDT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A1163BE051; Tue, 4 Sep 2018 03:15:51 -0600 (MDT) Received: from zyimindembp.cn.ibm.com (unknown [9.115.193.142]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 4 Sep 2018 03:15:51 -0600 (MDT) From: Yi Min Zhao To: qemu-devel@nongnu.org Date: Tue, 4 Sep 2018 17:15:49 +0800 X-Mailer: git-send-email 2.15.2 (Apple Git-101.1) X-TM-AS-GCONF: 00 x-cbid: 18090409-0036-0000-0000-00000A309F64 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00009668; HX=3.00000242; KW=3.00000007; PH=3.00000004; SC=3.00000266; SDB=6.01083339; UDB=6.00559062; IPR=6.00863339; MB=3.00023102; MTD=3.00000008; XFM=3.00000015; UTC=2018-09-04 09:15:57 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18090409-0037-0000-0000-000048D22ACE Message-Id: <20180904091549.6361-1-zyimin@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-09-04_05:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=3 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=981 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1807170000 definitions=main-1809040097 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.158.5 Subject: [Qemu-devel] [PATCH] s390x/pci: add common fmb 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: borntraeger@de.ibm.com, thuth@redhat.com, cohuck@redhat.com, pmorel@linux.ibm.com, zyimin@linux.ibm.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Common function measurement block is used to report counters of successfully issued pcilg/stg/stb and rpcit instructions. This patch introduces a new struct ZpciFmb and schedules a timer callback to copy fmb to the guest memory at a interval time which is set to 4s by default. While attemping to update fmb failed, an event error would be generated. After pcilg/stg/stb and rpcit interception handlers issue successfully, increase the related counter. The guest could pass null address to switch off FMB and stop corresponding timer. Signed-off-by: Yi Min Zhao Reviewed-by: Pierre Morel --- hw/s390x/s390-pci-bus.c | 3 +- hw/s390x/s390-pci-bus.h | 24 +++++++++++ hw/s390x/s390-pci-inst.c | 105 +++++++++++++++++++++++++++++++++++++++++++= ++-- hw/s390x/s390-pci-inst.h | 1 + 4 files changed, 129 insertions(+), 4 deletions(-) diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index e3e0ebb7f6..7bd0b9d1e5 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -967,6 +967,7 @@ static void s390_pcihost_hot_unplug(HotplugHandler *hot= plug_dev, bus =3D pci_get_bus(pci_dev); devfn =3D pci_dev->devfn; object_unparent(OBJECT(pci_dev)); + fmb_timer_free(pbdev); s390_pci_msix_free(pbdev); s390_pci_iommu_free(s, bus, devfn); pbdev->pdev =3D NULL; @@ -1139,7 +1140,7 @@ static void s390_pci_device_reset(DeviceState *dev) pci_dereg_ioat(pbdev->iommu); } =20 - pbdev->fmb_addr =3D 0; + fmb_timer_free(pbdev); } =20 static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name, diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h index 1f7f9b5814..fdf13a19c0 100644 --- a/hw/s390x/s390-pci-bus.h +++ b/hw/s390x/s390-pci-bus.h @@ -286,6 +286,28 @@ typedef struct S390PCIIOMMUTable { S390PCIIOMMU *iommu[PCI_SLOT_MAX]; } S390PCIIOMMUTable; =20 +/* Function Measurement Block */ +#define DEFAULT_MUI 4000 +#define UPDATE_U_BIT 0x1ULL +#define FMBK_MASK 0xfULL + +typedef struct ZpciFmbFmt0 { + uint64_t dma_rbytes; + uint64_t dma_wbytes; +} ZpciFmbFmt0; + +typedef struct ZpciFmb { + uint8_t format; + uint8_t fmt_ind[3]; + uint32_t sample; + uint64_t last_update; + uint64_t ld_ops; + uint64_t st_ops; + uint64_t stb_ops; + uint64_t rpcit_ops; + ZpciFmbFmt0 fmt0; +} QEMU_PACKED __attribute((__aligned__(8))) ZpciFmb; + struct S390PCIBusDevice { DeviceState qdev; PCIDevice *pdev; @@ -297,6 +319,8 @@ struct S390PCIBusDevice { uint32_t fid; bool fid_defined; uint64_t fmb_addr; + ZpciFmb fmb; + QEMUTimer *fmb_timer; uint8_t isc; uint16_t noi; uint16_t maxstbl; diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c index 7b61367ee3..1ed5cb91d0 100644 --- a/hw/s390x/s390-pci-inst.c +++ b/hw/s390x/s390-pci-inst.c @@ -19,6 +19,7 @@ #include "exec/memory-internal.h" #include "qemu/error-report.h" #include "sysemu/hw_accel.h" +#include "hw/s390x/tod.h" =20 #ifndef DEBUG_S390PCI_INST #define DEBUG_S390PCI_INST 0 @@ -293,7 +294,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_= t ra) resgrp->fr =3D 1; stq_p(&resgrp->dasm, 0); stq_p(&resgrp->msia, ZPCI_MSI_ADDR); - stw_p(&resgrp->mui, 0); + stw_p(&resgrp->mui, DEFAULT_MUI); stw_p(&resgrp->i, 128); stw_p(&resgrp->maxstbl, 128); resgrp->version =3D 0; @@ -456,6 +457,10 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8= _t r2, uintptr_t ra) return 0; } =20 + if (pbdev->fmb_addr) { + pbdev->fmb.ld_ops++; + } + env->regs[r1] =3D data; setcc(cpu, ZPCI_PCI_LS_OK); return 0; @@ -561,6 +566,10 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint= 8_t r2, uintptr_t ra) return 0; } =20 + if (pbdev->fmb_addr) { + pbdev->fmb.st_ops++; + } + setcc(cpu, ZPCI_PCI_LS_OK); return 0; } @@ -681,6 +690,9 @@ err: s390_set_status_code(env, r1, ZPCI_PCI_ST_FUNC_IN_ERR); s390_pci_generate_error_event(error, pbdev->fh, pbdev->fid, start,= 0); } else { + if (pbdev->fmb_addr) { + pbdev->fmb.rpcit_ops++; + } setcc(cpu, ZPCI_PCI_LS_OK); } return 0; @@ -783,6 +795,10 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint= 8_t r3, uint64_t gaddr, } } =20 + if (pbdev->fmb_addr) { + pbdev->fmb.stb_ops++; + } + setcc(cpu, ZPCI_PCI_LS_OK); return 0; =20 @@ -889,6 +905,63 @@ void pci_dereg_ioat(S390PCIIOMMU *iommu) iommu->g_iota =3D 0; } =20 +void fmb_timer_free(S390PCIBusDevice *pbdev) +{ + if (pbdev->fmb_timer) { + timer_del(pbdev->fmb_timer); + timer_free(pbdev->fmb_timer); + pbdev->fmb_timer =3D NULL; + } + pbdev->fmb_addr =3D 0; + memset(&pbdev->fmb, 0, sizeof(ZpciFmb)); +} + +static int fmb_do_update(S390PCIBusDevice *pbdev, uint8_t offset, int len) +{ + MemTxResult ret; + + ret =3D address_space_write(&address_space_memory, + pbdev->fmb_addr + (uint64_t)offset, + MEMTXATTRS_UNSPECIFIED, + (uint8_t *)&pbdev->fmb + offset, + len); + if (ret) { + s390_pci_generate_error_event(ERR_EVENT_FMBA, pbdev->fh, pbdev->fi= d, + pbdev->fmb_addr, 0); + fmb_timer_free(pbdev); + } + + return ret; +} + +static void fmb_update(void *opaque) +{ + S390PCIBusDevice *pbdev =3D opaque; + int64_t t =3D qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); + uint8_t offset =3D offsetof(ZpciFmb, last_update); + + /* Update U bit */ + pbdev->fmb.last_update |=3D UPDATE_U_BIT; + if (fmb_do_update(pbdev, offset, sizeof(uint64_t))) { + return; + } + + /* Update FMB counters */ + pbdev->fmb.sample++; + if (fmb_do_update(pbdev, 0, sizeof(ZpciFmb))) { + return; + } + + /* Clear U bit and update the time */ + pbdev->fmb.last_update =3D time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTU= AL)); + pbdev->fmb.last_update &=3D ~UPDATE_U_BIT; + if (fmb_do_update(pbdev, offset, sizeof(uint64_t))) { + return; + } + + timer_mod(pbdev->fmb_timer, t + DEFAULT_MUI); +} + int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t a= r, uintptr_t ra) { @@ -1018,9 +1091,35 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, ui= nt64_t fiba, uint8_t ar, s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE); } break; - case ZPCI_MOD_FC_SET_MEASURE: - pbdev->fmb_addr =3D ldq_p(&fib.fmb_addr); + case ZPCI_MOD_FC_SET_MEASURE: { + uint64_t fmb_addr =3D ldq_p(&fib.fmb_addr); + + if (fmb_addr & FMBK_MASK) { + cc =3D ZPCI_PCI_LS_ERR; + s390_pci_generate_error_event(ERR_EVENT_FMBPRO, pbdev->fh, + pbdev->fid, fmb_addr, 0); + fmb_timer_free(pbdev); + break; + } + + if (!fmb_addr) { + /* Stop updating FMB. */ + fmb_timer_free(pbdev); + break; + } + + pbdev->fmb_addr =3D fmb_addr; + if (!pbdev->fmb_timer) { + pbdev->fmb_timer =3D timer_new_ms(QEMU_CLOCK_VIRTUAL, + fmb_update, pbdev); + } else if (timer_pending(pbdev->fmb_timer)) { + /* Remove pending timer to update FMB address. */ + timer_del(pbdev->fmb_timer); + } + timer_mod(pbdev->fmb_timer, + qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + DEFAULT_MUI); break; + } default: s390_program_interrupt(&cpu->env, PGM_OPERAND, 6, ra); cc =3D ZPCI_PCI_LS_ERR; diff --git a/hw/s390x/s390-pci-inst.h b/hw/s390x/s390-pci-inst.h index 91c3d61f2a..fa3bf8b5aa 100644 --- a/hw/s390x/s390-pci-inst.h +++ b/hw/s390x/s390-pci-inst.h @@ -303,6 +303,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint6= 4_t fiba, uint8_t ar, uintptr_t ra); int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t = ar, uintptr_t ra); +void fmb_timer_free(S390PCIBusDevice *pbdev); =20 #define ZPCI_IO_BAR_MIN 0 #define ZPCI_IO_BAR_MAX 5 --=20 Yi Min