1 // SPDX-License-Identifier: GPL-2.0
3 * IOMMU API for s390 PCI devices
5 * Copyright IBM Corp. 2015
6 * Author(s): Gerald Schaefer <gerald.schaefer@de.ibm.com>
10 #include <linux/iommu.h>
11 #include <linux/iommu-helper.h>
12 #include <linux/sizes.h>
13 #include <asm/pci_dma.h>
16 * Physically contiguous memory regions can be mapped with 4 KiB alignment,
17 * we allow all page sizes that are an order of 4KiB (no special large page
20 #define S390_IOMMU_PGSIZES (~0xFFFUL)
22 static const struct iommu_ops s390_iommu_ops
;
25 struct iommu_domain domain
;
26 struct list_head devices
;
27 unsigned long *dma_table
;
28 spinlock_t dma_table_lock
;
32 struct s390_domain_device
{
33 struct list_head list
;
34 struct zpci_dev
*zdev
;
37 static struct s390_domain
*to_s390_domain(struct iommu_domain
*dom
)
39 return container_of(dom
, struct s390_domain
, domain
);
42 static bool s390_iommu_capable(enum iommu_cap cap
)
45 case IOMMU_CAP_CACHE_COHERENCY
:
47 case IOMMU_CAP_INTR_REMAP
:
54 static struct iommu_domain
*s390_domain_alloc(unsigned domain_type
)
56 struct s390_domain
*s390_domain
;
58 if (domain_type
!= IOMMU_DOMAIN_UNMANAGED
)
61 s390_domain
= kzalloc(sizeof(*s390_domain
), GFP_KERNEL
);
65 s390_domain
->dma_table
= dma_alloc_cpu_table();
66 if (!s390_domain
->dma_table
) {
71 spin_lock_init(&s390_domain
->dma_table_lock
);
72 spin_lock_init(&s390_domain
->list_lock
);
73 INIT_LIST_HEAD(&s390_domain
->devices
);
75 return &s390_domain
->domain
;
78 static void s390_domain_free(struct iommu_domain
*domain
)
80 struct s390_domain
*s390_domain
= to_s390_domain(domain
);
82 dma_cleanup_tables(s390_domain
->dma_table
);
86 static int s390_iommu_attach_device(struct iommu_domain
*domain
,
89 struct s390_domain
*s390_domain
= to_s390_domain(domain
);
90 struct zpci_dev
*zdev
= to_pci_dev(dev
)->sysdata
;
91 struct s390_domain_device
*domain_device
;
98 domain_device
= kzalloc(sizeof(*domain_device
), GFP_KERNEL
);
103 zpci_dma_exit_device(zdev
);
105 zdev
->dma_table
= s390_domain
->dma_table
;
106 rc
= zpci_register_ioat(zdev
, 0, zdev
->start_dma
, zdev
->end_dma
,
107 (u64
) zdev
->dma_table
);
111 spin_lock_irqsave(&s390_domain
->list_lock
, flags
);
112 /* First device defines the DMA range limits */
113 if (list_empty(&s390_domain
->devices
)) {
114 domain
->geometry
.aperture_start
= zdev
->start_dma
;
115 domain
->geometry
.aperture_end
= zdev
->end_dma
;
116 domain
->geometry
.force_aperture
= true;
117 /* Allow only devices with identical DMA range limits */
118 } else if (domain
->geometry
.aperture_start
!= zdev
->start_dma
||
119 domain
->geometry
.aperture_end
!= zdev
->end_dma
) {
121 spin_unlock_irqrestore(&s390_domain
->list_lock
, flags
);
124 domain_device
->zdev
= zdev
;
125 zdev
->s390_domain
= s390_domain
;
126 list_add(&domain_device
->list
, &s390_domain
->devices
);
127 spin_unlock_irqrestore(&s390_domain
->list_lock
, flags
);
132 zpci_dma_init_device(zdev
);
133 kfree(domain_device
);
138 static void s390_iommu_detach_device(struct iommu_domain
*domain
,
141 struct s390_domain
*s390_domain
= to_s390_domain(domain
);
142 struct zpci_dev
*zdev
= to_pci_dev(dev
)->sysdata
;
143 struct s390_domain_device
*domain_device
, *tmp
;
150 spin_lock_irqsave(&s390_domain
->list_lock
, flags
);
151 list_for_each_entry_safe(domain_device
, tmp
, &s390_domain
->devices
,
153 if (domain_device
->zdev
== zdev
) {
154 list_del(&domain_device
->list
);
155 kfree(domain_device
);
160 spin_unlock_irqrestore(&s390_domain
->list_lock
, flags
);
163 zdev
->s390_domain
= NULL
;
164 zpci_unregister_ioat(zdev
, 0);
165 zpci_dma_init_device(zdev
);
169 static int s390_iommu_add_device(struct device
*dev
)
171 struct iommu_group
*group
= iommu_group_get_for_dev(dev
);
172 struct zpci_dev
*zdev
= to_pci_dev(dev
)->sysdata
;
175 return PTR_ERR(group
);
177 iommu_group_put(group
);
178 iommu_device_link(&zdev
->iommu_dev
, dev
);
183 static void s390_iommu_remove_device(struct device
*dev
)
185 struct zpci_dev
*zdev
= to_pci_dev(dev
)->sysdata
;
186 struct iommu_domain
*domain
;
189 * This is a workaround for a scenario where the IOMMU API common code
190 * "forgets" to call the detach_dev callback: After binding a device
191 * to vfio-pci and completing the VFIO_SET_IOMMU ioctl (which triggers
192 * the attach_dev), removing the device via
193 * "echo 1 > /sys/bus/pci/devices/.../remove" won't trigger detach_dev,
194 * only remove_device will be called via the BUS_NOTIFY_REMOVED_DEVICE
197 * So let's call detach_dev from here if it hasn't been called before.
199 if (zdev
&& zdev
->s390_domain
) {
200 domain
= iommu_get_domain_for_dev(dev
);
202 s390_iommu_detach_device(domain
, dev
);
205 iommu_device_unlink(&zdev
->iommu_dev
, dev
);
206 iommu_group_remove_device(dev
);
209 static int s390_iommu_update_trans(struct s390_domain
*s390_domain
,
210 unsigned long pa
, dma_addr_t dma_addr
,
211 size_t size
, int flags
)
213 struct s390_domain_device
*domain_device
;
214 u8
*page_addr
= (u8
*) (pa
& PAGE_MASK
);
215 dma_addr_t start_dma_addr
= dma_addr
;
216 unsigned long irq_flags
, nr_pages
, i
;
217 unsigned long *entry
;
220 if (dma_addr
< s390_domain
->domain
.geometry
.aperture_start
||
221 dma_addr
+ size
> s390_domain
->domain
.geometry
.aperture_end
)
224 nr_pages
= PAGE_ALIGN(size
) >> PAGE_SHIFT
;
228 spin_lock_irqsave(&s390_domain
->dma_table_lock
, irq_flags
);
229 for (i
= 0; i
< nr_pages
; i
++) {
230 entry
= dma_walk_cpu_trans(s390_domain
->dma_table
, dma_addr
);
235 dma_update_cpu_trans(entry
, page_addr
, flags
);
236 page_addr
+= PAGE_SIZE
;
237 dma_addr
+= PAGE_SIZE
;
240 spin_lock(&s390_domain
->list_lock
);
241 list_for_each_entry(domain_device
, &s390_domain
->devices
, list
) {
242 rc
= zpci_refresh_trans((u64
) domain_device
->zdev
->fh
<< 32,
243 start_dma_addr
, nr_pages
* PAGE_SIZE
);
247 spin_unlock(&s390_domain
->list_lock
);
250 if (rc
&& ((flags
& ZPCI_PTE_VALID_MASK
) == ZPCI_PTE_VALID
)) {
251 flags
= ZPCI_PTE_INVALID
;
253 page_addr
-= PAGE_SIZE
;
254 dma_addr
-= PAGE_SIZE
;
255 entry
= dma_walk_cpu_trans(s390_domain
->dma_table
,
259 dma_update_cpu_trans(entry
, page_addr
, flags
);
262 spin_unlock_irqrestore(&s390_domain
->dma_table_lock
, irq_flags
);
267 static int s390_iommu_map(struct iommu_domain
*domain
, unsigned long iova
,
268 phys_addr_t paddr
, size_t size
, int prot
)
270 struct s390_domain
*s390_domain
= to_s390_domain(domain
);
271 int flags
= ZPCI_PTE_VALID
, rc
= 0;
273 if (!(prot
& IOMMU_READ
))
276 if (!(prot
& IOMMU_WRITE
))
277 flags
|= ZPCI_TABLE_PROTECTED
;
279 rc
= s390_iommu_update_trans(s390_domain
, (unsigned long) paddr
, iova
,
285 static phys_addr_t
s390_iommu_iova_to_phys(struct iommu_domain
*domain
,
288 struct s390_domain
*s390_domain
= to_s390_domain(domain
);
289 unsigned long *sto
, *pto
, *rto
, flags
;
290 unsigned int rtx
, sx
, px
;
291 phys_addr_t phys
= 0;
293 if (iova
< domain
->geometry
.aperture_start
||
294 iova
> domain
->geometry
.aperture_end
)
297 rtx
= calc_rtx(iova
);
300 rto
= s390_domain
->dma_table
;
302 spin_lock_irqsave(&s390_domain
->dma_table_lock
, flags
);
303 if (rto
&& reg_entry_isvalid(rto
[rtx
])) {
304 sto
= get_rt_sto(rto
[rtx
]);
305 if (sto
&& reg_entry_isvalid(sto
[sx
])) {
306 pto
= get_st_pto(sto
[sx
]);
307 if (pto
&& pt_entry_isvalid(pto
[px
]))
308 phys
= pto
[px
] & ZPCI_PTE_ADDR_MASK
;
311 spin_unlock_irqrestore(&s390_domain
->dma_table_lock
, flags
);
316 static size_t s390_iommu_unmap(struct iommu_domain
*domain
,
317 unsigned long iova
, size_t size
)
319 struct s390_domain
*s390_domain
= to_s390_domain(domain
);
320 int flags
= ZPCI_PTE_INVALID
;
324 paddr
= s390_iommu_iova_to_phys(domain
, iova
);
328 rc
= s390_iommu_update_trans(s390_domain
, (unsigned long) paddr
, iova
,
336 int zpci_init_iommu(struct zpci_dev
*zdev
)
340 rc
= iommu_device_sysfs_add(&zdev
->iommu_dev
, NULL
, NULL
,
341 "s390-iommu.%08x", zdev
->fid
);
345 iommu_device_set_ops(&zdev
->iommu_dev
, &s390_iommu_ops
);
347 rc
= iommu_device_register(&zdev
->iommu_dev
);
354 iommu_device_sysfs_remove(&zdev
->iommu_dev
);
360 void zpci_destroy_iommu(struct zpci_dev
*zdev
)
362 iommu_device_unregister(&zdev
->iommu_dev
);
363 iommu_device_sysfs_remove(&zdev
->iommu_dev
);
366 static const struct iommu_ops s390_iommu_ops
= {
367 .capable
= s390_iommu_capable
,
368 .domain_alloc
= s390_domain_alloc
,
369 .domain_free
= s390_domain_free
,
370 .attach_dev
= s390_iommu_attach_device
,
371 .detach_dev
= s390_iommu_detach_device
,
372 .map
= s390_iommu_map
,
373 .unmap
= s390_iommu_unmap
,
374 .iova_to_phys
= s390_iommu_iova_to_phys
,
375 .add_device
= s390_iommu_add_device
,
376 .remove_device
= s390_iommu_remove_device
,
377 .device_group
= generic_device_group
,
378 .pgsize_bitmap
= S390_IOMMU_PGSIZES
,
381 static int __init
s390_iommu_init(void)
383 return bus_set_iommu(&pci_bus_type
, &s390_iommu_ops
);
385 subsys_initcall(s390_iommu_init
);