Re: [PATCH 3/3] iommu: Disable passthrough mode when SME is active

2019-08-09 Thread Joerg Roedel
Hey Tom,

On Fri, Aug 09, 2019 at 04:50:48PM +, Lendacky, Thomas wrote:
> On 8/9/19 10:22 AM, Joerg Roedel wrote:
> > +   if ((iommu_def_domain_type == IOMMU_DOMAIN_IDENTITY) &&
> > +   sme_active()) {
> > +   pr_info("SME detected - Disabling default IOMMU passthrough\n");
> > +   iommu_def_domain_type = IOMMU_DOMAIN_DMA;
> 
> Should this also clear the iommu_pass_through variable (the one set by the
> iommu kernel parameter in arch/x86/kernel/pci-dma.c)?

This code is used on different architectures, so I can't cleanly access
architecture specific variables here.

> I guess this is more applicable to the original patchset that created the
> CONFIG_IOMMU_DEFAULT_PASSTHROUGH option, but should the default
> passthrough support be modified so that you don't have to specify multiple
> kernel parameters to change it?
> 
> Right now, if CONFIG_IOMMU_DEFAULT_PASSTHROUGH is set to yes, you can't
> just specify iommu=nopt to enable the IOMMU. You have to also specify
> iommu.passthrough=0. Do we want to fix that so that just specifying
> iommu=nopt or iommu.passthrough=0 does what is needed?

Yeah, that is currently a mess and I think cleaning that up is at least
partly in the scope of this patch-set. I'll look into that next week.


Regards,

Joerg

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 00/15] Arm SMMU refactoring

2019-08-09 Thread Robin Murphy

...and of course I had to forget someone's cc - sorry Jordan! :(

Robin.

On 09/08/2019 18:07, Robin Murphy wrote:

Hi all,

This is a big refactoring of arm-smmu in order to help cope with the
various divergent implementation details currently flying around. So
far we've been accruing various quirks and errata workarounds within
the main flow of the driver, but given that it's written to an
architecture rather than any particular hardware implementation, after
a point these start to become increasingly invasive and potentially
conflict with each other.

These patches clean up the existing quirks handled by the driver to
lay a foundation on which we can continue to add more in a maintainable
fashion. The idea is that major vendor customisations can then be kept
in arm-smmu-.c implementation files out of each others' way.

A branch is available at:

   git://linux-arm.org/linux-rm  iommu/smmu-impl

which I'll probably keep tweaking until I'm happy with the names of
things; I just didn't want to delay this initial posting any lomnger.

Robin.


Robin Murphy (15):
   iommu/arm-smmu: Convert GR0 registers to bitfields
   iommu/arm-smmu: Convert GR1 registers to bitfields
   iommu/arm-smmu: Convert context bank registers to bitfields
   iommu/arm-smmu: Rework cb_base handling
   iommu/arm-smmu: Split arm_smmu_tlb_inv_range_nosync()
   iommu/arm-smmu: Get rid of weird "atomic" write
   iommu/arm-smmu: Abstract GR1 accesses
   iommu/arm-smmu: Abstract context bank accesses
   iommu/arm-smmu: Abstract GR0 accesses
   iommu/arm-smmu: Rename arm-smmu-regs.h
   iommu/arm-smmu: Add implementation infrastructure
   iommu/arm-smmu: Move Secure access quirk to implementation
   iommu/arm-smmu: Add configuration implementation hook
   iommu/arm-smmu: Add reset implementation hook
   iommu/arm-smmu: Add context init implementation hook

  MAINTAINERS   |   3 +-
  drivers/iommu/Makefile|   2 +-
  drivers/iommu/arm-smmu-impl.c | 165 ++
  drivers/iommu/arm-smmu-regs.h | 210 -
  drivers/iommu/arm-smmu.c  | 570 +++---
  drivers/iommu/arm-smmu.h  | 386 +++
  drivers/iommu/qcom_iommu.c|  15 +-
  7 files changed, 743 insertions(+), 608 deletions(-)
  create mode 100644 drivers/iommu/arm-smmu-impl.c
  delete mode 100644 drivers/iommu/arm-smmu-regs.h
  create mode 100644 drivers/iommu/arm-smmu.h


___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 15/15] iommu/arm-smmu: Add context init implementation hook

2019-08-09 Thread Robin Murphy
Allocating and initialising a context for a domain is another point
where certain implementations are known to want special behaviour.
Currently the other half of the Cavium workaround comes into play here,
so let's finish the job to get the whole thing right out of the way.

Signed-off-by: Robin Murphy 
---
 drivers/iommu/arm-smmu-impl.c | 39 +--
 drivers/iommu/arm-smmu.c  | 51 +++
 drivers/iommu/arm-smmu.h  | 42 +++--
 3 files changed, 86 insertions(+), 46 deletions(-)

diff --git a/drivers/iommu/arm-smmu-impl.c b/drivers/iommu/arm-smmu-impl.c
index c8904da08354..7a657d47b6ec 100644
--- a/drivers/iommu/arm-smmu-impl.c
+++ b/drivers/iommu/arm-smmu-impl.c
@@ -48,6 +48,12 @@ const struct arm_smmu_impl calxeda_impl = {
 };
 
 
+struct cavium_smmu {
+   struct arm_smmu_device smmu;
+   u32 id_base;
+};
+#define to_csmmu(s)container_of(s, struct cavium_smmu, smmu)
+
 static int cavium_cfg_probe(struct arm_smmu_device *smmu)
 {
static atomic_t context_count = ATOMIC_INIT(0);
@@ -56,17 +62,46 @@ static int cavium_cfg_probe(struct arm_smmu_device *smmu)
 * Ensure ASID and VMID allocation is unique across all SMMUs in
 * the system.
 */
-   smmu->cavium_id_base = atomic_fetch_add(smmu->num_context_banks,
+   to_csmmu(smmu)->id_base = atomic_fetch_add(smmu->num_context_banks,
   &context_count);
dev_notice(smmu->dev, "\tenabling workaround for Cavium erratum 
27704\n");
 
return 0;
 }
 
+int cavium_init_context(struct arm_smmu_domain *smmu_domain)
+{
+   u32 id_base = to_csmmu(smmu_domain->smmu)->id_base;
+
+   if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2)
+   smmu_domain->cfg.vmid += id_base;
+   else
+   smmu_domain->cfg.asid += id_base;
+
+   return 0;
+}
+
 const struct arm_smmu_impl cavium_impl = {
.cfg_probe = cavium_cfg_probe,
+   .init_context = cavium_init_context,
 };
 
+struct arm_smmu_device *cavium_smmu_impl_init(struct arm_smmu_device *smmu)
+{
+   struct cavium_smmu *csmmu;
+
+   csmmu = devm_kzalloc(smmu->dev, sizeof(*csmmu), GFP_KERNEL);
+   if (!csmmu)
+   return ERR_PTR(-ENOMEM);
+
+   csmmu->smmu = *smmu;
+   csmmu->smmu.impl = &cavium_impl;
+
+   devm_kfree(smmu->dev, smmu);
+
+   return &csmmu->smmu;
+}
+
 
 #define ARM_MMU500_ACTLR_CPRE  (1 << 1)
 
@@ -121,7 +156,7 @@ struct arm_smmu_device *arm_smmu_impl_init(struct 
arm_smmu_device *smmu)
smmu->impl = &calxeda_impl;
 
if (smmu->model == CAVIUM_SMMUV2)
-   smmu->impl = &cavium_impl;
+   return cavium_smmu_impl_init(smmu);
 
if (smmu->model == ARM_MMU500)
smmu->impl = &arm_mmu500_impl;
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 298ab9e6a6cd..1c1c9ef91d7b 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -27,7 +27,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -111,44 +110,6 @@ struct arm_smmu_master_cfg {
 #define for_each_cfg_sme(fw, i, idx) \
for (i = 0; idx = fwspec_smendx(fw, i), i < fw->num_ids; ++i)
 
-enum arm_smmu_context_fmt {
-   ARM_SMMU_CTX_FMT_NONE,
-   ARM_SMMU_CTX_FMT_AARCH64,
-   ARM_SMMU_CTX_FMT_AARCH32_L,
-   ARM_SMMU_CTX_FMT_AARCH32_S,
-};
-
-struct arm_smmu_cfg {
-   u8  cbndx;
-   u8  irptndx;
-   union {
-   u16 asid;
-   u16 vmid;
-   };
-   enum arm_smmu_cbar_type cbar;
-   enum arm_smmu_context_fmt   fmt;
-};
-#define INVALID_IRPTNDX0xff
-
-enum arm_smmu_domain_stage {
-   ARM_SMMU_DOMAIN_S1 = 0,
-   ARM_SMMU_DOMAIN_S2,
-   ARM_SMMU_DOMAIN_NESTED,
-   ARM_SMMU_DOMAIN_BYPASS,
-};
-
-struct arm_smmu_domain {
-   struct arm_smmu_device  *smmu;
-   struct io_pgtable_ops   *pgtbl_ops;
-   const struct iommu_gather_ops   *tlb_ops;
-   struct arm_smmu_cfg cfg;
-   enum arm_smmu_domain_stage  stage;
-   boolnon_strict;
-   struct mutexinit_mutex; /* Protects smmu pointer */
-   spinlock_t  cb_lock; /* Serialises ATS1* ops and 
TLB syncs */
-   struct iommu_domain domain;
-};
-
 static bool using_legacy_binding, using_generic_binding;
 
 static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu)
@@ -749,9 +710,16 @@ static int arm_smmu_init_domain_context(struct 
iommu_domain *domain,
}
 
if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2)
-   cfg->vmid = cfg->cbndx + 1 + smmu->cavium_id_base;
+   cfg->vmid = cfg->cbndx + 1;
else
-   cfg->asid = cfg->c

[PATCH 14/15] iommu/arm-smmu: Add reset implementation hook

2019-08-09 Thread Robin Murphy
Reset is an activity rife with implementation-defined poking. Add a
corresponding hook, and use it to encapsulate the existing MMU-500
details.

Signed-off-by: Robin Murphy 
---
 drivers/iommu/arm-smmu-impl.c | 49 +++
 drivers/iommu/arm-smmu.c  | 39 +++-
 drivers/iommu/arm-smmu.h  |  1 +
 3 files changed, 54 insertions(+), 35 deletions(-)

diff --git a/drivers/iommu/arm-smmu-impl.c b/drivers/iommu/arm-smmu-impl.c
index 0b444e476525..c8904da08354 100644
--- a/drivers/iommu/arm-smmu-impl.c
+++ b/drivers/iommu/arm-smmu-impl.c
@@ -4,6 +4,7 @@
 
 #define pr_fmt(fmt) "arm-smmu: " fmt
 
+#include 
 #include 
 
 #include "arm-smmu.h"
@@ -67,6 +68,51 @@ const struct arm_smmu_impl cavium_impl = {
 };
 
 
+#define ARM_MMU500_ACTLR_CPRE  (1 << 1)
+
+#define ARM_MMU500_ACR_CACHE_LOCK  (1 << 26)
+#define ARM_MMU500_ACR_S2CRB_TLBEN (1 << 10)
+#define ARM_MMU500_ACR_SMTNMB_TLBEN(1 << 8)
+
+static int arm_mmu500_reset(struct arm_smmu_device *smmu)
+{
+   u32 reg, major;
+   int i;
+   /*
+* On MMU-500 r2p0 onwards we need to clear ACR.CACHE_LOCK before
+* writes to the context bank ACTLRs will stick. And we just hope that
+* Secure has also cleared SACR.CACHE_LOCK for this to take effect...
+*/
+   reg = arm_smmu_read_gr0(smmu, ARM_SMMU_GR0_ID7);
+   major = FIELD_GET(ID7_MAJOR, reg);
+   reg = arm_smmu_read_gr0(smmu, ARM_SMMU_GR0_sACR);
+   if (major >= 2)
+   reg &= ~ARM_MMU500_ACR_CACHE_LOCK;
+   /*
+* Allow unmatched Stream IDs to allocate bypass
+* TLB entries for reduced latency.
+*/
+   reg |= ARM_MMU500_ACR_SMTNMB_TLBEN | ARM_MMU500_ACR_S2CRB_TLBEN;
+   arm_smmu_write_gr0(smmu, ARM_SMMU_GR0_sACR, reg);
+
+   /*
+* Disable MMU-500's not-particularly-beneficial next-page
+* prefetcher for the sake of errata #841119 and #826419.
+*/
+   for (i = 0; i < smmu->num_context_banks; ++i) {
+   reg = arm_smmu_read_cb(smmu, i, ARM_SMMU_CB_ACTLR);
+   reg &= ~ARM_MMU500_ACTLR_CPRE;
+   arm_smmu_write_cb(smmu, i, ARM_SMMU_CB_ACTLR, reg);
+   }
+
+   return 0;
+}
+
+const struct arm_smmu_impl arm_mmu500_impl = {
+   .reset = arm_mmu500_reset,
+};
+
+
 struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
 {
/* The current quirks happen to be mutually-exclusive */
@@ -77,5 +123,8 @@ struct arm_smmu_device *arm_smmu_impl_init(struct 
arm_smmu_device *smmu)
if (smmu->model == CAVIUM_SMMUV2)
smmu->impl = &cavium_impl;
 
+   if (smmu->model == ARM_MMU500)
+   smmu->impl = &arm_mmu500_impl;
+
return smmu;
 }
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 80822d48f6c7..298ab9e6a6cd 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -54,12 +54,6 @@
  */
 #define QCOM_DUMMY_VAL -1
 
-#define ARM_MMU500_ACTLR_CPRE  (1 << 1)
-
-#define ARM_MMU500_ACR_CACHE_LOCK  (1 << 26)
-#define ARM_MMU500_ACR_S2CRB_TLBEN (1 << 10)
-#define ARM_MMU500_ACR_SMTNMB_TLBEN(1 << 8)
-
 #define TLB_LOOP_TIMEOUT   100 /* 1s! */
 #define TLB_SPIN_COUNT 10
 
@@ -1574,7 +1568,7 @@ static struct iommu_ops arm_smmu_ops = {
 static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
 {
int i;
-   u32 reg, major;
+   u32 reg;
 
/* clear global FSR */
reg = arm_smmu_read_gr0(smmu, ARM_SMMU_GR0_sGFSR);
@@ -1587,38 +1581,10 @@ static void arm_smmu_device_reset(struct 
arm_smmu_device *smmu)
for (i = 0; i < smmu->num_mapping_groups; ++i)
arm_smmu_write_sme(smmu, i);
 
-   if (smmu->model == ARM_MMU500) {
-   /*
-* Before clearing ARM_MMU500_ACTLR_CPRE, need to
-* clear CACHE_LOCK bit of ACR first. And, CACHE_LOCK
-* bit is only present in MMU-500r2 onwards.
-*/
-   reg = arm_smmu_read_gr0(smmu, ARM_SMMU_GR0_ID7);
-   major = FIELD_GET(ID7_MAJOR, reg);
-   reg = arm_smmu_read_gr0(smmu, ARM_SMMU_GR0_sACR);
-   if (major >= 2)
-   reg &= ~ARM_MMU500_ACR_CACHE_LOCK;
-   /*
-* Allow unmatched Stream IDs to allocate bypass
-* TLB entries for reduced latency.
-*/
-   reg |= ARM_MMU500_ACR_SMTNMB_TLBEN | ARM_MMU500_ACR_S2CRB_TLBEN;
-   arm_smmu_write_gr0(smmu, ARM_SMMU_GR0_sACR, reg);
-   }
-
/* Make sure all context banks are disabled and clear CB_FSR  */
for (i = 0; i < smmu->num_context_banks; ++i) {
arm_smmu_write_context_bank(smmu, i);
arm_smmu_write_cb(smmu, i, ARM_SMMU_CB_FSR, FSR_FAULT);
-   /*
-* Disable MMU-500's not-particularly-beneficial next-page
-* p

[PATCH 09/15] iommu/arm-smmu: Abstract GR0 accesses

2019-08-09 Thread Robin Murphy
Clean up the remaining accesses to GR0 registers, so that everything is
now neatly abstracted. This folds up the Non-Secure alias quirk as the
first step towards moving it out of the way entirely. Although GR0 does
technically contain some 64-bit registers (sGFAR and the weird SMMUv2
HYPC and MONC stuff), they're not ones we have any need to access.

Signed-off-by: Robin Murphy 
---
 drivers/iommu/arm-smmu.c | 101 +--
 1 file changed, 54 insertions(+), 47 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index abdcc3f52e2e..d1ba5d115713 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -69,19 +69,6 @@
 /* Maximum number of context banks per SMMU */
 #define ARM_SMMU_MAX_CBS   128
 
-/* SMMU global address space */
-#define ARM_SMMU_GR0(smmu) ((smmu)->base)
-
-/*
- * SMMU global address space with conditional offset to access secure
- * aliases of non-secure registers (e.g. nsCR0: 0x400, nsGFSR: 0x448,
- * nsGFSYNR0: 0x450)
- */
-#define ARM_SMMU_GR0_NS(smmu)  \
-   ((smmu)->base + \
-   ((smmu->options & ARM_SMMU_OPT_SECURE_CFG_ACCESS)   \
-   ? 0x400 : 0))
-
 #define MSI_IOVA_BASE  0x800
 #define MSI_IOVA_LENGTH0x10
 
@@ -246,6 +233,21 @@ struct arm_smmu_domain {
struct iommu_domain domain;
 };
 
+static int arm_smmu_gr0_ns(int offset)
+{
+   switch(offset) {
+   case ARM_SMMU_GR0_sCR0:
+   case ARM_SMMU_GR0_sACR:
+   case ARM_SMMU_GR0_sGFSR:
+   case ARM_SMMU_GR0_sGFSYNR0:
+   case ARM_SMMU_GR0_sGFSYNR1:
+   case ARM_SMMU_GR0_sGFSYNR2:
+   return offset + 0x400;
+   default:
+   return offset;
+   }
+}
+
 static void __iomem *arm_smmu_page(struct arm_smmu_device *smmu, int n)
 {
return smmu->base + (n << smmu->pgshift);
@@ -253,12 +255,18 @@ static void __iomem *arm_smmu_page(struct arm_smmu_device 
*smmu, int n)
 
 static u32 arm_smmu_readl(struct arm_smmu_device *smmu, int page, int offset)
 {
+   if ((smmu->options & ARM_SMMU_OPT_SECURE_CFG_ACCESS) && page == 0)
+   offset = arm_smmu_gr0_ns(offset);
+
return readl_relaxed(arm_smmu_page(smmu, page) + offset);
 }
 
 static void arm_smmu_writel(struct arm_smmu_device *smmu, int page, int offset,
u32 val)
 {
+   if ((smmu->options & ARM_SMMU_OPT_SECURE_CFG_ACCESS) && page == 0)
+   offset = arm_smmu_gr0_ns(offset);
+
writel_relaxed(val, arm_smmu_page(smmu, page) + offset);
 }
 
@@ -273,6 +281,9 @@ static void arm_smmu_writeq(struct arm_smmu_device *smmu, 
int page, int offset,
writeq_relaxed(val, arm_smmu_page(smmu, page) + offset);
 }
 
+#define arm_smmu_read_gr0(s, r)arm_smmu_readl((s), 0, (r))
+#define arm_smmu_write_gr0(s, r, v)arm_smmu_writel((s), 0, (r), (v))
+
 #define arm_smmu_read_gr1(s, r)arm_smmu_readl((s), 1, (r))
 #define arm_smmu_write_gr1(s, r, v)arm_smmu_writel((s), 1, (r), (v))
 
@@ -506,10 +517,10 @@ static void arm_smmu_tlb_inv_context_s2(void *cookie)
 {
struct arm_smmu_domain *smmu_domain = cookie;
struct arm_smmu_device *smmu = smmu_domain->smmu;
-   void __iomem *base = ARM_SMMU_GR0(smmu);
 
-   /* NOTE: see above */
-   writel(smmu_domain->cfg.vmid, base + ARM_SMMU_GR0_TLBIVMID);
+   /* See above */
+   wmb();
+   arm_smmu_write_gr0(smmu, ARM_SMMU_GR0_TLBIVMID, smmu_domain->cfg.vmid);
arm_smmu_tlb_sync_global(smmu);
 }
 
@@ -574,12 +585,12 @@ static void arm_smmu_tlb_inv_vmid_nosync(unsigned long 
iova, size_t size,
 size_t granule, bool leaf, void 
*cookie)
 {
struct arm_smmu_domain *smmu_domain = cookie;
-   void __iomem *base = ARM_SMMU_GR0(smmu_domain->smmu);
+   struct arm_smmu_device *smmu = smmu_domain->smmu;
 
-   if (smmu_domain->smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
+   if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
wmb();
 
-   writel_relaxed(smmu_domain->cfg.vmid, base + ARM_SMMU_GR0_TLBIVMID);
+   arm_smmu_write_gr0(smmu, ARM_SMMU_GR0_TLBIVMID, smmu_domain->cfg.vmid);
 }
 
 static const struct iommu_gather_ops arm_smmu_s1_tlb_ops = {
@@ -629,12 +640,11 @@ static irqreturn_t arm_smmu_global_fault(int irq, void 
*dev)
 {
u32 gfsr, gfsynr0, gfsynr1, gfsynr2;
struct arm_smmu_device *smmu = dev;
-   void __iomem *gr0_base = ARM_SMMU_GR0_NS(smmu);
 
-   gfsr = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSR);
-   gfsynr0 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSYNR0);
-   gfsynr1 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSYNR1);
-   gfsynr2 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSYNR2);
+   gfsr = arm_smmu_read_gr0(smmu, ARM_SMMU_GR0_sGFSR);
+ 

[PATCH 13/15] iommu/arm-smmu: Add configuration implementation hook

2019-08-09 Thread Robin Murphy
Probing the ID registers and setting up the SMMU configuration is an
area where overrides and workarounds may well be needed. Indeed, the
Cavium workaround detection lives there at the moment, so let's break
that out.

Signed-off-by: Robin Murphy 
---
 drivers/iommu/arm-smmu-impl.c | 24 
 drivers/iommu/arm-smmu.c  | 17 +++--
 drivers/iommu/arm-smmu.h  |  1 +
 3 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/drivers/iommu/arm-smmu-impl.c b/drivers/iommu/arm-smmu-impl.c
index f8b8895e1bbe..0b444e476525 100644
--- a/drivers/iommu/arm-smmu-impl.c
+++ b/drivers/iommu/arm-smmu-impl.c
@@ -47,11 +47,35 @@ const struct arm_smmu_impl calxeda_impl = {
 };
 
 
+static int cavium_cfg_probe(struct arm_smmu_device *smmu)
+{
+   static atomic_t context_count = ATOMIC_INIT(0);
+   /*
+* Cavium CN88xx erratum #27704.
+* Ensure ASID and VMID allocation is unique across all SMMUs in
+* the system.
+*/
+   smmu->cavium_id_base = atomic_fetch_add(smmu->num_context_banks,
+  &context_count);
+   dev_notice(smmu->dev, "\tenabling workaround for Cavium erratum 
27704\n");
+
+   return 0;
+}
+
+const struct arm_smmu_impl cavium_impl = {
+   .cfg_probe = cavium_cfg_probe,
+};
+
+
 struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
 {
+   /* The current quirks happen to be mutually-exclusive */
if (of_property_read_bool(smmu->dev->of_node,
  "calxeda,smmu-secure-config-access"))
smmu->impl = &calxeda_impl;
 
+   if (smmu->model == CAVIUM_SMMUV2)
+   smmu->impl = &cavium_impl;
+
return smmu;
 }
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 03159a1da4c9..80822d48f6c7 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -155,8 +155,6 @@ struct arm_smmu_domain {
struct iommu_domain domain;
 };
 
-static atomic_t cavium_smmu_context_count = ATOMIC_INIT(0);
-
 static bool using_legacy_binding, using_generic_binding;
 
 static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu)
@@ -1804,18 +1802,6 @@ static int arm_smmu_device_cfg_probe(struct 
arm_smmu_device *smmu)
}
dev_notice(smmu->dev, "\t%u context banks (%u stage-2 only)\n",
   smmu->num_context_banks, smmu->num_s2_context_banks);
-   /*
-* Cavium CN88xx erratum #27704.
-* Ensure ASID and VMID allocation is unique across all SMMUs in
-* the system.
-*/
-   if (smmu->model == CAVIUM_SMMUV2) {
-   smmu->cavium_id_base =
-   atomic_add_return(smmu->num_context_banks,
- &cavium_smmu_context_count);
-   smmu->cavium_id_base -= smmu->num_context_banks;
-   dev_notice(smmu->dev, "\tenabling workaround for Cavium erratum 
27704\n");
-   }
smmu->cbs = devm_kcalloc(smmu->dev, smmu->num_context_banks,
 sizeof(*smmu->cbs), GFP_KERNEL);
if (!smmu->cbs)
@@ -1884,6 +1870,9 @@ static int arm_smmu_device_cfg_probe(struct 
arm_smmu_device *smmu)
dev_notice(smmu->dev, "\tStage-2: %lu-bit IPA -> %lu-bit PA\n",
   smmu->ipa_size, smmu->pa_size);
 
+   if (smmu->impl && smmu->impl->cfg_probe)
+   return smmu->impl->cfg_probe(smmu);
+
return 0;
 }
 
diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
index 0485ee7fd4c1..e79cb32802e9 100644
--- a/drivers/iommu/arm-smmu.h
+++ b/drivers/iommu/arm-smmu.h
@@ -287,6 +287,7 @@ struct arm_smmu_impl {
u64 (*read_reg64)(struct arm_smmu_device *smmu, int page, int offset);
void (*write_reg64)(struct arm_smmu_device *smmu, int page, int offset,
u64 val);
+   int (*cfg_probe)(struct arm_smmu_device *smmu);
 };
 
 static inline void __iomem *arm_smmu_page(struct arm_smmu_device *smmu, int n)
-- 
2.21.0.dirty

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 11/15] iommu/arm-smmu: Add implementation infrastructure

2019-08-09 Thread Robin Murphy
Add some nascent infrastructure for handling implementation-specific
details outside the flow of the architectural code. This will allow us
to keep mutually-incompatible vendor-specific hooks in their own files
where the respective interested parties can maintain them with minimal
chance of conflicts. As somewhat of a template, we'll start with a
general place to collect the relatively trivial existing quirks.

Signed-off-by: Robin Murphy 
---
 MAINTAINERS   |  3 +-
 drivers/iommu/Makefile|  2 +-
 drivers/iommu/arm-smmu-impl.c | 13 +
 drivers/iommu/arm-smmu.c  | 82 ++--
 drivers/iommu/arm-smmu.h  | 89 +++
 5 files changed, 108 insertions(+), 81 deletions(-)
 create mode 100644 drivers/iommu/arm-smmu-impl.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 6426db5198f0..35ff49ac303b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1350,8 +1350,7 @@ M:Will Deacon 
 R: Robin Murphy 
 L: linux-arm-ker...@lists.infradead.org (moderated for non-subscribers)
 S: Maintained
-F: drivers/iommu/arm-smmu.c
-F: drivers/iommu/arm-smmu-v3.c
+F: drivers/iommu/arm-smmu*
 F: drivers/iommu/io-pgtable-arm.c
 F: drivers/iommu/io-pgtable-arm-v7s.c
 
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index f13f36ae1af6..a2729aadd300 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
 obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += amd_iommu_debugfs.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
-obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
+obj-$(CONFIG_ARM_SMMU) += arm-smmu.o arm-smmu-impl.o
 obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
 obj-$(CONFIG_DMAR_TABLE) += dmar.o
 obj-$(CONFIG_INTEL_IOMMU) += intel-iommu.o intel-pasid.o
diff --git a/drivers/iommu/arm-smmu-impl.c b/drivers/iommu/arm-smmu-impl.c
new file mode 100644
index ..efeb6d78da17
--- /dev/null
+++ b/drivers/iommu/arm-smmu-impl.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Miscellaneous Arm SMMU implementation and integration quirks
+// Copyright (C) 2019 Arm Limited
+
+#define pr_fmt(fmt) "arm-smmu: " fmt
+
+#include "arm-smmu.h"
+
+
+struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
+{
+   return smmu;
+}
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 09e2e71355d5..86e11141a0bb 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -19,7 +19,6 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -29,7 +28,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -41,7 +39,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include 
 #include 
@@ -66,9 +63,6 @@
 #define TLB_LOOP_TIMEOUT   100 /* 1s! */
 #define TLB_SPIN_COUNT 10
 
-/* Maximum number of context banks per SMMU */
-#define ARM_SMMU_MAX_CBS   128
-
 #define MSI_IOVA_BASE  0x800
 #define MSI_IOVA_LENGTH0x10
 
@@ -86,19 +80,6 @@ module_param(disable_bypass, bool, S_IRUGO);
 MODULE_PARM_DESC(disable_bypass,
"Disable bypass streams such that incoming transactions from devices 
that are not attached to an iommu domain will report an abort back to the 
device and will not be allowed to pass through the SMMU.");
 
-enum arm_smmu_arch_version {
-   ARM_SMMU_V1,
-   ARM_SMMU_V1_64K,
-   ARM_SMMU_V2,
-};
-
-enum arm_smmu_implementation {
-   GENERIC_SMMU,
-   ARM_MMU500,
-   CAVIUM_SMMUV2,
-   QCOM_SMMUV2,
-};
-
 struct arm_smmu_s2cr {
struct iommu_group  *group;
int count;
@@ -136,65 +117,6 @@ struct arm_smmu_master_cfg {
 #define for_each_cfg_sme(fw, i, idx) \
for (i = 0; idx = fwspec_smendx(fw, i), i < fw->num_ids; ++i)
 
-struct arm_smmu_device {
-   struct device   *dev;
-
-   void __iomem*base;
-   unsigned intcb_base;
-   unsigned intpgshift;
-
-#define ARM_SMMU_FEAT_COHERENT_WALK(1 << 0)
-#define ARM_SMMU_FEAT_STREAM_MATCH (1 << 1)
-#define ARM_SMMU_FEAT_TRANS_S1 (1 << 2)
-#define ARM_SMMU_FEAT_TRANS_S2 (1 << 3)
-#define ARM_SMMU_FEAT_TRANS_NESTED (1 << 4)
-#define ARM_SMMU_FEAT_TRANS_OPS(1 << 5)
-#define ARM_SMMU_FEAT_VMID16   (1 << 6)
-#define ARM_SMMU_FEAT_FMT_AARCH64_4K   (1 << 7)
-#define ARM_SMMU_FEAT_FMT_AARCH64_16K  (1 << 8)
-#define ARM_SMMU_FEAT_FMT_AARCH64_64K  (1 << 9)
-#define ARM_SMMU_FEAT_FMT_AARCH32_L(1 << 10)
-#define ARM_SMMU_FEAT_FMT_AARCH32_S(1 << 11)
-#define ARM_SMMU_FEAT_EXIDS(1 << 12)
-   u32 features;
-
-#define ARM_SMMU_OPT_SECURE_CFG_ACCESS (1 << 0)
-   u32 options;
-   enum

[PATCH 12/15] iommu/arm-smmu: Move Secure access quirk to implementation

2019-08-09 Thread Robin Murphy
Move detection of the Secure access quirk to its new home, trimming it
down in the process - time has proven that boolean DT flags are neither
ideal nor necessarily sufficient, so it's highly unlikely we'll ever add
more, let alone enough to justify the frankly overengineered parsing
machinery.

Signed-off-by: Robin Murphy 
---
 drivers/iommu/arm-smmu-impl.c | 44 +
 drivers/iommu/arm-smmu.c  | 89 ---
 drivers/iommu/arm-smmu.h  | 64 -
 3 files changed, 106 insertions(+), 91 deletions(-)

diff --git a/drivers/iommu/arm-smmu-impl.c b/drivers/iommu/arm-smmu-impl.c
index efeb6d78da17..f8b8895e1bbe 100644
--- a/drivers/iommu/arm-smmu-impl.c
+++ b/drivers/iommu/arm-smmu-impl.c
@@ -4,10 +4,54 @@
 
 #define pr_fmt(fmt) "arm-smmu: " fmt
 
+#include 
+
 #include "arm-smmu.h"
 
 
+static int arm_smmu_gr0_ns(int offset)
+{
+   switch(offset) {
+   case ARM_SMMU_GR0_sCR0:
+   case ARM_SMMU_GR0_sACR:
+   case ARM_SMMU_GR0_sGFSR:
+   case ARM_SMMU_GR0_sGFSYNR0:
+   case ARM_SMMU_GR0_sGFSYNR1:
+   case ARM_SMMU_GR0_sGFSYNR2:
+   return offset + 0x400;
+   default:
+   return offset;
+   }
+}
+
+static u32 arm_smmu_read_ns(struct arm_smmu_device *smmu, int page,
+   int offset)
+{
+   if (page == 0)
+   offset = arm_smmu_gr0_ns(offset);
+   return readl_relaxed(arm_smmu_page(smmu, page) + offset);
+}
+
+static void arm_smmu_write_ns(struct arm_smmu_device *smmu, int page,
+ int offset, u32 val)
+{
+   if (page == 0)
+   offset = arm_smmu_gr0_ns(offset);
+   writel_relaxed(val, arm_smmu_page(smmu, page) + offset);
+}
+
+/* Since we don't care for sGFAR, we can do without 64-bit accessors */
+const struct arm_smmu_impl calxeda_impl = {
+   .read_reg = arm_smmu_read_ns,
+   .write_reg = arm_smmu_write_ns,
+};
+
+
 struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
 {
+   if (of_property_read_bool(smmu->dev->of_node,
+ "calxeda,smmu-secure-config-access"))
+   smmu->impl = &calxeda_impl;
+
return smmu;
 }
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 86e11141a0bb..03159a1da4c9 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -155,83 +155,10 @@ struct arm_smmu_domain {
struct iommu_domain domain;
 };
 
-static int arm_smmu_gr0_ns(int offset)
-{
-   switch(offset) {
-   case ARM_SMMU_GR0_sCR0:
-   case ARM_SMMU_GR0_sACR:
-   case ARM_SMMU_GR0_sGFSR:
-   case ARM_SMMU_GR0_sGFSYNR0:
-   case ARM_SMMU_GR0_sGFSYNR1:
-   case ARM_SMMU_GR0_sGFSYNR2:
-   return offset + 0x400;
-   default:
-   return offset;
-   }
-}
-
-static void __iomem *arm_smmu_page(struct arm_smmu_device *smmu, int n)
-{
-   return smmu->base + (n << smmu->pgshift);
-}
-
-static u32 arm_smmu_readl(struct arm_smmu_device *smmu, int page, int offset)
-{
-   if ((smmu->options & ARM_SMMU_OPT_SECURE_CFG_ACCESS) && page == 0)
-   offset = arm_smmu_gr0_ns(offset);
-
-   return readl_relaxed(arm_smmu_page(smmu, page) + offset);
-}
-
-static void arm_smmu_writel(struct arm_smmu_device *smmu, int page, int offset,
-   u32 val)
-{
-   if ((smmu->options & ARM_SMMU_OPT_SECURE_CFG_ACCESS) && page == 0)
-   offset = arm_smmu_gr0_ns(offset);
-
-   writel_relaxed(val, arm_smmu_page(smmu, page) + offset);
-}
-
-static u64 arm_smmu_readq(struct arm_smmu_device *smmu, int page, int offset)
-{
-   return readq_relaxed(arm_smmu_page(smmu, page) + offset);
-}
-
-static void arm_smmu_writeq(struct arm_smmu_device *smmu, int page, int offset,
-   u64 val)
-{
-   writeq_relaxed(val, arm_smmu_page(smmu, page) + offset);
-}
-
-#define arm_smmu_read_gr0(s, r)arm_smmu_readl((s), 0, (r))
-#define arm_smmu_write_gr0(s, r, v)arm_smmu_writel((s), 0, (r), (v))
-
-#define arm_smmu_read_gr1(s, r)arm_smmu_readl((s), 1, (r))
-#define arm_smmu_write_gr1(s, r, v)arm_smmu_writel((s), 1, (r), (v))
-
-#define arm_smmu_read_cb(s, n, r)  \
-   arm_smmu_readl((s), (s)->cb_base + (n), (r))
-#define arm_smmu_write_cb(s, n, r, v)  \
-   arm_smmu_writel((s), (s)->cb_base + (n), (r), (v))
-#define arm_smmu_read_cb_q(s, n, r)\
-   arm_smmu_readq((s), (s)->cb_base + (n), (r))
-#define arm_smmu_write_cb_q(s, n, r, v)\
-   arm_smmu_writeq((s), (s)->cb_base + (n), (r), (v))
-
-struct arm_smmu_option_prop {
-   u32 opt;
-   const char *prop;
-};
-
 static atomic_t cavium_smmu_context_count = ATOMIC_INIT(0);
 
 static bool using_legacy_binding, using_generic_binding;
 
-static struct arm_smmu_option_prop arm_smm

[PATCH 10/15] iommu/arm-smmu: Rename arm-smmu-regs.h

2019-08-09 Thread Robin Murphy
We're about to start using it for more than just register definitions,
so generalise the name.

Signed-off-by: Robin Murphy 
---
 drivers/iommu/arm-smmu.c  | 2 +-
 drivers/iommu/{arm-smmu-regs.h => arm-smmu.h} | 6 +++---
 drivers/iommu/qcom_iommu.c| 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)
 rename drivers/iommu/{arm-smmu-regs.h => arm-smmu.h} (98%)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index d1ba5d115713..09e2e71355d5 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -46,7 +46,7 @@
 #include 
 #include 
 
-#include "arm-smmu-regs.h"
+#include "arm-smmu.h"
 
 /*
  * Apparently, some Qualcomm arm64 platforms which appear to expose their SMMU
diff --git a/drivers/iommu/arm-smmu-regs.h b/drivers/iommu/arm-smmu.h
similarity index 98%
rename from drivers/iommu/arm-smmu-regs.h
rename to drivers/iommu/arm-smmu.h
index 75056edad31d..3480f2621abe 100644
--- a/drivers/iommu/arm-smmu-regs.h
+++ b/drivers/iommu/arm-smmu.h
@@ -7,8 +7,8 @@
  * Author: Will Deacon 
  */
 
-#ifndef _ARM_SMMU_REGS_H
-#define _ARM_SMMU_REGS_H
+#ifndef _ARM_SMMU_H
+#define _ARM_SMMU_H
 
 #include 
 
@@ -194,4 +194,4 @@ enum arm_smmu_cbar_type {
 #define ARM_SMMU_CB_ATSR   0x8f0
 #define ATSR_ACTIVEBIT(0)
 
-#endif /* _ARM_SMMU_REGS_H */
+#endif /* _ARM_SMMU_H */
diff --git a/drivers/iommu/qcom_iommu.c b/drivers/iommu/qcom_iommu.c
index 746bf2a7df05..dadc707573a2 100644
--- a/drivers/iommu/qcom_iommu.c
+++ b/drivers/iommu/qcom_iommu.c
@@ -33,7 +33,7 @@
 #include 
 #include 
 
-#include "arm-smmu-regs.h"
+#include "arm-smmu.h"
 
 #define SMMU_INTR_SEL_NS 0x2000
 
-- 
2.21.0.dirty

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 08/15] iommu/arm-smmu: Abstract context bank accesses

2019-08-09 Thread Robin Murphy
Context bank accesses are fiddly enough to deserve a number of extra
helpers to keep the callsites looking sane, even though there are only
one or two of each.

Signed-off-by: Robin Murphy 
---
 drivers/iommu/arm-smmu.c | 137 ---
 1 file changed, 72 insertions(+), 65 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 72505647b77d..abdcc3f52e2e 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -82,9 +82,6 @@
((smmu->options & ARM_SMMU_OPT_SECURE_CFG_ACCESS)   \
? 0x400 : 0))
 
-/* Translation context bank */
-#define ARM_SMMU_CB(smmu, n)   ((smmu)->base + (((smmu)->cb_base + (n)) << 
(smmu)->pgshift))
-
 #define MSI_IOVA_BASE  0x800
 #define MSI_IOVA_LENGTH0x10
 
@@ -265,9 +262,29 @@ static void arm_smmu_writel(struct arm_smmu_device *smmu, 
int page, int offset,
writel_relaxed(val, arm_smmu_page(smmu, page) + offset);
 }
 
+static u64 arm_smmu_readq(struct arm_smmu_device *smmu, int page, int offset)
+{
+   return readq_relaxed(arm_smmu_page(smmu, page) + offset);
+}
+
+static void arm_smmu_writeq(struct arm_smmu_device *smmu, int page, int offset,
+   u64 val)
+{
+   writeq_relaxed(val, arm_smmu_page(smmu, page) + offset);
+}
+
 #define arm_smmu_read_gr1(s, r)arm_smmu_readl((s), 1, (r))
 #define arm_smmu_write_gr1(s, r, v)arm_smmu_writel((s), 1, (r), (v))
 
+#define arm_smmu_read_cb(s, n, r)  \
+   arm_smmu_readl((s), (s)->cb_base + (n), (r))
+#define arm_smmu_write_cb(s, n, r, v)  \
+   arm_smmu_writel((s), (s)->cb_base + (n), (r), (v))
+#define arm_smmu_read_cb_q(s, n, r)\
+   arm_smmu_readq((s), (s)->cb_base + (n), (r))
+#define arm_smmu_write_cb_q(s, n, r, v)\
+   arm_smmu_writeq((s), (s)->cb_base + (n), (r), (v))
+
 struct arm_smmu_option_prop {
u32 opt;
const char *prop;
@@ -423,15 +440,17 @@ static void __arm_smmu_free_bitmap(unsigned long *map, 
int idx)
 }
 
 /* Wait for any pending TLB invalidations to complete */
-static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu,
-   void __iomem *sync, void __iomem *status)
+static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu, int page,
+   int sync, int status)
 {
unsigned int spin_cnt, delay;
+   u32 reg;
 
-   writel_relaxed(QCOM_DUMMY_VAL, sync);
+   arm_smmu_writel(smmu, page, sync, QCOM_DUMMY_VAL);
for (delay = 1; delay < TLB_LOOP_TIMEOUT; delay *= 2) {
for (spin_cnt = TLB_SPIN_COUNT; spin_cnt > 0; spin_cnt--) {
-   if (!(readl_relaxed(status) & sTLBGSTATUS_GSACTIVE))
+   reg = arm_smmu_readl(smmu, page, status);
+   if (!(reg & sTLBGSTATUS_GSACTIVE))
return;
cpu_relax();
}
@@ -443,12 +462,11 @@ static void __arm_smmu_tlb_sync(struct arm_smmu_device 
*smmu,
 
 static void arm_smmu_tlb_sync_global(struct arm_smmu_device *smmu)
 {
-   void __iomem *base = ARM_SMMU_GR0(smmu);
unsigned long flags;
 
spin_lock_irqsave(&smmu->global_sync_lock, flags);
-   __arm_smmu_tlb_sync(smmu, base + ARM_SMMU_GR0_sTLBGSYNC,
-   base + ARM_SMMU_GR0_sTLBGSTATUS);
+   __arm_smmu_tlb_sync(smmu, 0, ARM_SMMU_GR0_sTLBGSYNC,
+   ARM_SMMU_GR0_sTLBGSTATUS);
spin_unlock_irqrestore(&smmu->global_sync_lock, flags);
 }
 
@@ -456,12 +474,11 @@ static void arm_smmu_tlb_sync_context(void *cookie)
 {
struct arm_smmu_domain *smmu_domain = cookie;
struct arm_smmu_device *smmu = smmu_domain->smmu;
-   void __iomem *base = ARM_SMMU_CB(smmu, smmu_domain->cfg.cbndx);
unsigned long flags;
 
spin_lock_irqsave(&smmu_domain->cb_lock, flags);
-   __arm_smmu_tlb_sync(smmu, base + ARM_SMMU_CB_TLBSYNC,
-   base + ARM_SMMU_CB_TLBSTATUS);
+   __arm_smmu_tlb_sync(smmu, smmu->cb_base + smmu_domain->cfg.cbndx,
+   ARM_SMMU_CB_TLBSYNC, ARM_SMMU_CB_TLBSTATUS);
spin_unlock_irqrestore(&smmu_domain->cb_lock, flags);
 }
 
@@ -475,14 +492,13 @@ static void arm_smmu_tlb_sync_vmid(void *cookie)
 static void arm_smmu_tlb_inv_context_s1(void *cookie)
 {
struct arm_smmu_domain *smmu_domain = cookie;
-   struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
-   void __iomem *base = ARM_SMMU_CB(smmu_domain->smmu, cfg->cbndx);
-
/*
-* NOTE: this is not a relaxed write; it needs to guarantee that PTEs
-* cleared by the current CPU are visible to the SMMU before the TLBI.
+* The TLBI write may be relaxed, so ensure that PTEs cleared by the
+* current CPU are visible bef

[PATCH 04/15] iommu/arm-smmu: Rework cb_base handling

2019-08-09 Thread Robin Murphy
To keep register-access quirks manageable, we want to structure things
to avoid needing too many individual overrides. It seems fairly clean to
have a single interface which handles both global and context registers
in terms of the architectural pages, so the first preparatory step is to
rework cb_base into a page number rather than an absolute address.

Signed-off-by: Robin Murphy 
---
 drivers/iommu/arm-smmu.c | 22 --
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index d9a93e5f422f..463bc8d98adb 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -95,7 +95,7 @@
 #endif
 
 /* Translation context bank */
-#define ARM_SMMU_CB(smmu, n)   ((smmu)->cb_base + ((n) << (smmu)->pgshift))
+#define ARM_SMMU_CB(smmu, n)   ((smmu)->base + (((smmu)->cb_base + (n)) << 
(smmu)->pgshift))
 
 #define MSI_IOVA_BASE  0x800
 #define MSI_IOVA_LENGTH0x10
@@ -168,8 +168,8 @@ struct arm_smmu_device {
struct device   *dev;
 
void __iomem*base;
-   void __iomem*cb_base;
-   unsigned long   pgshift;
+   unsigned intcb_base;
+   unsigned intpgshift;
 
 #define ARM_SMMU_FEAT_COHERENT_WALK(1 << 0)
 #define ARM_SMMU_FEAT_STREAM_MATCH (1 << 1)
@@ -1815,7 +1815,7 @@ static int arm_smmu_id_size_to_bits(int size)
 
 static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
 {
-   unsigned long size;
+   unsigned int size;
void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
u32 id;
bool cttw_reg, cttw_fw = smmu->features & ARM_SMMU_FEAT_COHERENT_WALK;
@@ -1899,7 +1899,7 @@ static int arm_smmu_device_cfg_probe(struct 
arm_smmu_device *smmu)
return -ENOMEM;
 
dev_notice(smmu->dev,
-  "\tstream matching with %lu register groups", size);
+  "\tstream matching with %u register groups", size);
}
/* s2cr->type == 0 means translation, so initialise explicitly */
smmu->s2crs = devm_kmalloc_array(smmu->dev, size, sizeof(*smmu->s2crs),
@@ -1925,11 +1925,12 @@ static int arm_smmu_device_cfg_probe(struct 
arm_smmu_device *smmu)
 
/* Check for size mismatch of SMMU address space from mapped region */
size = 1 << (FIELD_GET(ID1_NUMPAGENDXB, id) + 1);
-   size <<= smmu->pgshift;
-   if (smmu->cb_base != gr0_base + size)
+   if (smmu->cb_base != 2 * size << smmu->pgshift)
dev_warn(smmu->dev,
-   "SMMU address space size (0x%lx) differs from mapped 
region size (0x%tx)!\n",
-   size * 2, (smmu->cb_base - gr0_base) * 2);
+   "SMMU address space size (0x%x) differs from mapped 
region size (0x%x)!\n",
+   2 * size << smmu->pgshift, smmu->cb_base);
+   /* Now cb_base can reach its final form: a page number */
+   smmu->cb_base = size;
 
smmu->num_s2_context_banks = FIELD_GET(ID1_NUMS2CB, id);
smmu->num_context_banks = FIELD_GET(ID1_NUMCB, id);
@@ -2200,7 +2201,8 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
smmu->base = devm_ioremap_resource(dev, res);
if (IS_ERR(smmu->base))
return PTR_ERR(smmu->base);
-   smmu->cb_base = smmu->base + resource_size(res) / 2;
+   /* We'll finish calculating this later once we know the page size */
+   smmu->cb_base = resource_size(res);
 
num_irqs = 0;
while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, num_irqs))) {
-- 
2.21.0.dirty

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 05/15] iommu/arm-smmu: Split arm_smmu_tlb_inv_range_nosync()

2019-08-09 Thread Robin Murphy
Since we now use separate iommu_gather_ops for stage 1 and stage 2
contexts, we may as well divide up the monolithic callback into its
respective stage 1 and stage 2 parts.

Signed-off-by: Robin Murphy 
---
 drivers/iommu/arm-smmu.c | 66 ++--
 1 file changed, 37 insertions(+), 29 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 463bc8d98adb..a681e000e704 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -490,46 +490,54 @@ static void arm_smmu_tlb_inv_context_s2(void *cookie)
arm_smmu_tlb_sync_global(smmu);
 }
 
-static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
- size_t granule, bool leaf, void 
*cookie)
+static void arm_smmu_tlb_inv_range_s1(unsigned long iova, size_t size,
+ size_t granule, bool leaf, void *cookie)
 {
struct arm_smmu_domain *smmu_domain = cookie;
+   struct arm_smmu_device *smmu = smmu_domain->smmu;
struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
-   bool stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS;
-   void __iomem *reg = ARM_SMMU_CB(smmu_domain->smmu, cfg->cbndx);
+   void __iomem *reg = ARM_SMMU_CB(smmu, cfg->cbndx);
 
-   if (smmu_domain->smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
+   if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
wmb();
 
-   if (stage1) {
-   reg += leaf ? ARM_SMMU_CB_S1_TLBIVAL : ARM_SMMU_CB_S1_TLBIVA;
+   reg += leaf ? ARM_SMMU_CB_S1_TLBIVAL : ARM_SMMU_CB_S1_TLBIVA;
 
-   if (cfg->fmt != ARM_SMMU_CTX_FMT_AARCH64) {
-   iova &= ~12UL;
-   iova |= cfg->asid;
-   do {
-   writel_relaxed(iova, reg);
-   iova += granule;
-   } while (size -= granule);
-   } else {
-   iova >>= 12;
-   iova |= (u64)cfg->asid << 48;
-   do {
-   writeq_relaxed(iova, reg);
-   iova += granule >> 12;
-   } while (size -= granule);
-   }
-   } else {
-   reg += leaf ? ARM_SMMU_CB_S2_TLBIIPAS2L :
- ARM_SMMU_CB_S2_TLBIIPAS2;
-   iova >>= 12;
+   if (cfg->fmt != ARM_SMMU_CTX_FMT_AARCH64) {
+   iova &= ~12UL;
+   iova |= cfg->asid;
do {
-   smmu_write_atomic_lq(iova, reg);
+   writel_relaxed(iova, reg);
+   iova += granule;
+   } while (size -= granule);
+   } else {
+   iova >>= 12;
+   iova |= (u64)cfg->asid << 48;
+   do {
+   writeq_relaxed(iova, reg);
iova += granule >> 12;
} while (size -= granule);
}
 }
 
+static void arm_smmu_tlb_inv_range_s2(unsigned long iova, size_t size,
+ size_t granule, bool leaf, void *cookie)
+{
+   struct arm_smmu_domain *smmu_domain = cookie;
+   struct arm_smmu_device *smmu = smmu_domain->smmu;
+   void __iomem *reg = ARM_SMMU_CB(smmu, smmu_domain->cfg.cbndx);
+
+   if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
+   wmb();
+
+   reg += leaf ? ARM_SMMU_CB_S2_TLBIIPAS2L : ARM_SMMU_CB_S2_TLBIIPAS2;
+   iova >>= 12;
+   do {
+   smmu_write_atomic_lq(iova, reg);
+   iova += granule >> 12;
+   } while (size -= granule);
+}
+
 /*
  * On MMU-401 at least, the cost of firing off multiple TLBIVMIDs appears
  * almost negligible, but the benefit of getting the first one in as far ahead
@@ -550,13 +558,13 @@ static void arm_smmu_tlb_inv_vmid_nosync(unsigned long 
iova, size_t size,
 
 static const struct iommu_gather_ops arm_smmu_s1_tlb_ops = {
.tlb_flush_all  = arm_smmu_tlb_inv_context_s1,
-   .tlb_add_flush  = arm_smmu_tlb_inv_range_nosync,
+   .tlb_add_flush  = arm_smmu_tlb_inv_range_s1,
.tlb_sync   = arm_smmu_tlb_sync_context,
 };
 
 static const struct iommu_gather_ops arm_smmu_s2_tlb_ops_v2 = {
.tlb_flush_all  = arm_smmu_tlb_inv_context_s2,
-   .tlb_add_flush  = arm_smmu_tlb_inv_range_nosync,
+   .tlb_add_flush  = arm_smmu_tlb_inv_range_s2,
.tlb_sync   = arm_smmu_tlb_sync_context,
 };
 
-- 
2.21.0.dirty

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 06/15] iommu/arm-smmu: Get rid of weird "atomic" write

2019-08-09 Thread Robin Murphy
The smmu_write_atomic_lq oddity made some sense when the context
format was effectively tied to CONFIG_64BIT, but these days it's
simpler to just pick an explicit access size based on the format
for the one-and-a-half times we actually care.

Signed-off-by: Robin Murphy 
---
 drivers/iommu/arm-smmu.c | 23 +++
 1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index a681e000e704..544c992cf586 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -83,17 +83,6 @@
((smmu->options & ARM_SMMU_OPT_SECURE_CFG_ACCESS)   \
? 0x400 : 0))
 
-/*
- * Some 64-bit registers only make sense to write atomically, but in such
- * cases all the data relevant to AArch32 formats lies within the lower word,
- * therefore this actually makes more sense than it might first appear.
- */
-#ifdef CONFIG_64BIT
-#define smmu_write_atomic_lq   writeq_relaxed
-#else
-#define smmu_write_atomic_lq   writel_relaxed
-#endif
-
 /* Translation context bank */
 #define ARM_SMMU_CB(smmu, n)   ((smmu)->base + (((smmu)->cb_base + (n)) << 
(smmu)->pgshift))
 
@@ -533,7 +522,10 @@ static void arm_smmu_tlb_inv_range_s2(unsigned long iova, 
size_t size,
reg += leaf ? ARM_SMMU_CB_S2_TLBIIPAS2L : ARM_SMMU_CB_S2_TLBIIPAS2;
iova >>= 12;
do {
-   smmu_write_atomic_lq(iova, reg);
+   if (smmu_domain->cfg.fmt == ARM_SMMU_CTX_FMT_AARCH64)
+   writeq_relaxed(iova, reg);
+   else
+   writel_relaxed(iova, reg);
iova += granule >> 12;
} while (size -= granule);
 }
@@ -1371,11 +1363,10 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct 
iommu_domain *domain,
cb_base = ARM_SMMU_CB(smmu, cfg->cbndx);
 
spin_lock_irqsave(&smmu_domain->cb_lock, flags);
-   /* ATS1 registers can only be written atomically */
va = iova & ~0xfffUL;
-   if (smmu->version == ARM_SMMU_V2)
-   smmu_write_atomic_lq(va, cb_base + ARM_SMMU_CB_ATS1PR);
-   else /* Register is only 32-bit in v1 */
+   if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64)
+   writeq_relaxed(va, cb_base + ARM_SMMU_CB_ATS1PR);
+   else
writel_relaxed(va, cb_base + ARM_SMMU_CB_ATS1PR);
 
if (readl_poll_timeout_atomic(cb_base + ARM_SMMU_CB_ATSR, tmp,
-- 
2.21.0.dirty

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 07/15] iommu/arm-smmu: Abstract GR1 accesses

2019-08-09 Thread Robin Murphy
Introduce some register access abstractions which we will later use to
encapsulate various quirks. GR1 is the easiest page to start with.

Signed-off-by: Robin Murphy 
---
 drivers/iommu/arm-smmu.c | 30 +++---
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 544c992cf586..72505647b77d 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -71,7 +71,6 @@
 
 /* SMMU global address space */
 #define ARM_SMMU_GR0(smmu) ((smmu)->base)
-#define ARM_SMMU_GR1(smmu) ((smmu)->base + (1 << (smmu)->pgshift))
 
 /*
  * SMMU global address space with conditional offset to access secure
@@ -250,6 +249,25 @@ struct arm_smmu_domain {
struct iommu_domain domain;
 };
 
+static void __iomem *arm_smmu_page(struct arm_smmu_device *smmu, int n)
+{
+   return smmu->base + (n << smmu->pgshift);
+}
+
+static u32 arm_smmu_readl(struct arm_smmu_device *smmu, int page, int offset)
+{
+   return readl_relaxed(arm_smmu_page(smmu, page) + offset);
+}
+
+static void arm_smmu_writel(struct arm_smmu_device *smmu, int page, int offset,
+   u32 val)
+{
+   writel_relaxed(val, arm_smmu_page(smmu, page) + offset);
+}
+
+#define arm_smmu_read_gr1(s, r)arm_smmu_readl((s), 1, (r))
+#define arm_smmu_write_gr1(s, r, v)arm_smmu_writel((s), 1, (r), (v))
+
 struct arm_smmu_option_prop {
u32 opt;
const char *prop;
@@ -574,7 +592,6 @@ static irqreturn_t arm_smmu_context_fault(int irq, void 
*dev)
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
struct arm_smmu_device *smmu = smmu_domain->smmu;
-   void __iomem *gr1_base = ARM_SMMU_GR1(smmu);
void __iomem *cb_base;
 
cb_base = ARM_SMMU_CB(smmu, cfg->cbndx);
@@ -585,7 +602,7 @@ static irqreturn_t arm_smmu_context_fault(int irq, void 
*dev)
 
fsynr = readl_relaxed(cb_base + ARM_SMMU_CB_FSYNR0);
iova = readq_relaxed(cb_base + ARM_SMMU_CB_FAR);
-   cbfrsynra = readl_relaxed(gr1_base + 
ARM_SMMU_GR1_CBFRSYNRA(cfg->cbndx));
+   cbfrsynra = arm_smmu_read_gr1(smmu, ARM_SMMU_GR1_CBFRSYNRA(cfg->cbndx));
 
dev_err_ratelimited(smmu->dev,
"Unhandled context fault: fsr=0x%x, iova=0x%08lx, fsynr=0x%x, 
cbfrsynra=0x%x, cb=%d\n",
@@ -676,7 +693,7 @@ static void arm_smmu_write_context_bank(struct 
arm_smmu_device *smmu, int idx)
bool stage1;
struct arm_smmu_cb *cb = &smmu->cbs[idx];
struct arm_smmu_cfg *cfg = cb->cfg;
-   void __iomem *cb_base, *gr1_base;
+   void __iomem *cb_base;
 
cb_base = ARM_SMMU_CB(smmu, idx);
 
@@ -686,7 +703,6 @@ static void arm_smmu_write_context_bank(struct 
arm_smmu_device *smmu, int idx)
return;
}
 
-   gr1_base = ARM_SMMU_GR1(smmu);
stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS;
 
/* CBA2R */
@@ -699,7 +715,7 @@ static void arm_smmu_write_context_bank(struct 
arm_smmu_device *smmu, int idx)
if (smmu->features & ARM_SMMU_FEAT_VMID16)
reg |= FIELD_PREP(CBA2R_VMID16, cfg->vmid);
 
-   writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBA2R(idx));
+   arm_smmu_write_gr1(smmu, ARM_SMMU_GR1_CBA2R(idx), reg);
}
 
/* CBAR */
@@ -718,7 +734,7 @@ static void arm_smmu_write_context_bank(struct 
arm_smmu_device *smmu, int idx)
/* 8-bit VMIDs live in CBAR */
reg |= FIELD_PREP(CBAR_VMID, cfg->vmid);
}
-   writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(idx));
+   arm_smmu_write_gr1(smmu, ARM_SMMU_GR1_CBAR(idx), reg);
 
/*
 * TCR
-- 
2.21.0.dirty

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 01/15] iommu/arm-smmu: Convert GR0 registers to bitfields

2019-08-09 Thread Robin Murphy
FIELD_PREP remains a terrible name, but the overall simplification will
make further work on this stuff that much more manageable. This also
serves as an audit of the header, wherein we can impose a consistent
grouping and ordering of the offset and field definitions

Signed-off-by: Robin Murphy 
---
 drivers/iommu/arm-smmu-regs.h | 126 --
 drivers/iommu/arm-smmu.c  |  51 +++---
 2 files changed, 84 insertions(+), 93 deletions(-)

diff --git a/drivers/iommu/arm-smmu-regs.h b/drivers/iommu/arm-smmu-regs.h
index 1c278f7ae888..d189f025537a 100644
--- a/drivers/iommu/arm-smmu-regs.h
+++ b/drivers/iommu/arm-smmu-regs.h
@@ -10,111 +10,101 @@
 #ifndef _ARM_SMMU_REGS_H
 #define _ARM_SMMU_REGS_H
 
+#include 
+
 /* Configuration registers */
 #define ARM_SMMU_GR0_sCR0  0x0
-#define sCR0_CLIENTPD  (1 << 0)
-#define sCR0_GFRE  (1 << 1)
-#define sCR0_GFIE  (1 << 2)
-#define sCR0_EXIDENABLE(1 << 3)
-#define sCR0_GCFGFRE   (1 << 4)
-#define sCR0_GCFGFIE   (1 << 5)
-#define sCR0_USFCFG(1 << 10)
-#define sCR0_VMIDPNE   (1 << 11)
-#define sCR0_PTM   (1 << 12)
-#define sCR0_FB(1 << 13)
-#define sCR0_VMID16EN  (1 << 31)
-#define sCR0_BSU_SHIFT 14
-#define sCR0_BSU_MASK  0x3
+#define sCR0_VMID16EN  BIT(31)
+#define sCR0_BSU   GENMASK(15, 14)
+#define sCR0_FBBIT(13)
+#define sCR0_PTM   BIT(12)
+#define sCR0_VMIDPNE   BIT(11)
+#define sCR0_USFCFGBIT(10)
+#define sCR0_GCFGFIE   BIT(5)
+#define sCR0_GCFGFRE   BIT(4)
+#define sCR0_EXIDENABLEBIT(3)
+#define sCR0_GFIE  BIT(2)
+#define sCR0_GFRE  BIT(1)
+#define sCR0_CLIENTPD  BIT(0)
 
 /* Auxiliary Configuration register */
 #define ARM_SMMU_GR0_sACR  0x10
 
 /* Identification registers */
 #define ARM_SMMU_GR0_ID0   0x20
+#define ID0_S1TS   BIT(30)
+#define ID0_S2TS   BIT(29)
+#define ID0_NTSBIT(28)
+#define ID0_SMSBIT(27)
+#define ID0_ATOSNS BIT(26)
+#define ID0_PTFS_NO_AARCH32BIT(25)
+#define ID0_PTFS_NO_AARCH32S   BIT(24)
+#define ID0_CTTW   BIT(14)
+#define ID0_NUMIRPTGENMASK(23, 16)
+#define ID0_NUMSIDBGENMASK(12, 9)
+#define ID0_EXIDS  BIT(8)
+#define ID0_NUMSMRGGENMASK(7, 0)
+
 #define ARM_SMMU_GR0_ID1   0x24
+#define ID1_PAGESIZE   BIT(31)
+#define ID1_NUMPAGENDXBGENMASK(30, 28)
+#define ID1_NUMS2CBGENMASK(23, 16)
+#define ID1_NUMCB  GENMASK(7, 0)
+
 #define ARM_SMMU_GR0_ID2   0x28
+#define ID2_VMID16 BIT(15)
+#define ID2_PTFS_64K   BIT(14)
+#define ID2_PTFS_16K   BIT(13)
+#define ID2_PTFS_4KBIT(12)
+#define ID2_UBSGENMASK(11, 8)
+#define ID2_OASGENMASK(7, 4)
+#define ID2_IASGENMASK(3, 0)
+
 #define ARM_SMMU_GR0_ID3   0x2c
 #define ARM_SMMU_GR0_ID4   0x30
 #define ARM_SMMU_GR0_ID5   0x34
 #define ARM_SMMU_GR0_ID6   0x38
+
 #define ARM_SMMU_GR0_ID7   0x3c
+#define ID7_MAJOR  GENMASK(7, 4)
+#define ID7_MINOR  GENMASK(3, 0)
+
 #define ARM_SMMU_GR0_sGFSR 0x48
 #define ARM_SMMU_GR0_sGFSYNR0  0x50
 #define ARM_SMMU_GR0_sGFSYNR1  0x54
 #define ARM_SMMU_GR0_sGFSYNR2  0x58
 
-#define ID0_S1TS   (1 << 30)
-#define ID0_S2TS   (1 << 29)
-#define ID0_NTS(1 << 28)
-#define ID0_SMS(1 << 27)
-#define ID0_ATOSNS (1 << 26)
-#define ID0_PTFS_NO_AARCH32(1 << 25)
-#define ID0_PTFS_NO_AARCH32S   (1 << 24)
-#define ID0_CTTW   (1 << 14)
-#define ID0_NUMIRPT_SHIFT  16
-#define ID0_NUMIRPT_MASK   0xff
-#define ID0_NUMSIDB_SHIFT  9
-#define ID0_NUMSIDB_MASK   0xf
-#define ID0_EXIDS  (1 << 8)
-#define ID0_NUMSMRG_SHIFT  0
-#define ID0_NUMSMRG_MASK   0xff
-
-#define ID1_PAGESIZE   (1 << 31)
-#define ID1_NUMPAGENDXB_SHIFT  28
-#define ID1_NUMPAGENDXB_MASK   7
-#define ID1_NUMS2CB_SHIFT  16
-#define ID1_NUMS2CB_MASK   

[PATCH 02/15] iommu/arm-smmu: Convert GR1 registers to bitfields

2019-08-09 Thread Robin Murphy
As for GR0, use the bitfield helpers to make GR1 usage a little cleaner,
and use it as an opportunity to audit and tidy the definitions. This
tweaks the handling of CBAR types to match what we did for S2CR a while
back, and fixes a couple of names which didn't quite match the latest
architecture spec (IHI0062D.c).

Signed-off-by: Robin Murphy 
---
 drivers/iommu/arm-smmu-regs.h | 33 ++---
 drivers/iommu/arm-smmu.c  | 18 +-
 2 files changed, 23 insertions(+), 28 deletions(-)

diff --git a/drivers/iommu/arm-smmu-regs.h b/drivers/iommu/arm-smmu-regs.h
index d189f025537a..671c2d98c9da 100644
--- a/drivers/iommu/arm-smmu-regs.h
+++ b/drivers/iommu/arm-smmu-regs.h
@@ -108,30 +108,25 @@ enum arm_smmu_s2cr_type {
 
 /* Context bank attribute registers */
 #define ARM_SMMU_GR1_CBAR(n)   (0x0 + ((n) << 2))
-#define CBAR_VMID_SHIFT0
-#define CBAR_VMID_MASK 0xff
-#define CBAR_S1_BPSHCFG_SHIFT  8
-#define CBAR_S1_BPSHCFG_MASK   3
-#define CBAR_S1_BPSHCFG_NSH3
-#define CBAR_S1_MEMATTR_SHIFT  12
-#define CBAR_S1_MEMATTR_MASK   0xf
+#define CBAR_IRPTNDX   GENMASK(31, 24)
+#define CBAR_TYPE  GENMASK(17, 16)
+enum arm_smmu_cbar_type {
+   CBAR_TYPE_S2_TRANS,
+   CBAR_TYPE_S1_TRANS_S2_BYPASS,
+   CBAR_TYPE_S1_TRANS_S2_FAULT,
+   CBAR_TYPE_S1_TRANS_S2_TRANS,
+};
+#define CBAR_S1_MEMATTRGENMASK(15, 12)
 #define CBAR_S1_MEMATTR_WB 0xf
-#define CBAR_TYPE_SHIFT16
-#define CBAR_TYPE_MASK 0x3
-#define CBAR_TYPE_S2_TRANS (0 << CBAR_TYPE_SHIFT)
-#define CBAR_TYPE_S1_TRANS_S2_BYPASS   (1 << CBAR_TYPE_SHIFT)
-#define CBAR_TYPE_S1_TRANS_S2_FAULT(2 << CBAR_TYPE_SHIFT)
-#define CBAR_TYPE_S1_TRANS_S2_TRANS(3 << CBAR_TYPE_SHIFT)
-#define CBAR_IRPTNDX_SHIFT 24
-#define CBAR_IRPTNDX_MASK  0xff
+#define CBAR_S1_BPSHCFGGENMASK(9, 8)
+#define CBAR_S1_BPSHCFG_NSH3
+#define CBAR_VMID  GENMASK(7, 0)
 
 #define ARM_SMMU_GR1_CBFRSYNRA(n)  (0x400 + ((n) << 2))
 
 #define ARM_SMMU_GR1_CBA2R(n)  (0x800 + ((n) << 2))
-#define CBA2R_RW64_32BIT   (0 << 0)
-#define CBA2R_RW64_64BIT   (1 << 0)
-#define CBA2R_VMID_SHIFT   16
-#define CBA2R_VMID_MASK0x
+#define CBA2R_VMID16   GENMASK(31, 16)
+#define CBA2R_VA64 BIT(0)
 
 #define ARM_SMMU_CB_SCTLR  0x0
 #define ARM_SMMU_CB_ACTLR  0x4
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 89eddc54e41c..515fb1ce39ed 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -237,7 +237,7 @@ struct arm_smmu_cfg {
u16 asid;
u16 vmid;
};
-   u32 cbar;
+   enum arm_smmu_cbar_type cbar;
enum arm_smmu_context_fmt   fmt;
 };
 #define INVALID_IRPTNDX0xff
@@ -692,31 +692,31 @@ static void arm_smmu_write_context_bank(struct 
arm_smmu_device *smmu, int idx)
/* CBA2R */
if (smmu->version > ARM_SMMU_V1) {
if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64)
-   reg = CBA2R_RW64_64BIT;
+   reg = CBA2R_VA64;
else
-   reg = CBA2R_RW64_32BIT;
+   reg = 0;
/* 16-bit VMIDs live in CBA2R */
if (smmu->features & ARM_SMMU_FEAT_VMID16)
-   reg |= cfg->vmid << CBA2R_VMID_SHIFT;
+   reg |= FIELD_PREP(CBA2R_VMID16, cfg->vmid);
 
writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBA2R(idx));
}
 
/* CBAR */
-   reg = cfg->cbar;
+   reg = FIELD_PREP(CBAR_TYPE, cfg->cbar);
if (smmu->version < ARM_SMMU_V2)
-   reg |= cfg->irptndx << CBAR_IRPTNDX_SHIFT;
+   reg |= FIELD_PREP(CBAR_IRPTNDX, cfg->irptndx);
 
/*
 * Use the weakest shareability/memory types, so they are
 * overridden by the ttbcr/pte.
 */
if (stage1) {
-   reg |= (CBAR_S1_BPSHCFG_NSH << CBAR_S1_BPSHCFG_SHIFT) |
-   (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT);
+   reg |= FIELD_PREP(CBAR_S1_BPSHCFG, CBAR_S1_BPSHCFG_NSH) |
+   FIELD_PREP(CBAR_S1_MEMATTR, CBAR_S1_MEMATTR_WB);
} else if (!(smmu->features & ARM_SMMU_FEAT_VMID16)) {
/* 8-bit VMIDs live in CBAR */
-   reg |= cfg->vmid << CBAR_VMID_SHIFT;
+   reg |= FIELD_PREP(CBAR_VMID, cfg->vmid);
}
writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(idx));
 
-- 
2.21.0.dirty

___
iommu mailing list
iom

[PATCH 00/15] Arm SMMU refactoring

2019-08-09 Thread Robin Murphy
Hi all,

This is a big refactoring of arm-smmu in order to help cope with the
various divergent implementation details currently flying around. So
far we've been accruing various quirks and errata workarounds within
the main flow of the driver, but given that it's written to an
architecture rather than any particular hardware implementation, after
a point these start to become increasingly invasive and potentially
conflict with each other.

These patches clean up the existing quirks handled by the driver to
lay a foundation on which we can continue to add more in a maintainable
fashion. The idea is that major vendor customisations can then be kept
in arm-smmu-.c implementation files out of each others' way.

A branch is available at:

  git://linux-arm.org/linux-rm  iommu/smmu-impl

which I'll probably keep tweaking until I'm happy with the names of
things; I just didn't want to delay this initial posting any lomnger.

Robin.


Robin Murphy (15):
  iommu/arm-smmu: Convert GR0 registers to bitfields
  iommu/arm-smmu: Convert GR1 registers to bitfields
  iommu/arm-smmu: Convert context bank registers to bitfields
  iommu/arm-smmu: Rework cb_base handling
  iommu/arm-smmu: Split arm_smmu_tlb_inv_range_nosync()
  iommu/arm-smmu: Get rid of weird "atomic" write
  iommu/arm-smmu: Abstract GR1 accesses
  iommu/arm-smmu: Abstract context bank accesses
  iommu/arm-smmu: Abstract GR0 accesses
  iommu/arm-smmu: Rename arm-smmu-regs.h
  iommu/arm-smmu: Add implementation infrastructure
  iommu/arm-smmu: Move Secure access quirk to implementation
  iommu/arm-smmu: Add configuration implementation hook
  iommu/arm-smmu: Add reset implementation hook
  iommu/arm-smmu: Add context init implementation hook

 MAINTAINERS   |   3 +-
 drivers/iommu/Makefile|   2 +-
 drivers/iommu/arm-smmu-impl.c | 165 ++
 drivers/iommu/arm-smmu-regs.h | 210 -
 drivers/iommu/arm-smmu.c  | 570 +++---
 drivers/iommu/arm-smmu.h  | 386 +++
 drivers/iommu/qcom_iommu.c|  15 +-
 7 files changed, 743 insertions(+), 608 deletions(-)
 create mode 100644 drivers/iommu/arm-smmu-impl.c
 delete mode 100644 drivers/iommu/arm-smmu-regs.h
 create mode 100644 drivers/iommu/arm-smmu.h

-- 
2.21.0.dirty

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 03/15] iommu/arm-smmu: Convert context bank registers to bitfields

2019-08-09 Thread Robin Murphy
Finish the final part of the job, once again updating some names to
match the current spec.

Signed-off-by: Robin Murphy 
---
 drivers/iommu/arm-smmu-regs.h | 86 ++-
 drivers/iommu/arm-smmu.c  | 16 +++
 drivers/iommu/qcom_iommu.c| 13 +++---
 3 files changed, 59 insertions(+), 56 deletions(-)

diff --git a/drivers/iommu/arm-smmu-regs.h b/drivers/iommu/arm-smmu-regs.h
index 671c2d98c9da..75056edad31d 100644
--- a/drivers/iommu/arm-smmu-regs.h
+++ b/drivers/iommu/arm-smmu-regs.h
@@ -129,19 +129,59 @@ enum arm_smmu_cbar_type {
 #define CBA2R_VA64 BIT(0)
 
 #define ARM_SMMU_CB_SCTLR  0x0
+#define SCTLR_S1_ASIDPNE   BIT(12)
+#define SCTLR_CFCFGBIT(7)
+#define SCTLR_CFIE BIT(6)
+#define SCTLR_CFRE BIT(5)
+#define SCTLR_EBIT(4)
+#define SCTLR_AFE  BIT(2)
+#define SCTLR_TRE  BIT(1)
+#define SCTLR_MBIT(0)
+
 #define ARM_SMMU_CB_ACTLR  0x4
+
 #define ARM_SMMU_CB_RESUME 0x8
-#define ARM_SMMU_CB_TTBCR2 0x10
+#define RESUME_TERMINATE   BIT(0)
+
+#define ARM_SMMU_CB_TCR2   0x10
+#define TCR2_SEP   GENMASK(17, 15)
+#define TCR2_SEP_UPSTREAM  0x7
+#define TCR2_ASBIT(4)
+
 #define ARM_SMMU_CB_TTBR0  0x20
 #define ARM_SMMU_CB_TTBR1  0x28
-#define ARM_SMMU_CB_TTBCR  0x30
+#define TTBRn_ASID GENMASK_ULL(63, 48)
+
+#define ARM_SMMU_CB_TCR0x30
 #define ARM_SMMU_CB_CONTEXTIDR 0x34
 #define ARM_SMMU_CB_S1_MAIR0   0x38
 #define ARM_SMMU_CB_S1_MAIR1   0x3c
+
 #define ARM_SMMU_CB_PAR0x50
+#define CB_PAR_F   BIT(0)
+
 #define ARM_SMMU_CB_FSR0x58
+#define FSR_MULTI  BIT(31)
+#define FSR_SS BIT(30)
+#define FSR_UUTBIT(8)
+#define FSR_ASFBIT(7)
+#define FSR_TLBLKF BIT(6)
+#define FSR_TLBMCF BIT(5)
+#define FSR_EF BIT(4)
+#define FSR_PF BIT(3)
+#define FSR_AFFBIT(2)
+#define FSR_TF BIT(1)
+
+#define FSR_IGN(FSR_AFF | FSR_ASF | \
+FSR_TLBMCF | FSR_TLBLKF)
+#define FSR_FAULT  (FSR_MULTI | FSR_SS | FSR_UUT | \
+FSR_EF | FSR_PF | FSR_TF | FSR_IGN)
+
 #define ARM_SMMU_CB_FAR0x60
+
 #define ARM_SMMU_CB_FSYNR0 0x68
+#define FSYNR0_WNR BIT(4)
+
 #define ARM_SMMU_CB_S1_TLBIVA  0x600
 #define ARM_SMMU_CB_S1_TLBIASID0x610
 #define ARM_SMMU_CB_S1_TLBIVAL 0x620
@@ -150,46 +190,8 @@ enum arm_smmu_cbar_type {
 #define ARM_SMMU_CB_TLBSYNC0x7f0
 #define ARM_SMMU_CB_TLBSTATUS  0x7f4
 #define ARM_SMMU_CB_ATS1PR 0x800
+
 #define ARM_SMMU_CB_ATSR   0x8f0
-
-#define SCTLR_S1_ASIDPNE   (1 << 12)
-#define SCTLR_CFCFG(1 << 7)
-#define SCTLR_CFIE (1 << 6)
-#define SCTLR_CFRE (1 << 5)
-#define SCTLR_E(1 << 4)
-#define SCTLR_AFE  (1 << 2)
-#define SCTLR_TRE  (1 << 1)
-#define SCTLR_M(1 << 0)
-
-#define CB_PAR_F   (1 << 0)
-
-#define ATSR_ACTIVE(1 << 0)
-
-#define RESUME_RETRY   (0 << 0)
-#define RESUME_TERMINATE   (1 << 0)
-
-#define TTBCR2_SEP_SHIFT   15
-#define TTBCR2_SEP_UPSTREAM(0x7 << TTBCR2_SEP_SHIFT)
-#define TTBCR2_AS  (1 << 4)
-
-#define TTBRn_ASID_SHIFT   48
-
-#define FSR_MULTI  (1 << 31)
-#define FSR_SS (1 << 30)
-#define FSR_UUT(1 << 8)
-#define FSR_ASF(1 << 7)
-#define FSR_TLBLKF (1 << 6)
-#define FSR_TLBMCF (1 << 5)
-#define FSR_EF (1 << 4)
-#define FSR_PF (1 << 3)
-#define FSR_AFF(1 << 2)
-#define FSR_TF (1 << 1)
-
-#define FSR_IGN(FSR_AFF | FSR_ASF | \
-FSR_TLBMCF | FSR_TLBLKF)
-#define FSR_FAULT  (FSR_MULTI | FSR_SS | FSR_UUT | \
-FSR_EF | FSR_PF | FSR_TF | FSR_IGN)
-
-#define FSYNR0_WNR (1 << 4)
+#define ATSR_ACT

Re: [PATCH 3/3] iommu: Disable passthrough mode when SME is active

2019-08-09 Thread Lendacky, Thomas
On 8/9/19 10:22 AM, Joerg Roedel wrote:
> From: Joerg Roedel 
> 
> Using Passthrough mode when SME is active causes certain
> devices to use the SWIOTLB bounce buffer. The bounce buffer
> code has an upper limit of 256kb for the size of DMA
> allocations, which is too small for certain devices and
> causes them to fail.
> 
> With this patch we enable IOMMU by default when SME is
> active in the system, making the default configuration work
> for more systems than it does now.
> 
> Users that don't want IOMMUs to be enabled still can disable
> them with kernel parameters.
> 
> Signed-off-by: Joerg Roedel 
> ---
>   drivers/iommu/iommu.c | 6 ++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 62cae6db0970..fbe1aa51bce9 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -104,6 +104,12 @@ static int __init iommu_subsys_init(void)
>   else
>   iommu_def_domain_type = IOMMU_DOMAIN_DMA;
>   
> + if ((iommu_def_domain_type == IOMMU_DOMAIN_IDENTITY) &&
> + sme_active()) {
> + pr_info("SME detected - Disabling default IOMMU passthrough\n");
> + iommu_def_domain_type = IOMMU_DOMAIN_DMA;

Should this also clear the iommu_pass_through variable (the one set by the
iommu kernel parameter in arch/x86/kernel/pci-dma.c)?

I guess this is more applicable to the original patchset that created the
CONFIG_IOMMU_DEFAULT_PASSTHROUGH option, but should the default
passthrough support be modified so that you don't have to specify multiple
kernel parameters to change it?

Right now, if CONFIG_IOMMU_DEFAULT_PASSTHROUGH is set to yes, you can't
just specify iommu=nopt to enable the IOMMU. You have to also specify
iommu.passthrough=0. Do we want to fix that so that just specifying
iommu=nopt or iommu.passthrough=0 does what is needed?

Thanks,
Tom

> + }
> +
>   pr_info("Default domain type: %s\n",
>   iommu_domain_type_str(iommu_def_domain_type));
>   
> 


Re: [PATCH] iommu/omap: Fix compilation warnings suspend/resume control

2019-08-09 Thread Suman Anna via iommu
On 8/9/19 11:13 AM, Joerg Roedel wrote:
> On Wed, Aug 07, 2019 at 11:26:50AM +0300, Tero Kristo wrote:
>> +static inline int omap_iommu_domain_deactivate(struct iommu_domain *domain) 
>> {}
>> +static inline int omap_iommu_domain_activate(struct iommu_domain *domain) {}
> 
> This caused compilation warnings, I queued the fix below.
> 
> From 70c8a42adf482fba35e9e39ccd441a5ff8ffb657 Mon Sep 17 00:00:00 2001
> From: Joerg Roedel 
> Date: Fri, 9 Aug 2019 18:09:13 +0200
> Subject: [PATCH] iommu/omap: Fix compilation warnings
> 
> A recent patches introduced a new compiler warning because
> two functions with non-void return type have no return
> statement in omap-iommu.h for CONFIG_OMAP_IOMMU=n.
> 
> Fix this by adding return statements to these functions.

Thanks Joerg, looks like Tero missed them when he forward-ported the
patches.

regards
Suman

> 
> Fixes: d9c4d8a6cc0f8 ('iommu/omap: introduce new API for runtime 
> suspend/resume control')
> Signed-off-by: Joerg Roedel 
> ---
>  include/linux/omap-iommu.h | 11 +--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/omap-iommu.h b/include/linux/omap-iommu.h
> index 36b645726813..2c32ca09df02 100644
> --- a/include/linux/omap-iommu.h
> +++ b/include/linux/omap-iommu.h
> @@ -22,8 +22,15 @@ int omap_iommu_domain_activate(struct iommu_domain 
> *domain);
>  static inline void omap_iommu_save_ctx(struct device *dev) {}
>  static inline void omap_iommu_restore_ctx(struct device *dev) {}
>  
> -static inline int omap_iommu_domain_deactivate(struct iommu_domain *domain) 
> {}
> -static inline int omap_iommu_domain_activate(struct iommu_domain *domain) {}
> +static inline int omap_iommu_domain_deactivate(struct iommu_domain *domain)
> +{
> + return -ENODEV;
> +}
> +
> +static inline int omap_iommu_domain_activate(struct iommu_domain *domain)
> +{
> + return -ENODEV;
> +}
>  #endif
>  
>  #endif
> 

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH] iommu/omap: Fix compilation warnings suspend/resume control

2019-08-09 Thread Joerg Roedel
On Wed, Aug 07, 2019 at 11:26:50AM +0300, Tero Kristo wrote:
> +static inline int omap_iommu_domain_deactivate(struct iommu_domain *domain) 
> {}
> +static inline int omap_iommu_domain_activate(struct iommu_domain *domain) {}

This caused compilation warnings, I queued the fix below.

>From 70c8a42adf482fba35e9e39ccd441a5ff8ffb657 Mon Sep 17 00:00:00 2001
From: Joerg Roedel 
Date: Fri, 9 Aug 2019 18:09:13 +0200
Subject: [PATCH] iommu/omap: Fix compilation warnings

A recent patches introduced a new compiler warning because
two functions with non-void return type have no return
statement in omap-iommu.h for CONFIG_OMAP_IOMMU=n.

Fix this by adding return statements to these functions.

Fixes: d9c4d8a6cc0f8 ('iommu/omap: introduce new API for runtime suspend/resume 
control')
Signed-off-by: Joerg Roedel 
---
 include/linux/omap-iommu.h | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/include/linux/omap-iommu.h b/include/linux/omap-iommu.h
index 36b645726813..2c32ca09df02 100644
--- a/include/linux/omap-iommu.h
+++ b/include/linux/omap-iommu.h
@@ -22,8 +22,15 @@ int omap_iommu_domain_activate(struct iommu_domain *domain);
 static inline void omap_iommu_save_ctx(struct device *dev) {}
 static inline void omap_iommu_restore_ctx(struct device *dev) {}
 
-static inline int omap_iommu_domain_deactivate(struct iommu_domain *domain) {}
-static inline int omap_iommu_domain_activate(struct iommu_domain *domain) {}
+static inline int omap_iommu_domain_deactivate(struct iommu_domain *domain)
+{
+   return -ENODEV;
+}
+
+static inline int omap_iommu_domain_activate(struct iommu_domain *domain)
+{
+   return -ENODEV;
+}
 #endif
 
 #endif
-- 
2.16.4

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v4 0/6] Remove x86-specific code from generic headers

2019-08-09 Thread Thiago Jung Bauermann


m...@ellerman.id.au writes:

> Thiago Jung Bauermann  writes:
>> Hello,
>>
>> This version has only a small change in the last patch as requested by
>> Christoph and Halil, and collects Reviewed-by's.
>>
>> These patches are applied on top of v5.3-rc2.
>>
>> I don't have a way to test SME, SEV, nor s390's PEF so the patches have only
>> been build tested.
>
> I need to take this series via the powerpc tree because there is another
> fairly large powerpc specific series dependent on it.
>
> I think this series already has pretty much all the acks it needs, which
> almost never happens, amazing work!

Yes, thank you very much to everyone who reviewed the patches!

> I'll put the series in a topic branch, just in case there's any bad
> conflicts and other folks want to merge it later on. I'll then merge the
> topic branch into my next, and so this series will be tested in
> linux-next that way.

That's awesome. Thank you very much!

-- 
Thiago Jung Bauermann
IBM Linux Technology Center
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] iommu/amd: Override wrong IVRS IOAPIC on Raven Ridge systems

2019-08-09 Thread Joerg Roedel
On Thu, Aug 08, 2019 at 06:17:07PM +0800, Kai-Heng Feng wrote:
> Raven Ridge systems may have malfunction touchpad or hang at boot if
> incorrect IVRS IOAPIC is provided by BIOS.
> 
> Users already found correct "ivrs_ioapic=" values, let's put them inside
> kernel to workaround buggy BIOS.

Will that still work when a fixed BIOS for these laptops is released?


Joerg


Re: [PATCH 0/8] iommu/omap: misc fixes

2019-08-09 Thread Joerg Roedel
On Wed, Aug 07, 2019 at 11:26:44AM +0300, Tero Kristo wrote:
> Here are a few fixes for OMAP IOMMU. These are mostly towards getting
> runtime PM support functional again for the IOMMU.

Applied all, thanks.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/2] iommu/vt-d: Detach domain before using a private one

2019-08-09 Thread Joerg Roedel
On Tue, Aug 06, 2019 at 08:14:08AM +0800, Lu Baolu wrote:
>  drivers/iommu/intel-iommu.c | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)

Applied to iommu/fixes, thanks.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v6 22/57] iommu: Remove dev_err() usage after platform_get_irq()

2019-08-09 Thread Joerg Roedel
On Tue, Jul 30, 2019 at 11:15:22AM -0700, Stephen Boyd wrote:
> Please apply directly to subsystem trees

Applied, thanks.


Re: [PATCH] iommu/dma: Handle SG length overflow better

2019-08-09 Thread Joerg Roedel
On Tue, Aug 06, 2019 at 06:11:51PM -0700, Nicolin Chen wrote:
> Well..it was triggered in our downstream test that's supposed to
> cover large size (> 4G) corner case, so I don't feel it's "easy"
> but our test case was running with 4.14 kernel so I also feel it
> might be a good idea to Cc stable kernel even if we postpone the
> patch during the merge window. I'll personally be fine with any
> decision though -- if no one else cares that much, I'll backport
> to our downstream 4.14 on my own.

Okay, decided to apply it for v5.3.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] iommu/amd: Re-factor guest virtual APIC (de-)activation code

2019-08-09 Thread j...@8bytes.org
On Tue, Jul 23, 2019 at 07:00:37PM +, Suthikulpanit, Suravee wrote:
> Re-factore the logic for activate/deactivate guest virtual APIC mode (GAM)
> into helper functions, and export them for other drivers (e.g. SVM).
> to support run-time activate/deactivate of SVM AVIC.
> 
> Cc: Joerg Roedel 
> Signed-off-by: Suravee Suthikulpanit 
> ---
>  drivers/iommu/amd_iommu.c   | 85 
> +
>  drivers/iommu/amd_iommu_types.h |  9 +
>  include/linux/amd-iommu.h   | 12 ++
>  3 files changed, 82 insertions(+), 24 deletions(-)

Applied, thanks Suravee.


Re: [PATCH 1/1] iommu/vt-d: Correctly check format of page table in debugfs

2019-08-09 Thread Joerg Roedel
On Sat, Jul 20, 2019 at 10:01:26AM +0800, Lu Baolu wrote:
>  drivers/iommu/intel-iommu-debugfs.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Applied, thanks.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 0/3] Disable IOMMU Passthrough when SME is active

2019-08-09 Thread Joerg Roedel
Hi,

here is a small patch-set to disable IOMMU Passthrough mode when SME is
active even when CONFIG_IOMMU_DEFAULT_PASSTHROUGH=y is set.

The reason for that change is that SME with passthrough mode turned out
to be fragile with devices requiring SWIOTLB, mainly because SWIOTLB has
a maximum allocation size of 256kb and a limit overall size of the
bounce buffer.

Therefore having IOMMU in translation mode by default is better when SME
is active on a system.

Please review.

Thanks,

Joerg

Joerg Roedel (3):
  iommu: Print default domain type on boot
  iommu: Set default domain type at runtime
  iommu: Disable passthrough mode when SME is active

 drivers/iommu/iommu.c | 48 +--
 1 file changed, 42 insertions(+), 6 deletions(-)

-- 
2.17.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 1/3] iommu: Print default domain type on boot

2019-08-09 Thread Joerg Roedel
From: Joerg Roedel 

Introduce a subsys_initcall for IOMMU code and use it to
print the default domain type at boot.

Signed-off-by: Joerg Roedel 
---
 drivers/iommu/iommu.c | 30 +-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 0c674d80c37f..b57ce00c1310 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -80,12 +80,40 @@ struct iommu_group_attribute iommu_group_attr_##_name = 
\
 static LIST_HEAD(iommu_device_list);
 static DEFINE_SPINLOCK(iommu_device_lock);
 
+/*
+ * Use a function instead of an array here because the domain-type is a
+ * bit-field, so an array would waste memory.
+ */
+static const char *iommu_domain_type_str(unsigned int t)
+{
+   switch (t) {
+   case IOMMU_DOMAIN_BLOCKED:
+   return "Blocked";
+   case IOMMU_DOMAIN_IDENTITY:
+   return "Passthrough";
+   case IOMMU_DOMAIN_UNMANAGED:
+   return "Unmanaged";
+   case IOMMU_DOMAIN_DMA:
+   return "Translated";
+   default:
+   return "Unknown";
+   }
+}
+
+static int __init iommu_subsys_init(void)
+{
+   pr_info("Default domain type: %s\n",
+   iommu_domain_type_str(iommu_def_domain_type));
+
+   return 0;
+}
+subsys_initcall(iommu_subsys_init);
+
 int iommu_device_register(struct iommu_device *iommu)
 {
spin_lock(&iommu_device_lock);
list_add_tail(&iommu->list, &iommu_device_list);
spin_unlock(&iommu_device_lock);
-
return 0;
 }
 
-- 
2.17.1



[PATCH 2/3] iommu: Set default domain type at runtime

2019-08-09 Thread Joerg Roedel
From: Joerg Roedel 

Set the default domain-type at runtime, not at compile-time.
This keeps default domain type setting in one place when we
have to change it at runtime.

Signed-off-by: Joerg Roedel 
---
 drivers/iommu/iommu.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index b57ce00c1310..62cae6db0970 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -26,11 +26,8 @@
 
 static struct kset *iommu_group_kset;
 static DEFINE_IDA(iommu_group_ida);
-#ifdef CONFIG_IOMMU_DEFAULT_PASSTHROUGH
-static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_IDENTITY;
-#else
-static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_DMA;
-#endif
+
+static unsigned int iommu_def_domain_type __read_mostly;
 static bool iommu_dma_strict __read_mostly = true;
 
 struct iommu_group {
@@ -102,6 +99,11 @@ static const char *iommu_domain_type_str(unsigned int t)
 
 static int __init iommu_subsys_init(void)
 {
+   if (IS_ENABLED(CONFIG_IOMMU_DEFAULT_PASSTHROUGH))
+   iommu_def_domain_type = IOMMU_DOMAIN_IDENTITY;
+   else
+   iommu_def_domain_type = IOMMU_DOMAIN_DMA;
+
pr_info("Default domain type: %s\n",
iommu_domain_type_str(iommu_def_domain_type));
 
-- 
2.17.1



[PATCH 3/3] iommu: Disable passthrough mode when SME is active

2019-08-09 Thread Joerg Roedel
From: Joerg Roedel 

Using Passthrough mode when SME is active causes certain
devices to use the SWIOTLB bounce buffer. The bounce buffer
code has an upper limit of 256kb for the size of DMA
allocations, which is too small for certain devices and
causes them to fail.

With this patch we enable IOMMU by default when SME is
active in the system, making the default configuration work
for more systems than it does now.

Users that don't want IOMMUs to be enabled still can disable
them with kernel parameters.

Signed-off-by: Joerg Roedel 
---
 drivers/iommu/iommu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 62cae6db0970..fbe1aa51bce9 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -104,6 +104,12 @@ static int __init iommu_subsys_init(void)
else
iommu_def_domain_type = IOMMU_DOMAIN_DMA;
 
+   if ((iommu_def_domain_type == IOMMU_DOMAIN_IDENTITY) &&
+   sme_active()) {
+   pr_info("SME detected - Disabling default IOMMU passthrough\n");
+   iommu_def_domain_type = IOMMU_DOMAIN_DMA;
+   }
+
pr_info("Default domain type: %s\n",
iommu_domain_type_str(iommu_def_domain_type));
 
-- 
2.17.1



Re: [PATCH v4 0/6] Remove x86-specific code from generic headers

2019-08-09 Thread mpe
Thiago Jung Bauermann  writes:
> Hello,
>
> This version has only a small change in the last patch as requested by
> Christoph and Halil, and collects Reviewed-by's.
>
> These patches are applied on top of v5.3-rc2.
>
> I don't have a way to test SME, SEV, nor s390's PEF so the patches have only
> been build tested.

I need to take this series via the powerpc tree because there is another
fairly large powerpc specific series dependent on it.

I think this series already has pretty much all the acks it needs, which
almost never happens, amazing work!

I'll put the series in a topic branch, just in case there's any bad
conflicts and other folks want to merge it later on. I'll then merge the
topic branch into my next, and so this series will be tested in
linux-next that way.

cheers


> Changelog
>
> Since v3:
>
> - Patch "s390/mm: Remove sev_active() function"
>   - Preserve comment from sev_active() in force_dma_unencrypted().
> Suggested by Christoph Hellwig.
>
> Since v2:
>
> - Patch "x86,s390: Move ARCH_HAS_MEM_ENCRYPT definition to arch/Kconfig"
>   - Added "select ARCH_HAS_MEM_ENCRYPT" to config S390. Suggested by Janani.
>
> - Patch "DMA mapping: Move SME handling to x86-specific files"
>   - Split up into 3 new patches. Suggested by Christoph Hellwig.
>
> - Patch "swiotlb: Remove call to sme_active()"
>   - New patch.
>
> - Patch "dma-mapping: Remove dma_check_mask()"
>   - New patch.
>
> - Patch "x86,s390/mm: Move sme_active() and sme_me_mask to x86-specific 
> header"
>   - New patch.
>   - Removed export of sme_active symbol. Suggested by Christoph Hellwig.
>
> - Patch "fs/core/vmcore: Move sev_active() reference to x86 arch code"
>   - Removed export of sev_active symbol. Suggested by Christoph Hellwig.
>
> - Patch "s390/mm: Remove sev_active() function"
>   - New patch.
>
> Since v1:
>
> - Patch "x86,s390: Move ARCH_HAS_MEM_ENCRYPT definition to arch/Kconfig"
>   - Remove definition of ARCH_HAS_MEM_ENCRYPT from s390/Kconfig as well.
>   - Reworded patch title and message a little bit.
>
> - Patch "DMA mapping: Move SME handling to x86-specific files"
>   - Adapt s390's  as well.
>   - Remove dma_check_mask() from kernel/dma/mapping.c. Suggested by
> Christoph Hellwig.
>
> Thiago Jung Bauermann (6):
>   x86,s390: Move ARCH_HAS_MEM_ENCRYPT definition to arch/Kconfig
>   swiotlb: Remove call to sme_active()
>   dma-mapping: Remove dma_check_mask()
>   x86,s390/mm: Move sme_active() and sme_me_mask to x86-specific header
>   fs/core/vmcore: Move sev_active() reference to x86 arch code
>   s390/mm: Remove sev_active() function
>
>  arch/Kconfig|  3 +++
>  arch/s390/Kconfig   |  4 +---
>  arch/s390/include/asm/mem_encrypt.h |  5 +
>  arch/s390/mm/init.c |  7 +--
>  arch/x86/Kconfig|  4 +---
>  arch/x86/include/asm/mem_encrypt.h  | 10 ++
>  arch/x86/kernel/crash_dump_64.c |  5 +
>  arch/x86/mm/mem_encrypt.c   |  2 --
>  fs/proc/vmcore.c|  8 
>  include/linux/crash_dump.h  | 14 ++
>  include/linux/mem_encrypt.h | 15 +--
>  kernel/dma/mapping.c|  8 
>  kernel/dma/swiotlb.c|  3 +--
>  13 files changed, 42 insertions(+), 46 deletions(-)
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 6/8] arm-nommu: call dma_mmap_from_dev_coherent directly

2019-08-09 Thread Sergei Shtylyov

On 08.08.2019 19:00, Christoph Hellwig wrote:


Ther is no need to go through dma_common_mmap for the arm-nommu


   There. :-)


dma mmap implementation as the only possible memory not handled above
could be that from the per-device coherent pool.

Signed-off-by: Christoph Hellwig 

[...]

MBR, Sergei


Re: [PATCH 8/8] dma-mapping: remove CONFIG_ARCH_NO_COHERENT_DMA_MMAP

2019-08-09 Thread Geert Uytterhoeven
Hi Christoph,

On Thu, Aug 8, 2019 at 6:01 PM Christoph Hellwig  wrote:
> CONFIG_ARCH_NO_COHERENT_DMA_MMAP is now functionally identical to
> !CONFIG_MMU, so remove the separate symbol.  The only difference is that
> arm did not set it for !CONFIG_MMU, but arm uses a separate dma mapping
> implementation including its own mmap method, which is handled by moving
> the CONFIG_MMU check in dma_can_mmap so that is only applies to the
> dma-direct case, just as the other ifdefs for it.
>
> Signed-off-by: Christoph Hellwig 

>  arch/m68k/Kconfig   |  1 -

For m68k:
Acked-by: Geert Uytterhoeven 

Gr{oetje,eeting}s,

Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds


[PATCH v4 0/8] Replace strncmp with str_has_prefix

2019-08-09 Thread Chuhong Yuan
The commit 72921427d46b
("string.h: Add str_has_prefix() helper function")
introduced str_has_prefix() to substitute error-prone
strncmp(str, const, len).

strncmp(str, const, len) is easy to have error in len
because of counting error or sizeof(const) without - 1.

These patches replace such pattern with str_has_prefix()
to avoid hard coded constant length and sizeof.

Besides, str_has_prefix() returns the length of prefix
when the comparison returns true.
We can use this return value to substitute some hard-coding.

Changelog:

v1 -> v2:
  - Revise the description.
  - Use the return value of str_has_prefix() to eliminate
hard coding.
  - Remove possible false positives and add newly detected
one in upstream.

v2 -> v3:
  - Revise the description.
  - Remove else uses in printk.c.

v3 -> v4:
  - Eliminate assignments in if conditions.

Chuhong Yuan (8):
  dma: debug: Replace strncmp with str_has_prefix
  module: Replace strncmp with str_has_prefix
  PM/sleep: Replace strncmp with str_has_prefix
  printk: Replace strncmp with str_has_prefix
  reboot: Replace strncmp with str_has_prefix
  sched: Replace strncmp with str_has_prefix
  userns: Replace strncmp with str_has_prefix
  watchdog: Replace strncmp with str_has_prefix

 kernel/dma/debug.c   |  2 +-
 kernel/module.c  |  2 +-
 kernel/power/main.c  |  2 +-
 kernel/printk/braille.c  | 15 +++
 kernel/printk/printk.c   | 22 --
 kernel/reboot.c  |  7 +--
 kernel/sched/debug.c |  6 --
 kernel/sched/isolation.c | 11 +++
 kernel/user_namespace.c  | 20 
 kernel/watchdog.c|  8 
 10 files changed, 62 insertions(+), 33 deletions(-)

-- 
2.20.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v4 1/8] dma: debug: Replace strncmp with str_has_prefix

2019-08-09 Thread Chuhong Yuan
strncmp(str, const, len) is error-prone because len
is easy to have typo.
The example is the hard-coded len has counting error
or sizeof(const) forgets - 1.
So we prefer using newly introduced str_has_prefix()
to substitute such strncmp to make code better.

Signed-off-by: Chuhong Yuan 
---
 kernel/dma/debug.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c
index 099002d84f46..0f9e1aba3e1a 100644
--- a/kernel/dma/debug.c
+++ b/kernel/dma/debug.c
@@ -970,7 +970,7 @@ static __init int dma_debug_cmdline(char *str)
if (!str)
return -EINVAL;
 
-   if (strncmp(str, "off", 3) == 0) {
+   if (str_has_prefix(str, "off")) {
pr_info("debugging disabled on kernel command line\n");
global_disable = true;
}
-- 
2.20.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu