security: tlk_driver: support for secure ARM64 builds
Chris Johnson [Wed, 19 Feb 2014 18:10:12 +0000 (10:10 -0800)]
The only remaining warnings are in the non-compat path, which
will be removed, once we get the ote/lib change to use the new
structs.

Bug 1432005

Change-Id: Ie0bc95a76a8d5ace91ca0b0bf69ac15852007dc7
Signed-off-by: Chris Johnson <cwj@nvidia.com>
Reviewed-on: http://git-master/r/369403
Reviewed-by: Scott Long <scottl@nvidia.com>

arch/arm/mach-tegra/reset.c
security/tlk_driver/Makefile
security/tlk_driver/ote_asm.S [new file with mode: 0644]
security/tlk_driver/ote_comms.c
security/tlk_driver/ote_device.c
security/tlk_driver/ote_fs.c
security/tlk_driver/ote_irq.S [deleted file]
security/tlk_driver/ote_log.c
security/tlk_driver/ote_protocol.h

index d0743e6..e593db7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * arch/arm/mach-tegra/reset.c
  *
- * Copyright (C) 2011-2013, NVIDIA Corporation. All rights reserved.
+ * Copyright (C) 2011-2014, NVIDIA Corporation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -51,8 +51,10 @@ static void tegra_cpu_reset_handler_enable(void)
                tegra_cpu_reset_handler_size);
 
 #if defined(CONFIG_TEGRA_USE_SECURE_KERNEL)
+#ifndef CONFIG_ARM64
        tegra_generic_smc(0x82000001,
                TEGRA_RESET_HANDLER_BASE + tegra_cpu_reset_handler_offset, 0);
+#endif
 #else
        /* NOTE: This must be the one and only write to the EVP CPU reset
                 vector in the entire system. */
index 86a293d..9ab4168 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+# Copyright (c) 2013-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
 # 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 #
 
-plus_sec := $(call as-instr,.arch_extension sec,+sec)
-AFLAGS_ote_irq.o :=-Wa,-march=armv7-a$(plus_sec)
-CFLAGS_ote_comms.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
-CFLAGS_ote_fs.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
-
 tlk_driver-objs += ote_device.o
 tlk_driver-objs += ote_comms.o
 tlk_driver-objs += ote_fs.o
-tlk_driver-objs += ote_irq.o
+tlk_driver-objs += ote_asm.o
 tlk_driver-objs += ote_log.o
 
+ifeq ($(CONFIG_ARM),y)
+plus_sec := $(call as-instr,.arch_extension sec,+sec)
+AFLAGS_ote_asm.o :=-Wa,-march=armv7-a$(plus_sec)
+endif
+
 obj-$(CONFIG_TRUSTED_LITTLE_KERNEL) += tlk_driver.o
diff --git a/security/tlk_driver/ote_asm.S b/security/tlk_driver/ote_asm.S
new file mode 100644 (file)
index 0000000..2c5563b
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ *
+ * 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.
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+#ifdef CONFIG_ARM64
+
+ENTRY(tlk_irq_handler)
+       mov     x0, #0x5
+       movk    x0, #0x3200, lsl #16    // TE_SMC_NS_IRQ_DONE
+       smc     #0
+       ret
+ENDPROC(tlk_irq_handler)
+
+/* uint32_t tlk_generic_smc(uint32_t arg0, uint32_t arg1, uint32_t arg2) */
+ENTRY(_tlk_generic_smc)
+       smc     #0
+       ret
+ENDPROC(_tlk_generic_smc)
+
+       /* allows MAX_EXT_SMC_ARGS (r0-r11) to be passed in registers */
+
+/* uint32_t tlk_extended_smc(uint32_t *regs) */
+ENTRY(_tlk_extended_smc)
+       /*
+        * Allows MAX_EXT_SMC_ARGS (r0-r11) to be passed in registers
+        * (for aarch64, these are scratch, so no need to save them)
+        */
+       mov     x12, x0
+       ldp     x0, x1, [x12], #16
+       ldp     x2, x3, [x12], #16
+       ldp     x4, x5, [x12], #16
+       ldp     x6, x7, [x12], #16
+       ldp     x8, x9, [x12], #16
+       ldp     x10, x11, [x12], #16
+       smc     #0
+       ret
+ENDPROC(_tlk_extended_smc)
+
+#else
+
+ENTRY(tlk_irq_handler)
+       movw    r0, #0x5
+       movt    r0, #0x3200     @ TE_SMC_NS_IRQ_DONE
+       mov     r1, #0
+       mov     r2, #0
+       smc     #0
+ENDPROC(tlk_irq_handler)
+
+ENTRY(_tlk_generic_smc)
+       smc     #0
+       mov     pc, lr
+ENDPROC(_tlk_generic_smc)
+
+ENTRY(_tlk_extended_smc)
+       stmfd   sp!, {r4-r12}   @ save reg state
+       mov     r12, r0         @ reg ptr to r12
+       ldmia   r12, {r0-r11}   @ load arg regs
+       smc     #0
+       ldmfd   sp!, {r4-r12}   @ restore saved regs
+ENDPROC(_tlk_extended_smc)
+
+#endif
index 46d7fc6..1f380b7 100644 (file)
@@ -237,29 +237,7 @@ static inline void switch_cpumask_to_cpu0(void) {};
 static inline void restore_cpumask(void) {};
 #endif
 
-static 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;
-
-       asm volatile(
-               __asmeq("%0", "r0")
-               __asmeq("%1", "r0")
-               __asmeq("%2", "r1")
-               __asmeq("%3", "r2")
-#ifdef REQUIRES_SEC
-               ".arch_extension sec                            \n"
-#endif
-               "smc    #0              @ switch to secure world\n"
-               : "=r" (r0)
-               : "r" (r0), "r" (r1), "r" (r2)
-       );
-
-       return r0;
-}
-
-uint32_t tlk_generic_smc(uint32_t arg0, uint32_t arg1, uint32_t arg2)
+uint32_t tlk_generic_smc(uint32_t arg0, uintptr_t arg1, uintptr_t arg2)
 {
        uint32_t retval;
 
@@ -274,29 +252,7 @@ uint32_t tlk_generic_smc(uint32_t arg0, uint32_t arg1, uint32_t arg2)
        return retval;
 }
 
-static uint32_t _tlk_extended_smc(uint32_t *regs)
-{
-       register uint32_t r0 asm("r0") = (uint32_t)regs;
-
-       /* allows MAX_EXT_SMC_ARGS (r0-r11) to be passed in registers */
-       asm volatile(
-               __asmeq("%0", "r0")
-               "stmfd  sp!, {r4-r12}   @ save reg state\n"
-               "mov    r12, r0         @ reg ptr to r12\n"
-               "ldmia  r12, {r0-r11}   @ load arg regs\n"
-#ifdef REQUIRES_SEC
-               ".arch_extension sec\n"
-#endif
-               "smc    #0              @ switch to secure world\n"
-               "ldmfd  sp!, {r4-r12}   @ restore saved regs\n"
-               : "=r" (r0)
-               : "r" (r0)
-       );
-
-       return r0;
-}
-
-uint32_t tlk_extended_smc(uint32_t *regs)
+uint32_t tlk_extended_smc(uintptr_t *regs)
 {
        uint32_t retval;
 
@@ -373,7 +329,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, (uint32_t)vpr_base,
+       retval = tlk_generic_smc(TE_SMC_PROGRAM_VPR, (uintptr_t)vpr_base,
                        vpr_size);
 
        mutex_unlock(&smc_lock);
@@ -535,7 +491,7 @@ void te_launch_operation_compat(struct te_launchop_compat *cmd,
 static int __init tlk_register_irq_handler(void)
 {
        tlk_generic_smc(TE_SMC_REGISTER_IRQ_HANDLER,
-               (unsigned int)tlk_irq_handler, 0);
+               (uintptr_t)tlk_irq_handler, 0);
        return 0;
 }
 
index 170f46c..214e511 100644 (file)
@@ -68,7 +68,7 @@ static int te_create_free_cmd_list(struct tlk_device *dev)
                                        (dev->req_param_buf + PAGE_SIZE);
 
                tlk_generic_smc(TE_SMC_REGISTER_REQ_BUF,
-                               (uint32_t)dev->req_addr, (2 * PAGE_SIZE));
+                               (uintptr_t)dev->req_addr, (2 * PAGE_SIZE));
        } else {
                dev->req_addr = dma_alloc_coherent(NULL, PAGE_SIZE,
                                        &dev->req_addr_phys, GFP_KERNEL);
@@ -724,8 +724,9 @@ static long tlk_device_ioctl(struct file *file, unsigned int ioctl_num,
                break;
 
        default:
-               pr_err("%s: Invalid IOCTL (0x%x) id 0x%x max 0x%x\n", __func__,
-                       ioctl_num, _IOC_NR(ioctl_num), TE_IOCTL_MAX_NR);
+               pr_err("%s: Invalid IOCTL (0x%x) id 0x%x max 0x%lx\n",
+                       __func__, ioctl_num, _IOC_NR(ioctl_num),
+                       (unsigned long)TE_IOCTL_MAX_NR);
                err = -EINVAL;
                break;
        }
index d398beb..d305247 100644 (file)
@@ -259,7 +259,7 @@ void tlk_ss_op(uint32_t size)
 static int tlk_fs_register_handlers(void)
 {
        struct te_file_req_shmem *shmem_ptr;
-       uint32_t smc_args[MAX_EXT_SMC_ARGS];
+       uintptr_t smc_args[MAX_EXT_SMC_ARGS];
        dma_addr_t shmem_dma;
 
        shmem_ptr = dma_alloc_coherent(NULL, sizeof(struct te_file_req_shmem),
@@ -276,11 +276,11 @@ static int tlk_fs_register_handlers(void)
        init_completion(&req_complete);
 
        smc_args[0] = TE_SMC_REGISTER_FS_HANDLERS;
-       smc_args[1] = (uint32_t)tlk_fread;
-       smc_args[2] = (uint32_t)tlk_fwrite;
-       smc_args[3] = (uint32_t)tlk_fdelete;
-       smc_args[4] = (uint32_t)shmem_ptr->file_name;
-       smc_args[5] = (uint32_t)shmem_ptr->file_data;
+       smc_args[1] = (uintptr_t)tlk_fread;
+       smc_args[2] = (uintptr_t)tlk_fwrite;
+       smc_args[3] = (uintptr_t)tlk_fdelete;
+       smc_args[4] = (uintptr_t)shmem_ptr->file_name;
+       smc_args[5] = (uintptr_t)shmem_ptr->file_data;
 
        tlk_extended_smc(smc_args);
 
@@ -303,7 +303,7 @@ static int __init tlk_ss_init(void)
        }
 
        tlk_generic_smc(TE_SMC_SS_REGISTER_HANDLER,
-                       (uint32_t)tlk_ss_op, (uint32_t)ss_op_shmem);
+                       (uintptr_t)tlk_ss_op, (uintptr_t)ss_op_shmem);
 
        return 0;
 }
diff --git a/security/tlk_driver/ote_irq.S b/security/tlk_driver/ote_irq.S
deleted file mode 100644 (file)
index 3a4ca68..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2013 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.
- *
- * 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.
- */
-
-#include <linux/linkage.h>
-#include <linux/init.h>
-
-ENTRY(tlk_irq_handler)
-       movw    r0, #0x5
-       movt    r0, #0x3200     @ TE_SMC_NS_IRQ_DONE
-       mov     r1, #0
-       mov     r2, #0
-       smc     #0
-ENDPROC(tlk_irq_handler)
index 0cd4412..0a1fbd7 100644 (file)
@@ -172,14 +172,14 @@ void ote_print_logs(void) {}
  */
 static int __init ote_logger_init(void)
 {
-       uint32_t smc_args[MAX_EXT_SMC_ARGS];
+       uintptr_t smc_args[MAX_EXT_SMC_ARGS];
 
 #if defined(CONFIG_OTE_ENABLE_LOGGER)
        if (circ_buf_init(&cb) != 0)
                return -1;
 
        smc_args[0] = TE_SMC_INIT_LOGGER;
-       smc_args[1] = (uint32_t)cb;
+       smc_args[1] = (uintptr_t)cb;
        tlk_generic_smc(smc_args[0], smc_args[1], 0);
 
        ote_logging_enabled = 1;
index 66228e4..fd18183 100644 (file)
 #define MAX_EXT_SMC_ARGS       12
 
 extern struct mutex smc_lock;
+extern struct tlk_device tlk_dev;
 
-uint32_t tlk_generic_smc(uint32_t arg0, uint32_t arg1, uint32_t arg2);
-uint32_t tlk_extended_smc(uint32_t *args);
+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);
+uint32_t _tlk_extended_smc(uintptr_t *args);
+uint32_t tlk_extended_smc(uintptr_t *args);
 void tlk_irq_handler(void);
 
 struct tlk_device {