From: Zhenzhong Duan Date: Wed, 27 May 2026 05:46:42 +0000 (-0400) Subject: intel_iommu: Create the nested hwpt with IOMMU_HWPT_ALLOC_PASID flag X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=76330797b0eab06ebe2cbf5c8a21953da71ba4ba;p=thirdparty%2Fqemu.git intel_iommu: Create the nested hwpt with IOMMU_HWPT_ALLOC_PASID flag When pasid is enabled, any hwpt attached to non-PASID or PASID should be IOMMU_HWPT_ALLOC_PASID flagged, or else attachment fails. Change vtd_destroy_old_fs_hwpt() to pass in 'VTDHostIOMMUDevice *' for naming consistency. Signed-off-by: Zhenzhong Duan Reviewed-by: Clement Mathieu--Drif Reviewed-by: Yi Liu Tested-by: Xudong Hao Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Message-Id: <20260527054658.1021096-5-zhenzhong.duan@intel.com> --- diff --git a/hw/i386/intel_iommu_accel.c b/hw/i386/intel_iommu_accel.c index 3beadab035..6a12cdac10 100644 --- a/hw/i386/intel_iommu_accel.c +++ b/hw/i386/intel_iommu_accel.c @@ -69,11 +69,13 @@ VTDHostIOMMUDevice *vtd_find_hiod_iommufd(VTDAddressSpace *as) return NULL; } -static bool vtd_create_fs_hwpt(HostIOMMUDeviceIOMMUFD *hiodi, +static bool vtd_create_fs_hwpt(VTDHostIOMMUDevice *vtd_hiod, VTDPASIDEntry *pe, uint32_t *fs_hwpt_id, Error **errp) { + HostIOMMUDeviceIOMMUFD *hiodi = HOST_IOMMU_DEVICE_IOMMUFD(vtd_hiod->hiod); struct iommu_hwpt_vtd_s1 vtd = {}; + uint32_t flags = vtd_hiod->iommu_state->pasid ? IOMMU_HWPT_ALLOC_PASID : 0; vtd.flags = (VTD_SM_PASID_ENTRY_SRE(pe) ? IOMMU_VTD_S1_SRE : 0) | (VTD_SM_PASID_ENTRY_WPE(pe) ? IOMMU_VTD_S1_WPE : 0) | @@ -82,13 +84,16 @@ static bool vtd_create_fs_hwpt(HostIOMMUDeviceIOMMUFD *hiodi, vtd.pgtbl_addr = (uint64_t)vtd_pe_get_fspt_base(pe); return iommufd_backend_alloc_hwpt(hiodi->iommufd, hiodi->devid, - hiodi->hwpt_id, 0, IOMMU_HWPT_DATA_VTD_S1, - sizeof(vtd), &vtd, fs_hwpt_id, errp); + hiodi->hwpt_id, flags, + IOMMU_HWPT_DATA_VTD_S1, sizeof(vtd), &vtd, + fs_hwpt_id, errp); } -static void vtd_destroy_old_fs_hwpt(HostIOMMUDeviceIOMMUFD *hiodi, +static void vtd_destroy_old_fs_hwpt(VTDHostIOMMUDevice *vtd_hiod, VTDAddressSpace *vtd_as) { + HostIOMMUDeviceIOMMUFD *hiodi = HOST_IOMMU_DEVICE_IOMMUFD(vtd_hiod->hiod); + if (!vtd_as->fs_hwpt_id) { return; } @@ -116,7 +121,7 @@ static bool vtd_device_attach_iommufd(VTDHostIOMMUDevice *vtd_hiod, } if (vtd_pe_pgtt_is_fst(pe)) { - if (!vtd_create_fs_hwpt(hiodi, pe, &hwpt_id, errp)) { + if (!vtd_create_fs_hwpt(vtd_hiod, pe, &hwpt_id, errp)) { return false; } } @@ -126,7 +131,7 @@ static bool vtd_device_attach_iommufd(VTDHostIOMMUDevice *vtd_hiod, trace_vtd_device_attach_hwpt(hiodi->devid, IOMMU_NO_PASID, hwpt_id, ret); if (ret) { /* Destroy old fs_hwpt if it's a replacement */ - vtd_destroy_old_fs_hwpt(hiodi, vtd_as); + vtd_destroy_old_fs_hwpt(vtd_hiod, vtd_as); if (vtd_pe_pgtt_is_fst(pe)) { vtd_as->fs_hwpt_id = hwpt_id; } @@ -161,7 +166,7 @@ static bool vtd_device_detach_iommufd(VTDHostIOMMUDevice *vtd_hiod, } if (ret) { - vtd_destroy_old_fs_hwpt(hiodi, vtd_as); + vtd_destroy_old_fs_hwpt(vtd_hiod, vtd_as); } return ret;