aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Murphy <robin.murphy@arm.com>2018-03-26 08:35:13 -0400
committerWill Deacon <will.deacon@arm.com>2018-03-27 09:12:05 -0400
commit6c89928ff7a0f7b4ebc2ac1acab9f99d5f50ed75 (patch)
tree432659962b3ffa3dc11fba9bd103b42a1dd9427e
parent7417b99c49e5bb77e04d64c915da2ee4bfcbf8a8 (diff)
iommu/io-pgtable-arm: Support 52-bit physical address
Bring io-pgtable-arm in line with the ARMv8.2-LPA feature allowing 52-bit physical addresses when using the 64KB translation granule. This will be supported by SMMUv3.1. Tested-by: Nate Watterson <nwatters@codeaurora.org> Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--drivers/iommu/io-pgtable-arm.c67
1 files changed, 49 insertions, 18 deletions
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 51e5c43caed1..a5be4c92c5c8 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -21,6 +21,7 @@
21#define pr_fmt(fmt) "arm-lpae io-pgtable: " fmt 21#define pr_fmt(fmt) "arm-lpae io-pgtable: " fmt
22 22
23#include <linux/atomic.h> 23#include <linux/atomic.h>
24#include <linux/bitops.h>
24#include <linux/iommu.h> 25#include <linux/iommu.h>
25#include <linux/kernel.h> 26#include <linux/kernel.h>
26#include <linux/sizes.h> 27#include <linux/sizes.h>
@@ -32,7 +33,7 @@
32 33
33#include "io-pgtable.h" 34#include "io-pgtable.h"
34 35
35#define ARM_LPAE_MAX_ADDR_BITS 48 36#define ARM_LPAE_MAX_ADDR_BITS 52
36#define ARM_LPAE_S2_MAX_CONCAT_PAGES 16 37#define ARM_LPAE_S2_MAX_CONCAT_PAGES 16
37#define ARM_LPAE_MAX_LEVELS 4 38#define ARM_LPAE_MAX_LEVELS 4
38 39
@@ -86,6 +87,8 @@
86#define ARM_LPAE_PTE_TYPE_TABLE 3 87#define ARM_LPAE_PTE_TYPE_TABLE 3
87#define ARM_LPAE_PTE_TYPE_PAGE 3 88#define ARM_LPAE_PTE_TYPE_PAGE 3
88 89
90#define ARM_LPAE_PTE_ADDR_MASK GENMASK_ULL(47,12)
91
89#define ARM_LPAE_PTE_NSTABLE (((arm_lpae_iopte)1) << 63) 92#define ARM_LPAE_PTE_NSTABLE (((arm_lpae_iopte)1) << 63)
90#define ARM_LPAE_PTE_XN (((arm_lpae_iopte)3) << 53) 93#define ARM_LPAE_PTE_XN (((arm_lpae_iopte)3) << 53)
91#define ARM_LPAE_PTE_AF (((arm_lpae_iopte)1) << 10) 94#define ARM_LPAE_PTE_AF (((arm_lpae_iopte)1) << 10)
@@ -159,6 +162,7 @@
159#define ARM_LPAE_TCR_PS_42_BIT 0x3ULL 162#define ARM_LPAE_TCR_PS_42_BIT 0x3ULL
160#define ARM_LPAE_TCR_PS_44_BIT 0x4ULL 163#define ARM_LPAE_TCR_PS_44_BIT 0x4ULL
161#define ARM_LPAE_TCR_PS_48_BIT 0x5ULL 164#define ARM_LPAE_TCR_PS_48_BIT 0x5ULL
165#define ARM_LPAE_TCR_PS_52_BIT 0x6ULL
162 166
163#define ARM_LPAE_MAIR_ATTR_SHIFT(n) ((n) << 3) 167#define ARM_LPAE_MAIR_ATTR_SHIFT(n) ((n) << 3)
164#define ARM_LPAE_MAIR_ATTR_MASK 0xff 168#define ARM_LPAE_MAIR_ATTR_MASK 0xff
@@ -170,9 +174,7 @@
170#define ARM_LPAE_MAIR_ATTR_IDX_DEV 2 174#define ARM_LPAE_MAIR_ATTR_IDX_DEV 2
171 175
172/* IOPTE accessors */ 176/* IOPTE accessors */
173#define iopte_deref(pte,d) \ 177#define iopte_deref(pte,d) __va(iopte_to_paddr(pte, d))
174 (__va((pte) & ((1ULL << ARM_LPAE_MAX_ADDR_BITS) - 1) \
175 & ~(ARM_LPAE_GRANULE(d) - 1ULL)))
176 178
177#define iopte_type(pte,l) \ 179#define iopte_type(pte,l) \
178 (((pte) >> ARM_LPAE_PTE_TYPE_SHIFT) & ARM_LPAE_PTE_TYPE_MASK) 180 (((pte) >> ARM_LPAE_PTE_TYPE_SHIFT) & ARM_LPAE_PTE_TYPE_MASK)
@@ -184,12 +186,6 @@
184 (iopte_type(pte,l) == ARM_LPAE_PTE_TYPE_PAGE) : \ 186 (iopte_type(pte,l) == ARM_LPAE_PTE_TYPE_PAGE) : \
185 (iopte_type(pte,l) == ARM_LPAE_PTE_TYPE_BLOCK)) 187 (iopte_type(pte,l) == ARM_LPAE_PTE_TYPE_BLOCK))
186 188
187#define iopte_to_pfn(pte,d) \
188 (((pte) & ((1ULL << ARM_LPAE_MAX_ADDR_BITS) - 1)) >> (d)->pg_shift)
189
190#define pfn_to_iopte(pfn,d) \
191 (((pfn) << (d)->pg_shift) & ((1ULL << ARM_LPAE_MAX_ADDR_BITS) - 1))
192
193struct arm_lpae_io_pgtable { 189struct arm_lpae_io_pgtable {
194 struct io_pgtable iop; 190 struct io_pgtable iop;
195 191
@@ -203,6 +199,27 @@ struct arm_lpae_io_pgtable {
203 199
204typedef u64 arm_lpae_iopte; 200typedef u64 arm_lpae_iopte;
205 201
202static arm_lpae_iopte paddr_to_iopte(phys_addr_t paddr,
203 struct arm_lpae_io_pgtable *data)
204{
205 arm_lpae_iopte pte = paddr;
206
207 /* Of the bits which overlap, either 51:48 or 15:12 are always RES0 */
208 return (pte | (pte >> (48 - 12))) & ARM_LPAE_PTE_ADDR_MASK;
209}
210
211static phys_addr_t iopte_to_paddr(arm_lpae_iopte pte,
212 struct arm_lpae_io_pgtable *data)
213{
214 phys_addr_t paddr = pte & ARM_LPAE_PTE_ADDR_MASK;
215
216 if (data->pg_shift < 16)
217 return paddr;
218
219 /* Rotate the packed high-order bits back to the top */
220 return (paddr | (paddr << (48 - 12))) & (ARM_LPAE_PTE_ADDR_MASK << 4);
221}
222
206static bool selftest_running = false; 223static bool selftest_running = false;
207 224
208static dma_addr_t __arm_lpae_dma_addr(void *pages) 225static dma_addr_t __arm_lpae_dma_addr(void *pages)
@@ -287,7 +304,7 @@ static void __arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
287 pte |= ARM_LPAE_PTE_TYPE_BLOCK; 304 pte |= ARM_LPAE_PTE_TYPE_BLOCK;
288 305
289 pte |= ARM_LPAE_PTE_AF | ARM_LPAE_PTE_SH_IS; 306 pte |= ARM_LPAE_PTE_AF | ARM_LPAE_PTE_SH_IS;
290 pte |= pfn_to_iopte(paddr >> data->pg_shift, data); 307 pte |= paddr_to_iopte(paddr, data);
291 308
292 __arm_lpae_set_pte(ptep, pte, &data->iop.cfg); 309 __arm_lpae_set_pte(ptep, pte, &data->iop.cfg);
293} 310}
@@ -528,7 +545,7 @@ static int arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data,
528 if (size == split_sz) 545 if (size == split_sz)
529 unmap_idx = ARM_LPAE_LVL_IDX(iova, lvl, data); 546 unmap_idx = ARM_LPAE_LVL_IDX(iova, lvl, data);
530 547
531 blk_paddr = iopte_to_pfn(blk_pte, data) << data->pg_shift; 548 blk_paddr = iopte_to_paddr(blk_pte, data);
532 pte = iopte_prot(blk_pte); 549 pte = iopte_prot(blk_pte);
533 550
534 for (i = 0; i < tablesz / sizeof(pte); i++, blk_paddr += split_sz) { 551 for (i = 0; i < tablesz / sizeof(pte); i++, blk_paddr += split_sz) {
@@ -652,12 +669,13 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
652 669
653found_translation: 670found_translation:
654 iova &= (ARM_LPAE_BLOCK_SIZE(lvl, data) - 1); 671 iova &= (ARM_LPAE_BLOCK_SIZE(lvl, data) - 1);
655 return ((phys_addr_t)iopte_to_pfn(pte,data) << data->pg_shift) | iova; 672 return iopte_to_paddr(pte, data) | iova;
656} 673}
657 674
658static void arm_lpae_restrict_pgsizes(struct io_pgtable_cfg *cfg) 675static void arm_lpae_restrict_pgsizes(struct io_pgtable_cfg *cfg)
659{ 676{
660 unsigned long granule; 677 unsigned long granule, page_sizes;
678 unsigned int max_addr_bits = 48;
661 679
662 /* 680 /*
663 * We need to restrict the supported page sizes to match the 681 * We need to restrict the supported page sizes to match the
@@ -677,17 +695,24 @@ static void arm_lpae_restrict_pgsizes(struct io_pgtable_cfg *cfg)
677 695
678 switch (granule) { 696 switch (granule) {
679 case SZ_4K: 697 case SZ_4K:
680 cfg->pgsize_bitmap &= (SZ_4K | SZ_2M | SZ_1G); 698 page_sizes = (SZ_4K | SZ_2M | SZ_1G);
681 break; 699 break;
682 case SZ_16K: 700 case SZ_16K:
683 cfg->pgsize_bitmap &= (SZ_16K | SZ_32M); 701 page_sizes = (SZ_16K | SZ_32M);
684 break; 702 break;
685 case SZ_64K: 703 case SZ_64K:
686 cfg->pgsize_bitmap &= (SZ_64K | SZ_512M); 704 max_addr_bits = 52;
705 page_sizes = (SZ_64K | SZ_512M);
706 if (cfg->oas > 48)
707 page_sizes |= 1ULL << 42; /* 4TB */
687 break; 708 break;
688 default: 709 default:
689 cfg->pgsize_bitmap = 0; 710 page_sizes = 0;
690 } 711 }
712
713 cfg->pgsize_bitmap &= page_sizes;
714 cfg->ias = min(cfg->ias, max_addr_bits);
715 cfg->oas = min(cfg->oas, max_addr_bits);
691} 716}
692 717
693static struct arm_lpae_io_pgtable * 718static struct arm_lpae_io_pgtable *
@@ -784,6 +809,9 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
784 case 48: 809 case 48:
785 reg |= (ARM_LPAE_TCR_PS_48_BIT << ARM_LPAE_TCR_IPS_SHIFT); 810 reg |= (ARM_LPAE_TCR_PS_48_BIT << ARM_LPAE_TCR_IPS_SHIFT);
786 break; 811 break;
812 case 52:
813 reg |= (ARM_LPAE_TCR_PS_52_BIT << ARM_LPAE_TCR_IPS_SHIFT);
814 break;
787 default: 815 default:
788 goto out_free_data; 816 goto out_free_data;
789 } 817 }
@@ -891,6 +919,9 @@ arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
891 case 48: 919 case 48:
892 reg |= (ARM_LPAE_TCR_PS_48_BIT << ARM_LPAE_TCR_PS_SHIFT); 920 reg |= (ARM_LPAE_TCR_PS_48_BIT << ARM_LPAE_TCR_PS_SHIFT);
893 break; 921 break;
922 case 52:
923 reg |= (ARM_LPAE_TCR_PS_52_BIT << ARM_LPAE_TCR_PS_SHIFT);
924 break;
894 default: 925 default:
895 goto out_free_data; 926 goto out_free_data;
896 } 927 }