Re: [PATCHv3] iommu/arm-smmu-qcom: Add debug support for TLB sync timeouts

2022-07-09 Thread Akhil P Oommen

On 7/8/2022 3:12 PM, Sai Prakash Ranjan wrote:

TLB sync timeouts can be due to various reasons such as TBU power down
or pending TCU/TBU invalidation/sync and so on. Debugging these often
require dumping of some implementation defined registers to know the
status of TBU/TCU operations and some of these registers are not
accessible in non-secure world such as from kernel and requires SMC
calls to read them in the secure world. So, add this debug support
to dump implementation defined registers for TLB sync timeout issues.

Signed-off-by: Sai Prakash Ranjan 
---

Changes in v3:
  * Move this debug feature to arm-smmu-qcom-debug.c (Will Deacon).
  * Keep single ratelimit state and remove local variable (Robin).

Changes in v2:
  * Use scm call consistently so that it works on older chipsets where
some of these regs are secure registers.
  * Add device specific data to get the implementation defined register
offsets.

---
  drivers/iommu/Kconfig |  10 ++
  drivers/iommu/arm/arm-smmu/Makefile   |   1 +
  .../iommu/arm/arm-smmu/arm-smmu-qcom-debug.c  | 142 ++
  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c|  32 +++-
  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h|  28 
  drivers/iommu/arm/arm-smmu/arm-smmu.c |   6 +-
  drivers/iommu/arm/arm-smmu/arm-smmu.h |   1 +
  7 files changed, 211 insertions(+), 9 deletions(-)
  create mode 100644 drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c
  create mode 100644 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index c79a0df090c0..5c5cb5bee8b6 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -363,6 +363,16 @@ config ARM_SMMU_QCOM
  When running on a Qualcomm platform that has the custom variant
  of the ARM SMMU, this needs to be built into the SMMU driver.
  
+config ARM_SMMU_QCOM_DEBUG

+   bool "ARM SMMU QCOM implementation defined debug support"
+   depends on ARM_SMMU_QCOM
+   help
+ Support for implementation specific debug features in ARM SMMU
+ hardware found in QTI platforms.
+
+ Say Y here to enable debug for issues such as TLB sync timeouts
+ which requires implementation defined register dumps.
+
  config ARM_SMMU_V3
tristate "ARM Ltd. System MMU Version 3 (SMMUv3) Support"
depends on ARM64
diff --git a/drivers/iommu/arm/arm-smmu/Makefile 
b/drivers/iommu/arm/arm-smmu/Makefile
index b0cc01aa20c9..2a5a95e8e3f9 100644
--- a/drivers/iommu/arm/arm-smmu/Makefile
+++ b/drivers/iommu/arm/arm-smmu/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
  obj-$(CONFIG_ARM_SMMU) += arm_smmu.o
  arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-nvidia.o
  arm_smmu-$(CONFIG_ARM_SMMU_QCOM) += arm-smmu-qcom.o
+arm_smmu-$(CONFIG_ARM_SMMU_QCOM_DEBUG) += arm-smmu-qcom-debug.o
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c
new file mode 100644
index ..6eed8e67a0ca
--- /dev/null
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+
+#include "arm-smmu.h"
+#include "arm-smmu-qcom.h"
+
+enum qcom_smmu_impl_reg_offset {
+   QCOM_SMMU_TBU_PWR_STATUS,
+   QCOM_SMMU_STATS_SYNC_INV_TBU_ACK,
+   QCOM_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR,
+};
+
+struct qcom_smmu_config {
+   const u32 *reg_offset;
+};
+
+void qcom_smmu_tlb_sync_debug(struct arm_smmu_device *smmu)
+{
+   int ret;
+   u32 tbu_pwr_status, sync_inv_ack, sync_inv_progress;
+   struct qcom_smmu *qsmmu = container_of(smmu, struct qcom_smmu, smmu);
+   const struct qcom_smmu_config *cfg;
+   static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL,
+ DEFAULT_RATELIMIT_BURST);
+
+   if (__ratelimit(&rs)) {
+   dev_err(smmu->dev, "TLB sync timed out -- SMMU may be 
deadlocked\n");
+
+   cfg = qsmmu->cfg;
+   if (!cfg)
+   return;
+
+   ret = qcom_scm_io_readl(smmu->ioaddr + 
cfg->reg_offset[QCOM_SMMU_TBU_PWR_STATUS],
+   &tbu_pwr_status);
+   if (ret)
+   dev_err(smmu->dev,
+   "Failed to read TBU power status: %d\n", ret);
+
+   ret = qcom_scm_io_readl(smmu->ioaddr + 
cfg->reg_offset[QCOM_SMMU_STATS_SYNC_INV_TBU_ACK],
+   &sync_inv_ack);
+   if (ret)
+   dev_err(smmu->dev,
+   "Failed to read TBU sync/inv ack status: %d\n", 
ret);
+
+   ret = qcom_scm_io_readl(smmu->ioaddr + 
cfg->reg_offset[QCOM_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR],
+   &sync_inv_pro

Re: [PATCHv3] iommu/arm-smmu-qcom: Add debug support for TLB sync timeouts

2022-07-09 Thread Will Deacon
On Fri, 8 Jul 2022 15:12:30 +0530, Sai Prakash Ranjan wrote:
> TLB sync timeouts can be due to various reasons such as TBU power down
> or pending TCU/TBU invalidation/sync and so on. Debugging these often
> require dumping of some implementation defined registers to know the
> status of TBU/TCU operations and some of these registers are not
> accessible in non-secure world such as from kernel and requires SMC
> calls to read them in the secure world. So, add this debug support
> to dump implementation defined registers for TLB sync timeout issues.
> 
> [...]

Applied to will (for-joerg/arm-smmu/updates), thanks!

[1/1] iommu/arm-smmu-qcom: Add debug support for TLB sync timeouts
  https://git.kernel.org/will/c/b9b721d117e9

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCHv3] iommu/arm-smmu-qcom: Add debug support for TLB sync timeouts

2022-07-09 Thread Robin Murphy

On 2022-07-08 10:42, Sai Prakash Ranjan wrote:

TLB sync timeouts can be due to various reasons such as TBU power down
or pending TCU/TBU invalidation/sync and so on. Debugging these often
require dumping of some implementation defined registers to know the
status of TBU/TCU operations and some of these registers are not
accessible in non-secure world such as from kernel and requires SMC
calls to read them in the secure world. So, add this debug support
to dump implementation defined registers for TLB sync timeout issues.


FWIW,

Acked-by: Robin Murphy 


Signed-off-by: Sai Prakash Ranjan 
---

Changes in v3:
  * Move this debug feature to arm-smmu-qcom-debug.c (Will Deacon).
  * Keep single ratelimit state and remove local variable (Robin).

Changes in v2:
  * Use scm call consistently so that it works on older chipsets where
some of these regs are secure registers.
  * Add device specific data to get the implementation defined register
offsets.

---
  drivers/iommu/Kconfig |  10 ++
  drivers/iommu/arm/arm-smmu/Makefile   |   1 +
  .../iommu/arm/arm-smmu/arm-smmu-qcom-debug.c  | 142 ++
  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c|  32 +++-
  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h|  28 
  drivers/iommu/arm/arm-smmu/arm-smmu.c |   6 +-
  drivers/iommu/arm/arm-smmu/arm-smmu.h |   1 +
  7 files changed, 211 insertions(+), 9 deletions(-)
  create mode 100644 drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c
  create mode 100644 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index c79a0df090c0..5c5cb5bee8b6 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -363,6 +363,16 @@ config ARM_SMMU_QCOM
  When running on a Qualcomm platform that has the custom variant
  of the ARM SMMU, this needs to be built into the SMMU driver.
  
+config ARM_SMMU_QCOM_DEBUG

+   bool "ARM SMMU QCOM implementation defined debug support"
+   depends on ARM_SMMU_QCOM
+   help
+ Support for implementation specific debug features in ARM SMMU
+ hardware found in QTI platforms.
+
+ Say Y here to enable debug for issues such as TLB sync timeouts
+ which requires implementation defined register dumps.
+
  config ARM_SMMU_V3
tristate "ARM Ltd. System MMU Version 3 (SMMUv3) Support"
depends on ARM64
diff --git a/drivers/iommu/arm/arm-smmu/Makefile 
b/drivers/iommu/arm/arm-smmu/Makefile
index b0cc01aa20c9..2a5a95e8e3f9 100644
--- a/drivers/iommu/arm/arm-smmu/Makefile
+++ b/drivers/iommu/arm/arm-smmu/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
  obj-$(CONFIG_ARM_SMMU) += arm_smmu.o
  arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-nvidia.o
  arm_smmu-$(CONFIG_ARM_SMMU_QCOM) += arm-smmu-qcom.o
+arm_smmu-$(CONFIG_ARM_SMMU_QCOM_DEBUG) += arm-smmu-qcom-debug.o
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c
new file mode 100644
index ..6eed8e67a0ca
--- /dev/null
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+
+#include "arm-smmu.h"
+#include "arm-smmu-qcom.h"
+
+enum qcom_smmu_impl_reg_offset {
+   QCOM_SMMU_TBU_PWR_STATUS,
+   QCOM_SMMU_STATS_SYNC_INV_TBU_ACK,
+   QCOM_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR,
+};
+
+struct qcom_smmu_config {
+   const u32 *reg_offset;
+};
+
+void qcom_smmu_tlb_sync_debug(struct arm_smmu_device *smmu)
+{
+   int ret;
+   u32 tbu_pwr_status, sync_inv_ack, sync_inv_progress;
+   struct qcom_smmu *qsmmu = container_of(smmu, struct qcom_smmu, smmu);
+   const struct qcom_smmu_config *cfg;
+   static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL,
+ DEFAULT_RATELIMIT_BURST);
+
+   if (__ratelimit(&rs)) {
+   dev_err(smmu->dev, "TLB sync timed out -- SMMU may be 
deadlocked\n");
+
+   cfg = qsmmu->cfg;
+   if (!cfg)
+   return;
+
+   ret = qcom_scm_io_readl(smmu->ioaddr + 
cfg->reg_offset[QCOM_SMMU_TBU_PWR_STATUS],
+   &tbu_pwr_status);
+   if (ret)
+   dev_err(smmu->dev,
+   "Failed to read TBU power status: %d\n", ret);
+
+   ret = qcom_scm_io_readl(smmu->ioaddr + 
cfg->reg_offset[QCOM_SMMU_STATS_SYNC_INV_TBU_ACK],
+   &sync_inv_ack);
+   if (ret)
+   dev_err(smmu->dev,
+   "Failed to read TBU sync/inv ack status: %d\n", 
ret);
+
+   ret = qcom_scm_io_readl(smmu->ioaddr + 
cfg->reg_offset[QCOM_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR],
+  

[PATCHv3] iommu/arm-smmu-qcom: Add debug support for TLB sync timeouts

2022-07-09 Thread Sai Prakash Ranjan
TLB sync timeouts can be due to various reasons such as TBU power down
or pending TCU/TBU invalidation/sync and so on. Debugging these often
require dumping of some implementation defined registers to know the
status of TBU/TCU operations and some of these registers are not
accessible in non-secure world such as from kernel and requires SMC
calls to read them in the secure world. So, add this debug support
to dump implementation defined registers for TLB sync timeout issues.

Signed-off-by: Sai Prakash Ranjan 
---

Changes in v3:
 * Move this debug feature to arm-smmu-qcom-debug.c (Will Deacon).
 * Keep single ratelimit state and remove local variable (Robin).

Changes in v2:
 * Use scm call consistently so that it works on older chipsets where
   some of these regs are secure registers.
 * Add device specific data to get the implementation defined register
   offsets.

---
 drivers/iommu/Kconfig |  10 ++
 drivers/iommu/arm/arm-smmu/Makefile   |   1 +
 .../iommu/arm/arm-smmu/arm-smmu-qcom-debug.c  | 142 ++
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c|  32 +++-
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h|  28 
 drivers/iommu/arm/arm-smmu/arm-smmu.c |   6 +-
 drivers/iommu/arm/arm-smmu/arm-smmu.h |   1 +
 7 files changed, 211 insertions(+), 9 deletions(-)
 create mode 100644 drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c
 create mode 100644 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index c79a0df090c0..5c5cb5bee8b6 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -363,6 +363,16 @@ config ARM_SMMU_QCOM
  When running on a Qualcomm platform that has the custom variant
  of the ARM SMMU, this needs to be built into the SMMU driver.
 
+config ARM_SMMU_QCOM_DEBUG
+   bool "ARM SMMU QCOM implementation defined debug support"
+   depends on ARM_SMMU_QCOM
+   help
+ Support for implementation specific debug features in ARM SMMU
+ hardware found in QTI platforms.
+
+ Say Y here to enable debug for issues such as TLB sync timeouts
+ which requires implementation defined register dumps.
+
 config ARM_SMMU_V3
tristate "ARM Ltd. System MMU Version 3 (SMMUv3) Support"
depends on ARM64
diff --git a/drivers/iommu/arm/arm-smmu/Makefile 
b/drivers/iommu/arm/arm-smmu/Makefile
index b0cc01aa20c9..2a5a95e8e3f9 100644
--- a/drivers/iommu/arm/arm-smmu/Makefile
+++ b/drivers/iommu/arm/arm-smmu/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
 obj-$(CONFIG_ARM_SMMU) += arm_smmu.o
 arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-nvidia.o
 arm_smmu-$(CONFIG_ARM_SMMU_QCOM) += arm-smmu-qcom.o
+arm_smmu-$(CONFIG_ARM_SMMU_QCOM_DEBUG) += arm-smmu-qcom-debug.o
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c
new file mode 100644
index ..6eed8e67a0ca
--- /dev/null
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+
+#include "arm-smmu.h"
+#include "arm-smmu-qcom.h"
+
+enum qcom_smmu_impl_reg_offset {
+   QCOM_SMMU_TBU_PWR_STATUS,
+   QCOM_SMMU_STATS_SYNC_INV_TBU_ACK,
+   QCOM_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR,
+};
+
+struct qcom_smmu_config {
+   const u32 *reg_offset;
+};
+
+void qcom_smmu_tlb_sync_debug(struct arm_smmu_device *smmu)
+{
+   int ret;
+   u32 tbu_pwr_status, sync_inv_ack, sync_inv_progress;
+   struct qcom_smmu *qsmmu = container_of(smmu, struct qcom_smmu, smmu);
+   const struct qcom_smmu_config *cfg;
+   static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL,
+ DEFAULT_RATELIMIT_BURST);
+
+   if (__ratelimit(&rs)) {
+   dev_err(smmu->dev, "TLB sync timed out -- SMMU may be 
deadlocked\n");
+
+   cfg = qsmmu->cfg;
+   if (!cfg)
+   return;
+
+   ret = qcom_scm_io_readl(smmu->ioaddr + 
cfg->reg_offset[QCOM_SMMU_TBU_PWR_STATUS],
+   &tbu_pwr_status);
+   if (ret)
+   dev_err(smmu->dev,
+   "Failed to read TBU power status: %d\n", ret);
+
+   ret = qcom_scm_io_readl(smmu->ioaddr + 
cfg->reg_offset[QCOM_SMMU_STATS_SYNC_INV_TBU_ACK],
+   &sync_inv_ack);
+   if (ret)
+   dev_err(smmu->dev,
+   "Failed to read TBU sync/inv ack status: %d\n", 
ret);
+
+   ret = qcom_scm_io_readl(smmu->ioaddr + 
cfg->reg_offset[QCOM_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR],
+   &sync_inv_progress);
+   if (ret)
+   dev_err(smmu->