Lines Matching +full:pci +full:- +full:domain
1 // SPDX-License-Identifier: GPL-2.0
3 * IOMMU API for s390 PCI devices
9 #include <linux/pci.h>
11 #include <linux/iommu-helper.h>
25 struct iommu_domain domain; member
39 return container_of(dom, struct s390_domain, domain); in to_s390_domain()
65 s390_domain->dma_table = dma_alloc_cpu_table(); in s390_domain_alloc()
66 if (!s390_domain->dma_table) { in s390_domain_alloc()
71 spin_lock_init(&s390_domain->dma_table_lock); in s390_domain_alloc()
72 spin_lock_init(&s390_domain->list_lock); in s390_domain_alloc()
73 INIT_LIST_HEAD(&s390_domain->devices); in s390_domain_alloc()
75 return &s390_domain->domain; in s390_domain_alloc()
78 static void s390_domain_free(struct iommu_domain *domain) in s390_domain_free() argument
80 struct s390_domain *s390_domain = to_s390_domain(domain); in s390_domain_free()
82 dma_cleanup_tables(s390_domain->dma_table); in s390_domain_free()
86 static int s390_iommu_attach_device(struct iommu_domain *domain, in s390_iommu_attach_device() argument
89 struct s390_domain *s390_domain = to_s390_domain(domain); in s390_iommu_attach_device()
96 return -ENODEV; in s390_iommu_attach_device()
100 return -ENOMEM; in s390_iommu_attach_device()
102 if (zdev->dma_table) { in s390_iommu_attach_device()
105 rc = -EIO; in s390_iommu_attach_device()
110 zdev->dma_table = s390_domain->dma_table; in s390_iommu_attach_device()
111 cc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma, in s390_iommu_attach_device()
112 (u64) zdev->dma_table); in s390_iommu_attach_device()
114 rc = -EIO; in s390_iommu_attach_device()
118 spin_lock_irqsave(&s390_domain->list_lock, flags); in s390_iommu_attach_device()
120 if (list_empty(&s390_domain->devices)) { in s390_iommu_attach_device()
121 domain->geometry.aperture_start = zdev->start_dma; in s390_iommu_attach_device()
122 domain->geometry.aperture_end = zdev->end_dma; in s390_iommu_attach_device()
123 domain->geometry.force_aperture = true; in s390_iommu_attach_device()
125 } else if (domain->geometry.aperture_start != zdev->start_dma || in s390_iommu_attach_device()
126 domain->geometry.aperture_end != zdev->end_dma) { in s390_iommu_attach_device()
127 rc = -EINVAL; in s390_iommu_attach_device()
128 spin_unlock_irqrestore(&s390_domain->list_lock, flags); in s390_iommu_attach_device()
131 domain_device->zdev = zdev; in s390_iommu_attach_device()
132 zdev->s390_domain = s390_domain; in s390_iommu_attach_device()
133 list_add(&domain_device->list, &s390_domain->devices); in s390_iommu_attach_device()
134 spin_unlock_irqrestore(&s390_domain->list_lock, flags); in s390_iommu_attach_device()
146 static void s390_iommu_detach_device(struct iommu_domain *domain, in s390_iommu_detach_device() argument
149 struct s390_domain *s390_domain = to_s390_domain(domain); in s390_iommu_detach_device()
158 spin_lock_irqsave(&s390_domain->list_lock, flags); in s390_iommu_detach_device()
159 list_for_each_entry_safe(domain_device, tmp, &s390_domain->devices, in s390_iommu_detach_device()
161 if (domain_device->zdev == zdev) { in s390_iommu_detach_device()
162 list_del(&domain_device->list); in s390_iommu_detach_device()
168 spin_unlock_irqrestore(&s390_domain->list_lock, flags); in s390_iommu_detach_device()
171 zdev->s390_domain = NULL; in s390_iommu_detach_device()
181 return &zdev->iommu_dev; in s390_iommu_probe_device()
187 struct iommu_domain *domain; in s390_iommu_release_device() local
192 * to vfio-pci and completing the VFIO_SET_IOMMU ioctl (which triggers in s390_iommu_release_device()
194 * "echo 1 > /sys/bus/pci/devices/.../remove" won't trigger detach_dev, in s390_iommu_release_device()
200 if (zdev && zdev->s390_domain) { in s390_iommu_release_device()
201 domain = iommu_get_domain_for_dev(dev); in s390_iommu_release_device()
202 if (domain) in s390_iommu_release_device()
203 s390_iommu_detach_device(domain, dev); in s390_iommu_release_device()
218 if (dma_addr < s390_domain->domain.geometry.aperture_start || in s390_iommu_update_trans()
219 dma_addr + size > s390_domain->domain.geometry.aperture_end) in s390_iommu_update_trans()
220 return -EINVAL; in s390_iommu_update_trans()
226 spin_lock_irqsave(&s390_domain->dma_table_lock, irq_flags); in s390_iommu_update_trans()
228 entry = dma_walk_cpu_trans(s390_domain->dma_table, dma_addr); in s390_iommu_update_trans()
230 rc = -ENOMEM; in s390_iommu_update_trans()
238 spin_lock(&s390_domain->list_lock); in s390_iommu_update_trans()
239 list_for_each_entry(domain_device, &s390_domain->devices, list) { in s390_iommu_update_trans()
240 rc = zpci_refresh_trans((u64) domain_device->zdev->fh << 32, in s390_iommu_update_trans()
245 spin_unlock(&s390_domain->list_lock); in s390_iommu_update_trans()
250 while (i-- > 0) { in s390_iommu_update_trans()
251 page_addr -= PAGE_SIZE; in s390_iommu_update_trans()
252 dma_addr -= PAGE_SIZE; in s390_iommu_update_trans()
253 entry = dma_walk_cpu_trans(s390_domain->dma_table, in s390_iommu_update_trans()
260 spin_unlock_irqrestore(&s390_domain->dma_table_lock, irq_flags); in s390_iommu_update_trans()
265 static int s390_iommu_map(struct iommu_domain *domain, unsigned long iova, in s390_iommu_map() argument
268 struct s390_domain *s390_domain = to_s390_domain(domain); in s390_iommu_map()
272 return -EINVAL; in s390_iommu_map()
283 static phys_addr_t s390_iommu_iova_to_phys(struct iommu_domain *domain, in s390_iommu_iova_to_phys() argument
286 struct s390_domain *s390_domain = to_s390_domain(domain); in s390_iommu_iova_to_phys()
291 if (iova < domain->geometry.aperture_start || in s390_iommu_iova_to_phys()
292 iova > domain->geometry.aperture_end) in s390_iommu_iova_to_phys()
298 rto = s390_domain->dma_table; in s390_iommu_iova_to_phys()
300 spin_lock_irqsave(&s390_domain->dma_table_lock, flags); in s390_iommu_iova_to_phys()
309 spin_unlock_irqrestore(&s390_domain->dma_table_lock, flags); in s390_iommu_iova_to_phys()
314 static size_t s390_iommu_unmap(struct iommu_domain *domain, in s390_iommu_unmap() argument
318 struct s390_domain *s390_domain = to_s390_domain(domain); in s390_iommu_unmap()
323 paddr = s390_iommu_iova_to_phys(domain, iova); in s390_iommu_unmap()
339 rc = iommu_device_sysfs_add(&zdev->iommu_dev, NULL, NULL, in zpci_init_iommu()
340 "s390-iommu.%08x", zdev->fid); in zpci_init_iommu()
344 rc = iommu_device_register(&zdev->iommu_dev, &s390_iommu_ops, NULL); in zpci_init_iommu()
351 iommu_device_sysfs_remove(&zdev->iommu_dev); in zpci_init_iommu()
359 iommu_device_unregister(&zdev->iommu_dev); in zpci_destroy_iommu()
360 iommu_device_sysfs_remove(&zdev->iommu_dev); in zpci_destroy_iommu()