[FOSS_TLK]security: tlk_driver: add FIQ glue
Varun Wadekar [Mon, 4 Aug 2014 05:53:13 +0000 (10:53 +0530)]
Add FIQ glue for ARM64 cpus and register a handler with the secure world (TLK).
TLK handles the FIQ interrupts and calls our handler after it is done saving
the context. We then get the FIQ context via a SMC call and pass it to the
FIQ handler registered by the kernel (using fiq_glue_register_handler).

The FIQ debugger calls fiq_glue_register_handler() to register its handler
which we in turn call whenever a FIQ fires. The glue saves all the registers,
elr/spsr values and SP, which is then used by tlk_fiq_handler() to pass on to
the actual handler.

Change-Id: I6711c25892284dd82c9042479381eca5f707c9b4
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Reviewed-on: http://git-master/r/755001
Reviewed-by: Automatic_Commit_Validation_User

security/tlk_driver/Kconfig
security/tlk_driver/Makefile
security/tlk_driver/ote_asm.S
security/tlk_driver/ote_fiq_glue.c [new file with mode: 0644]
security/tlk_driver/ote_protocol.h

index b87d6d8..d43c17e 100644 (file)
@@ -1,5 +1,14 @@
+config FIQ
+       bool
+
+config FIQ_GLUE
+       bool
+
 config TRUSTED_LITTLE_KERNEL
        bool "Enable Open Trusted Execution driver"
+       select TEGRA_USE_SECURE_KERNEL
+       select FIQ
+       select FIQ_GLUE
        help
          This option adds kernel support for communication with the
          Trusted LK secure OS monitor/runtime support.
index 9ab4168..05e53d2 100644 (file)
@@ -28,3 +28,4 @@ AFLAGS_ote_asm.o :=-Wa,-march=armv7-a$(plus_sec)
 endif
 
 obj-$(CONFIG_TRUSTED_LITTLE_KERNEL) += tlk_driver.o
+obj-$(CONFIG_ARM64) += ote_fiq_glue.o
index 8353258..684f8ea 100644 (file)
@@ -11,6 +11,8 @@
  * more details.
  */
 
+#include <asm/asm-offsets.h>
+#include <asm/ptrace.h>
 #include <linux/linkage.h>
 #include <linux/init.h>
 
@@ -41,6 +43,35 @@ ENTRY(_tlk_extended_smc)
        ret
 ENDPROC(_tlk_extended_smc)
 
+ENTRY(tlk_fiq_glue_aarch64)
+       sub     sp, sp, #S_FRAME_SIZE - S_LR
+       stp     x0, x1, [sp, #-16]!
+       stp     x2, x3, [sp, #-16]!
+       stp     x4, x5, [sp, #-16]!
+       stp     x6, x7, [sp, #-16]!
+       stp     x8, x9, [sp, #-16]!
+       stp     x10, x11, [sp, #-16]!
+       stp     x12, x13, [sp, #-16]!
+       stp     x14, x15, [sp, #-16]!
+       stp     x16, x17, [sp, #-16]!
+       stp     x18, x19, [sp, #-16]!
+       stp     x20, x21, [sp, #-16]!
+       stp     x22, x23, [sp, #-16]!
+       stp     x24, x25, [sp, #-16]!
+       stp     x26, x27, [sp, #-16]!
+       stp     x28, x29, [sp, #-16]!
+       ldr     x0, =0x82000006         /* get FIQ regs */
+       smc     #0
+       stp     x0, x1, [sp, #S_PC]     /* original pc, cpsr */
+       tst     x1, PSR_MODE_MASK
+       csel    x2, x2, x3, eq          /* sp el0, sp el1 */
+       stp     x30, x2, [sp, #S_LR]    /* lr, original sp */
+       mov     x0, sp
+       mov     x1, x3
+       bl      tlk_fiq_handler         /* handle FIQ exception */
+       b       .
+ENDPROC(tlk_fiq_glue_aarch64)
+
 #else
 
 ENTRY(_tlk_generic_smc)
diff --git a/security/tlk_driver/ote_fiq_glue.c b/security/tlk_driver/ote_fiq_glue.c
new file mode 100644 (file)
index 0000000..69466af
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2014 NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/fiq_glue.h>
+
+#include "ote_protocol.h"
+
+static struct fiq_glue_handler *current_handler;
+
+void tlk_fiq_handler(struct pt_regs *regs, void *svc_sp)
+{
+       current_handler->fiq(current_handler, regs, svc_sp);
+}
+
+int fiq_glue_register_handler(struct fiq_glue_handler *handler)
+{
+       int ret;
+
+       if (!handler || !handler->fiq)
+               return -EINVAL;
+
+       if (current_handler)
+               return -EBUSY;
+
+       current_handler = handler;
+
+       ret = tlk_generic_smc(TE_SMC_REGISTER_FIQ_GLUE,
+                       (uintptr_t)tlk_fiq_glue_aarch64, 0);
+       if (ret)
+               pr_err("%s: failed to register FIQ glue\n", __func__);
+
+       return ret;
+}
index 864bf8f..75520ce 100644 (file)
@@ -47,6 +47,7 @@
 
 extern struct mutex smc_lock;
 extern struct tlk_device tlk_dev;
+extern void tlk_fiq_glue_aarch64(void);
 
 uint32_t _tlk_generic_smc(uint32_t arg0, uintptr_t arg1, uintptr_t arg2);
 uint32_t tlk_generic_smc(uint32_t arg0, uintptr_t arg1, uintptr_t arg2);
@@ -111,6 +112,7 @@ enum {
 
        /* SIP (SOC specific) calls.  */
        TE_SMC_PROGRAM_VPR              = 0x82000003,
+       TE_SMC_REGISTER_FIQ_GLUE        = 0x82000005,
 };
 
 enum {