From 5f318d40fab949ef5241f06254f10505b771f8ce Mon Sep 17 00:00:00 2001
From: Siyuan Zhou <siyuanzhou@google.com>
Date: Mon, 14 May 2018 18:12:40 -0700
Subject: [PATCH] Add timeout and panic when __scm_call_armv8_64 takes too
 long.

Device can stuck in the infinite loop in __scm_call_armv8_64 if TZ
subsystem stays in SCM_INTERRUPTED state. To get logs while the device
is in freeze state, added a timeout in __scm_call_armv8_64 and triggered
panic if SCM call takes too long.

This should be reverted when root cause in TZ is identified.

Bug:74358862
Test: Ran the kernel on device for >4hr without a crash.
Change-Id: I9ee3c592fca23209b72004dd95cabc51e398eb3b
Signed-off-by: Siyuan Zhou <siyuanzhou@google.com>
---
 drivers/soc/qcom/scm.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/soc/qcom/scm.c b/drivers/soc/qcom/scm.c
index 6f5bd217d0c9..1e4d9a403b21 100644
--- a/drivers/soc/qcom/scm.c
+++ b/drivers/soc/qcom/scm.c
@@ -36,6 +36,9 @@
 #define SCM_EBUSY		-55
 #define SCM_V2_EBUSY		-12
 
+/* in ms */
+#define SCM_PANIC_TIMEOUT 600000
+
 static DEFINE_MUTEX(scm_lock);
 
 /*
@@ -383,6 +386,7 @@ int scm_call_noalloc(u32 svc_id, u32 cmd_id, const void *cmd_buf,
 static int __scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5,
 				u64 *ret1, u64 *ret2, u64 *ret3)
 {
+	unsigned long timeout;
 	register u64 r0 asm("x0") = x0;
 	register u64 r1 asm("x1") = x1;
 	register u64 r2 asm("x2") = x2;
@@ -391,6 +395,8 @@ static int __scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5,
 	register u64 r5 asm("x5") = x5;
 	register u64 r6 asm("x6") = 0;
 
+	timeout = jiffies + msecs_to_jiffies(SCM_PANIC_TIMEOUT);
+
 	do {
 		asm volatile(
 			__asmeq("%0", R0_STR)
@@ -414,6 +420,9 @@ static int __scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5,
 			  "r" (r5), "r" (r6)
 			: "x7", "x8", "x9", "x10", "x11", "x12", "x13",
 			  "x14", "x15", "x16", "x17");
+		if (!time_after(timeout, jiffies)) {
+			panic("[DEBUG] SCM call took too long.\n");
+		}
 	} while (r0 == SCM_INTERRUPTED);
 
 	if (ret1)
-- 
GitLab