On 2023/10/13 20:40, Yi Liu wrote:
+ return -EINVAL; + }
+ if ((s1_cfg->flags & IOMMU_VTD_S1_SRE) && !ecap_srs(iommu-
ecap)) {
+ pr_err_ratelimited("No supervisor request support on %s\n", + iommu->name); + return -EINVAL; + }
+ if ((s1_cfg->flags & IOMMU_VTD_S1_EAFE) && !ecap_eafs(iommu-
ecap)) {
+ pr_err_ratelimited("No extended access flag support on %s\n", + iommu->name); + return -EINVAL; + }
+ spin_lock(&iommu->lock); + pte = intel_pasid_get_entry(dev, pasid); + if (!pte) { + spin_unlock(&iommu->lock); + return -ENODEV; + } + if (pasid_pte_is_present(pte)) { + spin_unlock(&iommu->lock); + return -EBUSY; + }
+ pasid_clear_entry(pte);
+ if (s1_cfg->addr_width == ADDR_WIDTH_5LEVEL) + pasid_set_flpm(pte, 1);
+ pasid_set_flptr(pte, (uintptr_t)s1_gpgd);
+ if (s1_cfg->flags & IOMMU_VTD_S1_SRE) { + pasid_set_sre(pte); + if (s1_cfg->flags & IOMMU_VTD_S1_WPE) + pasid_set_wpe(pte); + }
+ if (s1_cfg->flags & IOMMU_VTD_S1_EAFE) + pasid_set_eafe(pte);
+ if (s2_domain->force_snooping) + pasid_set_pgsnp(pte);
+ pasid_set_slptr(pte, virt_to_phys(pgd)); + pasid_set_fault_enable(pte); + pasid_set_domain_id(pte, did); + pasid_set_address_width(pte, s2_domain->agaw); + pasid_set_page_snoop(pte, !!ecap_smpwc(iommu->ecap)); + pasid_set_translation_type(pte, PASID_ENTRY_PGTT_NESTED); + pasid_set_present(pte); + spin_unlock(&iommu->lock);
All changes within iommu->lock are specific to the device specific PASID entry. Probably this is one potential cleanup TODO to use a per-device lock instead.
yeah, a separate cleanup. is it, @Baolu?
Sure. I'd like to take some time to consider this further. Please keep it as-is for the time being.
Best regards, baolu