xref: /linux/drivers/iommu/io-pgtable-dart.c (revision 336b4dae6dfecc9aa53a3a68c71b9c1c1d466388)
1  // SPDX-License-Identifier: GPL-2.0-only
2  /*
3   * Apple DART page table allocator.
4   *
5   * Copyright (C) 2022 The Asahi Linux Contributors
6   *
7   * Based on io-pgtable-arm.
8   *
9   * Copyright (C) 2014 ARM Limited
10   *
11   * Author: Will Deacon <will.deacon@arm.com>
12   */
13  
14  #define pr_fmt(fmt)	"dart io-pgtable: " fmt
15  
16  #include <linux/atomic.h>
17  #include <linux/bitfield.h>
18  #include <linux/bitops.h>
19  #include <linux/io-pgtable.h>
20  #include <linux/kernel.h>
21  #include <linux/sizes.h>
22  #include <linux/slab.h>
23  #include <linux/types.h>
24  
25  #include <asm/barrier.h>
26  #include "iommu-pages.h"
27  
28  #define DART1_MAX_ADDR_BITS	36
29  
30  #define DART_MAX_TABLES		4
31  #define DART_LEVELS		2
32  
33  /* Struct accessors */
34  #define io_pgtable_to_data(x)						\
35  	container_of((x), struct dart_io_pgtable, iop)
36  
37  #define io_pgtable_ops_to_data(x)					\
38  	io_pgtable_to_data(io_pgtable_ops_to_pgtable(x))
39  
40  #define DART_GRANULE(d)						\
41  	(sizeof(dart_iopte) << (d)->bits_per_level)
42  #define DART_PTES_PER_TABLE(d)					\
43  	(DART_GRANULE(d) >> ilog2(sizeof(dart_iopte)))
44  
45  #define APPLE_DART_PTE_SUBPAGE_START   GENMASK_ULL(63, 52)
46  #define APPLE_DART_PTE_SUBPAGE_END     GENMASK_ULL(51, 40)
47  
48  #define APPLE_DART1_PADDR_MASK	GENMASK_ULL(35, 12)
49  #define APPLE_DART2_PADDR_MASK	GENMASK_ULL(37, 10)
50  #define APPLE_DART2_PADDR_SHIFT	(4)
51  
52  /* Apple DART1 protection bits */
53  #define APPLE_DART1_PTE_PROT_NO_READ	BIT(8)
54  #define APPLE_DART1_PTE_PROT_NO_WRITE	BIT(7)
55  #define APPLE_DART1_PTE_PROT_SP_DIS	BIT(1)
56  
57  /* Apple DART2 protection bits */
58  #define APPLE_DART2_PTE_PROT_NO_READ	BIT(3)
59  #define APPLE_DART2_PTE_PROT_NO_WRITE	BIT(2)
60  #define APPLE_DART2_PTE_PROT_NO_CACHE	BIT(1)
61  
62  /* marks PTE as valid */
63  #define APPLE_DART_PTE_VALID		BIT(0)
64  
65  /* IOPTE accessors */
66  #define iopte_deref(pte, d) __va(iopte_to_paddr(pte, d))
67  
68  struct dart_io_pgtable {
69  	struct io_pgtable	iop;
70  
71  	int			tbl_bits;
72  	int			bits_per_level;
73  
74  	void			*pgd[DART_MAX_TABLES];
75  };
76  
77  typedef u64 dart_iopte;
78  
79  
paddr_to_iopte(phys_addr_t paddr,struct dart_io_pgtable * data)80  static dart_iopte paddr_to_iopte(phys_addr_t paddr,
81  				     struct dart_io_pgtable *data)
82  {
83  	dart_iopte pte;
84  
85  	if (data->iop.fmt == APPLE_DART)
86  		return paddr & APPLE_DART1_PADDR_MASK;
87  
88  	/* format is APPLE_DART2 */
89  	pte = paddr >> APPLE_DART2_PADDR_SHIFT;
90  	pte &= APPLE_DART2_PADDR_MASK;
91  
92  	return pte;
93  }
94  
iopte_to_paddr(dart_iopte pte,struct dart_io_pgtable * data)95  static phys_addr_t iopte_to_paddr(dart_iopte pte,
96  				  struct dart_io_pgtable *data)
97  {
98  	u64 paddr;
99  
100  	if (data->iop.fmt == APPLE_DART)
101  		return pte & APPLE_DART1_PADDR_MASK;
102  
103  	/* format is APPLE_DART2 */
104  	paddr = pte & APPLE_DART2_PADDR_MASK;
105  	paddr <<= APPLE_DART2_PADDR_SHIFT;
106  
107  	return paddr;
108  }
109  
__dart_alloc_pages(size_t size,gfp_t gfp)110  static void *__dart_alloc_pages(size_t size, gfp_t gfp)
111  {
112  	int order = get_order(size);
113  
114  	VM_BUG_ON((gfp & __GFP_HIGHMEM));
115  	return iommu_alloc_pages(gfp, order);
116  }
117  
dart_init_pte(struct dart_io_pgtable * data,unsigned long iova,phys_addr_t paddr,dart_iopte prot,int num_entries,dart_iopte * ptep)118  static int dart_init_pte(struct dart_io_pgtable *data,
119  			     unsigned long iova, phys_addr_t paddr,
120  			     dart_iopte prot, int num_entries,
121  			     dart_iopte *ptep)
122  {
123  	int i;
124  	dart_iopte pte = prot;
125  	size_t sz = data->iop.cfg.pgsize_bitmap;
126  
127  	for (i = 0; i < num_entries; i++)
128  		if (ptep[i] & APPLE_DART_PTE_VALID) {
129  			/* We require an unmap first */
130  			WARN_ON(ptep[i] & APPLE_DART_PTE_VALID);
131  			return -EEXIST;
132  		}
133  
134  	/* subpage protection: always allow access to the entire page */
135  	pte |= FIELD_PREP(APPLE_DART_PTE_SUBPAGE_START, 0);
136  	pte |= FIELD_PREP(APPLE_DART_PTE_SUBPAGE_END, 0xfff);
137  
138  	pte |= APPLE_DART_PTE_VALID;
139  
140  	for (i = 0; i < num_entries; i++)
141  		ptep[i] = pte | paddr_to_iopte(paddr + i * sz, data);
142  
143  	return 0;
144  }
145  
dart_install_table(dart_iopte * table,dart_iopte * ptep,dart_iopte curr,struct dart_io_pgtable * data)146  static dart_iopte dart_install_table(dart_iopte *table,
147  					     dart_iopte *ptep,
148  					     dart_iopte curr,
149  					     struct dart_io_pgtable *data)
150  {
151  	dart_iopte old, new;
152  
153  	new = paddr_to_iopte(__pa(table), data) | APPLE_DART_PTE_VALID;
154  
155  	/*
156  	 * Ensure the table itself is visible before its PTE can be.
157  	 * Whilst we could get away with cmpxchg64_release below, this
158  	 * doesn't have any ordering semantics when !CONFIG_SMP.
159  	 */
160  	dma_wmb();
161  
162  	old = cmpxchg64_relaxed(ptep, curr, new);
163  
164  	return old;
165  }
166  
dart_get_table(struct dart_io_pgtable * data,unsigned long iova)167  static int dart_get_table(struct dart_io_pgtable *data, unsigned long iova)
168  {
169  	return (iova >> (3 * data->bits_per_level + ilog2(sizeof(dart_iopte)))) &
170  		((1 << data->tbl_bits) - 1);
171  }
172  
dart_get_l1_index(struct dart_io_pgtable * data,unsigned long iova)173  static int dart_get_l1_index(struct dart_io_pgtable *data, unsigned long iova)
174  {
175  
176  	return (iova >> (2 * data->bits_per_level + ilog2(sizeof(dart_iopte)))) &
177  		 ((1 << data->bits_per_level) - 1);
178  }
179  
dart_get_l2_index(struct dart_io_pgtable * data,unsigned long iova)180  static int dart_get_l2_index(struct dart_io_pgtable *data, unsigned long iova)
181  {
182  
183  	return (iova >> (data->bits_per_level + ilog2(sizeof(dart_iopte)))) &
184  		 ((1 << data->bits_per_level) - 1);
185  }
186  
dart_get_l2(struct dart_io_pgtable * data,unsigned long iova)187  static  dart_iopte *dart_get_l2(struct dart_io_pgtable *data, unsigned long iova)
188  {
189  	dart_iopte pte, *ptep;
190  	int tbl = dart_get_table(data, iova);
191  
192  	ptep = data->pgd[tbl];
193  	if (!ptep)
194  		return NULL;
195  
196  	ptep += dart_get_l1_index(data, iova);
197  	pte = READ_ONCE(*ptep);
198  
199  	/* Valid entry? */
200  	if (!pte)
201  		return NULL;
202  
203  	/* Deref to get level 2 table */
204  	return iopte_deref(pte, data);
205  }
206  
dart_prot_to_pte(struct dart_io_pgtable * data,int prot)207  static dart_iopte dart_prot_to_pte(struct dart_io_pgtable *data,
208  					   int prot)
209  {
210  	dart_iopte pte = 0;
211  
212  	if (data->iop.fmt == APPLE_DART) {
213  		pte |= APPLE_DART1_PTE_PROT_SP_DIS;
214  		if (!(prot & IOMMU_WRITE))
215  			pte |= APPLE_DART1_PTE_PROT_NO_WRITE;
216  		if (!(prot & IOMMU_READ))
217  			pte |= APPLE_DART1_PTE_PROT_NO_READ;
218  	}
219  	if (data->iop.fmt == APPLE_DART2) {
220  		if (!(prot & IOMMU_WRITE))
221  			pte |= APPLE_DART2_PTE_PROT_NO_WRITE;
222  		if (!(prot & IOMMU_READ))
223  			pte |= APPLE_DART2_PTE_PROT_NO_READ;
224  		if (!(prot & IOMMU_CACHE))
225  			pte |= APPLE_DART2_PTE_PROT_NO_CACHE;
226  	}
227  
228  	return pte;
229  }
230  
dart_map_pages(struct io_pgtable_ops * ops,unsigned long iova,phys_addr_t paddr,size_t pgsize,size_t pgcount,int iommu_prot,gfp_t gfp,size_t * mapped)231  static int dart_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
232  			      phys_addr_t paddr, size_t pgsize, size_t pgcount,
233  			      int iommu_prot, gfp_t gfp, size_t *mapped)
234  {
235  	struct dart_io_pgtable *data = io_pgtable_ops_to_data(ops);
236  	struct io_pgtable_cfg *cfg = &data->iop.cfg;
237  	size_t tblsz = DART_GRANULE(data);
238  	int ret = 0, tbl, num_entries, max_entries, map_idx_start;
239  	dart_iopte pte, *cptep, *ptep;
240  	dart_iopte prot;
241  
242  	if (WARN_ON(pgsize != cfg->pgsize_bitmap))
243  		return -EINVAL;
244  
245  	if (WARN_ON(paddr >> cfg->oas))
246  		return -ERANGE;
247  
248  	if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE)))
249  		return -EINVAL;
250  
251  	tbl = dart_get_table(data, iova);
252  
253  	ptep = data->pgd[tbl];
254  	ptep += dart_get_l1_index(data, iova);
255  	pte = READ_ONCE(*ptep);
256  
257  	/* no L2 table present */
258  	if (!pte) {
259  		cptep = __dart_alloc_pages(tblsz, gfp);
260  		if (!cptep)
261  			return -ENOMEM;
262  
263  		pte = dart_install_table(cptep, ptep, 0, data);
264  		if (pte)
265  			iommu_free_pages(cptep, get_order(tblsz));
266  
267  		/* L2 table is present (now) */
268  		pte = READ_ONCE(*ptep);
269  	}
270  
271  	ptep = iopte_deref(pte, data);
272  
273  	/* install a leaf entries into L2 table */
274  	prot = dart_prot_to_pte(data, iommu_prot);
275  	map_idx_start = dart_get_l2_index(data, iova);
276  	max_entries = DART_PTES_PER_TABLE(data) - map_idx_start;
277  	num_entries = min_t(int, pgcount, max_entries);
278  	ptep += map_idx_start;
279  	ret = dart_init_pte(data, iova, paddr, prot, num_entries, ptep);
280  	if (!ret && mapped)
281  		*mapped += num_entries * pgsize;
282  
283  	/*
284  	 * Synchronise all PTE updates for the new mapping before there's
285  	 * a chance for anything to kick off a table walk for the new iova.
286  	 */
287  	wmb();
288  
289  	return ret;
290  }
291  
dart_unmap_pages(struct io_pgtable_ops * ops,unsigned long iova,size_t pgsize,size_t pgcount,struct iommu_iotlb_gather * gather)292  static size_t dart_unmap_pages(struct io_pgtable_ops *ops, unsigned long iova,
293  				   size_t pgsize, size_t pgcount,
294  				   struct iommu_iotlb_gather *gather)
295  {
296  	struct dart_io_pgtable *data = io_pgtable_ops_to_data(ops);
297  	struct io_pgtable_cfg *cfg = &data->iop.cfg;
298  	int i = 0, num_entries, max_entries, unmap_idx_start;
299  	dart_iopte pte, *ptep;
300  
301  	if (WARN_ON(pgsize != cfg->pgsize_bitmap || !pgcount))
302  		return 0;
303  
304  	ptep = dart_get_l2(data, iova);
305  
306  	/* Valid L2 IOPTE pointer? */
307  	if (WARN_ON(!ptep))
308  		return 0;
309  
310  	unmap_idx_start = dart_get_l2_index(data, iova);
311  	ptep += unmap_idx_start;
312  
313  	max_entries = DART_PTES_PER_TABLE(data) - unmap_idx_start;
314  	num_entries = min_t(int, pgcount, max_entries);
315  
316  	while (i < num_entries) {
317  		pte = READ_ONCE(*ptep);
318  		if (WARN_ON(!pte))
319  			break;
320  
321  		/* clear pte */
322  		*ptep = 0;
323  
324  		if (!iommu_iotlb_gather_queued(gather))
325  			io_pgtable_tlb_add_page(&data->iop, gather,
326  						iova + i * pgsize, pgsize);
327  
328  		ptep++;
329  		i++;
330  	}
331  
332  	return i * pgsize;
333  }
334  
dart_iova_to_phys(struct io_pgtable_ops * ops,unsigned long iova)335  static phys_addr_t dart_iova_to_phys(struct io_pgtable_ops *ops,
336  					 unsigned long iova)
337  {
338  	struct dart_io_pgtable *data = io_pgtable_ops_to_data(ops);
339  	dart_iopte pte, *ptep;
340  
341  	ptep = dart_get_l2(data, iova);
342  
343  	/* Valid L2 IOPTE pointer? */
344  	if (!ptep)
345  		return 0;
346  
347  	ptep += dart_get_l2_index(data, iova);
348  
349  	pte = READ_ONCE(*ptep);
350  	/* Found translation */
351  	if (pte) {
352  		iova &= (data->iop.cfg.pgsize_bitmap - 1);
353  		return iopte_to_paddr(pte, data) | iova;
354  	}
355  
356  	/* Ran out of page tables to walk */
357  	return 0;
358  }
359  
360  static struct dart_io_pgtable *
dart_alloc_pgtable(struct io_pgtable_cfg * cfg)361  dart_alloc_pgtable(struct io_pgtable_cfg *cfg)
362  {
363  	struct dart_io_pgtable *data;
364  	int tbl_bits, bits_per_level, va_bits, pg_shift;
365  
366  	pg_shift = __ffs(cfg->pgsize_bitmap);
367  	bits_per_level = pg_shift - ilog2(sizeof(dart_iopte));
368  
369  	va_bits = cfg->ias - pg_shift;
370  
371  	tbl_bits = max_t(int, 0, va_bits - (bits_per_level * DART_LEVELS));
372  	if ((1 << tbl_bits) > DART_MAX_TABLES)
373  		return NULL;
374  
375  	data = kzalloc(sizeof(*data), GFP_KERNEL);
376  	if (!data)
377  		return NULL;
378  
379  	data->tbl_bits = tbl_bits;
380  	data->bits_per_level = bits_per_level;
381  
382  	data->iop.ops = (struct io_pgtable_ops) {
383  		.map_pages	= dart_map_pages,
384  		.unmap_pages	= dart_unmap_pages,
385  		.iova_to_phys	= dart_iova_to_phys,
386  	};
387  
388  	return data;
389  }
390  
391  static struct io_pgtable *
apple_dart_alloc_pgtable(struct io_pgtable_cfg * cfg,void * cookie)392  apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
393  {
394  	struct dart_io_pgtable *data;
395  	int i;
396  
397  	if (!cfg->coherent_walk)
398  		return NULL;
399  
400  	if (cfg->oas != 36 && cfg->oas != 42)
401  		return NULL;
402  
403  	if (cfg->ias > cfg->oas)
404  		return NULL;
405  
406  	if (!(cfg->pgsize_bitmap == SZ_4K || cfg->pgsize_bitmap == SZ_16K))
407  		return NULL;
408  
409  	data = dart_alloc_pgtable(cfg);
410  	if (!data)
411  		return NULL;
412  
413  	cfg->apple_dart_cfg.n_ttbrs = 1 << data->tbl_bits;
414  
415  	for (i = 0; i < cfg->apple_dart_cfg.n_ttbrs; ++i) {
416  		data->pgd[i] = __dart_alloc_pages(DART_GRANULE(data), GFP_KERNEL);
417  		if (!data->pgd[i])
418  			goto out_free_data;
419  		cfg->apple_dart_cfg.ttbr[i] = virt_to_phys(data->pgd[i]);
420  	}
421  
422  	return &data->iop;
423  
424  out_free_data:
425  	while (--i >= 0) {
426  		iommu_free_pages(data->pgd[i],
427  				 get_order(DART_GRANULE(data)));
428  	}
429  	kfree(data);
430  	return NULL;
431  }
432  
apple_dart_free_pgtable(struct io_pgtable * iop)433  static void apple_dart_free_pgtable(struct io_pgtable *iop)
434  {
435  	struct dart_io_pgtable *data = io_pgtable_to_data(iop);
436  	int order = get_order(DART_GRANULE(data));
437  	dart_iopte *ptep, *end;
438  	int i;
439  
440  	for (i = 0; i < (1 << data->tbl_bits) && data->pgd[i]; ++i) {
441  		ptep = data->pgd[i];
442  		end = (void *)ptep + DART_GRANULE(data);
443  
444  		while (ptep != end) {
445  			dart_iopte pte = *ptep++;
446  
447  			if (pte)
448  				iommu_free_pages(iopte_deref(pte, data), order);
449  		}
450  		iommu_free_pages(data->pgd[i], order);
451  	}
452  
453  	kfree(data);
454  }
455  
456  struct io_pgtable_init_fns io_pgtable_apple_dart_init_fns = {
457  	.alloc	= apple_dart_alloc_pgtable,
458  	.free	= apple_dart_free_pgtable,
459  };
460