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