2019-03-29 14:12:17 +08:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
2019-01-23 17:39:12 +08:00
|
|
|
From: "Yan, Shaoou" <shaopu.yan@intel.com>
|
|
|
|
Date: Fri, 9 Dec 2016 05:32:20 +0000
|
2019-03-29 14:12:17 +08:00
|
|
|
Subject: [PATCH] trusty-log: Add vmm panic notifier for vmm deadloop dumping
|
2019-01-23 17:39:12 +08:00
|
|
|
|
|
|
|
register a new vmcall TRUSTY_VMCALL_DUMP_INIT.
|
|
|
|
|
|
|
|
Change-Id: Icee169358f30c64da44894dc5816ce5f3020fc70
|
|
|
|
Tracked-On: OAM-40748
|
|
|
|
Signed-off-by: syan10 <shaopu.yan@intel.com>
|
|
|
|
Reviewed-by: Ilkka Koskinen <ilkka.koskinen@intel.com>
|
|
|
|
---
|
2019-03-29 14:12:17 +08:00
|
|
|
drivers/trusty/trusty-log.c | 107 ++++++++++++++++++++++++++++++++++++
|
|
|
|
drivers/trusty/trusty-log.h | 22 ++++++++
|
2019-01-23 17:39:12 +08:00
|
|
|
2 files changed, 129 insertions(+)
|
|
|
|
|
|
|
|
diff --git a/drivers/trusty/trusty-log.c b/drivers/trusty/trusty-log.c
|
2020-05-05 09:02:46 +08:00
|
|
|
index 112287cd4..a066481c4 100644
|
2019-01-23 17:39:12 +08:00
|
|
|
--- a/drivers/trusty/trusty-log.c
|
|
|
|
+++ b/drivers/trusty/trusty-log.c
|
|
|
|
@@ -26,6 +26,8 @@
|
|
|
|
#define TRUSTY_LOG_SIZE (PAGE_SIZE * 2)
|
|
|
|
#define TRUSTY_LINE_BUFFER_SIZE 256
|
|
|
|
|
|
|
|
+static uint64_t g_vmm_debug_buf;
|
|
|
|
+
|
|
|
|
struct trusty_log_state {
|
|
|
|
struct device *dev;
|
|
|
|
struct device *trusty_dev;
|
|
|
|
@@ -135,6 +137,72 @@ static int trusty_log_panic_notify(struct notifier_block *nb,
|
|
|
|
return NOTIFY_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static void trusty_vmm_dump_header(struct deadloop_dump *dump)
|
|
|
|
+{
|
|
|
|
+ struct dump_header *header;
|
|
|
|
+
|
|
|
|
+ if (!dump)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ header = &(dump->header);
|
|
|
|
+ pr_info("VMM version = %s\n", header->vmm_version);
|
|
|
|
+ pr_info("Signature = %s\n", header->signature);
|
|
|
|
+ pr_info("Error_info = %s\n", header->error_info);
|
|
|
|
+ pr_info("Cpuid = %d\n", header->cpuid);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void trusty_vmm_dump_data(struct deadloop_dump *dump)
|
|
|
|
+{
|
|
|
|
+ struct dump_data *dump_data;
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ if (!dump)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ dump_data = &(dump->data);
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < dump_data->length; i++)
|
|
|
|
+ pr_info("%c", dump_data->data[i]);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int trusty_vmm_panic_notify(struct notifier_block *nb,
|
|
|
|
+ unsigned long action, void *data)
|
|
|
|
+{
|
|
|
|
+ struct deadloop_dump *dump_info;
|
|
|
|
+
|
|
|
|
+ if (g_vmm_debug_buf) {
|
|
|
|
+ dump_info = (struct deadloop_dump *)g_vmm_debug_buf;
|
|
|
|
+
|
|
|
|
+ if (dump_info->is_valid) {
|
|
|
|
+ pr_info("trusty-vmm panic start!\n");
|
|
|
|
+ trusty_vmm_dump_header(dump_info);
|
|
|
|
+ trusty_vmm_dump_data(dump_info);
|
|
|
|
+ pr_info("trusty-vmm panic dump end!\n");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return NOTIFY_OK;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static struct notifier_block trusty_vmm_panic_nb = {
|
|
|
|
+ .notifier_call = trusty_vmm_panic_notify,
|
|
|
|
+ .priority = 0,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+#define TRUSTY_VMCALL_DUMP_INIT 0x74727507
|
|
|
|
+static int trusty_vmm_dump_init(void *gva)
|
|
|
|
+{
|
|
|
|
+ int ret = -1;
|
|
|
|
+
|
|
|
|
+ __asm__ __volatile__(
|
|
|
|
+ "vmcall"
|
|
|
|
+ : "=a"(ret)
|
|
|
|
+ : "a"(TRUSTY_VMCALL_DUMP_INIT), "D"(gva)
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static bool trusty_supports_logging(struct device *device)
|
|
|
|
{
|
|
|
|
int result;
|
|
|
|
@@ -164,6 +232,7 @@ static int trusty_log_probe(struct platform_device *pdev)
|
|
|
|
struct trusty_log_state *s;
|
|
|
|
int result;
|
|
|
|
phys_addr_t pa;
|
|
|
|
+ struct deadloop_dump *dump;
|
|
|
|
|
|
|
|
dev_dbg(&pdev->dev, "%s\n", __func__);
|
|
|
|
if (!trusty_supports_logging(pdev->dev.parent)) {
|
|
|
|
@@ -216,10 +285,45 @@ static int trusty_log_probe(struct platform_device *pdev)
|
|
|
|
"failed to register panic notifier\n");
|
|
|
|
goto error_panic_notifier;
|
|
|
|
}
|
|
|
|
+
|
|
|
|
+ /* allocate debug buffer for vmm panic dump */
|
|
|
|
+ g_vmm_debug_buf = get_zeroed_page(GFP_KERNEL);
|
|
|
|
+ if (!g_vmm_debug_buf) {
|
|
|
|
+ result = -ENOMEM;
|
|
|
|
+ goto error_alloc_vmm;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ dump = (struct deadloop_dump *)g_vmm_debug_buf;
|
|
|
|
+ dump->version_of_this_struct = VMM_DUMP_VERSION;
|
|
|
|
+ dump->size_of_this_struct = sizeof(struct deadloop_dump);
|
|
|
|
+ dump->is_valid = false;
|
|
|
|
+
|
|
|
|
+ /* shared the buffer to vmm by VMCALL */
|
|
|
|
+ result = trusty_vmm_dump_init(dump);
|
|
|
|
+ if (result < 0) {
|
|
|
|
+ dev_err(&pdev->dev,
|
|
|
|
+ "failed to share the dump buffer to VMM\n");
|
|
|
|
+ goto error_vmm_panic_notifier;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* register the panic notifier for vmm */
|
|
|
|
+ result = atomic_notifier_chain_register(&panic_notifier_list,
|
|
|
|
+ &trusty_vmm_panic_nb);
|
|
|
|
+ if (result < 0) {
|
|
|
|
+ dev_err(&pdev->dev,
|
|
|
|
+ "failed to register vmm panic notifier\n");
|
|
|
|
+ goto error_vmm_panic_notifier;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
platform_set_drvdata(pdev, s);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
+error_vmm_panic_notifier:
|
|
|
|
+ free_page(g_vmm_debug_buf);
|
|
|
|
+error_alloc_vmm:
|
|
|
|
+ atomic_notifier_chain_unregister(&panic_notifier_list,
|
|
|
|
+ &s->panic_notifier);
|
|
|
|
error_panic_notifier:
|
|
|
|
trusty_call_notifier_unregister(s->trusty_dev, &s->call_notifier);
|
|
|
|
error_call_notifier:
|
2019-03-29 14:12:17 +08:00
|
|
|
@@ -241,6 +345,8 @@ static int trusty_log_remove(struct platform_device *pdev)
|
|
|
|
|
2019-01-23 17:39:12 +08:00
|
|
|
dev_dbg(&pdev->dev, "%s\n", __func__);
|
|
|
|
|
|
|
|
+ atomic_notifier_chain_unregister(&panic_notifier_list,
|
2019-03-29 14:12:17 +08:00
|
|
|
+ &trusty_vmm_panic_nb);
|
|
|
|
atomic_notifier_chain_unregister(&panic_notifier_list,
|
2019-01-23 17:39:12 +08:00
|
|
|
&s->panic_notifier);
|
|
|
|
trusty_call_notifier_unregister(s->trusty_dev, &s->call_notifier);
|
|
|
|
@@ -253,6 +359,7 @@ static int trusty_log_remove(struct platform_device *pdev)
|
|
|
|
}
|
|
|
|
__free_pages(s->log_pages, get_order(TRUSTY_LOG_SIZE));
|
|
|
|
kfree(s);
|
|
|
|
+ free_page(g_vmm_debug_buf);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
diff --git a/drivers/trusty/trusty-log.h b/drivers/trusty/trusty-log.h
|
2020-05-05 09:02:46 +08:00
|
|
|
index 09f60213e..587bc7aaa 100644
|
2019-01-23 17:39:12 +08:00
|
|
|
--- a/drivers/trusty/trusty-log.h
|
|
|
|
+++ b/drivers/trusty/trusty-log.h
|
|
|
|
@@ -18,5 +18,27 @@ struct log_rb {
|
|
|
|
|
|
|
|
#define TRUSTY_LOG_API_VERSION 1
|
|
|
|
|
|
|
|
+#define VMM_DUMP_VERSION 1
|
|
|
|
+
|
|
|
|
+struct dump_data {
|
|
|
|
+ uint32_t length;
|
|
|
|
+ uint8_t data[0];
|
|
|
|
+} __packed;
|
|
|
|
+
|
|
|
|
+struct dump_header {
|
|
|
|
+ uint8_t vmm_version[64]; /* version of the vmm */
|
|
|
|
+ uint8_t signature[16]; /* signature for the dump structure */
|
|
|
|
+ uint8_t error_info[32]; /* filename:linenum */
|
|
|
|
+ uint16_t cpuid;
|
|
|
|
+} __packed;
|
|
|
|
+
|
|
|
|
+struct deadloop_dump {
|
|
|
|
+ uint16_t size_of_this_struct;
|
|
|
|
+ uint16_t version_of_this_struct;
|
|
|
|
+ uint32_t is_valid;
|
|
|
|
+ struct dump_header header;
|
|
|
|
+ struct dump_data data;
|
|
|
|
+} __packed;
|
|
|
|
+
|
|
|
|
#endif
|
|
|
|
|
|
|
|
--
|
2019-04-08 18:08:36 +08:00
|
|
|
https://clearlinux.org
|
2019-01-23 17:39:12 +08:00
|
|
|
|