From nobody Sat May 4 03:54:31 2024 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1517815590092172.06580009572815; Sun, 4 Feb 2018 23:26:30 -0800 (PST) Received: from localhost ([::1]:34601 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eibAb-0001Oi-7f for importer@patchew.org; Mon, 05 Feb 2018 02:26:29 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44086) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eib7c-0007Qz-OZ for qemu-devel@nongnu.org; Mon, 05 Feb 2018 02:23:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eib7Y-0000gy-NF for qemu-devel@nongnu.org; Mon, 05 Feb 2018 02:23:24 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:56540) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eib7Y-0000gE-Dp for qemu-devel@nongnu.org; Mon, 05 Feb 2018 02:23:20 -0500 Received: from pps.filterd (m0098409.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w157JX5i016080 for ; Mon, 5 Feb 2018 02:23:19 -0500 Received: from e19.ny.us.ibm.com (e19.ny.us.ibm.com [129.33.205.209]) by mx0a-001b2d01.pphosted.com with ESMTP id 2fxj1c1ss0-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Mon, 05 Feb 2018 02:23:19 -0500 Received: from localhost by e19.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 5 Feb 2018 02:23:17 -0500 Received: from b01cxnp23033.gho.pok.ibm.com (9.57.198.28) by e19.ny.us.ibm.com (146.89.104.206) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 5 Feb 2018 02:23:14 -0500 Received: from b01ledav001.gho.pok.ibm.com (b01ledav001.gho.pok.ibm.com [9.57.199.106]) by b01cxnp23033.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w157NEK0262540; Mon, 5 Feb 2018 07:23:14 GMT Received: from b01ledav001.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3225E28050; Mon, 5 Feb 2018 02:22:38 -0500 (EST) Received: from zyimindembp.cn.ibm.com (unknown [9.115.192.114]) by b01ledav001.gho.pok.ibm.com (Postfix) with ESMTP id C307028041; Mon, 5 Feb 2018 02:22:29 -0500 (EST) From: Yi Min Zhao To: qemu-devel@nongnu.org Date: Mon, 5 Feb 2018 15:22:56 +0800 X-Mailer: git-send-email 2.14.3 (Apple Git-98) In-Reply-To: <20180205072258.5968-1-zyimin@linux.vnet.ibm.com> References: <20180205072258.5968-1-zyimin@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18020507-0056-0000-0000-00000415A8A9 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00008474; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000248; SDB=6.00985168; UDB=6.00499851; IPR=6.00764539; BA=6.00005811; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00019368; XFM=3.00000015; UTC=2018-02-05 07:23:16 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18020507-0057-0000-0000-0000084D1644 Message-Id: <20180205072258.5968-2-zyimin@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-02-05_01:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1802050094 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 v2 1/3] s390x/pci: fixup the code walking IOMMU tables 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: pasic@linux.vnet.ibm.com, zyimin@linux.vnet.ibm.com, cohuck@redhat.com, pmorel@linux.vnet.ibm.com, borntraeger@de.ibm.com, alex.williamson@redhat.com, marcel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Current s390x PCI IOMMU code is lack of flags' checking, including: 1) protection bit 2) table length 3) table offset 4) intermediate tables' invalid bit 5) format control bit This patch introduces a new struct named S390IOTLBEntry, and makes up these missed checkings. At the same time, inform the guest with the corresponding error number when the check fails. Finally, in order to get the error number, we export s390_guest_io_table_walk(). Reviewed-by: Pierre Morel Signed-off-by: Yi Min Zhao --- hw/s390x/s390-pci-bus.c | 223 ++++++++++++++++++++++++++++++++++++++-----= ---- hw/s390x/s390-pci-bus.h | 16 ++++ hw/s390x/s390-pci-inst.c | 64 ++++++-------- 3 files changed, 225 insertions(+), 78 deletions(-) diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index 7d9c65e719..e7ef7d28d9 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -309,49 +309,186 @@ static uint64_t get_st_pto(uint64_t entry) : 0; } =20 -static uint64_t s390_guest_io_table_walk(uint64_t guest_iota, - uint64_t guest_dma_address) +static bool rt_entry_isvalid(uint64_t entry) { - uint64_t sto_a, pto_a, px_a; - uint64_t sto, pto, pte; - uint32_t rtx, sx, px; - - rtx =3D calc_rtx(guest_dma_address); - sx =3D calc_sx(guest_dma_address); - px =3D calc_px(guest_dma_address); - - sto_a =3D guest_iota + rtx * sizeof(uint64_t); - sto =3D address_space_ldq(&address_space_memory, sto_a, - MEMTXATTRS_UNSPECIFIED, NULL); - sto =3D get_rt_sto(sto); - if (!sto) { - pte =3D 0; + return (entry & ZPCI_TABLE_VALID_MASK) =3D=3D ZPCI_TABLE_VALID; +} + +static bool pt_entry_isvalid(uint64_t entry) +{ + return (entry & ZPCI_PTE_VALID_MASK) =3D=3D ZPCI_PTE_VALID; +} + +static bool entry_isprotected(uint64_t entry) +{ + return (entry & ZPCI_TABLE_PROT_MASK) =3D=3D ZPCI_TABLE_PROTECTED; +} + +/* ett is expected table type, -1 page table, 0 segment table, 1 region ta= ble */ +static uint64_t get_table_index(uint64_t iova, int8_t ett) +{ + switch (ett) { + case ZPCI_ETT_PT: + return calc_px(iova); + case ZPCI_ETT_ST: + return calc_sx(iova); + case ZPCI_ETT_RT: + return calc_rtx(iova); + } + + return -1; +} + +static bool entry_isvalid(uint64_t entry, int8_t ett) +{ + switch (ett) { + case ZPCI_ETT_PT: + return pt_entry_isvalid(entry); + case ZPCI_ETT_ST: + case ZPCI_ETT_RT: + return rt_entry_isvalid(entry); + } + + return false; +} + +/* Return true if address translation is done */ +static bool translate_iscomplete(uint64_t entry, int8_t ett) +{ + switch (ett) { + case 0: + return (entry & ZPCI_TABLE_FC) ? true : false; + case 1: + return false; + } + + return true; +} + +static uint64_t get_frame_size(int8_t ett) +{ + switch (ett) { + case ZPCI_ETT_PT: + return 1ULL << 12; + case ZPCI_ETT_ST: + return 1ULL << 20; + case ZPCI_ETT_RT: + return 1ULL << 31; + } + + return 0; +} + +static uint64_t get_next_table_origin(uint64_t entry, int8_t ett) +{ + switch (ett) { + case ZPCI_ETT_PT: + return entry & ZPCI_PTE_ADDR_MASK; + case ZPCI_ETT_ST: + return get_st_pto(entry); + case ZPCI_ETT_RT: + return get_rt_sto(entry); + } + + return 0; +} + +/** + * table_translate: do translation within one table and return the followi= ng + * table origin + * + * @entry: the entry being translated, the result is stored in this. + * @to: the address of table origin. + * @ett: expected table type, 1 region table, 0 segment table and -1 page = table. + * @error: error code + */ +static uint64_t table_translate(S390IOTLBEntry *entry, uint64_t to, int8_t= ett, + uint16_t *error) +{ + uint64_t tx, te, nto =3D 0; + uint16_t err =3D 0; + + tx =3D get_table_index(entry->iova, ett); + te =3D address_space_ldq(&address_space_memory, to + tx * sizeof(uint6= 4_t), + MEMTXATTRS_UNSPECIFIED, NULL); + + if (!te) { + err =3D ERR_EVENT_INVALTE; goto out; } =20 - pto_a =3D sto + sx * sizeof(uint64_t); - pto =3D address_space_ldq(&address_space_memory, pto_a, - MEMTXATTRS_UNSPECIFIED, NULL); - pto =3D get_st_pto(pto); - if (!pto) { - pte =3D 0; + if (!entry_isvalid(te, ett)) { + entry->perm &=3D IOMMU_NONE; goto out; } =20 - px_a =3D pto + px * sizeof(uint64_t); - pte =3D address_space_ldq(&address_space_memory, px_a, - MEMTXATTRS_UNSPECIFIED, NULL); + if (ett =3D=3D ZPCI_ETT_RT && ((te & ZPCI_TABLE_LEN_RTX) !=3D ZPCI_TAB= LE_LEN_RTX + || te & ZPCI_TABLE_OFFSET_MASK)) { + err =3D ERR_EVENT_INVALTL; + goto out; + } =20 + nto =3D get_next_table_origin(te, ett); + if (!nto) { + err =3D ERR_EVENT_TT; + goto out; + } + + if (entry_isprotected(te)) { + entry->perm &=3D IOMMU_RO; + } else { + entry->perm &=3D IOMMU_RW; + } + + if (translate_iscomplete(te, ett)) { + switch (ett) { + case ZPCI_ETT_PT: + entry->translated_addr =3D te & ZPCI_PTE_ADDR_MASK; + break; + case ZPCI_ETT_ST: + entry->translated_addr =3D (te & ZPCI_SFAA_MASK) | + (entry->iova & ~ZPCI_SFAA_MASK); + break; + } + nto =3D 0; + } out: - return pte; + if (err) { + entry->perm =3D IOMMU_NONE; + *error =3D err; + } + entry->len =3D get_frame_size(ett); + return nto; +} + +uint16_t s390_guest_io_table_walk(uint64_t g_iota, hwaddr addr, + S390IOTLBEntry *entry) +{ + uint64_t to =3D s390_pci_get_table_origin(g_iota); + int8_t ett =3D 1; + uint16_t error =3D 0; + + entry->iova =3D addr & PAGE_MASK; + entry->translated_addr =3D 0; + entry->perm =3D IOMMU_RW; + + if (entry_isprotected(g_iota)) { + entry->perm &=3D IOMMU_RO; + } + + while (to) { + to =3D table_translate(entry, to, ett--, &error); + } + + return error; } =20 static IOMMUTLBEntry s390_translate_iommu(IOMMUMemoryRegion *mr, hwaddr ad= dr, IOMMUAccessFlags flag) { - uint64_t pte; - uint32_t flags; S390PCIIOMMU *iommu =3D container_of(mr, S390PCIIOMMU, iommu_mr); + S390IOTLBEntry entry; + uint16_t error =3D 0; IOMMUTLBEntry ret =3D { .target_as =3D &address_space_memory, .iova =3D 0, @@ -374,26 +511,26 @@ static IOMMUTLBEntry s390_translate_iommu(IOMMUMemory= Region *mr, hwaddr addr, DPRINTF("iommu trans addr 0x%" PRIx64 "\n", addr); =20 if (addr < iommu->pba || addr > iommu->pal) { - return ret; + error =3D ERR_EVENT_OORANGE; + goto err; } =20 - pte =3D s390_guest_io_table_walk(s390_pci_get_table_origin(iommu->g_io= ta), - addr); - if (!pte) { - return ret; - } + error =3D s390_guest_io_table_walk(iommu->g_iota, addr, &entry); =20 - flags =3D pte & ZPCI_PTE_FLAG_MASK; - ret.iova =3D addr; - ret.translated_addr =3D pte & ZPCI_PTE_ADDR_MASK; - ret.addr_mask =3D 0xfff; + ret.iova =3D entry.iova; + ret.translated_addr =3D entry.translated_addr; + ret.addr_mask =3D entry.len - 1; + ret.perm =3D entry.perm; =20 - if (flags & ZPCI_PTE_INVALID) { - ret.perm =3D IOMMU_NONE; - } else { - ret.perm =3D IOMMU_RW; + if (flag !=3D IOMMU_NONE && !(flag & ret.perm)) { + error =3D ERR_EVENT_TPROTE; + } +err: + if (error) { + iommu->pbdev->state =3D ZPCI_FS_ERROR; + s390_pci_generate_error_event(error, iommu->pbdev->fh, + iommu->pbdev->fid, addr, 0); } - return ret; } =20 diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h index 2993f0ddef..7ed577c806 100644 --- a/hw/s390x/s390-pci-bus.h +++ b/hw/s390x/s390-pci-bus.h @@ -148,6 +148,8 @@ enum ZpciIoatDtype { #define ZPCI_STE_FLAG_MASK 0x7ffULL #define ZPCI_STE_ADDR_MASK (~ZPCI_STE_FLAG_MASK) =20 +#define ZPCI_SFAA_MASK (~((1ULL << 20) - 1)) + /* I/O Page tables */ #define ZPCI_PTE_VALID_MASK 0x400 #define ZPCI_PTE_INVALID 0x400 @@ -165,10 +167,15 @@ enum ZpciIoatDtype { #define ZPCI_TABLE_INVALID 0x20 #define ZPCI_TABLE_PROTECTED 0x200 #define ZPCI_TABLE_UNPROTECTED 0x000 +#define ZPCI_TABLE_FC 0x400 =20 #define ZPCI_TABLE_VALID_MASK 0x20 #define ZPCI_TABLE_PROT_MASK 0x200 =20 +#define ZPCI_ETT_RT 1 +#define ZPCI_ETT_ST 0 +#define ZPCI_ETT_PT -1 + /* PCI Function States * * reserved: default; device has just been plugged or is in progress of be= ing @@ -253,6 +260,13 @@ typedef struct S390MsixInfo { uint32_t pba_offset; } S390MsixInfo; =20 +typedef struct S390IOTLBEntry { + uint64_t iova; + uint64_t translated_addr; + uint64_t len; + uint64_t perm; +} S390IOTLBEntry; + typedef struct S390PCIBusDevice S390PCIBusDevice; typedef struct S390PCIIOMMU { Object parent_obj; @@ -320,6 +334,8 @@ void s390_pci_iommu_enable(S390PCIIOMMU *iommu); void s390_pci_iommu_disable(S390PCIIOMMU *iommu); void s390_pci_generate_error_event(uint16_t pec, uint32_t fh, uint32_t fid, uint64_t faddr, uint32_t e); +uint16_t s390_guest_io_table_walk(uint64_t g_iota, hwaddr addr, + S390IOTLBEntry *entry); S390PCIBusDevice *s390_pci_find_dev_by_idx(S390pciState *s, uint32_t idx); S390PCIBusDevice *s390_pci_find_dev_by_fh(S390pciState *s, uint32_t fh); S390PCIBusDevice *s390_pci_find_dev_by_fid(S390pciState *s, uint32_t fid); diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c index be449210d9..1d33a89351 100644 --- a/hw/s390x/s390-pci-inst.c +++ b/hw/s390x/s390-pci-inst.c @@ -575,23 +575,23 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint= 8_t r2, uintptr_t ra) { CPUS390XState *env =3D &cpu->env; uint32_t fh; + uint16_t error =3D 0; S390PCIBusDevice *pbdev; S390PCIIOMMU *iommu; + S390IOTLBEntry entry; hwaddr start, end; - IOMMUTLBEntry entry; - IOMMUMemoryRegion *iommu_mr; - IOMMUMemoryRegionClass *imrc; + IOMMUTLBEntry notify; =20 cpu_synchronize_state(CPU(cpu)); =20 if (env->psw.mask & PSW_MASK_PSTATE) { s390_program_interrupt(env, PGM_PRIVILEGED, 4, ra); - goto out; + return 0; } =20 if (r2 & 0x1) { s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra); - goto out; + return 0; } =20 fh =3D env->regs[r1] >> 32; @@ -602,7 +602,7 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_= t r2, uintptr_t ra) if (!pbdev) { DPRINTF("rpcit no pci dev\n"); setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE); - goto out; + return 0; } =20 switch (pbdev->state) { @@ -622,44 +622,38 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint= 8_t r2, uintptr_t ra) =20 iommu =3D pbdev->iommu; if (!iommu->g_iota) { - pbdev->state =3D ZPCI_FS_ERROR; - setcc(cpu, ZPCI_PCI_LS_ERR); - s390_set_status_code(env, r1, ZPCI_PCI_ST_INSUF_RES); - s390_pci_generate_error_event(ERR_EVENT_INVALAS, pbdev->fh, pbdev-= >fid, - start, 0); - goto out; + error =3D ERR_EVENT_INVALAS; + goto err; } =20 if (end < iommu->pba || start > iommu->pal) { - pbdev->state =3D ZPCI_FS_ERROR; - setcc(cpu, ZPCI_PCI_LS_ERR); - s390_set_status_code(env, r1, ZPCI_PCI_ST_INSUF_RES); - s390_pci_generate_error_event(ERR_EVENT_OORANGE, pbdev->fh, pbdev-= >fid, - start, 0); - goto out; + error =3D ERR_EVENT_OORANGE; + goto err; } =20 - iommu_mr =3D &iommu->iommu_mr; - imrc =3D IOMMU_MEMORY_REGION_GET_CLASS(iommu_mr); - while (start < end) { - entry =3D imrc->translate(iommu_mr, start, IOMMU_NONE); - - if (!entry.translated_addr) { - pbdev->state =3D ZPCI_FS_ERROR; - setcc(cpu, ZPCI_PCI_LS_ERR); - s390_set_status_code(env, r1, ZPCI_PCI_ST_INSUF_RES); - s390_pci_generate_error_event(ERR_EVENT_SERR, pbdev->fh, pbdev= ->fid, - start, ERR_EVENT_Q_BIT); - goto out; + error =3D s390_guest_io_table_walk(iommu->g_iota, start, &entry); + if (error) { + break; } - - memory_region_notify_iommu(iommu_mr, entry); - start +=3D entry.addr_mask + 1; + notify.target_as =3D &address_space_memory; + notify.iova =3D entry.iova; + notify.translated_addr =3D entry.translated_addr; + notify.addr_mask =3D entry.len - 1; + notify.perm =3D entry.perm; + memory_region_notify_iommu(&iommu->iommu_mr, notify); + start +=3D entry.len; } =20 - setcc(cpu, ZPCI_PCI_LS_OK); -out: +err: + if (error) { + pbdev->state =3D ZPCI_FS_ERROR; + setcc(cpu, ZPCI_PCI_LS_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 { + setcc(cpu, ZPCI_PCI_LS_OK); + } return 0; } =20 --=20 2.14.3 (Apple Git-98) From nobody Sat May 4 03:54:31 2024 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1517815528453956.5592847996918; Sun, 4 Feb 2018 23:25:28 -0800 (PST) Received: from localhost ([::1]:34558 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eib9Y-0000Nr-C0 for importer@patchew.org; Mon, 05 Feb 2018 02:25:24 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44094) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eib7d-0007Ru-Su for qemu-devel@nongnu.org; Mon, 05 Feb 2018 02:23:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eib7Z-0000i9-Ua for qemu-devel@nongnu.org; Mon, 05 Feb 2018 02:23:25 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:32950 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 1eib7Z-0000hO-Ns for qemu-devel@nongnu.org; Mon, 05 Feb 2018 02:23:21 -0500 Received: from pps.filterd (m0098417.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w157JW1c119768 for ; Mon, 5 Feb 2018 02:23:21 -0500 Received: from e16.ny.us.ibm.com (e16.ny.us.ibm.com [129.33.205.206]) by mx0a-001b2d01.pphosted.com with ESMTP id 2fxdbe23h3-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Mon, 05 Feb 2018 02:23:20 -0500 Received: from localhost by e16.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 5 Feb 2018 02:23:20 -0500 Received: from b01cxnp22036.gho.pok.ibm.com (9.57.198.26) by e16.ny.us.ibm.com (146.89.104.203) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 5 Feb 2018 02:23:18 -0500 Received: from b01ledav001.gho.pok.ibm.com (b01ledav001.gho.pok.ibm.com [9.57.199.106]) by b01cxnp22036.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w157NHNZ49217662; Mon, 5 Feb 2018 07:23:17 GMT Received: from b01ledav001.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D9FA028046; Mon, 5 Feb 2018 02:22:41 -0500 (EST) Received: from zyimindembp.cn.ibm.com (unknown [9.115.192.114]) by b01ledav001.gho.pok.ibm.com (Postfix) with ESMTP id A44F12803F; Mon, 5 Feb 2018 02:22:38 -0500 (EST) From: Yi Min Zhao To: qemu-devel@nongnu.org Date: Mon, 5 Feb 2018 15:22:57 +0800 X-Mailer: git-send-email 2.14.3 (Apple Git-98) In-Reply-To: <20180205072258.5968-1-zyimin@linux.vnet.ibm.com> References: <20180205072258.5968-1-zyimin@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18020507-0024-0000-0000-0000031EB7EE X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00008474; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000248; SDB=6.00985168; UDB=6.00499851; IPR=6.00764539; BA=6.00005811; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00019368; XFM=3.00000015; UTC=2018-02-05 07:23:19 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18020507-0025-0000-0000-000046E06669 Message-Id: <20180205072258.5968-3-zyimin@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-02-05_01:, , 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 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1802050094 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 2/3] s390x/pci: fixup global refresh 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: pasic@linux.vnet.ibm.com, zyimin@linux.vnet.ibm.com, cohuck@redhat.com, pmorel@linux.vnet.ibm.com, borntraeger@de.ibm.com, alex.williamson@redhat.com, marcel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The VFIO common code doesn't provide the possibility to modify a previous mapping entry in another way than unmapping and mapping again with new properties. To avoid -EEXIST DMA mapping error, we introduce a GHashTable to store S390IOTLBEntry instances in order to cache the mapped entries. When intercepting rpcit instruction, ignore the identical mapped entries to avoid doing map operations multiple times and do unmap and re-map operations for the case of updating the valid entries. Acked-by: Pierre Morel Signed-off-by: Yi Min Zhao --- hw/s390x/s390-pci-bus.c | 24 +++++++++++++++------- hw/s390x/s390-pci-bus.h | 1 + hw/s390x/s390-pci-inst.c | 53 ++++++++++++++++++++++++++++++++++++++++----= ---- 3 files changed, 63 insertions(+), 15 deletions(-) diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index e7ef7d28d9..77a50cab36 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -487,7 +487,8 @@ static IOMMUTLBEntry s390_translate_iommu(IOMMUMemoryRe= gion *mr, hwaddr addr, IOMMUAccessFlags flag) { S390PCIIOMMU *iommu =3D container_of(mr, S390PCIIOMMU, iommu_mr); - S390IOTLBEntry entry; + S390IOTLBEntry *entry; + uint64_t iova =3D addr & PAGE_MASK; uint16_t error =3D 0; IOMMUTLBEntry ret =3D { .target_as =3D &address_space_memory, @@ -515,12 +516,17 @@ static IOMMUTLBEntry s390_translate_iommu(IOMMUMemory= Region *mr, hwaddr addr, goto err; } =20 - error =3D s390_guest_io_table_walk(iommu->g_iota, addr, &entry); - - ret.iova =3D entry.iova; - ret.translated_addr =3D entry.translated_addr; - ret.addr_mask =3D entry.len - 1; - ret.perm =3D entry.perm; + entry =3D g_hash_table_lookup(iommu->iotlb, &iova); + if (entry) { + ret.iova =3D entry->iova; + ret.translated_addr =3D entry->translated_addr; + ret.addr_mask =3D entry->len - 1; + ret.perm =3D entry->perm; + } else { + ret.iova =3D iova; + ret.addr_mask =3D ~PAGE_MASK; + ret.perm =3D IOMMU_NONE; + } =20 if (flag !=3D IOMMU_NONE && !(flag & ret.perm)) { error =3D ERR_EVENT_TPROTE; @@ -572,6 +578,8 @@ static S390PCIIOMMU *s390_pci_get_iommu(S390pciState *s= , PCIBus *bus, PCI_FUNC(devfn)); memory_region_init(&iommu->mr, OBJECT(iommu), mr_name, UINT64_MAX); address_space_init(&iommu->as, &iommu->mr, as_name); + iommu->iotlb =3D g_hash_table_new_full(g_int64_hash, g_int64_equal, + NULL, g_free); table->iommu[PCI_SLOT(devfn)] =3D iommu; =20 g_free(mr_name); @@ -661,6 +669,7 @@ void s390_pci_iommu_enable(S390PCIIOMMU *iommu) void s390_pci_iommu_disable(S390PCIIOMMU *iommu) { iommu->enabled =3D false; + g_hash_table_remove_all(iommu->iotlb); memory_region_del_subregion(&iommu->mr, MEMORY_REGION(&iommu->iommu_mr= )); object_unparent(OBJECT(&iommu->iommu_mr)); } @@ -676,6 +685,7 @@ static void s390_pci_iommu_free(S390pciState *s, PCIBus= *bus, int32_t devfn) } =20 table->iommu[PCI_SLOT(devfn)] =3D NULL; + g_hash_table_destroy(iommu->iotlb); address_space_destroy(&iommu->as); object_unparent(OBJECT(&iommu->mr)); object_unparent(OBJECT(iommu)); diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h index 7ed577c806..1f7f9b5814 100644 --- a/hw/s390x/s390-pci-bus.h +++ b/hw/s390x/s390-pci-bus.h @@ -278,6 +278,7 @@ typedef struct S390PCIIOMMU { uint64_t g_iota; uint64_t pba; uint64_t pal; + GHashTable *iotlb; } S390PCIIOMMU; =20 typedef struct S390PCIIOMMUTable { diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c index 1d33a89351..997a9cc2e9 100644 --- a/hw/s390x/s390-pci-inst.c +++ b/hw/s390x/s390-pci-inst.c @@ -571,6 +571,45 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint= 8_t r2, uintptr_t ra) return 0; } =20 +static void s390_pci_update_iotlb(S390PCIIOMMU *iommu, S390IOTLBEntry *ent= ry) +{ + S390IOTLBEntry *cache =3D g_hash_table_lookup(iommu->iotlb, &entry->io= va); + IOMMUTLBEntry notify =3D { + .target_as =3D &address_space_memory, + .iova =3D entry->iova, + .translated_addr =3D entry->translated_addr, + .perm =3D entry->perm, + .addr_mask =3D ~PAGE_MASK, + }; + + if (entry->perm =3D=3D IOMMU_NONE) { + if (!cache) { + return; + } + g_hash_table_remove(iommu->iotlb, &entry->iova); + } else { + if (cache) { + if (cache->perm =3D=3D entry->perm && + cache->translated_addr =3D=3D entry->translated_addr) { + return; + } + + notify.perm =3D IOMMU_NONE; + memory_region_notify_iommu(&iommu->iommu_mr, notify); + notify.perm =3D entry->perm; + } + + cache =3D g_new(S390IOTLBEntry, 1); + cache->iova =3D entry->iova; + cache->translated_addr =3D entry->translated_addr; + cache->len =3D PAGE_SIZE; + cache->perm =3D entry->perm; + g_hash_table_replace(iommu->iotlb, &cache->iova, cache); + } + + memory_region_notify_iommu(&iommu->iommu_mr, notify); +} + int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra) { CPUS390XState *env =3D &cpu->env; @@ -580,7 +619,6 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_= t r2, uintptr_t ra) S390PCIIOMMU *iommu; S390IOTLBEntry entry; hwaddr start, end; - IOMMUTLBEntry notify; =20 cpu_synchronize_state(CPU(cpu)); =20 @@ -636,15 +674,14 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint= 8_t r2, uintptr_t ra) if (error) { break; } - notify.target_as =3D &address_space_memory; - notify.iova =3D entry.iova; - notify.translated_addr =3D entry.translated_addr; - notify.addr_mask =3D entry.len - 1; - notify.perm =3D entry.perm; - memory_region_notify_iommu(&iommu->iommu_mr, notify); + start +=3D entry.len; + while (entry.iova < start && entry.iova < end) { + s390_pci_update_iotlb(iommu, &entry); + entry.iova +=3D PAGE_SIZE; + entry.translated_addr +=3D PAGE_SIZE; + } } - err: if (error) { pbdev->state =3D ZPCI_FS_ERROR; --=20 2.14.3 (Apple Git-98) From nobody Sat May 4 03:54:31 2024 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1517815682421388.8547474068521; Sun, 4 Feb 2018 23:28:02 -0800 (PST) Received: from localhost ([::1]:34813 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eibC5-0002xi-Np for importer@patchew.org; Mon, 05 Feb 2018 02:28:01 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44122) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eib7k-0007YB-HL for qemu-devel@nongnu.org; Mon, 05 Feb 2018 02:23:36 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eib7g-0000sK-He for qemu-devel@nongnu.org; Mon, 05 Feb 2018 02:23:32 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:39312 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 1eib7g-0000s5-CK for qemu-devel@nongnu.org; Mon, 05 Feb 2018 02:23:28 -0500 Received: from pps.filterd (m0098420.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w157JY4r082799 for ; Mon, 5 Feb 2018 02:23:24 -0500 Received: from e11.ny.us.ibm.com (e11.ny.us.ibm.com [129.33.205.201]) by mx0b-001b2d01.pphosted.com with ESMTP id 2fxepxqdky-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Mon, 05 Feb 2018 02:23:23 -0500 Received: from localhost by e11.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 5 Feb 2018 02:23:23 -0500 Received: from b01cxnp23034.gho.pok.ibm.com (9.57.198.29) by e11.ny.us.ibm.com (146.89.104.198) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 5 Feb 2018 02:23:21 -0500 Received: from b01ledav001.gho.pok.ibm.com (b01ledav001.gho.pok.ibm.com [9.57.199.106]) by b01cxnp23034.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w157NKjr45482158; Mon, 5 Feb 2018 07:23:20 GMT Received: from b01ledav001.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 0CA6A28048; Mon, 5 Feb 2018 02:22:45 -0500 (EST) Received: from zyimindembp.cn.ibm.com (unknown [9.115.192.114]) by b01ledav001.gho.pok.ibm.com (Postfix) with ESMTP id 546CC2803D; Mon, 5 Feb 2018 02:22:42 -0500 (EST) From: Yi Min Zhao To: qemu-devel@nongnu.org Date: Mon, 5 Feb 2018 15:22:58 +0800 X-Mailer: git-send-email 2.14.3 (Apple Git-98) In-Reply-To: <20180205072258.5968-1-zyimin@linux.vnet.ibm.com> References: <20180205072258.5968-1-zyimin@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18020507-2213-0000-0000-00000267BDA5 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00008474; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000248; SDB=6.00985168; UDB=6.00499851; IPR=6.00764539; BA=6.00005811; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00019368; XFM=3.00000015; UTC=2018-02-05 07:23:22 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18020507-2214-0000-0000-0000590168AD Message-Id: <20180205072258.5968-4-zyimin@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-02-05_01:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1802050094 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 3/3] s390x/pci: use the right pal and pba in reg_ioat() 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: pasic@linux.vnet.ibm.com, zyimin@linux.vnet.ibm.com, cohuck@redhat.com, pmorel@linux.vnet.ibm.com, borntraeger@de.ibm.com, alex.williamson@redhat.com, marcel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" When registering ioat, pba should be comprised of leftmost 52 bits and rightmost 12 binary zeros, and pal should be comprised of leftmost 52 bits and right most 12 binary ones. The lower 12 bits of words 5 and 7 of the FIB are ignored by the facility. Let's fixup this. Reviewed-by: Pierre Morel Signed-off-by: Yi Min Zhao --- hw/s390x/s390-pci-inst.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c index 997a9cc2e9..3fcc330fe3 100644 --- a/hw/s390x/s390-pci-inst.c +++ b/hw/s390x/s390-pci-inst.c @@ -865,6 +865,8 @@ static int reg_ioat(CPUS390XState *env, S390PCIIOMMU *i= ommu, ZpciFib fib, uint8_t dt =3D (g_iota >> 2) & 0x7; uint8_t t =3D (g_iota >> 11) & 0x1; =20 + pba &=3D ~0xfff; + pal |=3D 0xfff; if (pba > pal || pba < ZPCI_SDMA_ADDR || pal > ZPCI_EDMA_ADDR) { s390_program_interrupt(env, PGM_OPERAND, 6, ra); return -EINVAL; --=20 2.14.3 (Apple Git-98)