summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorVarun Wadekar <vwadekar@nvidia.com>2013-11-19 12:15:20 +0530
committerVarun Wadekar <vwadekar@nvidia.com>2013-12-03 20:04:43 -0800
commit3f2221cc49a7d8084a78e2b8ae9110d8f9d39fbc (patch)
tree06a5ac42cefe344bebe4e1ca4e3b9a614cd501c3 /security
parent159d4bdb5bb5a3aefa4f77442b232c812584267d (diff)
security: tlk_driver: use ARM's DEN0028 v0.9 spec to define SMCs
Use Trusted Application calls (0x30000000-0x31000000) and Trusted OS calls (0x32000000-0x3F000000) from the spec. Trusted App calls are used to Open/Close session and launch a new operation. Trusted OS calls are used to talk with the TLK for IRQ handling, FS handling, VPR settings, logger init, etc. SMCs that are interrupted return a special status code to the NS world. Modify our tlk_driver to look for that status and send a restart SMC (value = 60 << 24) when received. Also removed save/restore of registers across SMC calls. This restore buffer was stored in r3 and expected to persist across the SMC. This saving/restoring isn't necessary and adds undesired overhead. Change-Id: I0b59604dfe2c4e3f4673797d756422cd7d5b64a3 Signed-off-by: Scott Long <scottl@nvidia.com> Signed-off-by: Varun Wadekar <vwadekar@nvidia.com> Reviewed-on: http://git-master/r/332791 GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'security')
-rw-r--r--security/tlk_driver/ote_comms.c15
-rw-r--r--security/tlk_driver/ote_irq.S6
-rw-r--r--security/tlk_driver/ote_protocol.h29
3 files changed, 25 insertions, 25 deletions
diff --git a/security/tlk_driver/ote_comms.c b/security/tlk_driver/ote_comms.c
index f79753aaa85a..9355d07dbb62 100644
--- a/security/tlk_driver/ote_comms.c
+++ b/security/tlk_driver/ote_comms.c
@@ -32,8 +32,6 @@
bool verbose_smc;
core_param(verbose_smc, verbose_smc, bool, 0644);
-static unsigned long saved_regs[16];
-
#define SET_RESULT(req, r, ro) { req->result = r; req->result_origin = ro; }
static int te_pin_user_pages(void *buffer, size_t size,
@@ -220,27 +218,18 @@ uint32_t tlk_generic_smc(uint32_t arg0, uint32_t arg1, uint32_t arg2)
register uint32_t r0 asm("r0") = arg0;
register uint32_t r1 asm("r1") = arg1;
register uint32_t r2 asm("r2") = arg2;
- register uint32_t r3 asm("r3") =
- (arg0 == TE_SMC_FS_OP_DONE) ? 0 : (uint32_t)saved_regs;
asm volatile(
__asmeq("%0", "r0")
__asmeq("%1", "r0")
__asmeq("%2", "r1")
__asmeq("%3", "r2")
- __asmeq("%4", "r3")
- "cmp r3, #0 \n"
- "beq avoid_save_regs \n"
- "stmia r3, {r4-r12} @ save reg state \n"
- "avoid_save_regs: \n"
#ifdef REQUIRES_SEC
".arch_extension sec \n"
#endif
"smc #0 @ switch to secure world\n"
- __asmeq("%4", "r3")
- "ldmia r3, {r4-r12} @ restore saved regs \n"
: "=r" (r0)
- : "r" (r0), "r" (r1), "r" (r2), "r" (r3)
+ : "r" (r0), "r" (r1), "r" (r2)
);
return r0;
@@ -306,7 +295,7 @@ int te_set_vpr_params(void *vpr_base, size_t vpr_size)
/* Share the same lock used when request is send from user side */
mutex_lock(&smc_lock);
- retval = TLK_GENERIC_SMC(TE_SMC_PROGRAM_VPR, vpr_base, vpr_size);
+ retval = TLK_GENERIC_SMC(TE_SMC_PROGRAM_VPR, (uint32_t)vpr_base, vpr_size);
mutex_unlock(&smc_lock);
diff --git a/security/tlk_driver/ote_irq.S b/security/tlk_driver/ote_irq.S
index 6305e0799440..3a4ca6875801 100644
--- a/security/tlk_driver/ote_irq.S
+++ b/security/tlk_driver/ote_irq.S
@@ -15,7 +15,9 @@
#include <linux/init.h>
ENTRY(tlk_irq_handler)
- movw r0, #0x1FF1
- movt r0, #0xFFFF @ TE_SMC_NS_IRQ_DONE
+ movw r0, #0x5
+ movt r0, #0x3200 @ TE_SMC_NS_IRQ_DONE
+ mov r1, #0
+ mov r2, #0
smc #0
ENDPROC(tlk_irq_handler)
diff --git a/security/tlk_driver/ote_protocol.h b/security/tlk_driver/ote_protocol.h
index f5d9639c3262..74214517bba1 100644
--- a/security/tlk_driver/ote_protocol.h
+++ b/security/tlk_driver/ote_protocol.h
@@ -65,6 +65,9 @@ TLK_GENERIC_SMC(uint32_t arg0, uint32_t arg1, uint32_t arg2)
switch_cpumask_to_cpu0();
retval = tlk_generic_smc(arg0, arg1, arg2);
+ while (retval == 0xFFFFFFFD) {
+ retval = tlk_generic_smc((60 << 24), 0, 0);
+ }
restore_cpumask();
return retval;
@@ -77,6 +80,9 @@ TLK_EXTENDED_SMC(uint32_t *args)
switch_cpumask_to_cpu0();
retval = tlk_extended_smc(args);
+ while (retval == 0xFFFFFFFD) {
+ retval = tlk_generic_smc((60 << 24), 0, 0);
+ }
restore_cpumask();
return retval;
@@ -116,16 +122,19 @@ struct tlk_context {
};
enum {
- TE_SMC_OPEN_SESSION = 0xFFFF1004,
- TE_SMC_CLOSE_SESSION = 0xFFFF1005,
- TE_SMC_LAUNCH_OPERATION = 0xFFFF1000,
- TE_SMC_REGISTER_IRQ_HANDLER = 0xFFFF1FF0,
- TE_SMC_NS_IRQ_DONE = 0xFFFF1FF1,
- TE_SMC_REGISTER_FS_HANDLERS = 0xFFFF1FF2,
- TE_SMC_REGISTER_REQ_BUF = 0xFFFF1FF3,
- TE_SMC_PROGRAM_VPR = 0xFFFF1FF5,
- TE_SMC_FS_OP_DONE = 0xFFFF1FFF,
- TE_SMC_INIT_LOGGER = 0xFFFF1FF4,
+ /* Trusted Application Calls */
+ TE_SMC_OPEN_SESSION = 0x30000001,
+ TE_SMC_CLOSE_SESSION = 0x30000002,
+ TE_SMC_LAUNCH_OPERATION = 0x30000003,
+
+ /* Trusted OS calls */
+ TE_SMC_REGISTER_FS_HANDLERS = 0x32000001,
+ TE_SMC_REGISTER_REQ_BUF = 0x32000002,
+ TE_SMC_PROGRAM_VPR = 0x32000003,
+ TE_SMC_REGISTER_IRQ_HANDLER = 0x32000004,
+ TE_SMC_NS_IRQ_DONE = 0x32000005,
+ TE_SMC_FS_OP_DONE = 0x32000006,
+ TE_SMC_INIT_LOGGER = 0x32000007,
};