From: Joerg Roedel Date: Fri, 17 Jan 2025 08:02:35 +0000 (+0100) Subject: Merge branches 'arm/smmu/updates', 'arm/smmu/bindings', 'qualcomm/msm', 'rockchip... X-Git-Tag: v6.14-rc1~116^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=125f34e4c107b151029ccbeea92631481bf5a6a1;p=thirdparty%2Flinux.git Merge branches 'arm/smmu/updates', 'arm/smmu/bindings', 'qualcomm/msm', 'rockchip', 'riscv', 'core', 'intel/vt-d' and 'amd/amd-vi' into next --- 125f34e4c107b151029ccbeea92631481bf5a6a1 diff --cc drivers/iommu/amd/iommu.c index 16f40b8000d79,3f691e1fd22ce,3f691e1fd22ce,16f40b8000d79,16f40b8000d79,16f40b8000d79,d6590cdd6d15e,16f40b8000d79,12c1245baaf93..d75f1b13b3dc7 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@@@@@@@@@ -1843,73 -1838,73 -1838,73 -1843,73 -1843,73 -1843,73 -1843,73 -1843,73 -2040,49 +2040,49 @@@@@@@@@@ static void set_dte_entry(struct amd_io else domid = domain->id; ++++++++ make_clear_dte(dev_data, dte, &new); ++++++++ if (domain->iop.mode != PAGE_MODE_NONE) -------- pte_root = iommu_virt_to_phys(domain->iop.root); ++++++++ new.data[0] = iommu_virt_to_phys(domain->iop.root); -------- pte_root |= (domain->iop.mode & DEV_ENTRY_MODE_MASK) ++++++++ new.data[0] |= (domain->iop.mode & DEV_ENTRY_MODE_MASK) << DEV_ENTRY_MODE_SHIFT; -------- pte_root |= DTE_FLAG_IR | DTE_FLAG_IW | DTE_FLAG_V; ++++++++ new.data[0] |= DTE_FLAG_IR | DTE_FLAG_IW | DTE_FLAG_V; /* -------- * When SNP is enabled, Only set TV bit when IOMMU -------- * page translation is in use. ++++++++ * When SNP is enabled, we can only support TV=1 with non-zero domain ID. ++++++++ * This is prevented by the SNP-enable and IOMMU_DOMAIN_IDENTITY check in ++++++++ * do_iommu_domain_alloc(). */ -------- if (!amd_iommu_snp_en || (domid != 0)) -------- pte_root |= DTE_FLAG_TV; -------- -------- flags = dev_table[devid].data[1]; -------- -------- if (dev_data->ats_enabled) -------- flags |= DTE_FLAG_IOTLB; ++++++++ WARN_ON(amd_iommu_snp_en && (domid == 0)); ++++++++ new.data[0] |= DTE_FLAG_TV; if (dev_data->ppr) -------- pte_root |= 1ULL << DEV_ENTRY_PPR; ++++++++ new.data[0] |= 1ULL << DEV_ENTRY_PPR; if (domain->dirty_tracking) -------- pte_root |= DTE_FLAG_HAD; -------- -------- if (gcr3_info && gcr3_info->gcr3_tbl) { -------- u64 gcr3 = iommu_virt_to_phys(gcr3_info->gcr3_tbl); -------- u64 glx = gcr3_info->glx; -------- u64 tmp; -- - -- - pte_root |= DTE_FLAG_GV; -- - pte_root |= (glx & DTE_GLX_MASK) << DTE_GLX_SHIFT; - - /* First mask out possible old values for GCR3 table */ - tmp = DTE_GCR3_VAL_B(~0ULL) << DTE_GCR3_SHIFT_B; - flags &= ~tmp; ++++++++ new.data[0] |= DTE_FLAG_HAD; - --- - pte_root |= DTE_FLAG_GV; - --- - pte_root |= (glx & DTE_GLX_MASK) << DTE_GLX_SHIFT; - --- - ------ - /* First mask out possible old values for GCR3 table */ ------ - tmp = DTE_GCR3_VAL_B(~0ULL) << DTE_GCR3_SHIFT_B; ------ - flags &= ~tmp; ------ - -------- tmp = DTE_GCR3_VAL_C(~0ULL) << DTE_GCR3_SHIFT_C; -------- flags &= ~tmp; -------- -------- /* Encode GCR3 table into DTE */ -------- tmp = DTE_GCR3_VAL_A(gcr3) << DTE_GCR3_SHIFT_A; -------- pte_root |= tmp; -------- -------- tmp = DTE_GCR3_VAL_B(gcr3) << DTE_GCR3_SHIFT_B; -------- flags |= tmp; -------- -------- tmp = DTE_GCR3_VAL_C(gcr3) << DTE_GCR3_SHIFT_C; -------- flags |= tmp; ++++++++ if (dev_data->ats_enabled) ++++++++ new.data[1] |= DTE_FLAG_IOTLB; -------- if (amd_iommu_gpt_level == PAGE_MODE_5_LEVEL) { -------- dev_table[devid].data[2] |= -------- ((u64)GUEST_PGTABLE_5_LEVEL << DTE_GPT_LEVEL_SHIFT); -------- } ++++++++ old_domid = READ_ONCE(dte->data[1]) & DEV_DOMID_MASK; ++++++++ new.data[1] |= domid; -------- /* GIOV is supported with V2 page table mode only */ -------- if (pdom_is_v2_pgtbl_mode(domain)) -------- pte_root |= DTE_FLAG_GIOV; ++++++++ /* ++++++++ * Restore cached persistent DTE bits, which can be set by information ++++++++ * in IVRS table. See set_dev_entry_from_acpi(). ++++++++ */ ++++++++ initial_dte = amd_iommu_get_ivhd_dte_flags(iommu->pci_seg->id, dev_data->devid); ++++++++ if (initial_dte) { ++++++++ new.data128[0] |= initial_dte->data128[0]; ++++++++ new.data128[1] |= initial_dte->data128[1]; } -------- flags &= ~DEV_DOMID_MASK; -------- flags |= domid; ++++++++ set_dte_gcr3_table(iommu, dev_data, &new); -------- old_domid = dev_table[devid].data[1] & DEV_DOMID_MASK; -------- dev_table[devid].data[1] = flags; -------- dev_table[devid].data[0] = pte_root; ++++++++ update_dte256(iommu, dev_data, &new); /* * A kdump kernel might be replacing a domain ID that was copied from @@@@@@@@@@ -1921,19 -1916,19 -1916,19 -1921,19 -1921,19 -1921,19 -1921,19 -1921,19 -2094,16 +2094,16 @@@@@@@@@@ } } -------- static void clear_dte_entry(struct amd_iommu *iommu, u16 devid) ++++++++ /* ++++++++ * Clear DMA-remap related flags to block all DMA (blockeded domain) ++++++++ */ ++++++++ static void clear_dte_entry(struct amd_iommu *iommu, struct iommu_dev_data *dev_data) { -------- struct dev_table_entry *dev_table = get_dev_table(iommu); - --- - - --- - /* remove entry from the device table seen by the hardware */ - --- - dev_table[devid].data[0] = DTE_FLAG_V; - --- - - --- - if (!amd_iommu_snp_en) - --- - dev_table[devid].data[0] |= DTE_FLAG_TV; ++++++++ struct dev_table_entry new = {}; ++++++++ struct dev_table_entry *dte = &get_dev_table(iommu)[dev_data->devid]; -- - /* remove entry from the device table seen by the hardware */ -- - dev_table[devid].data[0] = DTE_FLAG_V; -- - -- - if (!amd_iommu_snp_en) -- - dev_table[devid].data[0] |= DTE_FLAG_TV; -- - -------- dev_table[devid].data[1] &= DTE_FLAG_MASK; -------- -------- amd_iommu_apply_erratum_63(iommu, devid); ++++++++ make_clear_dte(dev_data, dte, &new); ++++++++ update_dte256(iommu, dev_data, &new); } /* Update and flush DTE for the given device */ diff --cc drivers/iommu/intel/iommu.c index 79e0da9eb626c,7d0acb74d5a54,7d0acb74d5a54,79e0da9eb626c,79e0da9eb626c,79e0da9eb626c,aecfbcf1206c0,a1e2544173077,79e0da9eb626c..85173fe0a18a7 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@@@@@@@@@ -4095,12 -4093,12 -4093,12 -4095,12 -4095,12 -4095,12 -4100,13 -4085,14 -4095,12 +4090,15 @@@@@@@@@@ void domain_remove_dev_pasid(struct iom cache_tag_unassign_domain(dmar_domain, dev, pasid); domain_detach_iommu(dmar_domain, iommu); ------- - intel_iommu_debugfs_remove_dev_pasid(dev_pasid); ------- - kfree(dev_pasid); +++++++ + if (!WARN_ON_ONCE(!dev_pasid)) { +++++++ + intel_iommu_debugfs_remove_dev_pasid(dev_pasid); +++++++ + kfree(dev_pasid); +++++++ + } } ------ --static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid, ------ -- struct iommu_domain *domain) ++++++ ++static int blocking_domain_set_dev_pasid(struct iommu_domain *domain, ++++++ ++ struct device *dev, ioasid_t pasid, ++++++ ++ struct iommu_domain *old) { struct device_domain_info *info = dev_iommu_priv_get(dev);