From nobody Wed Oct 29 06:44:02 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 (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1540199106954460.83578326491977; Mon, 22 Oct 2018 02:05:06 -0700 (PDT) Received: from localhost ([::1]:33638 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gEW8w-0001kg-3v for importer@patchew.org; Mon, 22 Oct 2018 05:04:58 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37517) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gEW7I-000126-L1 for qemu-devel@nongnu.org; Mon, 22 Oct 2018 05:03:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gEW7D-0000nc-7x for qemu-devel@nongnu.org; Mon, 22 Oct 2018 05:03:15 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:60096 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 1gEW7C-0000mv-TR for qemu-devel@nongnu.org; Mon, 22 Oct 2018 05:03:11 -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 w9M8xh0O060775 for ; Mon, 22 Oct 2018 05:03:09 -0400 Received: from e36.co.us.ibm.com (e36.co.us.ibm.com [32.97.110.154]) by mx0a-001b2d01.pphosted.com with ESMTP id 2n9b7j0yn9-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 22 Oct 2018 05:03:08 -0400 Received: from localhost by e36.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 22 Oct 2018 03:03:08 -0600 Received: from b03cxnp08026.gho.boulder.ibm.com (9.17.130.18) by e36.co.us.ibm.com (192.168.1.136) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Mon, 22 Oct 2018 03:03:05 -0600 Received: from b03ledav001.gho.boulder.ibm.com (b03ledav001.gho.boulder.ibm.com [9.17.130.232]) by b03cxnp08026.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w9M932dS39256252 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 22 Oct 2018 02:03:02 -0700 Received: from b03ledav001.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 735926E05B; Mon, 22 Oct 2018 09:03:02 +0000 (GMT) Received: from b03ledav001.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E39846E054; Mon, 22 Oct 2018 09:03:00 +0000 (GMT) Received: from zyimindembp.cn.ibm.com (unknown [9.115.192.238]) by b03ledav001.gho.boulder.ibm.com (Postfix) with ESMTP; Mon, 22 Oct 2018 09:03:00 +0000 (GMT) From: Yi Min Zhao To: qemu-devel@nongnu.org Date: Mon, 22 Oct 2018 17:02:55 +0800 X-Mailer: git-send-email 2.17.1 (Apple Git-112) X-TM-AS-GCONF: 00 x-cbid: 18102209-0020-0000-0000-00000E7D97EA X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00009916; HX=3.00000242; KW=3.00000007; PH=3.00000004; SC=3.00000268; SDB=6.01106256; UDB=6.00572865; IPR=6.00886341; MB=3.00023854; MTD=3.00000008; XFM=3.00000015; UTC=2018-10-22 09:03:07 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18102209-0021-0000-0000-00006375BF70 Message-Id: <20181022090255.19671-1-zyimin@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-10-21_14:, , 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=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1807170000 definitions=main-1810220082 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 v2] 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 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 --- Change Log: v2: 1. Use QEMU_BUILD_BUG_MSG for ZpciFmb struct instead of QEMU_PACKED. --- hw/s390x/s390-pci-bus.c | 3 +- hw/s390x/s390-pci-bus.h | 25 ++++++++++ hw/s390x/s390-pci-inst.c | 105 +++++++++++++++++++++++++++++++++++++-- hw/s390x/s390-pci-inst.h | 1 + 4 files changed, 130 insertions(+), 4 deletions(-) diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index e42e1b80d6..6cd23175cd 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -976,6 +976,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; @@ -1147,7 +1148,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..bfbbaca26c 100644 --- a/hw/s390x/s390-pci-bus.h +++ b/hw/s390x/s390-pci-bus.h @@ -286,6 +286,29 @@ 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; +} ZpciFmb; +QEMU_BUILD_BUG_MSG(offsetof(ZpciFmb, fmt0) !=3D 48, "padding in ZpciFmb"); + struct S390PCIBusDevice { DeviceState qdev; PCIDevice *pdev; @@ -297,6 +320,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