clear-pkgs-linux-iot-lts2018/0922-trusty-Update-Trusty-t...

153 lines
4.5 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Zhang, Qi" <qi1.zhang@intel.com>
Date: Tue, 12 Dec 2017 15:16:21 +0800
Subject: [PATCH] trusty: Update Trusty timer solution
1. Add new customized SMC calls
2. Move send pending interrupt implementation to trusty-irq.c
3. Invokes new added standard SMC call to inject timer interrupt to
secure side
Change-Id: I6c9a94c8ff50f42b58abd2e2b2dd5efd26c126e2
Signed-off-by: Zhong,Fangjian <fangjian.zhong@intel.com>
---
drivers/trusty/trusty-irq.c | 9 +++++++++
drivers/trusty/trusty-timer.c | 38 +++++++++++++++++++++++++++++++++--
include/linux/trusty/trusty.h | 11 ----------
3 files changed, 45 insertions(+), 13 deletions(-)
diff --git a/drivers/trusty/trusty-irq.c b/drivers/trusty/trusty-irq.c
index 868a31c01f19..04df531bf9d0 100644
--- a/drivers/trusty/trusty-irq.c
+++ b/drivers/trusty/trusty-irq.c
@@ -59,6 +59,15 @@ struct trusty_irq_state {
static enum cpuhp_state trusty_irq_online;
+#define TRUSTY_VMCALL_PENDING_INTR 0x74727505
+static inline void set_pending_intr_to_lk(uint8_t vector)
+{
+ __asm__ __volatile__(
+ "vmcall"
+ ::"a"(TRUSTY_VMCALL_PENDING_INTR), "b"(vector)
+ );
+}
+
static void trusty_irq_enable_pending_irqs(struct trusty_irq_state *is,
struct trusty_irq_irqset *irqset,
bool percpu)
diff --git a/drivers/trusty/trusty-timer.c b/drivers/trusty/trusty-timer.c
index e88dc5f4cdf8..43e43265c3c6 100644
--- a/drivers/trusty/trusty-timer.c
+++ b/drivers/trusty/trusty-timer.c
@@ -24,6 +24,7 @@
struct trusty_timer {
struct sec_timer_state *sts;
struct hrtimer tm;
+ struct work_struct work;
};
struct trusty_timer_dev_state {
@@ -32,16 +33,33 @@ struct trusty_timer_dev_state {
struct device *trusty_dev;
struct notifier_block call_notifier;
struct trusty_timer timer;
+ struct workqueue_struct *workqueue;
};
+/* Max entity defined as SMC_NUM_ENTITIES(64) */
+#define SMC_ENTITY_SMC_X86 63 /* Used for customized SMC calls */
+
+#define SMC_SC_LK_TIMER SMC_STDCALL_NR(SMC_ENTITY_SMC_X86, 0)
+
+static void timer_work_func(struct work_struct *work)
+{
+ int ret;
+ struct trusty_timer_dev_state *s;
+
+ s = container_of(work, struct trusty_timer_dev_state, timer.work);
+
+ ret = trusty_std_call32(s->trusty_dev, SMC_SC_LK_TIMER, 0, 0, 0);
+ if (ret != 0)
+ dev_err(s->dev, "%s failed %d\n", __func__, ret);
+}
+
static enum hrtimer_restart trusty_timer_cb(struct hrtimer *tm)
{
struct trusty_timer_dev_state *s;
s = container_of(tm, struct trusty_timer_dev_state, timer.tm);
- set_pending_intr_to_lk(0x31);
- trusty_enqueue_nop(s->trusty_dev, NULL);
+ queue_work(s->workqueue, &s->timer.work);
return HRTIMER_NORESTART;
}
@@ -114,6 +132,12 @@ static int trusty_timer_probe(struct platform_device *pdev)
sizeof(*tt->sts));
WARN_ON(!tt->sts);
+ s->workqueue = alloc_workqueue("trusty-timer-wq", WQ_CPU_INTENSIVE, 0);
+ if (!s->workqueue) {
+ ret = -ENODEV;
+ dev_err(&pdev->dev, "Failed to allocate work queue\n");
+ goto err_allocate_work_queue;
+ }
/* register notifier */
s->call_notifier.notifier_call = trusty_timer_call_notify;
@@ -124,10 +148,18 @@ static int trusty_timer_probe(struct platform_device *pdev)
return ret;
}
+ INIT_WORK(&s->timer.work, timer_work_func);
+
dev_info(s->dev, "initialized\n");
return 0;
+err_register_call_notifier:
+ destroy_workqueue(s->workqueue);
+err_allocate_work_queue:
+ kfree(s);
+ return ret;
+
}
static int trusty_timer_remove(struct platform_device *pdev)
@@ -144,6 +176,8 @@ static int trusty_timer_remove(struct platform_device *pdev)
tt = &s->timer;
hrtimer_cancel(&tt->tm);
+ flush_work(&tt->work);
+ destroy_workqueue(s->workqueue);
/* free state */
kfree(s);
return 0;
diff --git a/include/linux/trusty/trusty.h b/include/linux/trusty/trusty.h
index 1e9b4559d1b6..3189c7ec967c 100644
--- a/include/linux/trusty/trusty.h
+++ b/include/linux/trusty/trusty.h
@@ -85,17 +85,6 @@ static inline void trusty_nop_init(struct trusty_nop *nop,
void trusty_enqueue_nop(struct device *dev, struct trusty_nop *nop);
void trusty_dequeue_nop(struct device *dev, struct trusty_nop *nop);
-#define TRUSTY_VMCALL_PENDING_INTR 0x74727505
-static inline void set_pending_intr_to_lk(uint8_t vector)
-{
-#ifdef CONFIG_X86
- __asm__ __volatile__(
- "vmcall"
- ::"a"(TRUSTY_VMCALL_PENDING_INTR), "b"(vector)
- );
-#endif
-}
-
void trusty_update_wall_info(struct device *dev, void *va, size_t sz);
void *trusty_wall_base(struct device *dev);
void *trusty_wall_per_cpu_item_ptr(struct device *dev, unsigned int cpu,
--
https://clearlinux.org