On a system influenced by ERRATA_772415, IOMMU_HW_INFO_VTD_ERRATA_772415_SPR17 is repored by IOMMU_DEVICE_GET_HW_INFO. Due to this errata, even the readonly range mapped on stage-2 page table could still be written.
Reference from 4th Gen Intel Xeon Processor Scalable Family Specification Update, Errata Details, SPR17. https://edc.intel.com/content/www/us/en/design/products-and-solutions/processors-and-chipsets/eagle-stream/sapphire-rapids-specification-update/ Also copied the SPR17 details from above link: "Problem: When remapping hardware is configured by system software in scalable mode as Nested (PGTT=011b) and with PWSNP field Set in the PASID-table-entry, it may Set Accessed bit and Dirty bit (and Extended Access bit if enabled) in first-stage page-table entries even when second-stage mappings indicate that corresponding first-stage page-table is Read-Only. Implication: Due to this erratum, pages mapped as Read-only in second-stage page-tables may be modified by remapping hardware Access/Dirty bit updates. Workaround: None identified. System software enabling nested translations for a VM should ensure that there are no read-only pages in the corresponding second-stage mappings." Signed-off-by: Zhenzhong Duan <zhenzhong.d...@intel.com> --- hw/vfio/iommufd.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c index c172c177fc..a28641b5f5 100644 --- a/hw/vfio/iommufd.c +++ b/hw/vfio/iommufd.c @@ -325,6 +325,7 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev, { ERRP_GUARD(); IOMMUFDBackend *iommufd = vbasedev->iommufd; + struct iommu_hw_info_vtd vtd; uint32_t type, flags = 0; uint64_t hw_caps; VFIOIOASHwpt *hwpt; @@ -372,10 +373,15 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev, * instead. */ if (!iommufd_backend_get_device_info(vbasedev->iommufd, vbasedev->devid, - &type, NULL, 0, &hw_caps, errp)) { + &type, &vtd, sizeof(vtd), &hw_caps, + errp)) { return false; } + if (vtd.flags & IOMMU_HW_INFO_VTD_ERRATA_772415_SPR17) { + container->bcontainer.bypass_ro = true; + } + if (hw_caps & IOMMU_HW_CAP_DIRTY_TRACKING) { flags = IOMMU_HWPT_ALLOC_DIRTY_TRACKING; } -- 2.47.1