ANDROID: trusty-log: On trusty panic, unthrottle sink to the kernel log

Bug: 189138546
Change-Id: Id828f5aae97e6e497048eb0fd4824ce02deeec7c
Signed-off-by: Armelle Laine <[email protected]>
diff --git a/drivers/trusty/trusty-log.c b/drivers/trusty/trusty-log.c
index 99c6b6e..c4395e1 100644
--- a/drivers/trusty/trusty-log.c
+++ b/drivers/trusty/trusty-log.c
@@ -48,6 +48,8 @@
 	spinlock_t lock;
 	struct log_rb *log;
 	u32 get;
+	/* index for the next line after the last successful get */
+	u32 last_successful_next;
 
 	struct page *log_pages;
 	struct scatterlist sg;
@@ -79,6 +81,7 @@
 	struct log_rb *log = s->log;
 	u32 get, put, alloc;
 	int read_chars;
+	bool trusty_panicked = trusty_get_panic_status(s->trusty_dev);
 
 	if (WARN_ON(!is_power_of_2(log->sz)))
 		return;
@@ -90,7 +93,7 @@
 	 * that the above condition is maintained. A read barrier is needed
 	 * to make sure the hardware and compiler keep the reads ordered.
 	 */
-	get = s->get;
+	get = trusty_panicked ? s->last_successful_next : s->get;
 	while ((put = log->put) != get) {
 		/* Make sure that the read of put occurs before the read of log data */
 		rmb();
@@ -111,11 +114,13 @@
 			get = alloc - log->sz;
 			continue;
 		}
-
-		if (__ratelimit(&trusty_log_rate_limit))
-			dev_info(s->dev, "%s", s->line_buffer);
-
+		/* compute next line index */
 		get += read_chars;
+		if (trusty_panicked || __ratelimit(&trusty_log_rate_limit)) {
+			dev_info(s->dev, "%s", s->line_buffer);
+			/* next line after last successful get */
+			s->last_successful_next = get;
+		}
 	}
 	s->get = get;
 }
diff --git a/drivers/trusty/trusty.c b/drivers/trusty/trusty.c
index 627e10f..27c5eb8 100644
--- a/drivers/trusty/trusty.c
+++ b/drivers/trusty/trusty.c
@@ -126,6 +126,8 @@
 		atomic_notifier_call_chain(&s->notifier, TRUSTY_CALL_PREPARE,
 					   NULL);
 		ret = trusty_std_call_inner(dev, smcnr, a0, a1, a2);
+		if (WARN_ONCE(ret == SM_ERR_PANIC, "trusty crashed"))
+			s->trusty_panicked = true;
 		atomic_notifier_call_chain(&s->notifier, TRUSTY_CALL_RETURNED,
 					   NULL);
 		if (ret == SM_ERR_INTERRUPTED) {
@@ -211,9 +213,6 @@
 	dev_dbg(dev, "%s(0x%x 0x%x 0x%x 0x%x) returned 0x%x\n",
 		__func__, smcnr, a0, a1, a2, ret);
 
-	if (WARN_ONCE(ret == SM_ERR_PANIC, "trusty crashed"))
-		s->trusty_panicked = true;
-
 	if (smcnr == SMC_SC_NOP)
 		complete(&s->cpu_idle_completion);
 	else
@@ -670,6 +669,15 @@
 }
 EXPORT_SYMBOL(trusty_get_api_version);
 
+bool trusty_get_panic_status(struct device *dev)
+{
+	struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
+	if (WARN_ON(dev->driver != &trusty_driver.driver))
+		return false;
+	return s->trusty_panicked;
+}
+EXPORT_SYMBOL(trusty_get_panic_status);
+
 static int trusty_init_api_version(struct trusty_state *s, struct device *dev)
 {
 	u32 api_version;
diff --git a/include/linux/trusty/trusty.h b/include/linux/trusty/trusty.h
index 05a271b..adf3c20 100644
--- a/include/linux/trusty/trusty.h
+++ b/include/linux/trusty/trusty.h
@@ -49,6 +49,7 @@
 				    struct notifier_block *n);
 const char *trusty_version_str_get(struct device *dev);
 u32 trusty_get_api_version(struct device *dev);
+bool trusty_get_panic_status(struct device *dev);
 
 struct ns_mem_page_info {
 	u64 paddr;