iommu/io-pgtable-arm: Rationalise TTBRn handling
authorRobin Murphy <robin.murphy@arm.com>
Fri, 25 Oct 2019 18:08:37 +0000 (19:08 +0100)
committerWill Deacon <will@kernel.org>
Fri, 10 Jan 2020 15:39:23 +0000 (15:39 +0000)
TTBR1 values have so far been redundant since no users implement any
support for split address spaces. Crucially, though, one of the main
reasons for wanting to do so is to be able to manage each half entirely
independently, e.g. context-switching one set of mappings without
disturbing the other. Thus it seems unlikely that tying two tables
together in a single io_pgtable_cfg would ever be particularly desirable
or useful.

Streamline the configs to just a single conceptual TTBR value
representing the allocated table. This paves the way for future users to
support split address spaces by simply allocating a table and dealing
with the detailed TTBRn logistics themselves.

Tested-by: Jordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
[will: Drop change to ttbr value]
Signed-off-by: Will Deacon <will@kernel.org>
drivers/iommu/arm-smmu-v3.c
drivers/iommu/arm-smmu.c
drivers/iommu/io-pgtable-arm-v7s.c
drivers/iommu/io-pgtable-arm.c
drivers/iommu/ipmmu-vmsa.c
drivers/iommu/msm_iommu.c
drivers/iommu/mtk_iommu.c
drivers/iommu/qcom_iommu.c
include/linux/io-pgtable.h

index aa7e530235852bd68c7df0d9c7cc4a10aed23555..cf2ae065a6c2a6da725aeb30e7042b93980564ae 100644 (file)
@@ -2166,7 +2166,7 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
        }
 
        cfg->cd.asid    = (u16)asid;
-       cfg->cd.ttbr    = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
+       cfg->cd.ttbr    = pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
        cfg->cd.tcr     = pgtbl_cfg->arm_lpae_s1_cfg.tcr;
        cfg->cd.mair    = pgtbl_cfg->arm_lpae_s1_cfg.mair;
        return 0;
index 46b87740d708f0c34f0e7c83c91a8d78d00e0558..72640e045268f05eca1bf11fbcf0c2e4d66e16b0 100644 (file)
@@ -553,13 +553,12 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
        /* TTBRs */
        if (stage1) {
                if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) {
-                       cb->ttbr[0] = pgtbl_cfg->arm_v7s_cfg.ttbr[0];
-                       cb->ttbr[1] = pgtbl_cfg->arm_v7s_cfg.ttbr[1];
+                       cb->ttbr[0] = pgtbl_cfg->arm_v7s_cfg.ttbr;
+                       cb->ttbr[1] = 0;
                } else {
-                       cb->ttbr[0] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
+                       cb->ttbr[0] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
                        cb->ttbr[0] |= FIELD_PREP(TTBRn_ASID, cfg->asid);
-                       cb->ttbr[1] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
-                       cb->ttbr[1] |= FIELD_PREP(TTBRn_ASID, cfg->asid);
+                       cb->ttbr[1] = FIELD_PREP(TTBRn_ASID, cfg->asid);
                }
        } else {
                cb->ttbr[0] = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
index 7c3bd2c3cdca9c08fd77f1e8ad48e99080e4f178..eac886f7619da15f05a2f30481aac3e63c526723 100644 (file)
@@ -822,15 +822,14 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
        /* Ensure the empty pgd is visible before any actual TTBR write */
        wmb();
 
-       /* TTBRs */
-       cfg->arm_v7s_cfg.ttbr[0] = virt_to_phys(data->pgd) |
-                                  ARM_V7S_TTBR_S | ARM_V7S_TTBR_NOS |
-                                  (cfg->coherent_walk ?
-                                  (ARM_V7S_TTBR_IRGN_ATTR(ARM_V7S_RGN_WBWA) |
-                                   ARM_V7S_TTBR_ORGN_ATTR(ARM_V7S_RGN_WBWA)) :
-                                  (ARM_V7S_TTBR_IRGN_ATTR(ARM_V7S_RGN_NC) |
-                                   ARM_V7S_TTBR_ORGN_ATTR(ARM_V7S_RGN_NC)));
-       cfg->arm_v7s_cfg.ttbr[1] = 0;
+       /* TTBR */
+       cfg->arm_v7s_cfg.ttbr = virt_to_phys(data->pgd) |
+                               ARM_V7S_TTBR_S | ARM_V7S_TTBR_NOS |
+                               (cfg->coherent_walk ?
+                               (ARM_V7S_TTBR_IRGN_ATTR(ARM_V7S_RGN_WBWA) |
+                                ARM_V7S_TTBR_ORGN_ATTR(ARM_V7S_RGN_WBWA)) :
+                               (ARM_V7S_TTBR_IRGN_ATTR(ARM_V7S_RGN_NC) |
+                                ARM_V7S_TTBR_ORGN_ATTR(ARM_V7S_RGN_NC)));
        return &data->iop;
 
 out_free_data:
index bdf47f74526879d1316f640e2308a0a3871931f1..7b422b9fe05b124e474039a1fc3de8168716d026 100644 (file)
@@ -872,9 +872,8 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
        /* Ensure the empty pgd is visible before any actual TTBR write */
        wmb();
 
-       /* TTBRs */
-       cfg->arm_lpae_s1_cfg.ttbr[0] = virt_to_phys(data->pgd);
-       cfg->arm_lpae_s1_cfg.ttbr[1] = 0;
+       /* TTBR */
+       cfg->arm_lpae_s1_cfg.ttbr = virt_to_phys(data->pgd);
        return &data->iop;
 
 out_free_data:
index d02edd2751f32077bdb1ebed449c5958b8abcd19..ecb3f9464dd5c894583fe88ef84fb0d1093511fd 100644 (file)
@@ -374,7 +374,7 @@ static void ipmmu_domain_setup_context(struct ipmmu_vmsa_domain *domain)
        u32 tmp;
 
        /* TTBR0 */
-       ttbr = domain->cfg.arm_lpae_s1_cfg.ttbr[0];
+       ttbr = domain->cfg.arm_lpae_s1_cfg.ttbr;
        ipmmu_ctx_write_root(domain, IMTTLBR0, ttbr);
        ipmmu_ctx_write_root(domain, IMTTUBR0, ttbr >> 32);
 
index 93f14bca26ee0292ce51578236c59131e58bfc85..94a6df1bddd60b8b1607555ae4fa6e77a7ac7231 100644 (file)
@@ -279,8 +279,8 @@ static void __program_context(void __iomem *base, int ctx,
        SET_V2PCFG(base, ctx, 0x3);
 
        SET_TTBCR(base, ctx, priv->cfg.arm_v7s_cfg.tcr);
-       SET_TTBR0(base, ctx, priv->cfg.arm_v7s_cfg.ttbr[0]);
-       SET_TTBR1(base, ctx, priv->cfg.arm_v7s_cfg.ttbr[1]);
+       SET_TTBR0(base, ctx, priv->cfg.arm_v7s_cfg.ttbr);
+       SET_TTBR1(base, ctx, 0);
 
        /* Set prrr and nmrr */
        SET_PRRR(base, ctx, priv->cfg.arm_v7s_cfg.prrr);
index 6fc1f5ecf91e5109e62146ff4be90a070099166c..95945f467c03f949bc07abc801152e181f2ecfce 100644 (file)
@@ -367,7 +367,7 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
        /* Update the pgtable base address register of the M4U HW */
        if (!data->m4u_dom) {
                data->m4u_dom = dom;
-               writel(dom->cfg.arm_v7s_cfg.ttbr[0] & MMU_PT_ADDR_MASK,
+               writel(dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK,
                       data->base + REG_MMU_PT_BASE_ADDR);
        }
 
@@ -765,7 +765,7 @@ static int __maybe_unused mtk_iommu_resume(struct device *dev)
        writel_relaxed(reg->ivrp_paddr, base + REG_MMU_IVRP_PADDR);
        writel_relaxed(reg->vld_pa_rng, base + REG_MMU_VLD_PA_RNG);
        if (m4u_dom)
-               writel(m4u_dom->cfg.arm_v7s_cfg.ttbr[0] & MMU_PT_ADDR_MASK,
+               writel(m4u_dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK,
                       base + REG_MMU_PT_BASE_ADDR);
        return 0;
 }
index 52f38292df5b634e6c25adf56649b90eef76610e..c200bc0662576b4181123b17946f1ea10c682a39 100644 (file)
@@ -269,10 +269,9 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain,
 
                /* TTBRs */
                iommu_writeq(ctx, ARM_SMMU_CB_TTBR0,
-                               pgtbl_cfg.arm_lpae_s1_cfg.ttbr[0] |
+                               pgtbl_cfg.arm_lpae_s1_cfg.ttbr |
                                FIELD_PREP(TTBRn_ASID, ctx->asid));
                iommu_writeq(ctx, ARM_SMMU_CB_TTBR1,
-                               pgtbl_cfg.arm_lpae_s1_cfg.ttbr[1] |
                                FIELD_PREP(TTBRn_ASID, ctx->asid));
 
                /* TCR */
index ee21eedafe986817ea63f079458b34c593cce933..53bca5343f528757ddd077c37fa2043d516042e9 100644 (file)
@@ -100,7 +100,7 @@ struct io_pgtable_cfg {
        /* Low-level data specific to the table format */
        union {
                struct {
-                       u64     ttbr[2];
+                       u64     ttbr;
                        u64     tcr;
                        u64     mair;
                } arm_lpae_s1_cfg;
@@ -111,7 +111,7 @@ struct io_pgtable_cfg {
                } arm_lpae_s2_cfg;
 
                struct {
-                       u32     ttbr[2];
+                       u32     ttbr;
                        u32     tcr;
                        u32     nmrr;
                        u32     prrr;