[PATCH V3] iommu/arm-smmu-v2: ThunderX mis-extends 64bit registers

2015-08-17 Thread tchalamarla
From: Tirumalesh Chalamarla tchalama...@caviumnetworks.com

The SMMU architecture defines two different behaviors when 64-bit
registers are written with 32-bit writes.  The first behavior causes
zero extension into the upper 32-bits.  The second behavior splits a
64-bit register into normal 32-bit register pairs.

On some buggy implementations, registers incorrectly zero extended
when they should instead behave as normal 32-bit register pairs.

Signed-off-by: Tirumalesh Chalamarla tchalama...@caviumnetworks.com

Changes from V2:
- removed unused definitions

Changes from V1:
- Introduced smmu_writeq
---
 drivers/iommu/arm-smmu.c | 57 +---
 1 file changed, 30 insertions(+), 27 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 66a803b..26572d6 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -69,6 +69,18 @@
((smmu-options  ARM_SMMU_OPT_SECURE_CFG_ACCESS)   \
? 0x400 : 0))
 
+#ifdef CONFIG_64BIT
+#define smmu_writeq(reg64, addr)   writeq_relaxed((reg64), (addr))
+#else
+#define smmu_writeq(reg64, addr)   \
+   do {\
+   u64 __val = (reg64);\
+   void __iomem *__addr = (addr);  \
+   writel_relaxed(__val  32, __addr + 4);\
+   writel_relaxed(__val, __addr);  \
+   } while (0)
+#endif
+
 /* Configuration registers */
 #define ARM_SMMU_GR0_sCR0  0x0
 #define sCR0_CLIENTPD  (1  0)
@@ -184,10 +196,8 @@
 #define ARM_SMMU_CB_SCTLR  0x0
 #define ARM_SMMU_CB_RESUME 0x8
 #define ARM_SMMU_CB_TTBCR2 0x10
-#define ARM_SMMU_CB_TTBR0_LO   0x20
-#define ARM_SMMU_CB_TTBR0_HI   0x24
-#define ARM_SMMU_CB_TTBR1_LO   0x28
-#define ARM_SMMU_CB_TTBR1_HI   0x2c
+#define ARM_SMMU_CB_TTBR0  0x20
+#define ARM_SMMU_CB_TTBR1  0x28
 #define ARM_SMMU_CB_TTBCR  0x30
 #define ARM_SMMU_CB_S1_MAIR0   0x38
 #define ARM_SMMU_CB_S1_MAIR1   0x3c
@@ -202,8 +212,7 @@
 #define ARM_SMMU_CB_S1_TLBIVAL 0x620
 #define ARM_SMMU_CB_S2_TLBIIPAS2   0x630
 #define ARM_SMMU_CB_S2_TLBIIPAS2L  0x638
-#define ARM_SMMU_CB_ATS1PR_LO  0x800
-#define ARM_SMMU_CB_ATS1PR_HI  0x804
+#define ARM_SMMU_CB_ATS1PR 0x800
 #define ARM_SMMU_CB_ATSR   0x8f0
 
 #define SCTLR_S1_ASIDPNE   (1  12)
@@ -226,7 +235,7 @@
 #define TTBCR2_SEP_SHIFT   15
 #define TTBCR2_SEP_UPSTREAM(0x7  TTBCR2_SEP_SHIFT)
 
-#define TTBRn_HI_ASID_SHIFT16
+#define TTBRn_ASID_SHIFT   48
 
 #define FSR_MULTI  (1  31)
 #define FSR_SS (1  30)
@@ -719,6 +728,7 @@ static void arm_smmu_init_context_bank(struct 
arm_smmu_domain *smmu_domain,
   struct io_pgtable_cfg *pgtbl_cfg)
 {
u32 reg;
+   u64 reg64;
bool stage1;
struct arm_smmu_cfg *cfg = smmu_domain-cfg;
struct arm_smmu_device *smmu = smmu_domain-smmu;
@@ -762,22 +772,17 @@ static void arm_smmu_init_context_bank(struct 
arm_smmu_domain *smmu_domain,
 
/* TTBRs */
if (stage1) {
-   reg = pgtbl_cfg-arm_lpae_s1_cfg.ttbr[0];
-   writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);
-   reg = pgtbl_cfg-arm_lpae_s1_cfg.ttbr[0]  32;
-   reg |= ARM_SMMU_CB_ASID(cfg)  TTBRn_HI_ASID_SHIFT;
-   writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);
-
-   reg = pgtbl_cfg-arm_lpae_s1_cfg.ttbr[1];
-   writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_LO);
-   reg = pgtbl_cfg-arm_lpae_s1_cfg.ttbr[1]  32;
-   reg |= ARM_SMMU_CB_ASID(cfg)  TTBRn_HI_ASID_SHIFT;
-   writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_HI);
+   reg64 = pgtbl_cfg-arm_lpae_s1_cfg.ttbr[0];
+
+   reg64 |= ((u64)ARM_SMMU_CB_ASID(cfg))  TTBRn_ASID_SHIFT;
+   smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR0);
+
+   reg64 = pgtbl_cfg-arm_lpae_s1_cfg.ttbr[1];
+   reg64 |= ((u64)ARM_SMMU_CB_ASID(cfg))  TTBRn_ASID_SHIFT;
+   smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR1);
} else {
-   reg = pgtbl_cfg-arm_lpae_s2_cfg.vttbr;
-   writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);
-   reg = pgtbl_cfg-arm_lpae_s2_cfg.vttbr  32;
-   writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);
+   reg64 = pgtbl_cfg-arm_lpae_s2_cfg.vttbr;
+   smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR0);
}
 
/* TTBCR */
@@ -1234,12 +1239,10 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct 
iommu_domain 

Re: [GIT PULL 6/9] iommu/tegra-smmu: Changes for v4.3-rc1

2015-08-17 Thread Joerg Roedel
On Fri, Aug 14, 2015 at 04:48:37PM +0200, Thierry Reding wrote:
 Hi Joerg,
 
 The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
 
   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
 
 are available in the git repository at:
 
   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git 
 tags/tegra-for-4.3-iommu


Pulled, thanks.

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


RE: [PATCH v2] iommu/fsl: Really fix init section(s) content

2015-08-17 Thread Varun Sethi
Thanks Madalin.

Joerg,
Can you please pick this patch.

Regards
Varun


 Original message 
From: Bucur Madalin-Cristian-B32716
Date:08/17/2015 8:28 PM (GMT+05:30)
To: j...@8bytes.org,iommu@lists.linux-foundation.org,Sethi Varun-B16395
Cc: sta...@vger.kernel.org
Subject: RE: [PATCH v2] iommu/fsl: Really fix init section(s) content

Patch working on all tested platforms: B4860QDS, P2041RDB,
P3041DS, P4080DS, P5020DS, P5040DS, T1024RDB, T1040RDB,
T2080RDB, T4240QDS.

Tested-by: Madalin Bucur madalin.bu...@freescale.com

 -Original Message-
 From: Sethi Varun-B16395
 Sent: Monday, August 03, 2015 3:29 PM
 To: iommu@lists.linux-foundation.org; j...@8bytes.org
 Cc: sta...@vger.kernel.org; Medve Emilian-EMMEDVE1; Bucur Madalin-
 Cristian-B32716
 Subject: RE: [PATCH v2] iommu/fsl: Really fix init section(s) content

 Hi Joerg,
 This patch doesn't seem to be applied to the PAMU driver.

 Regards
 Varun

  -Original Message-
  From: iommu-boun...@lists.linux-foundation.org [mailto:iommu-
  boun...@lists.linux-foundation.org] On Behalf Of Emil Medve
  Sent: Wednesday, March 25, 2015 10:59 AM
  To: iommu@lists.linux-foundation.org; j...@8bytes.org
  Cc: sta...@vger.kernel.org; Medve Emilian-EMMEDVE1
  Subject: [PATCH v2] iommu/fsl: Really fix init section(s) content
 
  '0f1fb99 iommu/fsl: Fix section mismatch' was intended to address the
  modpost warning and the potential crash. Crash which is actually easy to
  trigger with a 'unbind' followed by a 'bind' sequence. The fix is wrong as
  fsl_of_pamu_driver.driver gets added by bus_add_driver() to a couple of
  klist(s) which become invalid/corrupted as soon as the init sections are
 freed.
  Depending on when/how the init sections storage is reused
 various/random
  errors and crashes will happen
 
  'cd70d46 iommu/fsl: Various cleanups' contains annotations that go further
  down the wrong path laid by '0f1fb99 iommu/fsl: Fix section mismatch'
 
  Now remove all the incorrect annotations from the above mentioned
  patches (not exactly a revert) and those previously existing in the code,
 This
  fixes the modpost warning(s), the unbind/bind sequence crashes and the
  random errors/crashes
 
  Fixes: 0f1fb99b62ce (iommu/fsl: Fix section mismatch)
  Fixes: cd70d4659ff3 (iommu/fsl: Various cleanups)
  Signed-off-by: Emil Medve emilian.me...@freescale.com
  Acked-by: Varun Sethi varun.se...@freescale.com
  Cc: sta...@vger.kernel.org
  ---
   drivers/iommu/fsl_pamu.c | 26 +-
   1 file changed, 13 insertions(+), 13 deletions(-)
 
  diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c index
  abeedc9..2570f2a 100644
  --- a/drivers/iommu/fsl_pamu.c
  +++ b/drivers/iommu/fsl_pamu.c
  @@ -41,7 +41,6 @@ struct pamu_isr_data {
 
   static struct paace *ppaact;
   static struct paace *spaact;
  -static struct ome *omt __initdata;
 
   /*
* Table for matching compatible strings, for device tree @@ -50,7 +49,7
 @@
  static struct ome *omt __initdata;
* SOCs. For the older SOCs fsl,qoriq-device-config-1.0
* string would be used.
*/
  -static const struct of_device_id guts_device_ids[] __initconst = {
  +static const struct of_device_id guts_device_ids[] = {
   { .compatible = fsl,qoriq-device-config-1.0, },
   { .compatible = fsl,qoriq-device-config-2.0, },
   {}
  @@ -599,7 +598,7 @@ found_cpu_node:
* Memory accesses to QMAN and BMAN private memory need not be
  coherent, so
* clear the PAACE entry coherency attribute for them.
*/
  -static void __init setup_qbman_paace(struct paace *ppaace, int
  paace_type)
  +static void setup_qbman_paace(struct paace *ppaace, int  paace_type)
   {
   switch (paace_type) {
   case QMAN_PAACE:
  @@ -629,7 +628,7 @@ static void __init setup_qbman_paace(struct paace
  *ppaace, int  paace_type)
* this table to translate device transaction to appropriate corenet
* transaction.
*/
  -static void __init setup_omt(struct ome *omt)
  +static void setup_omt(struct ome *omt)
   {
   struct ome *ome;
 
  @@ -666,7 +665,7 @@ static void __init setup_omt(struct ome *omt)
* Get the maximum number of PAACT table entries
* and subwindows supported by PAMU
*/
  -static void __init get_pamu_cap_values(unsigned long pamu_reg_base)
  +static void get_pamu_cap_values(unsigned long pamu_reg_base)
   {
   u32 pc_val;
 
  @@ -676,9 +675,9 @@ static void __init get_pamu_cap_values(unsigned
  long pamu_reg_base)  }
 
   /* Setup PAMU registers pointing to PAACT, SPAACT and OMT */ -static int
  __init setup_one_pamu(unsigned long pamu_reg_base, unsigned long
  pamu_reg_size,
  -phys_addr_t ppaact_phys, phys_addr_t
  spaact_phys,
  -phys_addr_t omt_phys)
  +static int setup_one_pamu(unsigned long pamu_reg_base, unsigned long
  pamu_reg_size,
  + phys_addr_t ppaact_phys, phys_addr_t
  spaact_phys,
  + phys_addr_t omt_phys)
   {