From nobody Sat Nov 15 08:35:15 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass header.i=@intel.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1753781010; cv=none; d=zohomail.com; s=zohoarc; b=RuN/aQqZdfYBEv6mvwjQdxwrKA56gEEzbecBgCw0m8U/dj3l1QqG3oxFoG4IhQuuamTUgVJEy16c5untwcHBXLUPptgsQGdAtHwe4pHhQfZgDqjizbYL/jhLRlitTzSNcya4PdbIyaNjK/ceQ0jZMIhdnHZnZkdKoQN8RVBVW3k= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753781010; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=zE367n9eqfimoyyldo5VwYSpb7hrqHQJYQAoQACN9fI=; b=FuHvxWJhpe2NdK6b4HIfIfDuwk/kpey66w2k1p8qag7ysbVnBlY7fgDBXdltQFMrDg9lDCX4K2DS6IVtwAYfGwKHb7XRQBh/3ZB9fz4SFQiNlsvugw+ru8P9pXLrC2RLvIs3+Lfz9pJKTv/5JRztUIJPxjle3jxYNqYkOX8uSRM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=@intel.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1753781010664809.837370091606; Tue, 29 Jul 2025 02:23:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uggXp-0007jA-Q3; Tue, 29 Jul 2025 05:22:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uggXg-0006YS-6e for qemu-devel@nongnu.org; Tue, 29 Jul 2025 05:22:40 -0400 Received: from mgamail.intel.com ([192.198.163.17]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uggXd-0002ij-Ok for qemu-devel@nongnu.org; Tue, 29 Jul 2025 05:22:39 -0400 Received: from orviesa007.jf.intel.com ([10.64.159.147]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Jul 2025 02:22:26 -0700 Received: from unknown (HELO gnr-sp-2s-612.sh.intel.com) ([10.112.230.229]) by orviesa007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Jul 2025 02:22:07 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1753780958; x=1785316958; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=A7ziMebD1eq3SZROnPapkMEc5GJkaqLHyMAAW5H6z3A=; b=L3QEjUBj9rePGTOSV09VHOtiQ4ev+FOVSf2ZUfrjmcQlhBaT1Xm4h0tG 2JFW6qcplZR65JpBP1vFuw3q+AMTqBS2O5AG55a0tMng/f9bURVNE+khX mGspvJ9byaBALv/KA1DAtLzRC7NM2zvn0LXLzaCV3knP9LPbgFiWqKcu3 ZSf5TgJjwIHI6QJEpOse5inzilZCD3fITsRfAeSYsAMj0WXepTh+vugxs xlnN8Yiyp/pWgvNjmTugdyft3t/Lk72TxugHatuvYNb8ZsTUQ8FgWmLFd SxLtr4PipE21Jne3iT4l0daV7ssKPTaX96uKmiiYNLGD1RARYmdEDgzcj w==; X-CSE-ConnectionGUID: oPOCvgrVTyy8aksCpN+K8w== X-CSE-MsgGUID: M63kihxtT5aFDTjtI/0oYA== X-IronPort-AV: E=McAfee;i="6800,10657,11505"; a="55982045" X-IronPort-AV: E=Sophos;i="6.16,348,1744095600"; d="scan'208";a="55982045" X-CSE-ConnectionGUID: 0C8IJTgtQ72AXrhcC9N2RA== X-CSE-MsgGUID: MaehrCswTT6Nlh/SyBn+5g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.16,348,1744095600"; d="scan'208";a="162691441" From: Zhenzhong Duan To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, eric.auger@redhat.com, mst@redhat.com, jasowang@redhat.com, peterx@redhat.com, ddutile@redhat.com, jgg@nvidia.com, nicolinc@nvidia.com, shameerali.kolothum.thodi@huawei.com, joao.m.martins@oracle.com, clement.mathieu--drif@eviden.com, kevin.tian@intel.com, yi.l.liu@intel.com, chao.p.peng@intel.com, Yi Sun , Zhenzhong Duan Subject: [PATCH v4 16/20] intel_iommu: Propagate PASID-based iotlb invalidation to host Date: Tue, 29 Jul 2025 05:20:38 -0400 Message-ID: <20250729092043.785836-17-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250729092043.785836-1-zhenzhong.duan@intel.com> References: <20250729092043.785836-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=192.198.163.17; envelope-from=zhenzhong.duan@intel.com; helo=mgamail.intel.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @intel.com) X-ZM-MESSAGEID: 1753781012236116600 Content-Type: text/plain; charset="utf-8" From: Yi Liu This traps the guest PASID-based iotlb invalidation request and propagate it to host. Intel VT-d 3.0 supports nested translation in PASID granularity. Guest SVA support could be implemented by configuring nested translation on specific pasid. This is also known as dual stage DMA translation. Under such configuration, guest owns the GVA->GPA translation which is configured as stage-1 page table on host side for a specific pasid, and host owns GPA->HPA translation. As guest owns stage-1 translation table, piotlb invalidation should be propagated to host since host IOMMU will cache first level page table related mappings during DMA address translation. Signed-off-by: Yi Liu Signed-off-by: Yi Sun Signed-off-by: Zhenzhong Duan --- hw/i386/intel_iommu_internal.h | 6 +++ hw/i386/intel_iommu.c | 95 +++++++++++++++++++++++++++++++++- 2 files changed, 99 insertions(+), 2 deletions(-) diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index 8af1004888..c1a9263651 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -596,6 +596,12 @@ typedef struct VTDPASIDCacheInfo { uint16_t devfn; } VTDPASIDCacheInfo; =20 +typedef struct VTDPIOTLBInvInfo { + uint16_t domain_id; + uint32_t pasid; + struct iommu_hwpt_vtd_s1_invalidate *inv_data; +} VTDPIOTLBInvInfo; + /* PASID Table Related Definitions */ #define VTD_PASID_DIR_BASE_ADDR_MASK (~0xfffULL) #define VTD_PASID_TABLE_BASE_ADDR_MASK (~0xfffULL) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 6620e975f3..27bd8c4c89 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -2611,12 +2611,99 @@ static int vtd_bind_guest_pasid(VTDAddressSpace *vt= d_as, VTDPASIDOp op, =20 return ret; } + +static void +vtd_invalidate_piotlb_locked(VTDAddressSpace *vtd_as, + struct iommu_hwpt_vtd_s1_invalidate *cache) +{ + IntelIOMMUState *s =3D vtd_as->iommu_state; + VTDHostIOMMUDevice *vtd_hiod =3D vtd_find_hiod_iommufd(s, vtd_as); + HostIOMMUDeviceIOMMUFD *idev; + uint32_t entry_num =3D 1; /* Only implement one request for simplicity= */ + Error *local_err =3D NULL; + + if (!vtd_hiod || !vtd_as->s1_hwpt) { + return; + } + idev =3D HOST_IOMMU_DEVICE_IOMMUFD(vtd_hiod->hiod); + + if (!iommufd_backend_invalidate_cache(idev->iommufd, vtd_as->s1_hwpt, + IOMMU_HWPT_INVALIDATE_DATA_VTD_S= 1, + sizeof(*cache), &entry_num, cach= e, + &local_err)) { + /* Something wrong in kernel, but trying to continue */ + error_report_err(local_err); + } +} + +/* + * This function is a loop function for the s->vtd_address_spaces + * list with VTDPIOTLBInvInfo as execution filter. It propagates + * the piotlb invalidation to host. + */ +static void vtd_flush_host_piotlb_locked(gpointer key, gpointer value, + gpointer user_data) +{ + VTDPIOTLBInvInfo *piotlb_info =3D user_data; + VTDAddressSpace *vtd_as =3D value; + VTDPASIDCacheEntry *pc_entry =3D &vtd_as->pasid_cache_entry; + uint32_t pasid; + uint16_t did; + + /* Replay only fills pasid entry cache for passthrough device */ + if (!pc_entry->valid || + !vtd_pe_pgtt_is_flt(&pc_entry->pasid_entry)) { + return; + } + + if (vtd_as_to_iommu_pasid_locked(vtd_as, &pasid)) { + return; + } + + did =3D VTD_SM_PASID_ENTRY_DID(&pc_entry->pasid_entry); + + if (piotlb_info->domain_id =3D=3D did && piotlb_info->pasid =3D=3D pas= id) { + vtd_invalidate_piotlb_locked(vtd_as, piotlb_info->inv_data); + } +} + +static void +vtd_flush_host_piotlb_all_locked(IntelIOMMUState *s, + uint16_t domain_id, uint32_t pasid, + hwaddr addr, uint64_t npages, bool ih) +{ + struct iommu_hwpt_vtd_s1_invalidate cache_info =3D { 0 }; + VTDPIOTLBInvInfo piotlb_info; + + cache_info.addr =3D addr; + cache_info.npages =3D npages; + cache_info.flags =3D ih ? IOMMU_VTD_INV_FLAGS_LEAF : 0; + + piotlb_info.domain_id =3D domain_id; + piotlb_info.pasid =3D pasid; + piotlb_info.inv_data =3D &cache_info; + + /* + * Go through each vtd_as instance in s->vtd_address_spaces, find out + * the affected host device which need host piotlb invalidation. Piotlb + * invalidation should check pasid cache per architecture point of vie= w. + */ + g_hash_table_foreach(s->vtd_address_spaces, + vtd_flush_host_piotlb_locked, &piotlb_info); +} #else static int vtd_bind_guest_pasid(VTDAddressSpace *vtd_as, VTDPASIDOp op, Error **errp) { return 0; } + +static void +vtd_flush_host_piotlb_all_locked(IntelIOMMUState *s, + uint16_t domain_id, uint32_t pasid, + hwaddr addr, uint64_t npages, bool ih) +{ +} #endif =20 static int vtd_bind_guest_pasid_report_err(VTDAddressSpace *vtd_as, @@ -3292,6 +3379,7 @@ static void vtd_piotlb_pasid_invalidate(IntelIOMMUSta= te *s, vtd_iommu_lock(s); g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_pasid, &info); + vtd_flush_host_piotlb_all_locked(s, domain_id, pasid, 0, (uint64_t)-1,= 0); vtd_iommu_unlock(s); =20 QLIST_FOREACH(vtd_as, &s->vtd_as_with_notifiers, next) { @@ -3313,7 +3401,8 @@ static void vtd_piotlb_pasid_invalidate(IntelIOMMUSta= te *s, } =20 static void vtd_piotlb_page_invalidate(IntelIOMMUState *s, uint16_t domain= _id, - uint32_t pasid, hwaddr addr, uint8_= t am) + uint32_t pasid, hwaddr addr, uint8_= t am, + bool ih) { VTDIOTLBPageInvInfo info; =20 @@ -3325,6 +3414,7 @@ static void vtd_piotlb_page_invalidate(IntelIOMMUStat= e *s, uint16_t domain_id, vtd_iommu_lock(s); g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_page_piotlb, &info); + vtd_flush_host_piotlb_all_locked(s, domain_id, pasid, addr, 1 << am, i= h); vtd_iommu_unlock(s); =20 vtd_iotlb_page_invalidate_notify(s, domain_id, addr, am, pasid); @@ -3356,7 +3446,8 @@ static bool vtd_process_piotlb_desc(IntelIOMMUState *= s, case VTD_INV_DESC_PIOTLB_PSI_IN_PASID: am =3D VTD_INV_DESC_PIOTLB_AM(inv_desc->val[1]); addr =3D (hwaddr) VTD_INV_DESC_PIOTLB_ADDR(inv_desc->val[1]); - vtd_piotlb_page_invalidate(s, domain_id, pasid, addr, am); + vtd_piotlb_page_invalidate(s, domain_id, pasid, addr, am, + VTD_INV_DESC_PIOTLB_IH(inv_desc->val[1]= )); break; =20 default: --=20 2.47.1