blob: e7001bcd7474ea5d7f5bd2bdb42897f52ca72840 [file] [log] [blame]
xjb04a4022021-11-25 15:01:52 +08001/*
2 * CPU-agnostic ARM page table allocator.
3 *
4 * ARMv7 Short-descriptor format, supporting
5 * - Basic memory attributes
6 * - Simplified access permissions (AP[2:1] model)
7 * - Backwards-compatible TEX remap
8 * - Large pages/supersections (if indicated by the caller)
9 *
10 * Not supporting:
11 * - Legacy access permissions (AP[2:0] model)
12 *
13 * Almost certainly never supporting:
14 * - PXN
15 * - Domains
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License version 2 as
19 * published by the Free Software Foundation.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program. If not, see <http://www.gnu.org/licenses/>.
28 *
29 * Copyright (C) 2014-2015 ARM Limited
30 * Copyright (c) 2014-2015 MediaTek Inc.
31 */
32
33#define pr_fmt(fmt) "arm-v7s io-pgtable: " fmt
34
35#include <linux/atomic.h>
36#include <linux/dma-mapping.h>
37#include <linux/gfp.h>
38#include <linux/io-pgtable.h>
39#include <linux/iommu.h>
40#include <linux/kernel.h>
41#include <linux/kmemleak.h>
42#include <linux/sizes.h>
43#include <linux/slab.h>
44#include <linux/spinlock.h>
45#include <linux/types.h>
46
47#include <asm/barrier.h>
48
49/* Struct accessors */
50#define io_pgtable_to_data(x) \
51 container_of((x), struct arm_v7s_io_pgtable, iop)
52
53#define io_pgtable_ops_to_data(x) \
54 io_pgtable_to_data(io_pgtable_ops_to_pgtable(x))
55
56#define MTK_PGTABLE_DEBUG_ENABLED
57
58#if defined(CONFIG_MTK_IOMMU_PGTABLE_EXT) && \
59 (CONFIG_MTK_IOMMU_PGTABLE_EXT == 34)
60#define ARM_V7S_ADDR_BITS 34
61#define ARM_V7S_PHYS_ADDR_BITS 35
62#else
63#define ARM_V7S_ADDR_BITS 32
64#define ARM_V7S_PHYS_ADDR_BITS 34
65#endif
66#define IOVA_ALIGN(addr) (addr & (DMA_BIT_MASK(ARM_V7S_ADDR_BITS)))
67#define PA_ALIGN(addr) (addr & (DMA_BIT_MASK(ARM_V7S_PHYS_ADDR_BITS)))
68
69/* 1st 12bits, 2nd 8bits*/
70#define _ARM_V7S_LVL_BITS_32BIT(lvl) (16 - (lvl) * 4)
71/* 1st 14bits, 2nd 8bits*/
72#define _ARM_V7S_LVL_BITS_34BIT(lvl) (20 - (lvl) * 6)
73
74/* 1st bit20, 2nd bit12*/
75#define ARM_V7S_LVL_SHIFT(lvl) (32 - (4 + 8 * (lvl)))
76#define ARM_V7S_TABLE_SHIFT 10
77
78/* 1st 4096 pgd, 2nd 256 pte */
79#define ARM_V7S_PTES_PER_LVL_32BIT(lvl) (1 << _ARM_V7S_LVL_BITS_32BIT(lvl))
80/* 1st 16384 pgd, 2nd 256 pte */
81#define ARM_V7S_PTES_PER_LVL_34BIT(lvl) (1 << _ARM_V7S_LVL_BITS_34BIT(lvl))
82
83/* 1st 16KB pgd object, 2nd 1KB pte object */
84#define ARM_V7S_TABLE_SIZE_32BIT(lvl) \
85 (ARM_V7S_PTES_PER_LVL_32BIT(lvl) * sizeof(arm_v7s_iopte))
86/* 1st 64KB pgd object, 2nd 1KB pte object */
87#define ARM_V7S_TABLE_SIZE_34BIT(lvl) \
88 (ARM_V7S_PTES_PER_LVL_34BIT(lvl) * sizeof(arm_v7s_iopte))
89
90/* 1st 1MB page size, 2nd 4KB page size*/
91#define ARM_V7S_BLOCK_SIZE(lvl) (1UL << ARM_V7S_LVL_SHIFT(lvl))
92
93/* 32bit, 1st IOVA[31:20], 2nd IOVA[31:12]*/
94/* 34bit, 1st IOVA[33:20], 2nd IOVA[33:12]*/
95#define ARM_V7S_LVL_MASK(lvl) \
96 IOVA_ALIGN((u64)(~0UL << ARM_V7S_LVL_SHIFT(lvl)))
97
98/* 1st descriptor value[31:10]*/
99#define ARM_V7S_TABLE_MASK ((u32)(~0U << ARM_V7S_TABLE_SHIFT))
100
101/* 1st IOVA mask 0xfff, 2nd IOVA mask 0xff */
102#define _ARM_V7S_IDX_MASK_32BIT(lvl) (ARM_V7S_PTES_PER_LVL_32BIT(lvl) - 1)
103/* 1st IOVA mask 0x3fff, 2nd IOVA mask 0xff */
104#define _ARM_V7S_IDX_MASK_34BIT(lvl) (ARM_V7S_PTES_PER_LVL_34BIT(lvl) - 1)
105
106/* 1st IOVA[31:20] 2nd IOVA[19:12] */
107#define ARM_V7S_LVL_IDX_32BIT(addr, lvl) ({ \
108 int _l = lvl; \
109 ((u32)(addr) >> ARM_V7S_LVL_SHIFT(_l)) & _ARM_V7S_IDX_MASK_32BIT(_l); \
110})
111
112#if defined(CONFIG_MTK_IOMMU_PGTABLE_EXT) && \
113 (CONFIG_MTK_IOMMU_PGTABLE_EXT == 34)
114/* 1st IOVA[33:20] 2nd IOVA[19:12] */
115#define ARM_V7S_LVL_IDX_34BIT(addr, lvl) ({ \
116 int _l = lvl; \
117 (((u64)(addr) & DMA_BIT_MASK(CONFIG_MTK_IOMMU_PGTABLE_EXT)) >> \
118 ARM_V7S_LVL_SHIFT(_l)) & _ARM_V7S_IDX_MASK_34BIT(_l); \
119})
120
121#define ARM_V7S_PTES_PER_LVL(lvl) ARM_V7S_PTES_PER_LVL_34BIT(lvl)
122#define ARM_V7S_TABLE_SIZE(lvl) ARM_V7S_TABLE_SIZE_34BIT(lvl)
123#define ARM_V7S_LVL_IDX(addr, lvl) ARM_V7S_LVL_IDX_34BIT(addr, lvl)
124#else
125#define ARM_V7S_PTES_PER_LVL(lvl) ARM_V7S_PTES_PER_LVL_32BIT(lvl)
126#define ARM_V7S_TABLE_SIZE(lvl) ARM_V7S_TABLE_SIZE_32BIT(lvl)
127#define ARM_V7S_LVL_IDX(addr, lvl) ARM_V7S_LVL_IDX_32BIT(addr, lvl)
128#endif
129
130/*
131 * Large page/supersection entries are effectively a block of 16 page/section
132 * entries, along the lines of the LPAE contiguous hint, but all with the
133 * same output address. For want of a better common name we'll call them
134 * "contiguous" versions of their respective page/section entries here, but
135 * noting the distinction (WRT to TLB maintenance) that they represent *one*
136 * entry repeated 16 times, not 16 separate entries (as in the LPAE case).
137 */
138#define ARM_V7S_CONT_PAGES 16
139
140/* PTE type bits: these are all mixed up with XN/PXN bits in most cases */
141#define ARM_V7S_PTE_TYPE_TABLE 0x1
142#define ARM_V7S_PTE_TYPE_PAGE 0x2
143#define ARM_V7S_PTE_TYPE_CONT_PAGE 0x1
144
145#define ARM_V7S_PTE_IS_VALID(pte) (((pte) & 0x3) != 0)
146#define ARM_V7S_PTE_IS_TABLE(pte, lvl) \
147 ((lvl) == 1 && (((pte) & 0x3) == ARM_V7S_PTE_TYPE_TABLE))
148
149/* Page table bits */
150#define ARM_V7S_ATTR_XN(lvl) BIT(4 * (2 - (lvl)))
151#define ARM_V7S_ATTR_B BIT(2)
152#define ARM_V7S_ATTR_C BIT(3)
153#define ARM_V7S_ATTR_NS_TABLE BIT(3)
154#define ARM_V7S_ATTR_NS_SECTION BIT(19)
155
156#define ARM_V7S_CONT_SECTION BIT(18)
157#define ARM_V7S_CONT_PAGE_XN_SHIFT 15
158
159/*
160 * The attribute bits are consistently ordered*, but occupy bits [17:10] of
161 * a level 1 PTE vs. bits [11:4] at level 2. Thus we define the individual
162 * fields relative to that 8-bit block, plus a total shift relative to the PTE.
163 */
164#define ARM_V7S_ATTR_SHIFT(lvl) (16 - (lvl) * 6)
165
166#define ARM_V7S_ATTR_MASK 0xff
167#define ARM_V7S_ATTR_AP0 BIT(0)
168#define ARM_V7S_ATTR_AP1 BIT(1)
169#define ARM_V7S_ATTR_AP2 BIT(5)
170#define ARM_V7S_ATTR_S BIT(6)
171#define ARM_V7S_ATTR_NG BIT(7)
172#define ARM_V7S_TEX_SHIFT 2
173#define ARM_V7S_TEX_MASK 0x7
174#define ARM_V7S_ATTR_TEX(val) (((val) & ARM_V7S_TEX_MASK) << ARM_V7S_TEX_SHIFT)
175
176/* MediaTek extend the two bits below for over 4GB mode */
177#define ARM_V7S_ATTR_MTK_PA_BIT32 BIT(9)
178#define ARM_V7S_ATTR_MTK_PA_BIT33 BIT(4)
179#define ARM_V7S_ATTR_MTK_PA_BIT34 BIT(5)
180
181/* *well, except for TEX on level 2 large pages, of course :( */
182#define ARM_V7S_CONT_PAGE_TEX_SHIFT 6
183#define ARM_V7S_CONT_PAGE_TEX_MASK (ARM_V7S_TEX_MASK << ARM_V7S_CONT_PAGE_TEX_SHIFT)
184
185/* Simplified access permissions */
186#define ARM_V7S_PTE_AF ARM_V7S_ATTR_AP0
187#define ARM_V7S_PTE_AP_UNPRIV ARM_V7S_ATTR_AP1
188#define ARM_V7S_PTE_AP_RDONLY ARM_V7S_ATTR_AP2
189
190/* Register bits */
191#define ARM_V7S_RGN_NC 0
192#define ARM_V7S_RGN_WBWA 1
193#define ARM_V7S_RGN_WT 2
194#define ARM_V7S_RGN_WB 3
195
196#define ARM_V7S_PRRR_TYPE_DEVICE 1
197#define ARM_V7S_PRRR_TYPE_NORMAL 2
198#define ARM_V7S_PRRR_TR(n, type) (((type) & 0x3) << ((n) * 2))
199#define ARM_V7S_PRRR_DS0 BIT(16)
200#define ARM_V7S_PRRR_DS1 BIT(17)
201#define ARM_V7S_PRRR_NS0 BIT(18)
202#define ARM_V7S_PRRR_NS1 BIT(19)
203#define ARM_V7S_PRRR_NOS(n) BIT((n) + 24)
204
205#define ARM_V7S_NMRR_IR(n, attr) (((attr) & 0x3) << ((n) * 2))
206#define ARM_V7S_NMRR_OR(n, attr) (((attr) & 0x3) << ((n) * 2 + 16))
207
208#define ARM_V7S_TTBR_S BIT(1)
209#define ARM_V7S_TTBR_NOS BIT(5)
210#define ARM_V7S_TTBR_ORGN_ATTR(attr) (((attr) & 0x3) << 3)
211#define ARM_V7S_TTBR_IRGN_ATTR(attr) \
212 ((((attr) & 0x1) << 6) | (((attr) & 0x2) >> 1))
213
214#define ARM_V7S_TCR_PD1 BIT(5)
215
216#ifdef CONFIG_ZONE_DMA32
217#define ARM_V7S_TABLE_GFP_DMA GFP_DMA32
218#define ARM_V7S_TABLE_SLAB_FLAGS SLAB_CACHE_DMA32
219#else
220#define ARM_V7S_TABLE_GFP_DMA GFP_DMA
221#define ARM_V7S_TABLE_SLAB_FLAGS SLAB_CACHE_DMA
222#endif
223
224typedef u32 arm_v7s_iopte;
225
226static bool selftest_running;
227
228struct arm_v7s_io_pgtable {
229 struct io_pgtable iop;
230
231 arm_v7s_iopte *pgd;
232 struct kmem_cache *l2_tables;
233 spinlock_t split_lock;
234};
235
236static bool arm_v7s_pte_is_cont(arm_v7s_iopte pte, int lvl);
237
238static dma_addr_t __arm_v7s_dma_addr(void *pages)
239{
240 return (dma_addr_t)virt_to_phys(pages);
241}
242
243static arm_v7s_iopte paddr_to_iopte(phys_addr_t paddr, int lvl,
244 struct io_pgtable_cfg *cfg)
245{
246 arm_v7s_iopte pte = paddr & ARM_V7S_LVL_MASK(lvl);
247
248 if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_4GB) {
249 if (paddr & BIT_ULL(32))
250 pte |= ARM_V7S_ATTR_MTK_PA_BIT32;
251 if (paddr & BIT_ULL(33))
252 pte |= ARM_V7S_ATTR_MTK_PA_BIT33;
253 if (paddr & BIT_ULL(34))
254 pte |= ARM_V7S_ATTR_MTK_PA_BIT34;
255 }
256 return pte;
257}
258
259static phys_addr_t iopte_to_paddr(arm_v7s_iopte pte, int lvl,
260 struct io_pgtable_cfg *cfg)
261{
262 arm_v7s_iopte mask;
263 phys_addr_t paddr;
264
265 if (ARM_V7S_PTE_IS_TABLE(pte, lvl))
266 mask = ARM_V7S_TABLE_MASK;
267 else if (arm_v7s_pte_is_cont(pte, lvl))
268 mask = ARM_V7S_LVL_MASK(lvl) * ARM_V7S_CONT_PAGES;
269 else
270 mask = ARM_V7S_LVL_MASK(lvl);
271
272 paddr = pte & mask;
273 if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_4GB) {
274 if (pte & ARM_V7S_ATTR_MTK_PA_BIT32)
275 paddr |= BIT_ULL(32);
276 if (pte & ARM_V7S_ATTR_MTK_PA_BIT33)
277 paddr |= BIT_ULL(33);
278 if (pte & ARM_V7S_ATTR_MTK_PA_BIT34)
279 paddr |= BIT_ULL(34);
280 }
281 return paddr;
282}
283
284static arm_v7s_iopte *iopte_deref(arm_v7s_iopte pte, int lvl,
285 struct arm_v7s_io_pgtable *data)
286{
287 return phys_to_virt(iopte_to_paddr(pte, lvl, &data->iop.cfg));
288}
289
290static void *__arm_v7s_alloc_table(int lvl, gfp_t gfp,
291 struct arm_v7s_io_pgtable *data)
292{
293 struct io_pgtable_cfg *cfg = &data->iop.cfg;
294 struct device *dev = cfg->iommu_dev;
295 phys_addr_t phys;
296 dma_addr_t dma;
297 size_t size = ARM_V7S_TABLE_SIZE(lvl);
298 void *table = NULL;
299
300 if (lvl == 1)
301 table = (void *)__get_free_pages(
302 __GFP_ZERO | ARM_V7S_TABLE_GFP_DMA, get_order(size));
303 else if (lvl == 2)
304 table = kmem_cache_zalloc(data->l2_tables, gfp);
305 phys = virt_to_phys(table);
306 if (phys != (arm_v7s_iopte)phys) {
307 /* Doesn't fit in PTE */
308 dev_err(dev, "Page table does not fit in PTE: %pa", &phys);
309 goto out_free;
310 }
311 if (table && !(cfg->quirks & IO_PGTABLE_QUIRK_NO_DMA)) {
312 dma = dma_map_single(dev, table, size, DMA_TO_DEVICE);
313 if (dma_mapping_error(dev, dma))
314 goto out_free;
315 /*
316 * We depend on the IOMMU being able to work with any physical
317 * address directly, so if the DMA layer suggests otherwise by
318 * translating or truncating them, that bodes very badly...
319 */
320 if (dma != phys)
321 goto out_unmap;
322 }
323 if (lvl == 2)
324 kmemleak_ignore(table);
325 return table;
326
327out_unmap:
328 dev_err(dev, "Cannot accommodate DMA translation for IOMMU page tables\n");
329 dma_unmap_single(dev, dma, size, DMA_TO_DEVICE);
330out_free:
331 if (lvl == 1)
332 free_pages((unsigned long)table, get_order(size));
333 else
334 kmem_cache_free(data->l2_tables, table);
335 return NULL;
336}
337
338static void __arm_v7s_free_table(void *table, int lvl,
339 struct arm_v7s_io_pgtable *data)
340{
341 struct io_pgtable_cfg *cfg = &data->iop.cfg;
342 struct device *dev = cfg->iommu_dev;
343 size_t size = ARM_V7S_TABLE_SIZE(lvl);
344
345 if (!(cfg->quirks & IO_PGTABLE_QUIRK_NO_DMA))
346 dma_unmap_single(dev, __arm_v7s_dma_addr(table), size,
347 DMA_TO_DEVICE);
348 if (lvl == 1)
349 free_pages((unsigned long)table, get_order(size));
350 else
351 kmem_cache_free(data->l2_tables, table);
352}
353
354static void __arm_v7s_pte_sync(arm_v7s_iopte *ptep, int num_entries,
355 struct io_pgtable_cfg *cfg)
356{
357 if (cfg->quirks & IO_PGTABLE_QUIRK_NO_DMA)
358 return;
359
360 dma_sync_single_for_device(cfg->iommu_dev, __arm_v7s_dma_addr(ptep),
361 num_entries * sizeof(*ptep), DMA_TO_DEVICE);
362}
363static void __arm_v7s_set_pte(arm_v7s_iopte *ptep, arm_v7s_iopte pte,
364 int num_entries, struct io_pgtable_cfg *cfg)
365{
366 int i;
367
368 for (i = 0; i < num_entries; i++)
369 ptep[i] = pte;
370
371 __arm_v7s_pte_sync(ptep, num_entries, cfg);
372}
373
374static arm_v7s_iopte arm_v7s_prot_to_pte(int prot, int lvl,
375 struct io_pgtable_cfg *cfg)
376{
377 bool ap = !(cfg->quirks & IO_PGTABLE_QUIRK_NO_PERMS);
378 arm_v7s_iopte pte = ARM_V7S_ATTR_NG | ARM_V7S_ATTR_S;
379
380 if (!(prot & IOMMU_MMIO))
381 pte |= ARM_V7S_ATTR_TEX(1);
382 if (ap) {
383 pte |= ARM_V7S_PTE_AF;
384 if (!(prot & IOMMU_PRIV))
385 pte |= ARM_V7S_PTE_AP_UNPRIV;
386 if (!(prot & IOMMU_WRITE))
387 pte |= ARM_V7S_PTE_AP_RDONLY;
388 }
389 pte <<= ARM_V7S_ATTR_SHIFT(lvl);
390
391 if ((prot & IOMMU_NOEXEC) && ap)
392 pte |= ARM_V7S_ATTR_XN(lvl);
393 if (prot & IOMMU_MMIO)
394 pte |= ARM_V7S_ATTR_B;
395 else if (prot & IOMMU_CACHE)
396 pte |= ARM_V7S_ATTR_B | ARM_V7S_ATTR_C;
397
398 pte |= ARM_V7S_PTE_TYPE_PAGE;
399 if (lvl == 1 && (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS))
400 pte |= ARM_V7S_ATTR_NS_SECTION;
401
402 return pte;
403}
404
405static int arm_v7s_pte_to_prot(arm_v7s_iopte pte, int lvl)
406{
407 int prot = IOMMU_READ;
408 arm_v7s_iopte attr = pte >> ARM_V7S_ATTR_SHIFT(lvl);
409
410 if (!(attr & ARM_V7S_PTE_AP_RDONLY))
411 prot |= IOMMU_WRITE;
412 if (!(attr & ARM_V7S_PTE_AP_UNPRIV))
413 prot |= IOMMU_PRIV;
414 if ((attr & (ARM_V7S_TEX_MASK << ARM_V7S_TEX_SHIFT)) == 0)
415 prot |= IOMMU_MMIO;
416 else if (pte & ARM_V7S_ATTR_C)
417 prot |= IOMMU_CACHE;
418 if (pte & ARM_V7S_ATTR_XN(lvl))
419 prot |= IOMMU_NOEXEC;
420
421 return prot;
422}
423
424static arm_v7s_iopte arm_v7s_pte_to_cont(arm_v7s_iopte pte, int lvl)
425{
426 if (lvl == 1) {
427 pte |= ARM_V7S_CONT_SECTION;
428 } else if (lvl == 2) {
429 arm_v7s_iopte xn = pte & ARM_V7S_ATTR_XN(lvl);
430 arm_v7s_iopte tex = pte & ARM_V7S_CONT_PAGE_TEX_MASK;
431
432 pte ^= xn | tex | ARM_V7S_PTE_TYPE_PAGE;
433 pte |= (xn << ARM_V7S_CONT_PAGE_XN_SHIFT) |
434 (tex << ARM_V7S_CONT_PAGE_TEX_SHIFT) |
435 ARM_V7S_PTE_TYPE_CONT_PAGE;
436 }
437 return pte;
438}
439
440static arm_v7s_iopte arm_v7s_cont_to_pte(arm_v7s_iopte pte, int lvl)
441{
442 if (lvl == 1) {
443 pte &= ~ARM_V7S_CONT_SECTION;
444 } else if (lvl == 2) {
445 arm_v7s_iopte xn = pte & BIT(ARM_V7S_CONT_PAGE_XN_SHIFT);
446 arm_v7s_iopte tex = pte & (ARM_V7S_CONT_PAGE_TEX_MASK <<
447 ARM_V7S_CONT_PAGE_TEX_SHIFT);
448
449 pte ^= xn | tex | ARM_V7S_PTE_TYPE_CONT_PAGE;
450 pte |= (xn >> ARM_V7S_CONT_PAGE_XN_SHIFT) |
451 (tex >> ARM_V7S_CONT_PAGE_TEX_SHIFT) |
452 ARM_V7S_PTE_TYPE_PAGE;
453 }
454 return pte;
455}
456
457static bool arm_v7s_pte_is_cont(arm_v7s_iopte pte, int lvl)
458{
459 if (lvl == 1 && !ARM_V7S_PTE_IS_TABLE(pte, lvl))
460 return pte & ARM_V7S_CONT_SECTION;
461 else if (lvl == 2)
462 return !(pte & ARM_V7S_PTE_TYPE_PAGE);
463 return false;
464}
465
466static size_t __arm_v7s_unmap(struct arm_v7s_io_pgtable *, unsigned long,
467 size_t, int, arm_v7s_iopte *);
468
469static int arm_v7s_init_pte(struct arm_v7s_io_pgtable *data,
470 unsigned long iova, phys_addr_t paddr, int prot,
471 int lvl, int num_entries, arm_v7s_iopte *ptep)
472{
473 struct io_pgtable_cfg *cfg = &data->iop.cfg;
474 arm_v7s_iopte pte;
475 int i;
476
477 for (i = 0; i < num_entries; i++)
478 if (ARM_V7S_PTE_IS_TABLE(ptep[i], lvl)) {
479 /*
480 * We need to unmap and free the old table before
481 * overwriting it with a block entry.
482 */
483 arm_v7s_iopte *tblp;
484 size_t sz = ARM_V7S_BLOCK_SIZE(lvl);
485
486 tblp = ptep - ARM_V7S_LVL_IDX(iova, lvl);
487 if (WARN_ON(__arm_v7s_unmap(data, iova + i * sz,
488 sz, lvl, tblp) != sz))
489 return -EINVAL;
490 } else if (ptep[i]) {
491 /* We require an unmap first */
492 WARN_ON(!selftest_running);
493 return -EEXIST;
494 }
495
496 pte = arm_v7s_prot_to_pte(prot, lvl, cfg);
497 if (num_entries > 1)
498 pte = arm_v7s_pte_to_cont(pte, lvl);
499
500 pte |= paddr_to_iopte(paddr, lvl, cfg);
501
502 __arm_v7s_set_pte(ptep, pte, num_entries, cfg);
503 return 0;
504}
505
506static arm_v7s_iopte arm_v7s_install_table(arm_v7s_iopte *table,
507 arm_v7s_iopte *ptep,
508 arm_v7s_iopte curr,
509 struct io_pgtable_cfg *cfg)
510{
511 arm_v7s_iopte old, new;
512
513 new = virt_to_phys(table) | ARM_V7S_PTE_TYPE_TABLE;
514 if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS)
515 new |= ARM_V7S_ATTR_NS_TABLE;
516
517 /*
518 * Ensure the table itself is visible before its PTE can be.
519 * Whilst we could get away with cmpxchg64_release below, this
520 * doesn't have any ordering semantics when !CONFIG_SMP.
521 */
522 dma_wmb();
523
524 old = cmpxchg_relaxed(ptep, curr, new);
525 __arm_v7s_pte_sync(ptep, 1, cfg);
526
527 return old;
528}
529
530static int __arm_v7s_map(struct arm_v7s_io_pgtable *data, unsigned long iova,
531 phys_addr_t paddr, size_t size, int prot,
532 int lvl, arm_v7s_iopte *ptep)
533{
534 struct io_pgtable_cfg *cfg = &data->iop.cfg;
535 arm_v7s_iopte pte, *cptep;
536 int num_entries = size >> ARM_V7S_LVL_SHIFT(lvl);
537
538 /* Find our entry at the current level */
539 ptep += ARM_V7S_LVL_IDX(iova, lvl);
540
541 /* If we can install a leaf entry at this level, then do so */
542 if (num_entries)
543 return arm_v7s_init_pte(data, iova, paddr, prot,
544 lvl, num_entries, ptep);
545
546 /* We can't allocate tables at the final level */
547 if (WARN_ON(lvl == 2))
548 return -EINVAL;
549
550 /* Grab a pointer to the next level */
551 pte = READ_ONCE(*ptep);
552 if (!pte) {
553 cptep = __arm_v7s_alloc_table(lvl + 1, GFP_ATOMIC, data);
554 if (!cptep)
555 return -ENOMEM;
556
557 pte = arm_v7s_install_table(cptep, ptep, 0, cfg);
558 if (pte)
559 __arm_v7s_free_table(cptep, lvl + 1, data);
560 } else {
561 /* We've no easy way of knowing if it's synced yet, so... */
562 __arm_v7s_pte_sync(ptep, 1, cfg);
563 }
564
565 if (ARM_V7S_PTE_IS_TABLE(pte, lvl)) {
566 cptep = iopte_deref(pte, lvl, data);
567 } else if (pte) {
568 /* We require an unmap first */
569 WARN_ON(!selftest_running);
570 return -EEXIST;
571 }
572
573 /* Rinse, repeat */
574 return __arm_v7s_map(data, iova, paddr, size, prot, lvl + 1, cptep);
575}
576
577static int arm_v7s_map(struct io_pgtable_ops *ops, unsigned long iova,
578 phys_addr_t paddr, size_t size, int prot)
579{
580 struct arm_v7s_io_pgtable *data = io_pgtable_ops_to_data(ops);
581 struct io_pgtable *iop = &data->iop;
582 int ret;
583
584 /* If no access, then nothing to do */
585 if (!(prot & (IOMMU_READ | IOMMU_WRITE)))
586 return 0;
587
588 if (WARN_ON(upper_32_bits(iova)) ||
589 WARN_ON(upper_32_bits(paddr) &&
590 !(iop->cfg.quirks & IO_PGTABLE_QUIRK_ARM_MTK_4GB)))
591 return -ERANGE;
592
593 ret = __arm_v7s_map(data, iova, paddr, size, prot, 1, data->pgd);
594 /*
595 * Synchronise all PTE updates for the new mapping before there's
596 * a chance for anything to kick off a table walk for the new iova.
597 */
598 if (iop->cfg.quirks & IO_PGTABLE_QUIRK_TLBI_ON_MAP) {
599 io_pgtable_tlb_add_flush(iop, iova, size,
600 ARM_V7S_BLOCK_SIZE(2), false);
601 io_pgtable_tlb_sync(iop);
602 } else {
603 wmb();
604 }
605
606 return ret;
607}
608
609static void arm_v7s_free_pgtable(struct io_pgtable *iop)
610{
611 struct arm_v7s_io_pgtable *data = io_pgtable_to_data(iop);
612 int i;
613
614 for (i = 0; i < ARM_V7S_PTES_PER_LVL(1); i++) {
615 arm_v7s_iopte pte = data->pgd[i];
616
617 if (ARM_V7S_PTE_IS_TABLE(pte, 1))
618 __arm_v7s_free_table(iopte_deref(pte, 1, data),
619 2, data);
620 }
621 __arm_v7s_free_table(data->pgd, 1, data);
622 kmem_cache_destroy(data->l2_tables);
623 kfree(data);
624}
625
626static arm_v7s_iopte arm_v7s_split_cont(struct arm_v7s_io_pgtable *data,
627 unsigned long iova, int idx, int lvl,
628 arm_v7s_iopte *ptep)
629{
630 struct io_pgtable *iop = &data->iop;
631 arm_v7s_iopte pte;
632 size_t size = ARM_V7S_BLOCK_SIZE(lvl);
633 int i;
634
635 /* Check that we didn't lose a race to get the lock */
636 pte = *ptep;
637 if (!arm_v7s_pte_is_cont(pte, lvl))
638 return pte;
639
640 ptep -= idx & (ARM_V7S_CONT_PAGES - 1);
641 pte = arm_v7s_cont_to_pte(pte, lvl);
642 for (i = 0; i < ARM_V7S_CONT_PAGES; i++)
643 ptep[i] = pte + i * size;
644
645 __arm_v7s_pte_sync(ptep, ARM_V7S_CONT_PAGES, &iop->cfg);
646
647 size *= ARM_V7S_CONT_PAGES;
648 io_pgtable_tlb_add_flush(iop, iova, size, size, true);
649 io_pgtable_tlb_sync(iop);
650 return pte;
651}
652
653static size_t arm_v7s_split_blk_unmap(struct arm_v7s_io_pgtable *data,
654 unsigned long iova, size_t size,
655 arm_v7s_iopte blk_pte,
656 arm_v7s_iopte *ptep)
657{
658 struct io_pgtable_cfg *cfg = &data->iop.cfg;
659 arm_v7s_iopte pte, *tablep;
660 int i, unmap_idx, num_entries, num_ptes;
661
662 tablep = __arm_v7s_alloc_table(2, GFP_ATOMIC, data);
663 if (!tablep)
664 return 0; /* Bytes unmapped */
665
666 num_ptes = ARM_V7S_PTES_PER_LVL(2);
667 num_entries = size >> ARM_V7S_LVL_SHIFT(2);
668 unmap_idx = ARM_V7S_LVL_IDX(iova, 2);
669
670 pte = arm_v7s_prot_to_pte(arm_v7s_pte_to_prot(blk_pte, 1), 2, cfg);
671 if (num_entries > 1)
672 pte = arm_v7s_pte_to_cont(pte, 2);
673
674 for (i = 0; i < num_ptes; i += num_entries, pte += size) {
675 /* Unmap! */
676 if (i == unmap_idx)
677 continue;
678
679 __arm_v7s_set_pte(&tablep[i], pte, num_entries, cfg);
680 }
681
682 pte = arm_v7s_install_table(tablep, ptep, blk_pte, cfg);
683 if (pte != blk_pte) {
684 __arm_v7s_free_table(tablep, 2, data);
685
686 if (!ARM_V7S_PTE_IS_TABLE(pte, 1))
687 return 0;
688
689 tablep = iopte_deref(pte, 1, data);
690 return __arm_v7s_unmap(data, iova, size, 2, tablep);
691 }
692
693 io_pgtable_tlb_add_flush(&data->iop, iova, size, size, true);
694 return size;
695}
696
697static size_t __arm_v7s_unmap(struct arm_v7s_io_pgtable *data,
698 unsigned long iova, size_t size, int lvl,
699 arm_v7s_iopte *ptep)
700{
701 arm_v7s_iopte pte[ARM_V7S_CONT_PAGES];
702 struct io_pgtable *iop = &data->iop;
703 int idx, i = 0, num_entries = size >> ARM_V7S_LVL_SHIFT(lvl);
704
705 /* Something went horribly wrong and we ran out of page table */
706 if (WARN_ON(lvl > 2))
707 return 0;
708
709 idx = ARM_V7S_LVL_IDX(iova, lvl);
710 ptep += idx;
711 do {
712 pte[i] = READ_ONCE(ptep[i]);
713 if (WARN_ON(!ARM_V7S_PTE_IS_VALID(pte[i])))
714 return 0;
715 } while (++i < num_entries);
716
717 /*
718 * If we've hit a contiguous 'large page' entry at this level, it
719 * needs splitting first, unless we're unmapping the whole lot.
720 *
721 * For splitting, we can't rewrite 16 PTEs atomically, and since we
722 * can't necessarily assume TEX remap we don't have a software bit to
723 * mark live entries being split. In practice (i.e. DMA API code), we
724 * will never be splitting large pages anyway, so just wrap this edge
725 * case in a lock for the sake of correctness and be done with it.
726 */
727 if (num_entries <= 1 && arm_v7s_pte_is_cont(pte[0], lvl)) {
728 unsigned long flags;
729
730 spin_lock_irqsave(&data->split_lock, flags);
731 pte[0] = arm_v7s_split_cont(data, iova, idx, lvl, ptep);
732 spin_unlock_irqrestore(&data->split_lock, flags);
733 }
734
735 /* If the size matches this level, we're in the right place */
736 if (num_entries) {
737 size_t blk_size = ARM_V7S_BLOCK_SIZE(lvl);
738
739 __arm_v7s_set_pte(ptep, 0, num_entries, &iop->cfg);
740
741 for (i = 0; i < num_entries; i++) {
742 if (ARM_V7S_PTE_IS_TABLE(pte[i], lvl)) {
743 /* Also flush any partial walks */
744 io_pgtable_tlb_add_flush(iop, iova, blk_size,
745 ARM_V7S_BLOCK_SIZE(lvl + 1), false);
746 io_pgtable_tlb_sync(iop);
747 ptep = iopte_deref(pte[i], lvl, data);
748 __arm_v7s_free_table(ptep, lvl + 1, data);
749 } else {
750 io_pgtable_tlb_add_flush(iop, iova, blk_size,
751 blk_size, true);
752 }
753 iova += blk_size;
754 }
755 return size;
756 } else if (lvl == 1 && !ARM_V7S_PTE_IS_TABLE(pte[0], lvl)) {
757 /*
758 * Insert a table at the next level to map the old region,
759 * minus the part we want to unmap
760 */
761 return arm_v7s_split_blk_unmap(data, iova, size, pte[0], ptep);
762 }
763
764 /* Keep on walkin' */
765 ptep = iopte_deref(pte[0], lvl, data);
766 return __arm_v7s_unmap(data, iova, size, lvl + 1, ptep);
767}
768
769static size_t arm_v7s_unmap(struct io_pgtable_ops *ops, unsigned long iova,
770 size_t size)
771{
772 struct arm_v7s_io_pgtable *data = io_pgtable_ops_to_data(ops);
773
774 if (WARN_ON(upper_32_bits(iova)))
775 return 0;
776
777 return __arm_v7s_unmap(data, iova, size, 1, data->pgd);
778}
779
780static phys_addr_t arm_v7s_iova_to_phys(struct io_pgtable_ops *ops,
781 unsigned long iova)
782{
783 struct arm_v7s_io_pgtable *data = io_pgtable_ops_to_data(ops);
784 arm_v7s_iopte *ptep = data->pgd, pte;
785 int lvl = 0;
786 u32 mask;
787
788 do {
789 ptep += ARM_V7S_LVL_IDX(iova, ++lvl);
790 pte = READ_ONCE(*ptep);
791 ptep = iopte_deref(pte, lvl, data);
792 } while (ARM_V7S_PTE_IS_TABLE(pte, lvl));
793
794 if (!ARM_V7S_PTE_IS_VALID(pte))
795 return 0;
796
797 mask = ARM_V7S_LVL_MASK(lvl);
798 if (arm_v7s_pte_is_cont(pte, lvl))
799 mask *= ARM_V7S_CONT_PAGES;
800 return iopte_to_paddr(pte, lvl, &data->iop.cfg) | (iova & ~mask);
801}
802
803static int mtk_pgtable_align(arm_v7s_iopte *ptep)
804{
805 unsigned long pgd_pa;
806#if defined(CONFIG_MTK_IOMMU_PGTABLE_EXT)
807 unsigned long align_mask = SZ_16K * (1 <<
808 (CONFIG_MTK_IOMMU_PGTABLE_EXT - 32)) - 1;
809#else
810 unsigned long align_mask = SZ_16K - 1;
811#endif
812
813 pgd_pa = (unsigned long)virt_to_phys(ptep);
814 if (pgd_pa != (pgd_pa & ~align_mask)) {
815 pr_notice("%s, %d, pgd not align, pgd_pa:0x%lx, mask=0x%lx\n",
816 __func__, __LINE__, pgd_pa, ~align_mask);
817 return -1;
818 }
819 return 0;
820}
821
822static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
823 void *cookie)
824{
825 struct arm_v7s_io_pgtable *data;
826 u64 base = 0;
827#ifdef MTK_PGTABLE_DEBUG_ENABLED
828 phys_addr_t phys_addr;
829#endif
830
831 if (cfg->ias > ARM_V7S_ADDR_BITS || cfg->oas > ARM_V7S_ADDR_BITS)
832 return NULL;
833
834 if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
835 IO_PGTABLE_QUIRK_NO_PERMS |
836 IO_PGTABLE_QUIRK_TLBI_ON_MAP |
837 IO_PGTABLE_QUIRK_ARM_MTK_4GB |
838 IO_PGTABLE_QUIRK_NO_DMA))
839 return NULL;
840
841 /* If ARM_MTK_4GB is enabled, the NO_PERMS is also expected. */
842 if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_4GB &&
843 !(cfg->quirks & IO_PGTABLE_QUIRK_NO_PERMS))
844 return NULL;
845
846 data = kmalloc(sizeof(*data), GFP_KERNEL);
847 if (!data)
848 return NULL;
849
850 spin_lock_init(&data->split_lock);
851 data->l2_tables = kmem_cache_create("io-pgtable_armv7s_l2",
852 ARM_V7S_TABLE_SIZE(2),
853 ARM_V7S_TABLE_SIZE(2),
854 ARM_V7S_TABLE_SLAB_FLAGS, NULL);
855 if (!data->l2_tables)
856 goto out_free_data;
857
858 data->iop.ops = (struct io_pgtable_ops) {
859 .map = arm_v7s_map,
860 .unmap = arm_v7s_unmap,
861 .iova_to_phys = arm_v7s_iova_to_phys,
862 };
863
864 /* We have to do this early for __arm_v7s_alloc_table to work... */
865 data->iop.cfg = *cfg;
866
867 /*
868 * Unless the IOMMU driver indicates supersection support by
869 * having SZ_16M set in the initial bitmap, they won't be used.
870 */
871 cfg->pgsize_bitmap &= SZ_4K | SZ_64K | SZ_1M | SZ_16M;
872
873 /* TCR: T0SZ=0, disable TTBR1 */
874 cfg->arm_v7s_cfg.tcr = ARM_V7S_TCR_PD1;
875
876 /*
877 * TEX remap: the indices used map to the closest equivalent types
878 * under the non-TEX-remap interpretation of those attribute bits,
879 * excepting various implementation-defined aspects of shareability.
880 */
881 cfg->arm_v7s_cfg.prrr = ARM_V7S_PRRR_TR(1, ARM_V7S_PRRR_TYPE_DEVICE) |
882 ARM_V7S_PRRR_TR(4, ARM_V7S_PRRR_TYPE_NORMAL) |
883 ARM_V7S_PRRR_TR(7, ARM_V7S_PRRR_TYPE_NORMAL) |
884 ARM_V7S_PRRR_DS0 | ARM_V7S_PRRR_DS1 |
885 ARM_V7S_PRRR_NS1 | ARM_V7S_PRRR_NOS(7);
886 cfg->arm_v7s_cfg.nmrr = ARM_V7S_NMRR_IR(7, ARM_V7S_RGN_WBWA) |
887 ARM_V7S_NMRR_OR(7, ARM_V7S_RGN_WBWA);
888
889 /* Looking good; allocate a pgd */
890 data->pgd = __arm_v7s_alloc_table(1, GFP_KERNEL, data);
891 if (!data->pgd) {
892 pr_notice("%s, %d, err pgd\n", __func__, __LINE__);
893 goto out_free_data;
894 }
895
896#ifdef CONFIG_MTK_IOMMU_V2
897 if (mtk_pgtable_align(data->pgd)) {
898 pr_notice("%s, %d, err align\n", __func__, __LINE__);
899 goto out_free_data;
900 }
901#endif
902 base = (unsigned long)virt_to_phys(data->pgd);
903
904 /* Ensure the empty pgd is visible before any actual TTBR write */
905 wmb();
906
907 /* TTBRs */
908 cfg->arm_v7s_cfg.ttbr[0] = (unsigned int)base |
909 ARM_V7S_TTBR_S | ARM_V7S_TTBR_NOS |
910 ARM_V7S_TTBR_IRGN_ATTR(ARM_V7S_RGN_WBWA) |
911 ARM_V7S_TTBR_ORGN_ATTR(ARM_V7S_RGN_WBWA);
912#ifdef CONFIG_MTK_IOMMU_V2
913 cfg->arm_v7s_cfg.ttbr[1] = base >> 32;
914#else
915 cfg->arm_v7s_cfg.ttbr[1] = 0;
916#endif
917#ifdef MTK_PGTABLE_DEBUG_ENABLED
918 phys_addr = virt_to_phys(data->pgd);
919 pr_notice("%s, %d, cf.ttbr=0x%x_%x,pgd_pa=0x%lx, quirks=0x%lx\n",
920 __func__, __LINE__, cfg->arm_v7s_cfg.ttbr[1],
921 cfg->arm_v7s_cfg.ttbr[0], (unsigned long)phys_addr, cfg->quirks);
922#endif
923 return &data->iop;
924
925out_free_data:
926 kmem_cache_destroy(data->l2_tables);
927 kfree(data);
928 return NULL;
929}
930
931struct io_pgtable_init_fns io_pgtable_arm_v7s_init_fns = {
932 .alloc = arm_v7s_alloc_pgtable,
933 .free = arm_v7s_free_pgtable,
934};
935
936#ifdef CONFIG_IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
937
938static struct io_pgtable_cfg *cfg_cookie;
939
940static void dummy_tlb_flush_all(void *cookie)
941{
942 WARN_ON(cookie != cfg_cookie);
943}
944
945static void dummy_tlb_add_flush(unsigned long iova, size_t size,
946 size_t granule, bool leaf, void *cookie)
947{
948 WARN_ON(cookie != cfg_cookie);
949 WARN_ON(!(size & cfg_cookie->pgsize_bitmap));
950}
951
952static void dummy_tlb_sync(void *cookie)
953{
954 WARN_ON(cookie != cfg_cookie);
955}
956
957static const struct iommu_gather_ops dummy_tlb_ops = {
958 .tlb_flush_all = dummy_tlb_flush_all,
959 .tlb_add_flush = dummy_tlb_add_flush,
960 .tlb_sync = dummy_tlb_sync,
961};
962
963#define __FAIL(ops) ({ \
964 WARN(1, "selftest: test failed\n"); \
965 selftest_running = false; \
966 -EFAULT; \
967})
968
969static int __init arm_v7s_do_selftests(void)
970{
971 struct io_pgtable_ops *ops;
972 struct io_pgtable_cfg cfg = {
973 .tlb = &dummy_tlb_ops,
974 .oas = 32,
975 .ias = 32,
976 .quirks = IO_PGTABLE_QUIRK_ARM_NS | IO_PGTABLE_QUIRK_NO_DMA,
977 .pgsize_bitmap = SZ_4K | SZ_64K | SZ_1M | SZ_16M,
978 };
979 unsigned int iova, size, iova_start;
980 unsigned int i, loopnr = 0;
981
982 selftest_running = true;
983
984 cfg_cookie = &cfg;
985
986 ops = alloc_io_pgtable_ops(ARM_V7S, &cfg, &cfg);
987 if (!ops) {
988 pr_err("selftest: failed to allocate io pgtable ops\n");
989 return -EINVAL;
990 }
991
992 /*
993 * Initial sanity checks.
994 * Empty page tables shouldn't provide any translations.
995 */
996 if (ops->iova_to_phys(ops, 42))
997 return __FAIL(ops);
998
999 if (ops->iova_to_phys(ops, SZ_1G + 42))
1000 return __FAIL(ops);
1001
1002 if (ops->iova_to_phys(ops, SZ_2G + 42))
1003 return __FAIL(ops);
1004
1005 /*
1006 * Distinct mappings of different granule sizes.
1007 */
1008 iova = 0;
1009 for_each_set_bit(i, &cfg.pgsize_bitmap, BITS_PER_LONG) {
1010 size = 1UL << i;
1011 if (ops->map(ops, iova, iova, size, IOMMU_READ |
1012 IOMMU_WRITE |
1013 IOMMU_NOEXEC |
1014 IOMMU_CACHE))
1015 return __FAIL(ops);
1016
1017 /* Overlapping mappings */
1018 if (!ops->map(ops, iova, iova + size, size,
1019 IOMMU_READ | IOMMU_NOEXEC))
1020 return __FAIL(ops);
1021
1022 if (ops->iova_to_phys(ops, iova + 42) != (iova + 42))
1023 return __FAIL(ops);
1024
1025 iova += SZ_16M;
1026 loopnr++;
1027 }
1028
1029 /* Partial unmap */
1030 i = 1;
1031 size = 1UL << __ffs(cfg.pgsize_bitmap);
1032 while (i < loopnr) {
1033 iova_start = i * SZ_16M;
1034 if (ops->unmap(ops, iova_start + size, size) != size)
1035 return __FAIL(ops);
1036
1037 /* Remap of partial unmap */
1038 if (ops->map(ops, iova_start + size, size, size, IOMMU_READ))
1039 return __FAIL(ops);
1040
1041 if (ops->iova_to_phys(ops, iova_start + size + 42)
1042 != (size + 42))
1043 return __FAIL(ops);
1044 i++;
1045 }
1046
1047 /* Full unmap */
1048 iova = 0;
1049 for_each_set_bit(i, &cfg.pgsize_bitmap, BITS_PER_LONG) {
1050 size = 1UL << i;
1051
1052 if (ops->unmap(ops, iova, size) != size)
1053 return __FAIL(ops);
1054
1055 if (ops->iova_to_phys(ops, iova + 42))
1056 return __FAIL(ops);
1057
1058 /* Remap full block */
1059 if (ops->map(ops, iova, iova, size, IOMMU_WRITE))
1060 return __FAIL(ops);
1061
1062 if (ops->iova_to_phys(ops, iova + 42) != (iova + 42))
1063 return __FAIL(ops);
1064
1065 iova += SZ_16M;
1066 }
1067
1068 free_io_pgtable_ops(ops);
1069
1070 selftest_running = false;
1071
1072 pr_info("self test ok\n");
1073 return 0;
1074}
1075subsys_initcall(arm_v7s_do_selftests);
1076#endif