diff --git a/drivers/Kconfig b/drivers/Kconfig index a73d713f7df6..de482fc9d7dd 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -146,8 +146,6 @@ source "drivers/virt/Kconfig" source "drivers/devfreq/Kconfig" -source "drivers/gud/Kconfig" - source "drivers/coresight/Kconfig" endmenu diff --git a/drivers/Makefile b/drivers/Makefile index e239a5dc3a03..571f55b64c19 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -138,7 +138,4 @@ obj-$(CONFIG_HYPERV) += hv/ obj-$(CONFIG_PM_DEVFREQ) += devfreq/ -#MobiCore -obj-$(CONFIG_MOBICORE_SUPPORT) += gud/ - obj-$(CONFIG_CORESIGHT) += coresight/ diff --git a/drivers/gud/Kconfig b/drivers/gud/Kconfig deleted file mode 100644 index 3a241b765162..000000000000 --- a/drivers/gud/Kconfig +++ /dev/null @@ -1,32 +0,0 @@ -# -# MobiCore configuration -# -config MOBICORE_SUPPORT - tristate "Linux MobiCore Support" - #depends on ARM_TRUSTZONE - ---help--- - Enable Linux Kernel MobiCore Support - -config MOBICORE_DEBUG - bool "MobiCore Module debug mode" - depends on MOBICORE_SUPPORT - ---help--- - Enable Debug mode in the MobiCore Driver. - It enables printing information about mobicore operations - -config MOBICORE_VERBOSE - bool "MobiCore Module verbose debug mode" - depends on MOBICORE_DEBUG - ---help--- - Enable Verbose Debug mode in the MobiCore Driver. - It enables printing extra information about mobicore operations - Beware: this is only useful for debuging deep in the driver because - it prints too much logs - - -config MOBICORE_API - tristate "Linux MobiCore API" - depends on MOBICORE_SUPPORT - ---help--- - Enable Linux Kernel MobiCore API - diff --git a/drivers/gud/Makefile b/drivers/gud/Makefile deleted file mode 100644 index ea212c523bd6..000000000000 --- a/drivers/gud/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# -# Makefile for the kernel mobicore drivers -# -GUD_ROOT_FOLDER := drivers/gud -# add our modules to kernel. -obj-$(CONFIG_MOBICORE_API) += mckernelapi.o -obj-$(CONFIG_MOBICORE_SUPPORT) += mcdrvmodule.o - -mcdrvmodule-objs := mobicore_driver/logging.o mobicore_driver/main.o - -mckernelapi-objs := mobicore_kernelapi/main.o \ - mobicore_kernelapi/clientlib.o \ - mobicore_kernelapi/device.o \ - mobicore_kernelapi/session.o \ - mobicore_kernelapi/connection.o - -# Release mode by default -ccflags-y := -DNDEBUG -ccflags-y += -Wno-declaration-after-statement - -ccflags-$(CONFIG_MOBICORE_DEBUG) += -DDEBUG -ccflags-$(CONFIG_MOBICORE_VERBOSE) += -DDEBUG_VERBOSE - -# Choose one platform from the folder -MOBICORE_PLATFORM := $(shell (ls -1 $(PWD)/$(GUD_ROOT_FOLDER)/mobicore_driver/platforms | tail -1) ) -# Use the available platform folder -ccflags-y += -I$(GUD_ROOT_FOLDER)/mobicore_driver/platforms/$(MOBICORE_PLATFORM) - - -ccflags-y += -I$(GUD_ROOT_FOLDER)/mobicore_driver/public -ccflags-y += -I$(GUD_ROOT_FOLDER)/mobicore_kernelapi/include diff --git a/drivers/gud/README b/drivers/gud/README deleted file mode 100644 index c6d62a1e6515..000000000000 --- a/drivers/gud/README +++ /dev/null @@ -1,6 +0,0 @@ -MobiCore is an operating system being shipped with TZBSP -on msm chipsets. MobiCore consists of several components in -the secure world(TrustZone) and non-secure world(linux -kernel, Android user space). The MobiCore driver -communicates with the MobiCore kernel that exists in -TrustZone. diff --git a/drivers/gud/mobicore_driver/build_tag.h b/drivers/gud/mobicore_driver/build_tag.h deleted file mode 100644 index 43541bbe2753..000000000000 --- a/drivers/gud/mobicore_driver/build_tag.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - * - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#define MOBICORE_COMPONENT_BUILD_TAG "*** GC_MSM8960_Release_V010 ###" diff --git a/drivers/gud/mobicore_driver/logging.c b/drivers/gud/mobicore_driver/logging.c deleted file mode 100644 index eb44c8ad7ee4..000000000000 --- a/drivers/gud/mobicore_driver/logging.c +++ /dev/null @@ -1,336 +0,0 @@ -/** MobiCore driver module.(interface to the secure world SWD) - * @addtogroup MCD_MCDIMPL_KMOD_LOGGING MobiCore Driver Logging Subsystem. - * @ingroup MCD_MCDIMPL_KMOD - * @{ - * @file - * MobiCore Driver Logging Subsystem. - * The logging subsytem provides the interface between the Mobicore trace - * buffer and the Linux log - * - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include "mc_drv_module.h" -#include "mc_drv_module_linux_api.h" -#include "mc_drv_module_fastcalls.h" - -/* Default len of the log ring buffer 256KB*/ -#define LOG_BUF_SIZE (64 * PAGE_SIZE) - -/* Max Len of a log line for printing */ -#define LOG_LINE_SIZE 256 - -static uint32_t log_size = LOG_BUF_SIZE; -module_param(log_size, uint, 0); -MODULE_PARM_DESC(log_size, " Size of the MobiCore log ringbuffer " - "(or 256KB default)."); - -/*----------------------------------------------------------------------------*/ -/* Definitions for log version 2 */ -#define LOG_TYPE_MASK (0x0007) -#define LOG_TYPE_CHAR 0 -#define LOG_TYPE_INTEGER 1 -/* Field length */ -#define LOG_LENGTH_MASK (0x00F8) -#define LOG_LENGTH_SHIFT 3 -/* Extra attributes */ -#define LOG_EOL (0x0100) -#define LOG_INTEGER_DECIMAL (0x0200) -#define LOG_INTEGER_SIGNED (0x0400) - -struct logmsg_struct { - /* Type and format of data */ - uint16_t ctrl; - /* Unique value for each event source */ - uint16_t source; - /* Value, if any */ - uint32_t log_data; -}; - -/** MobiCore log previous position */ -static uint32_t log_pos; -/** MobiCore log buffer structure */ -static struct mc_trace_buf *log_buf; -/** Log Thread task structure */ -struct task_struct *log_thread; -/** Log Line buffer */ -static char *log_line; - -static void log_msg(struct logmsg_struct *msg); - -/*----------------------------------------------------------------------------*/ -static void log_eol(void) -{ - if (!strnlen(log_line, LOG_LINE_SIZE)) - return; - printk(KERN_INFO "%s\n", log_line); - log_line[0] = 0; -} -/*----------------------------------------------------------------------------*/ -/** - * Put a char to the log line if there is enough space if not then also - * output the line. Assume nobody else is updating the line! */ -static void log_char(char ch) -{ - uint32_t len; - if (ch == '\n' || ch == '\r') { - log_eol(); - return; - } - - if (strnlen(log_line, LOG_LINE_SIZE) >= LOG_LINE_SIZE - 1) { - printk(KERN_INFO "%s\n", log_line); - log_line[0] = 0; - } - - len = strnlen(log_line, LOG_LINE_SIZE); - log_line[len] = ch; - log_line[len + 1] = 0; -} - -/*----------------------------------------------------------------------------*/ -/** - * Put a string to the log line if there is enough space if not then also - * output the line. Assume nobody else is updating the line! */ -static void log_str(const char *s) -{ - int i; - for (i = 0; i < strnlen(s, LOG_LINE_SIZE); i++) - log_char(s[i]); -} - -/*----------------------------------------------------------------------------*/ -static uint32_t process_v1log(void) -{ - char *last_char = log_buf->buff + log_buf->write_pos; - char *buff = log_buf->buff + log_pos; - while (buff != last_char) { - log_char(*(buff++)); - /* Wrap around */ - if (buff - (char *)log_buf >= log_size) - buff = log_buf->buff; - } - return buff - log_buf->buff; -} - -/*----------------------------------------------------------------------------*/ -static uint32_t process_v2log(void) -{ - char *last_msg = log_buf->buff + log_buf->write_pos; - char *buff = log_buf->buff + log_pos; - while (buff != last_msg) { - log_msg((struct logmsg_struct *)buff); - buff += sizeof(struct logmsg_struct); - /* Wrap around */ - if (buff + sizeof(struct logmsg_struct) > - (char *)log_buf + log_size) - buff = log_buf->buff; - } - return buff - log_buf->buff; -} - -static const uint8_t HEX2ASCII[16] = { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - -/*----------------------------------------------------------------------------*/ -static void dbg_raw_nro(uint32_t format, uint32_t value) -{ - int digits = 1; - uint32_t base = (format & LOG_INTEGER_DECIMAL) ? 10 : 16; - int width = (format & LOG_LENGTH_MASK) >> LOG_LENGTH_SHIFT; - int negative = FALSE; - uint32_t digit_base = 1; - - if ((format & LOG_INTEGER_SIGNED) != 0 && ((signed int)value) < 0) { - negative = TRUE; - value = (uint32_t)(-(signed int)value); - width--; - } - - /* Find length and divider to get largest digit */ - while (value / digit_base >= base) { - digit_base *= base; - digits++; - } - - if (width > digits) { - char ch = (base == 10) ? ' ' : '0'; - while (width > digits) { - log_char(ch); - width--; - } - } - - if (negative) - log_char('-'); - - while (digits-- > 0) { - uint32_t d = value / digit_base; - log_char(HEX2ASCII[d]); - value = value - d * digit_base; - digit_base /= base; - } -} - -/*----------------------------------------------------------------------------*/ -static void log_msg(struct logmsg_struct *msg) -{ - unsigned char msgtxt[5]; - int mpos = 0; - switch (msg->ctrl & LOG_TYPE_MASK) { - case LOG_TYPE_CHAR: { - uint32_t ch; - ch = msg->log_data; - while (ch != 0) { - msgtxt[mpos++] = ch&0xFF; - ch >>= 8; - } - msgtxt[mpos] = 0; - log_str(msgtxt); - break; - } - case LOG_TYPE_INTEGER: { - dbg_raw_nro(msg->ctrl, msg->log_data); - break; - } - default: - break; - } - if (msg->ctrl & LOG_EOL) - log_eol(); -} - -/*----------------------------------------------------------------------------*/ -static int log_worker(void *p) -{ - if (log_buf == NULL) - return -EFAULT; - - /* The thread should have never started */ - if (log_buf == NULL) - return -EFAULT; - - while (!kthread_should_stop()) { - if (log_buf->write_pos == log_pos) - schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT); - - switch (log_buf->version) { - case 1: - log_pos = process_v1log(); - break; - case 2: - log_pos = process_v2log(); - break; - default: - MCDRV_DBG_ERROR("Unknown Mobicore log data " - "version %d logging disabled.", - log_buf->version); - log_pos = log_buf->write_pos; - /* Stop the thread as we have no idea what - * happens next */ - return -EFAULT; - } - } - MCDRV_DBG("Logging thread stopped!"); - return 0; -} - - -/*----------------------------------------------------------------------------*/ -/** - * Wakeup the log reader thread - * This should be called from the places where calls into MobiCore have - * generated some logs(eg, yield, SIQ...) - */ -void mobicore_log_read(void) -{ - if (log_thread == NULL || IS_ERR(log_thread)) - return; - - wake_up_process(log_thread); -} - -/*----------------------------------------------------------------------------*/ -/** - * Setup mobicore kernel log. It assumes it's running on CORE 0! - * The fastcall will complain is that is not the case! - */ -long mobicore_log_setup(void *data) -{ - unsigned long phys_log_buf; - union fc_generic fc_log; - - log_pos = 0; - log_buf = NULL; - log_thread = NULL; - log_line = NULL; - - /* Sanity check for the log size */ - if (log_size < PAGE_SIZE) - return -EFAULT; - else - log_size = - get_nr_of_pages_for_buffer(NULL, log_size) * PAGE_SIZE; - - log_line = kzalloc(LOG_LINE_SIZE, GFP_KERNEL); - if (IS_ERR(log_line)) { - MCDRV_DBG_ERROR("failed to allocate log line!"); - return -ENOMEM; - } - - log_thread = kthread_create(log_worker, NULL, "mobicore_log"); - if (IS_ERR(log_thread)) { - MCDRV_DBG_ERROR("mobicore log thread creation failed!"); - return -EFAULT; - } - - log_pos = 0; - log_buf = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, - size_to_order(log_size)); - if (!log_buf) { - MCDRV_DBG_ERROR("Failed to get page for logger!"); - return -ENOMEM; - } - phys_log_buf = virt_to_phys(log_buf); - - memset(&fc_log, 0, sizeof(fc_log)); - fc_log.as_in.cmd = MC_FC_NWD_TRACE; - fc_log.as_in.param[0] = phys_log_buf; - fc_log.as_in.param[1] = log_size; - - MCDRV_DBG("fc_log virt=%p phys=%p ", log_buf, (void *)phys_log_buf); - mc_fastcall(&fc_log); - MCDRV_DBG("fc_log out ret=0x%08x", fc_log.as_out.ret); - /* If the setup failed we must free the memory allocated */ - if (fc_log.as_out.ret) { - MCDRV_DBG_ERROR("MobiCore shared traces setup failed!"); - kthread_stop(log_thread); - free_pages((unsigned long)log_buf, size_to_order(log_size)); - - log_buf = NULL; - log_thread = NULL; - return -EIO; - } - - MCDRV_DBG("fc_log Logger version %u\n", log_buf->version); - return 0; -} - -/*----------------------------------------------------------------------------*/ -/** - * Free kernel log componenets. - * ATTN: We can't free the log buffer because it's also in use by MobiCore and - * even if the module is unloaded MobiCore is still running. - */ -void mobicore_log_free(void) -{ - if (log_thread && !IS_ERR(log_thread)) { - /* We don't really care what the thread returns for exit */ - kthread_stop(log_thread); - } - - kfree(log_line); -} diff --git a/drivers/gud/mobicore_driver/main.c b/drivers/gud/mobicore_driver/main.c deleted file mode 100644 index 8a8ea1e2e9e6..000000000000 --- a/drivers/gud/mobicore_driver/main.c +++ /dev/null @@ -1,2869 +0,0 @@ -/** MobiCore driver module.(interface to the secure world SWD) - * @addtogroup MCD_MCDIMPL_KMOD_IMPL - * @{ - * @file - * MobiCore Driver Kernel Module. - * This module is written as a Linux device driver. - * This driver represents the command proxy on the lowest layer, from the - * secure world to the non secure world, and vice versa. - * This driver is located in the non secure world (Linux). - * This driver offers IOCTL commands, for access to the secure world, and has - * the interface from the secure world to the normal world. - * The access to the driver is possible with a file descriptor, - * which has to be created by the fd = open(/dev/mobicore) command. - * - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include "mc_drv_module.h" -#include "mc_drv_module_linux_api.h" -#include "mc_drv_module_android.h" -#include "mc_drv_module_fastcalls.h" -#include "public/mc_kernel_api.h" - -/* Initial value for the daemon sempahore signaling */ -#define DAEMON_SEM_VAL 0 - -/** MobiCore interrupt context data */ -static struct mc_drv_kmod_ctx mc_drv_kmod_ctx; - -/** MobiCore MCI information */ -static uint32_t mci_base; -/* -############################################################################# -## -## Convenience functions for Linux API functions -## -#############################################################################*/ -static int goto_cpu0(void); -static int goto_all_cpu(void) __attribute__ ((unused)); - - -/*----------------------------------------------------------------------------*/ -static void init_and_add_to_list( - struct list_head *item, - struct list_head *list_head -) -{ - INIT_LIST_HEAD(item); - - list_add(item, list_head); -} - -/*----------------------------------------------------------------------------*/ -/** check if CPU supports the ARM TrustZone Security Extensions - * @return int TRUE or FALSE */ -static int has_security_extensions( - void -) -{ - u32 fea = 0; - asm volatile( - "mrc p15, 0, %[fea], cr0, cr1, 0" : - [fea]"=r" (fea)); - - MCDRV_DBG_VERBOSE("CPU Features: 0x%X", fea); - - /* If the CPU features ID has 0 for security features then the CPU - * doesn't support TrustZone at all! - */ - if ((fea & ARM_SECURITY_EXTENSION_MASK) == 0) - return 0; - - return 1; -} - -/*----------------------------------------------------------------------------*/ -/** check if running in secure mode - * @return int TRUE or FALSE */ -static int is_secure_mode( - void -) -{ - u32 cpsr = 0, nsacr = 0; - asm volatile( - "mrc p15, 0, %[nsacr], cr1, cr1, 2\n" - "mrs %[cpsr], cpsr\n" : - [nsacr]"=r" (nsacr), - [cpsr]"=r"(cpsr)); - - MCDRV_DBG_VERBOSE("CPRS.M = set to 0x%X\n", cpsr & ARM_CPSR_MASK); - MCDRV_DBG_VERBOSE("SCR.NS = set to 0x%X\n", nsacr); - - /* If the NSACR contains the reset value(=0) then most likely we are - * running in Secure MODE. - * If the cpsr mode is set to monitor mode then we cannot load! - */ - if (nsacr == 0 || ((cpsr & ARM_CPSR_MASK) == ARM_MONITOR_MODE)) - return 1; - - return 0; -} - -/*----------------------------------------------------------------------------*/ -/** check if userland caller is privileged (aka has "root" access rights). - @return int TRUE or FALSE */ -static int is_userland_caller_privileged( - void -) { - /* For some platforms we cannot run the Daemon as root - for Android - * compliance tests it is not allowed, thus we assume the daemon is ran - * as the system user. - * In Android the system user for daemons has no particular capabilities - * other than a fixed UID: AID_SYSTEM 1000 - * The actual number is guaranteed to be the same in all Android systems - * so we will take it for granted: see android_filesystem_config.h in - * the Android source tree for all UIDs and their meaning: - * http://android-dls.com/wiki/index.php?title=Android_UIDs_and_GIDs - */ -#ifdef MC_ANDROID_UID_CHECK - return current_euid() <= AID_SYSTEM; -#else - /* capable should cover all possibilities, root or sudo, uid checking - * was not very reliable */ - return capable(CAP_SYS_ADMIN); -#endif -} - - - -/*----------------------------------------------------------------------------*/ -static void unlock_page_from_used_l2_table( - struct page *page -){ - /* REV axh: check if we should do this. */ - SetPageDirty(page); - - /* release page, old api was page_cache_release() */ - ClearPageReserved(page); - put_page(page); -} - -/*----------------------------------------------------------------------------*/ -/* convert L2 PTE to page pointer */ -static struct page *l2_pte_to_page( - pte_t pte -) { - void *phys_page_addr = (void *)((unsigned int)pte & PAGE_MASK); - unsigned int pfn = addr_to_pfn(phys_page_addr); - struct page *page = pfn_to_page(pfn); - return page; -} - -/*----------------------------------------------------------------------------*/ -/* convert page pointer to L2 PTE */ -static pte_t page_to_l2_pte( - struct page *page -) -{ - unsigned int pfn = page_to_pfn(page); - void *phys_addr = pfn_to_addr(pfn); - pte_t pte = (pte_t)((unsigned int)phys_addr & PAGE_MASK); - return pte; -} - - -/*----------------------------------------------------------------------------*/ -static inline int lock_user_pages( - struct task_struct *task, - void *virt_start_page_addr, - int nr_of_pages, - struct page **pages -) -{ - int ret = 0; - int locked_pages = 0; - unsigned int i; - - do { - - /* lock user pages, must hold the mmap_sem to do this. */ - down_read(&(task->mm->mmap_sem)); - locked_pages = get_user_pages( - task, - task->mm, - (unsigned long)virt_start_page_addr, - nr_of_pages, - 1, /* write access */ - 0, /* they say drivers should always - pass 0 here..... */ - pages, - NULL); /* we don't need the VMAs */ - up_read(&(task->mm->mmap_sem)); - - /* could as lock all pages? */ - if (locked_pages != nr_of_pages) { - MCDRV_DBG_ERROR( - "get_user_pages() failed, " - "locked_pages=%d\n", - locked_pages); - ret = -ENOMEM; - /* check if an error has been returned. */ - if (locked_pages < 0) { - ret = locked_pages; - locked_pages = 0; - } - break; - } - - /* do cache maintenance on locked pages. */ - for (i = 0; i < nr_of_pages; i++) - flush_dcache_page(pages[i]); - - } while (FALSE); - - - if (ret != 0) { - /* release all locked pages. */ - MCDRV_ASSERT(locked_pages >= 0); - for (i = 0; i < locked_pages; i++) - put_page(pages[i]); - } - - return ret; - -} - -/* -############################################################################# -## -## Driver implementation functions -## -#############################################################################*/ -/*----------------------------------------------------------------------------*/ -/* check if caller is MobiCore Daemon */ -static unsigned int is_caller_mc_daemon( - struct mc_instance *instance -) -{ - return ((instance != NULL) - && (mc_drv_kmod_ctx.daemon_inst == instance)); -} - - -/*----------------------------------------------------------------------------*/ -/* Get process context from file pointer */ -static struct mc_instance *get_instance( - struct file *file -) { - MCDRV_ASSERT(file != NULL); - - return (struct mc_instance *)(file->private_data); -} - - -/*----------------------------------------------------------------------------*/ -/* Get a unique ID */ -static unsigned int get_mc_kmod_unique_id( - void -) -{ - return (unsigned int)atomic_inc_return( - &(mc_drv_kmod_ctx.unique_counter)); -} - - -/*----------------------------------------------------------------------------*/ -/* Get kernel pointer to shared L2 table given a per-process reference */ -static struct l2table *get_l2_table_kernel_virt( - struct mc_used_l2_table *used_l2table -) -{ - MCDRV_ASSERT(used_l2table != NULL); - MCDRV_ASSERT(used_l2table->set != NULL); - MCDRV_ASSERT(used_l2table->set->kernel_virt != NULL); - return &(used_l2table->set->kernel_virt->table[used_l2table->idx]); -} - -/*----------------------------------------------------------------------------*/ -/* Get physical address of a shared L2 table given a per-process reference */ -static struct l2table *get_l2_table_phys( - struct mc_used_l2_table *used_l2table -) -{ - MCDRV_ASSERT(used_l2table != NULL); - MCDRV_ASSERT(used_l2table->set != NULL); - MCDRV_ASSERT(used_l2table->set->phys != NULL); - return &(used_l2table->set->phys->table[used_l2table->idx]); -} - -/*----------------------------------------------------------------------------*/ -static unsigned int is_in_use_used_l2_table( - struct mc_used_l2_table *used_l2table -) -{ - return ((used_l2table->flags & - (MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_APP - | MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC)) != 0); -} - - - -/*----------------------------------------------------------------------------*/ -static struct mc_used_l2_table *find_used_l2_table_by_handle( - unsigned int handle -) { - struct mc_used_l2_table *used_l2table; - struct mc_used_l2_table *used_l2table_with_handle = NULL; - - list_for_each_entry( - used_l2table, - &(mc_drv_kmod_ctx.mc_used_l2_tables), - list - ) { - if (handle == used_l2table->handle) { - used_l2table_with_handle = used_l2table; - break; - } - } - - return used_l2table_with_handle; -} - -/* -############################################################################# -## -## L2 Table Pool -## -#############################################################################*/ - -/*----------------------------------------------------------------------------*/ -static struct mc_used_l2_table *allocate_used_l2_table( - struct mc_instance *instance -) { - int ret = 0; - struct mc_l2_table_store *l2table_store = NULL; - struct mc_l2_tables_set *l2table_set = NULL; - struct mc_used_l2_table *used_l2table = NULL; - struct page *page; - unsigned int i = 0; - - do { - /* allocate a WSM L2 descriptor */ - used_l2table = kmalloc(sizeof(*used_l2table), GFP_KERNEL); - if (used_l2table == NULL) { - ret = -ENOMEM; - MCDRV_DBG_ERROR("out of memory\n"); - break; - } - /* clean */ - memset(used_l2table, 0, sizeof(*used_l2table)); - used_l2table->handle = get_mc_kmod_unique_id(); - used_l2table->owner = instance; - - /* add to global list. */ - init_and_add_to_list( - &(used_l2table->list), - &(mc_drv_kmod_ctx.mc_used_l2_tables)); - - /* walk though list to find free set. */ - list_for_each_entry( - l2table_set, - &(mc_drv_kmod_ctx.mc_l2_tables_sets), - list - ) { - for (i = 0; i < MC_DRV_KMOD_L2_TABLE_PER_PAGES; i++) { - if ((l2table_set->usage_bitmap & (1U << i)) - == 0) { - /* found a set, - l2table_set and i are set. */ - l2table_store = - l2table_set->kernel_virt; - break; - } - } - if (l2table_store != NULL) - break; - } /* end while */ - - if (l2table_store == NULL) { - l2table_store = (struct mc_l2_table_store *) - get_zeroed_page(GFP_KERNEL); - if (l2table_store == NULL) { - ret = -ENOMEM; - break; - } - - /* Actually, locking is not necessary, because kernel - memory is not supposed to get swapped out. But - we play safe.... */ - page = virt_to_page(l2table_store); - SetPageReserved(page); - - /* allocate a descriptor */ - l2table_set = kmalloc(sizeof(*l2table_set), GFP_KERNEL); - if (l2table_set == NULL) { - kfree(l2table_store); - ret = -ENOMEM; - break; - } - /* initialize */ - memset(l2table_set, 0, sizeof(*l2table_set)); - - l2table_set->kernel_virt = l2table_store; - l2table_set->page = page; - l2table_set->phys = (void *)virt_to_phys(l2table_store); - - /* init add to list. */ - init_and_add_to_list( - &(l2table_set->list), - &(mc_drv_kmod_ctx.mc_l2_tables_sets)); - - /* use first table */ - i = 0; - } - - /* set set usage */ - l2table_set->usage_bitmap |= (1U << i); - - /* set set reference */ - used_l2table->set = l2table_set; - used_l2table->idx = i; - - MCDRV_DBG_VERBOSE( - "chunkPhys=%p,idx=%d\n", - l2table_set->phys, i); - - } while (FALSE); - - if (ret != 0) { - if (used_l2table != NULL) { - /* remove from list */ - list_del(&(l2table_set->list)); - /* free memory */ - kfree(used_l2table); - used_l2table = NULL; - } - } - - return used_l2table; -} - -/*----------------------------------------------------------------------------*/ -static void free_used_l2_table( - struct mc_used_l2_table *used_l2table -) -{ - struct mc_l2_tables_set *l2table_set; - unsigned int idx; - - MCDRV_ASSERT(used_l2table != NULL); - - l2table_set = used_l2table->set; - MCDRV_ASSERT(l2table_set != NULL); - - /* clean usage flag */ - idx = used_l2table->idx; - MCDRV_ASSERT(idx < MC_DRV_KMOD_L2_TABLE_PER_PAGES); - l2table_set->usage_bitmap &= ~(1U << idx); - - /* if nobody uses this set, we can release it. */ - if (l2table_set->usage_bitmap == 0) { - MCDRV_ASSERT(l2table_set->page != NULL); - ClearPageReserved(l2table_set->page); - - MCDRV_ASSERT(l2table_set->kernel_virt != NULL); - free_page((unsigned long)l2table_set->kernel_virt); - - /* remove from list */ - list_del(&(l2table_set->list)); - - /* free memory */ - kfree(l2table_set); - } - - return; -} - - - -/*----------------------------------------------------------------------------*/ -/** - * Create a L2 table in a WSM container that has been allocates previously. - * - * @param task pointer to task owning WSM - * @param wsm_buffer user space WSM start - * @param wsm_len WSM length - * @param used_l2table Pointer to L2 table details - */ -static int map_buffer_into_used_l2_table( - struct task_struct *task, - void *wsm_buffer, - unsigned int wsm_len, - struct mc_used_l2_table *used_l2table -) -{ - int ret = 0; - unsigned int i, nr_of_pages; - void *virt_addr_page; - struct page *page; - struct l2table *l2table; - struct page **l2table_as_array_of_pointers_to_page; - - /* task can be null when called from kernel space */ - MCDRV_ASSERT(wsm_buffer != NULL); - MCDRV_ASSERT(wsm_len != 0); - MCDRV_ASSERT(used_l2table != NULL); - - MCDRV_DBG_VERBOSE("WSM addr=0x%p, len=0x%08x\n", wsm_buffer, wsm_len); - - /* Check if called from kernel space wsm_buffer is actually - * vmalloced or not */ - if (task == NULL && !is_vmalloc_addr(wsm_buffer)) { - MCDRV_DBG_ERROR("WSM addr is not a vmalloc address"); - return -EINVAL; - } - - l2table = get_l2_table_kernel_virt(used_l2table); - /* We use the memory for the L2 table to hold the pointer - and convert them later. This works, as everything comes - down to a 32 bit value. */ - l2table_as_array_of_pointers_to_page = (struct page **)l2table; - - do { - - /* no size > 1Mib supported */ - if (wsm_len > SZ_1M) { - MCDRV_DBG_ERROR("size > 1 MiB\n"); - ret = -EINVAL; - break; - } - - /* calculate page usage */ - virt_addr_page = get_page_start(wsm_buffer); - nr_of_pages = get_nr_of_pages_for_buffer(wsm_buffer, wsm_len); - - - MCDRV_DBG_VERBOSE("virt addr pageStart=0x%p,pages=%d\n", - virt_addr_page, - nr_of_pages); - - /* L2 table can hold max 1MiB in 256 pages. */ - if ((nr_of_pages*PAGE_SIZE) > SZ_1M) { - MCDRV_DBG_ERROR("WSM paged exceed 1 MiB\n"); - ret = -EINVAL; - break; - } - - /* Request comes from user space */ - if (task != NULL) { - /* lock user page in memory, so they do not get swapped - * out. - * REV axh: - * Kernel 2.6.27 added a new get_user_pages_fast() - * function, maybe it is called fast_gup() in some - * versions. - * handle user process doing a fork(). - * Child should not get things. - * http://osdir.com/ml/linux-media/2009-07/msg00813.html - * http://lwn.net/Articles/275808/ */ - - ret = lock_user_pages( - task, - virt_addr_page, - nr_of_pages, - l2table_as_array_of_pointers_to_page); - if (ret != 0) { - MCDRV_DBG_ERROR("lock_user_pages() failed\n"); - break; - } - } - /* Request comes from kernel space(vmalloc buffer) */ - else { - void *uaddr = wsm_buffer; - for (i = 0; i < nr_of_pages; i++) { - page = vmalloc_to_page(uaddr); - if (!page) { - MCDRV_DBG_ERROR( - "vmalloc_to_Page()" - " failed to map address\n"); - ret = -EINVAL; - break; - } - get_page(page); - /* Lock the page in memory, it can't be swapped - * out */ - SetPageReserved(page); - l2table_as_array_of_pointers_to_page[i] = page; - uaddr += PAGE_SIZE; - } - } - - used_l2table->nr_of_pages = nr_of_pages; - used_l2table->flags |= MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_APP; - - /* create L2 Table entries. used_l2table->table contains a list - of page pointers here. For a proper cleanup we have to ensure - that the following code either works and used_l2table contains - a valid L2 table - or fails and used_l2table->table contains the - list of page pointers. Any mixed contents will make cleanup - difficult.*/ - - for (i = 0; i < nr_of_pages; i++) { - pte_t pte; - page = l2table_as_array_of_pointers_to_page[i]; - - /* create L2 table entry, see ARM MMU docu for details - about flags stored in the lowest 12 bits. As a side - reference, the Article "ARM's multiply-mapped memory - mess" found in the collection at at - http://lwn.net/Articles/409032/ is also worth reading.*/ - pte = page_to_l2_pte(page) - | L2_FLAG_AP1 | L2_FLAG_AP0 - | L2_FLAG_C | L2_FLAG_B - | L2_FLAG_SMALL | L2_FLAG_SMALL_XN - /* Linux uses different mappings for SMP systems(the - * sharing flag is set for the pte. In order not to - * confuse things too much in Mobicore make sure the - * shared buffers have the same flags. - * This should also be done in SWD side - */ -#ifdef CONFIG_SMP - | L2_FLAG_S | L2_FLAG_SMALL_TEX0 -#endif - ; - - l2table->table_entries[i] = pte; - MCDRV_DBG_VERBOSE("L2 entry %d: 0x%08x\n", i, - (unsigned int)(pte)); - } - - /* ensure rest of table is empty */ - while (i < 255) - l2table->table_entries[i++] = (pte_t)0; - - } while (FALSE); - - return ret; -} - - -/*----------------------------------------------------------------------------*/ -/** - * Remove a L2 table in a WSM container. Afterwards the container may be - * released. - * - * @param used_l2table Pointer to L2 table details - */ - -static void unmap_buffers_from_used_l2_table( - struct mc_used_l2_table *used_l2table -) -{ - unsigned int i; - struct l2table *l2table; - - MCDRV_ASSERT(used_l2table != NULL); - /* this should not happen, as we have no empty tables. */ - MCDRV_ASSERT(!is_in_use_used_l2_table(used_l2table)); - - /* found the table, now release the resources. */ - MCDRV_DBG_VERBOSE("clear L2 table, phys_base=%p, nr_of_pages=%d\n", - get_l2_table_phys(used_l2table), - used_l2table->nr_of_pages); - - l2table = get_l2_table_kernel_virt(used_l2table); - - /* release all locked user space pages */ - for (i = 0; i < used_l2table->nr_of_pages; i++) { - /* convert physical entries from L2 table to page pointers */ - pte_t pte = get_l2_table_kernel_virt(used_l2table)-> - table_entries[i]; - struct page *page = l2_pte_to_page(pte); - unlock_page_from_used_l2_table(page); - } - - /* remember that all pages have been freed */ - used_l2table->nr_of_pages = 0; - - return; -} - - -/* -############################################################################# -## -## Helper functions -## -#############################################################################*/ -/*----------------------------------------------------------------------------*/ -#define FREE_FROM_SWD TRUE -#define FREE_FROM_NWD FALSE -/** Delete a used l2 table. */ -static void delete_used_l2_table( - struct mc_used_l2_table *used_l2table, - unsigned int is_swd -) -{ - if (is_swd) { - used_l2table->flags &= - ~MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC; - } else { - used_l2table->flags &= - ~MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_APP; - used_l2table->owner = NULL; - } - - /* release if Nwd and Swd/MC do no longer use it. */ - if (is_in_use_used_l2_table(used_l2table)) { - MCDRV_DBG_WARN( - "WSM L2 table still in use: physBase=%p, " - "nr_of_pages=%d\n", - get_l2_table_phys(used_l2table), - used_l2table->nr_of_pages); - } else { - unmap_buffers_from_used_l2_table(used_l2table); - free_used_l2_table(used_l2table); - - list_del(&(used_l2table->list)); - - kfree(used_l2table); - } - return; -} - -/*----------------------------------------------------------------------------*/ -/** Allocate L2 table and map buffer into it. That is, create respective table - entries. Must hold Semaphore mc_drv_kmod_ctx.wsm_l2_sem */ -static struct mc_used_l2_table *new_used_l2_table( - struct mc_instance *instance, - struct task_struct *task, - void *wsm_buffer, - unsigned int wsm_len -) { - int ret = 0; - struct mc_used_l2_table *used_l2table; - - do { - used_l2table = allocate_used_l2_table(instance); - if (used_l2table == NULL) { - MCDRV_DBG_ERROR( - "allocate_used_l2_table() failed\n"); - break; - } - - /* create the L2 page for the WSM */ - ret = map_buffer_into_used_l2_table( - task, - wsm_buffer, - wsm_len, - used_l2table); - if (ret != 0) { - MCDRV_DBG_ERROR( - "map_buffer_into_used_l2_table() failed\n"); - delete_used_l2_table(used_l2table, FREE_FROM_NWD); - used_l2table = NULL; - break; - } - - } while (FALSE); - - - return used_l2table; -} - -/* -############################################################################# -## -## IoCtl handler -## -#############################################################################*/ - -/** - * Map a virtual memory buffer structure to Mobicore - * @param instance - * @param addr address of the buffer(NB it must be kernel virtual!) - * @param len buffer length - * @param handle pointer to handle - * @param phys_wsm_l2_table pointer to physical L2 table(?) - * - * @return 0 if no error - * - */ -/*----------------------------------------------------------------------------*/ -int mobicore_map_vmem( - struct mc_instance *instance, - void *addr, - uint32_t len, - uint32_t *handle, - void **phys_wsm_l2_table -) -{ - int ret = 0; - struct mc_used_l2_table *used_l2table = NULL; - MCDRV_ASSERT(instance != NULL); - - MCDRV_DBG_VERBOSE("enter\n"); - - do { - if (len == 0) { - MCDRV_DBG_ERROR("len=0 is not supported!\n"); - ret = -EINVAL; - break; - } - - /* try to get the semaphore */ - ret = down_interruptible(&(mc_drv_kmod_ctx.wsm_l2_sem)); - if (ret != 0) { - MCDRV_DBG_ERROR("down_interruptible() failed with %d\n", - ret); - ret = -ERESTARTSYS; - break; - } - - do { - used_l2table = new_used_l2_table( - instance, - NULL, - addr, - len); - - if (used_l2table == NULL) { - MCDRV_DBG_ERROR("new_used_l2_table() failed\n"); - ret = -EINVAL; - break; - } - - /* set response */ - *handle = used_l2table->handle; - *phys_wsm_l2_table = - (void *)get_l2_table_phys(used_l2table); - MCDRV_DBG_VERBOSE("handle: %d, phys=%p\n", - *handle, - (void *)(*phys_wsm_l2_table)); - - } while (FALSE); - - /* release semaphore */ - up(&(mc_drv_kmod_ctx.wsm_l2_sem)); - - } while (FALSE); - - MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret); - - return ret; -} -EXPORT_SYMBOL(mobicore_map_vmem); -/*----------------------------------------------------------------------------*/ -/** - * - * @param instance - * @param arg - * - * @return 0 if no error - * - */ -static int handle_ioctl_app_register_wsm_l2( - struct mc_instance *instance, - union mc_ioctl_app_reg_wsm_l2_params *user_params -) -{ - int ret = 0; - union mc_ioctl_app_reg_wsm_l2_params params; - struct mc_used_l2_table *used_l2table = NULL; - struct pid *pid_struct = NULL; - struct task_struct *task = current; - - MCDRV_ASSERT(instance != NULL); - - MCDRV_DBG_VERBOSE("enter\n"); - - do { - /* get use parameters */ - ret = copy_from_user( - &(params.in), - &(user_params->in), - sizeof(params.in)); - if (ret != 0) { - MCDRV_DBG_ERROR("copy_from_user() failed\n"); - break; - } - - /* daemon can do this for another task. */ - if (params.in.pid != 0) { - MCDRV_DBG_ERROR("pid != 0 unsupported\n"); - ret = -EINVAL; - break; - } - if (params.in.len == 0) { - MCDRV_DBG_ERROR("len=0 is not supported!\n"); - ret = -EINVAL; - break; - } - - /* try to get the semaphore */ - ret = down_interruptible(&(mc_drv_kmod_ctx.wsm_l2_sem)); - if (ret != 0) { - MCDRV_DBG_ERROR("down_interruptible() failed with %d\n", - ret); - ret = -ERESTARTSYS; - break; - } - - do { - used_l2table = new_used_l2_table( - instance, - task, - (void *)(params.in.buffer), - params.in.len); - - if (used_l2table == NULL) { - MCDRV_DBG_ERROR("new_used_l2_table() failed\n"); - ret = -EINVAL; - break; - } - - /* if the daemon does this, we set the MC lock */ - if (is_caller_mc_daemon(instance)) - used_l2table->flags |= - MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC; - - /* set response */ - memset(¶ms.out, 0, sizeof(params.out)); - params.out.handle = used_l2table->handle; - /* TODO: return the physical address for daemon only, - otherwise set NULL */ - params.out.phys_wsm_l2_table = - (uint32_t)get_l2_table_phys(used_l2table); - - MCDRV_DBG_VERBOSE("handle: %d, phys=%p\n", - params.out.handle, - (void *)(params.out.phys_wsm_l2_table)); - - - /* copy L2Table to user space */ - ret = copy_to_user( - &(user_params->out), - &(params.out), - sizeof(params.out)); - if (ret != 0) { - MCDRV_DBG_ERROR("copy_to_user() failed\n"); - - /* free the table again, as app does not know - about anything. */ - if (is_caller_mc_daemon(instance)) { - used_l2table->flags &= - ~MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC; - } - delete_used_l2_table(used_l2table, - FREE_FROM_NWD); - used_l2table = NULL; - break; - } - - } while (FALSE); - - /* release semaphore */ - up(&(mc_drv_kmod_ctx.wsm_l2_sem)); - - } while (FALSE); - - - - /* release PID struct reference */ - if (pid_struct != NULL) - put_pid(pid_struct); - - - MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret); - - return ret; -} - - -/*----------------------------------------------------------------------------*/ -/** - * Unmap a virtual memory buffer from mobicore - * @param instance - * @param handle - * - * @return 0 if no error - * - */ -int mobicore_unmap_vmem( - struct mc_instance *instance, - uint32_t handle -) -{ - int ret = 0; - struct mc_used_l2_table *used_l2table = NULL; - - MCDRV_ASSERT(instance != NULL); - MCDRV_DBG_VERBOSE("enter\n"); - - do { - /* try to get the semaphore */ - ret = down_interruptible(&(mc_drv_kmod_ctx.wsm_l2_sem)); - if (ret != 0) { - MCDRV_DBG_ERROR("processOpenSession() failed with %d\n", - ret); - ret = -ERESTARTSYS; - break; - } - - do { - used_l2table = find_used_l2_table_by_handle(handle); - if (used_l2table == NULL) { - ret = -EINVAL; - MCDRV_DBG_ERROR("entry not found\n"); - break; - } - - if (instance != used_l2table->owner) { - ret = -EINVAL; - MCDRV_DBG_ERROR("instance does no own it\n"); - break; - } - - /* free table (if no further locks exist) */ - delete_used_l2_table(used_l2table, FREE_FROM_NWD); - used_l2table = NULL; - /* there are no out parameters */ - } while (FALSE); - /* release semaphore */ - up(&(mc_drv_kmod_ctx.wsm_l2_sem)); - - } while (FALSE); - - MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret); - - return ret; -} -EXPORT_SYMBOL(mobicore_unmap_vmem); -/*----------------------------------------------------------------------------*/ -/** - * - * @param instance - * @param arg - * - * @return 0 if no error - * - */ -static int handle_ioctl_app_unregister_wsm_l2( - struct mc_instance *instance, - struct mc_ioctl_app_unreg_wsm_l2_params *user_params -) -{ - int ret = 0; - struct mc_ioctl_app_unreg_wsm_l2_params params; - struct mc_used_l2_table *used_l2table = NULL; - - MCDRV_ASSERT(instance != NULL); - MCDRV_DBG_VERBOSE("enter\n"); - - do { - ret = copy_from_user( - &(params.in), - &(user_params->in), - sizeof(params.in)); - - if (ret != 0) { - MCDRV_DBG_ERROR("copy_from_user\n"); - break; - } - - /* try to get the semaphore */ - ret = down_interruptible(&(mc_drv_kmod_ctx.wsm_l2_sem)); - if (ret != 0) { - MCDRV_DBG_ERROR("down_interruptible() failed with %d\n", - ret); - ret = -ERESTARTSYS; - break; - } - - do { - /* daemon can do this for another task. */ - if (params.in.pid != 0) { - MCDRV_DBG_ERROR("pid != 0 unsupported\n"); - ret = -EINVAL; - break; - } - - used_l2table = - find_used_l2_table_by_handle(params.in.handle); - if (used_l2table == NULL) { - ret = -EINVAL; - MCDRV_DBG_ERROR("entry not found\n"); - break; - } - - if (is_caller_mc_daemon(instance)) { - /* if daemon does this, we have to release the - MobiCore lock. */ - used_l2table->flags &= - ~MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC; - } else if (instance != used_l2table->owner) { - ret = -EINVAL; - MCDRV_DBG_ERROR("instance does no own it\n"); - break; - } - - /* free table (if no further locks exist) */ - delete_used_l2_table(used_l2table, FREE_FROM_NWD); - used_l2table = NULL; - - /* there are no out parameters */ - - } while (FALSE); - - /* release semaphore */ - up(&(mc_drv_kmod_ctx.wsm_l2_sem)); - - } while (FALSE); - - MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret); - - return ret; -} - - -/*----------------------------------------------------------------------------*/ -static int handle_ioctl_daemon_lock_wsm_l2( - struct mc_instance *instance, - struct mc_ioctl_daemon_lock_wsm_l2_params *user_params -) -{ - int ret = 0; - struct mc_ioctl_daemon_lock_wsm_l2_params params; - struct mc_used_l2_table *used_l2table = NULL; - - MCDRV_ASSERT(instance != NULL); - MCDRV_DBG_VERBOSE("enter\n"); - - do { - if (!is_caller_mc_daemon(instance)) { - MCDRV_DBG_ERROR("caller not MobiCore Daemon\n"); - ret = -EFAULT; - break; - } - - ret = copy_from_user( - &(params.in), - &(user_params->in), - sizeof(params.in)); - - if (ret != 0) { - MCDRV_DBG_ERROR("copy_from_user\n"); - break; - } - /* try to get the semaphore */ - ret = down_interruptible(&(mc_drv_kmod_ctx.wsm_l2_sem)); - if (ret != 0) { - MCDRV_DBG_ERROR("down_interruptible() failed with %d\n", - ret); - ret = -ERESTARTSYS; - break; - } - - do { - used_l2table = - find_used_l2_table_by_handle(params.in.handle); - if (used_l2table == NULL) { - ret = -EINVAL; - MCDRV_DBG_ERROR("entry not found\n"); - break; - } - if (instance != used_l2table->owner) { - ret = -EINVAL; - MCDRV_DBG_ERROR("instance does no own it\n"); - break; - } - - /* lock entry */ - if ((used_l2table->flags & - MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC) != 0) { - MCDRV_DBG_WARN("entry already locked\n"); - } - used_l2table->flags |= - MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC; - - /* prepare response */ - memset(&(params.out), 0, sizeof(params.out)); - params.out.phys_wsm_l2_table = - (uint32_t)get_l2_table_phys(used_l2table); - - /* copy to user space */ - ret = copy_to_user( - &(user_params->out), - &(params.out), - sizeof(params.out)); - if (ret != 0) { - MCDRV_DBG_ERROR("copy_to_user() failed\n"); - - /* undo, as userspace did not get it. */ - used_l2table->flags |= - MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC; - break; - } - - } while (FALSE); - - /* release semaphore */ - up(&(mc_drv_kmod_ctx.wsm_l2_sem)); - - } while (FALSE); - - MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret); - - return ret; -} - - -/*----------------------------------------------------------------------------*/ -static int handle_ioctl_daemon_unlock_wsm_l2( - struct mc_instance *instance, - struct mc_ioctl_daemon_unlock_wsm_l2_params *user_params -) -{ - int ret = 0; - struct mc_ioctl_daemon_unlock_wsm_l2_params params; - struct mc_used_l2_table *used_l2table = NULL; - - MCDRV_ASSERT(instance != NULL); - MCDRV_DBG_VERBOSE("enter\n"); - - do { - if (!is_caller_mc_daemon(instance)) { - MCDRV_DBG_ERROR("caller not MobiCore Daemon\n"); - ret = -EFAULT; - break; - } - - ret = copy_from_user( - &(params.in), - &(user_params->in), - sizeof(params.in)); - - if (ret != 0) { - MCDRV_DBG_ERROR("copy_from_user\n"); - break; - } - /* try to get the semaphore */ - ret = down_interruptible(&(mc_drv_kmod_ctx.wsm_l2_sem)); - if (ret != 0) { - MCDRV_DBG_ERROR("down_interruptible() failed with %d\n", - ret); - ret = -ERESTARTSYS; - break; - } - - do { - used_l2table = - find_used_l2_table_by_handle(params.in.handle); - if (used_l2table == NULL) { - ret = -EINVAL; - MCDRV_DBG_ERROR("entry not found\n"); - break; - } - if (instance != used_l2table->owner) { - ret = -EINVAL; - MCDRV_DBG_ERROR("instance does no own it\n"); - break; - } - - /* lock entry */ - if ((used_l2table->flags & - MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC) == 0) { - MCDRV_DBG_WARN("entry is not locked locked\n"); - } - - /* free table (if no further locks exist) */ - delete_used_l2_table(used_l2table, FREE_FROM_SWD); - used_l2table = NULL; - - /* there are no out parameters */ - - } while (FALSE); - - } while (FALSE); - - - MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret); - - return ret; -} - -/*----------------------------------------------------------------------------*/ -/** Clears the reserved bit of each page and frees the pages */ -static inline void free_continguous_pages( - void *addr, - unsigned int size -) -{ - struct page *page = virt_to_page(addr); - int i; - for (i = 0; i < size; i++) { - MCDRV_DBG_VERBOSE("free page at 0x%p\n", page); - ClearPageReserved(page); - page++; - } - /* REV luh: see man kmalloc */ - free_pages((unsigned long)addr, size_to_order(size)); -} - -/*----------------------------------------------------------------------------*/ -/** - * Free a WSM buffer allocated with mobicore_allocate_wsm - * @param instance - * @param handle handle of the buffer - * - * @return 0 if no error - * - */ -int mobicore_free( - struct mc_instance *instance, - uint32_t handle -) -{ - int ret = 0; - unsigned int i; - struct mc_contg_buffer *contg_buffer; - - do { - /* search for the given address in the contg_buffers list */ - for (i = 0; i < MC_DRV_KMOD_CONTG_BUFFER_MAX; i++) { - contg_buffer = &(instance->contg_buffers[i]); - if (contg_buffer->handle == handle) - break; - } - if (i == MC_DRV_KMOD_CONTG_BUFFER_MAX) { - MCDRV_DBG_ERROR("contigous buffer not found\n"); - ret = -EFAULT; - break; - } - - MCDRV_DBG_VERBOSE("phys_addr=0x%p, virt_addr=0x%p\n", - contg_buffer->phys_addr, - contg_buffer->virt_kernel_addr); - - free_continguous_pages(contg_buffer->virt_kernel_addr, - contg_buffer->num_pages); - - memset(contg_buffer, 0, sizeof(*contg_buffer)); - - /* there are no out parameters */ - - } while (FALSE); - - - return ret; -} -EXPORT_SYMBOL(mobicore_free); -/*----------------------------------------------------------------------------*/ - -/** - * - * @param instance - * @param arg - * - * @return 0 if no error - * - */ -static int handle_ioctl_free( - struct mc_instance *instance, - union mc_ioctl_free_params *user_params -) -{ - int ret = 0; - union mc_ioctl_free_params params; - - - MCDRV_ASSERT(instance != NULL); - MCDRV_DBG_VERBOSE("enter\n"); - - do { - ret = copy_from_user( - &(params.in), - &(user_params->in), - sizeof(params.in)); - - if (ret != 0) { - MCDRV_DBG_ERROR("copy_from_user\n"); - break; - } - - /* daemon can do this for another task. */ - if (params.in.pid != 0) { - MCDRV_DBG_ERROR("pid != 0 unsupported\n"); - ret = -EINVAL; - break; - } - - ret = mobicore_free(instance, params.in.handle); - - /* there are no out parameters */ - - } while (FALSE); - - MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret); - - return ret; - -} - - -/*----------------------------------------------------------------------------*/ -/** - * - * @param instance - * @param arg - * - * @return 0 if no error - * - */ -static int handle_ioctl_info( - struct mc_instance *instance, - union mc_ioctl_info_params *user_params -) -{ - int ret = 0; - union mc_ioctl_info_params params; - union mc_fc_info fc_info; - - - MCDRV_ASSERT(instance != NULL); - MCDRV_DBG_VERBOSE("enter\n"); - - do { - /* only the MobiCore Daemon is allowed to call this function */ - if (!is_caller_mc_daemon(instance)) { - MCDRV_DBG_ERROR("caller not MobiCore Daemon\n"); - ret = -EFAULT; - break; - } - - ret = copy_from_user( - &(params.in), - &(user_params->in), - sizeof(params.in)); - - if (ret != 0) { - MCDRV_DBG_ERROR("copy_from_user\n"); - break; - } - - - memset(&fc_info, 0, sizeof(fc_info)); - fc_info.as_in.cmd = MC_FC_INFO; - fc_info.as_in.ext_info_id = params.in.ext_info_id; - - MCDRV_DBG( - "fc_info in cmd=0x%08x, ext_info_id=0x%08x " - "rfu=(0x%08x, 0x%08x)\n", - fc_info.as_in.cmd, - fc_info.as_in.ext_info_id, - fc_info.as_in.rfu[0], - fc_info.as_in.rfu[1]); - - mc_fastcall(&(fc_info.as_generic)); - - MCDRV_DBG( - "fc_info out resp=0x%08x, ret=0x%08x " - "state=0x%08x, ext_info=0x%08x\n", - fc_info.as_out.resp, - fc_info.as_out.ret, - fc_info.as_out.state, - fc_info.as_out.ext_info); - - ret = convert_fc_ret(fc_info.as_out.ret); - if (ret != 0) - break; - - memset(&(params.out), 0, sizeof(params.out)); - params.out.state = fc_info.as_out.state; - params.out.ext_info = fc_info.as_out.ext_info; - - ret = copy_to_user( - &(user_params->out), - &(params.out), - sizeof(params.out)); - - if (ret != 0) { - MCDRV_DBG_ERROR("copy_to_user\n"); - break; - } - } while (FALSE); - - MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret); - - return ret; -} - -/*----------------------------------------------------------------------------*/ -/** - * - * @param instance - * @param arg - * - * @return 0 if no error - * - */ -static int handle_ioctl_yield( - struct mc_instance *instance -) -{ - int ret = 0; - union mc_fc_s_yield fc_s_yield; - - MCDRV_ASSERT(instance != NULL); - - /* avoid putting debug output here, as we do this very often */ - MCDRV_DBG_VERBOSE("enter\n"); - - do { - /* only the MobiCore Daemon is allowed to call this function */ - if (!is_caller_mc_daemon(instance)) { - MCDRV_DBG_ERROR("caller not MobiCore Daemon\n"); - ret = -EFAULT; - break; - } - - memset(&fc_s_yield, 0, sizeof(fc_s_yield)); - fc_s_yield.as_in.cmd = MC_SMC_N_YIELD; - mc_fastcall(&(fc_s_yield.as_generic)); - ret = convert_fc_ret(fc_s_yield.as_out.ret); - if (ret != 0) - break; - - } while (FALSE); - - MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret); - - return ret; -} - -/*----------------------------------------------------------------------------*/ -/** - * handle ioctl and call common notify - * - * @param instance - * @param arg - * - * @return 0 if no error - * - */ -static int handle_ioctl_nsiq( - struct mc_instance *instance, - unsigned long arg -) -{ - int ret = 0; - - MCDRV_ASSERT(instance != NULL); - - /* avoid putting debug output here, as we do this very often */ - MCDRV_DBG_VERBOSE("enter\n"); - /* only the MobiCore Daemon is allowed to call this function */ - if (!is_caller_mc_daemon(instance)) { - MCDRV_DBG_ERROR("caller not MobiCore Daemon\n"); - return -EFAULT; - } - - do { - union mc_fc_nsiq fc_nsiq; - memset(&fc_nsiq, 0, sizeof(fc_nsiq)); - fc_nsiq.as_in.cmd = MC_SMC_N_SIQ; - mc_fastcall(&(fc_nsiq.as_generic)); - ret = convert_fc_ret(fc_nsiq.as_out.ret); - if (ret != 0) - break; - } while (FALSE); - - MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret); - - return ret; -} - -/*----------------------------------------------------------------------------*/ -/** - * - * @param instance - * @param arg - * - * @return 0 if no error - * - */ -static int handle_ioctl_dump_status( - struct mc_instance *instance, - unsigned long arg -) -{ - int ret = 0; - int i = 0; - union mc_fc_info fc_info; - - MCDRV_ASSERT(instance != NULL); - MCDRV_DBG_VERBOSE("enter\n"); - - do { - /* anybody with root access can do this. */ - if (!is_userland_caller_privileged()) { - MCDRV_DBG_ERROR("caller must have root privileges\n"); - ret = -EFAULT; - break; - } - - /* loop ext_info */ - while (TRUE) { - memset(&fc_info, 0, sizeof(fc_info)); - fc_info.as_in.cmd = MC_FC_INFO; - fc_info.as_in.ext_info_id = i; - - MCDRV_DBG( - "fc_info in cmd=0x%08x, ext_info_id=0x%08x " - "rfu=(0x%08x, 0x%08x)\n", - fc_info.as_in.cmd, - fc_info.as_in.ext_info_id, - fc_info.as_in.rfu[0], - fc_info.as_in.rfu[1]); - - mc_fastcall(&(fc_info.as_generic)); - - MCDRV_DBG( - "fc_info out resp=0x%08x, ret=0x%08x " - "state=0x%08x, ext_info=0x%08x\n", - fc_info.as_out.resp, - fc_info.as_out.ret, - fc_info.as_out.state, - fc_info.as_out.ext_info); - - ret = convert_fc_ret(fc_info.as_out.ret); - if (ret != 0) - break; - - MCDRV_DBG("state=%08X, idx=%02d: ext_info=%08X\n", - fc_info.as_out.state, - i, - fc_info.as_out.ext_info); - i++; - }; - - if (ret != 0) - break; - - - } while (FALSE); - - MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret); - - return ret; -} - -/*----------------------------------------------------------------------------*/ -/** - * - * @param instance - * @param arg - * - * @return 0 if no error - * - */ -static int handle_ioctl_init( - struct mc_instance *instance, - union mc_ioctl_init_params *user_params -) -{ - int ret = 0; - union mc_ioctl_init_params params; - union mc_fc_init fc_init; - - MCDRV_ASSERT(instance != NULL); - MCDRV_DBG_VERBOSE("enter\n"); - - do { - /* only the MobiCore Daemon is allowed to call this function */ - if (!is_caller_mc_daemon(instance)) { - MCDRV_DBG_ERROR("caller not MobiCore Daemon\n"); - ret = -EFAULT; - break; - } - - ret = copy_from_user( - &(params.in), - &(user_params->in), - sizeof(params.in)); - if (ret != 0) { - MCDRV_DBG_ERROR("copy_from_user failed\n"); - break; - } - - memset(&fc_init, 0, sizeof(fc_init)); - - fc_init.as_in.cmd = MC_FC_INIT; - /* base address of mci buffer 4KB aligned */ - fc_init.as_in.base = (uint32_t)params.in.base; - /* notification buffer start/length [16:16] [start, length] */ - fc_init.as_in.nq_info = (params.in.nq_offset << 16) - | (params.in.nq_length & 0xFFFF); - /* mcp buffer start/length [16:16] [start, length] */ - fc_init.as_in.mcp_info = (params.in.mcp_offset << 16) - | (params.in.mcp_length & 0xFFFF); - - /* Set KMOD notification queue to start of MCI - mciInfo was already set up in mmap */ - if (!mci_base) { - MCDRV_DBG_ERROR("No MCI set yet.\n"); - return -EFAULT; - } - MCDRV_DBG("in cmd=0x%08x, base=0x%08x, " - "nq_info=0x%08x, mcp_info=0x%08x\n", - fc_init.as_in.cmd, - fc_init.as_in.base, - fc_init.as_in.nq_info, - fc_init.as_in.mcp_info); - - mc_fastcall(&(fc_init.as_generic)); - - MCDRV_DBG("out cmd=0x%08x, ret=0x%08x rfu=(0x%08x, 0x%08x)\n", - fc_init.as_out.resp, - fc_init.as_out.ret, - fc_init.as_out.rfu[0], - fc_init.as_out.rfu[1]); - - ret = convert_fc_ret(fc_init.as_out.ret); - if (ret != 0) - break; - - /* no ioctl response parameters */ - - } while (FALSE); - - MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret); - - return ret; -} - -/*----------------------------------------------------------------------------*/ -/** - * - * @param instance - * @param arg - * - * @return 0 if no error - * - */ -static int handle_ioctl_fc_execute( - struct mc_instance *instance, - union mc_ioctl_fc_execute_params *user_params -) -{ - int ret = 0; - union mc_ioctl_fc_execute_params params; - union fc_generic fc_params; - - MCDRV_ASSERT(instance != NULL); - MCDRV_DBG_VERBOSE("enter\n"); - - do { - /* only the MobiCore Daemon is allowed to call this function */ - if (!is_caller_mc_daemon(instance)) { - MCDRV_DBG_ERROR("caller not MobiCore Daemon\n"); - ret = -EFAULT; - break; - } - - ret = copy_from_user( - &(params.in), - &(user_params->in), - sizeof(params.in)); - if (ret != 0) { - MCDRV_DBG_ERROR("copy_from_user failed\n"); - break; - } - - fc_params.as_in.cmd = -4;/*FC_EXECUTE */ - fc_params.as_in.param[0] = params.in.phys_start_addr; - fc_params.as_in.param[1] = params.in.length; - fc_params.as_in.param[2] = 0; - - MCDRV_DBG("in cmd=0x%08x, startAddr=0x%08x, length=0x%08x\n", - fc_params.as_in.cmd, - fc_params.as_in.param[0], - fc_params.as_in.param[1]); - - mc_fastcall(&fc_params); - - MCDRV_DBG("out cmd=0x%08x, ret=0x%08x rfu=(0x%08x, 0x%08x)\n", - fc_params.as_out.resp, - fc_params.as_out.ret, - fc_params.as_out.param[0], - fc_params.as_out.param[1]); - - ret = convert_fc_ret(fc_params.as_out.ret); - if (ret != 0) - break; - - /* no ioctl response parameters */ - - } while (FALSE); - - MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret); - - return ret; -} - -/*----------------------------------------------------------------------------*/ -#define MC_MAKE_VERSION(major, minor) \ - (((major & 0x0000ffff) << 16) | (minor & 0x0000ffff)) -/** - * - * @param instance - * @param arg - * - * @return 0 if no error - * - */ -static int handle_ioctl_get_version( - struct mc_instance *instance, - struct mc_ioctl_get_version_params *user_params -) -{ - int ret = 0; - struct mc_ioctl_get_version_params params = { - { - MC_MAKE_VERSION(MCDRVMODULEAPI_VERSION_MAJOR, - MCDRVMODULEAPI_VERSION_MINOR) - } - }; - - MCDRV_ASSERT(instance != NULL); - MCDRV_DBG_VERBOSE("enter\n"); - - do { - MCDRV_DBG("mcDrvModuleApi version is %i.%i\n", - MCDRVMODULEAPI_VERSION_MAJOR, - MCDRVMODULEAPI_VERSION_MINOR); - - /* no ioctl response parameters */ - ret = copy_to_user( - &(user_params->out), - &(params.out), - sizeof(params.out)); - if (ret != 0) - MCDRV_DBG_ERROR("copy_to_user() failed\n"); - - } while (FALSE); - - MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret); - - return ret; -} - -/*----------------------------------------------------------------------------*/ -/** - * This function will be called from user space as ioctl(...). - * @param file pointer to file - * @param cmd command - * @param arg arguments - * - * @return int 0 for OK and an errno in case of error - */ -static long mc_kernel_module_ioctl( - struct file *file, - unsigned int cmd, - unsigned long arg -) -{ - int ret; - struct mc_instance *instance = get_instance(file); - - MCDRV_ASSERT(instance != NULL); - - switch (cmd) { - /*--------------------------------------------------------------------*/ - case MC_DRV_KMOD_IOCTL_DUMP_STATUS: - ret = handle_ioctl_dump_status( - instance, - arg); - break; - - /*--------------------------------------------------------------------*/ - case MC_DRV_KMOD_IOCTL_FC_INIT: - ret = handle_ioctl_init( - instance, - (union mc_ioctl_init_params *)arg); - break; - /*--------------------------------------------------------------------*/ - case MC_DRV_KMOD_IOCTL_FC_INFO: - ret = handle_ioctl_info( - instance, - (union mc_ioctl_info_params *)arg); - break; - - /*--------------------------------------------------------------------*/ - case MC_DRV_KMOD_IOCTL_FC_YIELD: - ret = handle_ioctl_yield( - instance); - break; - - /*--------------------------------------------------------------------*/ - case MC_DRV_KMOD_IOCTL_FC_NSIQ: - ret = handle_ioctl_nsiq( - instance, - arg); - break; - - /*--------------------------------------------------------------------*/ - case MC_DRV_KMOD_IOCTL_DAEMON_LOCK_WSM_L2: - ret = handle_ioctl_daemon_lock_wsm_l2( - instance, - (struct mc_ioctl_daemon_lock_wsm_l2_params *)arg); - break; - - /*--------------------------------------------------------------------*/ - case MC_DRV_KMOD_IOCTL_DAEMON_UNLOCK_WSM_L2: - ret = handle_ioctl_daemon_unlock_wsm_l2( - instance, - (struct mc_ioctl_daemon_unlock_wsm_l2_params *)arg); - break; - - /*--------------------------------------------------------------------*/ - case MC_DRV_KMOD_IOCTL_FREE: - /* called by ClientLib */ - ret = handle_ioctl_free( - instance, - (union mc_ioctl_free_params *)arg); - break; - - /*--------------------------------------------------------------------*/ - case MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2: - /* called by ClientLib */ - ret = handle_ioctl_app_register_wsm_l2( - instance, - (union mc_ioctl_app_reg_wsm_l2_params *)arg); - break; - - /*--------------------------------------------------------------------*/ - case MC_DRV_KMOD_IOCTL_APP_UNREGISTER_WSM_L2: - /* called by ClientLib */ - ret = handle_ioctl_app_unregister_wsm_l2( - instance, - (struct mc_ioctl_app_unreg_wsm_l2_params *)arg); - break; - - /*--------------------------------------------------------------------*/ - case MC_DRV_KMOD_IOCTL_FC_EXECUTE: - ret = handle_ioctl_fc_execute( - instance, - (union mc_ioctl_fc_execute_params *)arg); - break; - - /*--------------------------------------------------------------------*/ - case MC_DRV_KMOD_IOCTL_GET_VERSION: - ret = handle_ioctl_get_version( - instance, - (struct mc_ioctl_get_version_params *)arg); - break; - - /*--------------------------------------------------------------------*/ - default: - MCDRV_DBG_ERROR("unsupported cmd=%d\n", cmd); - ret = -EFAULT; - break; - - } /* end switch(cmd) */ - -#ifdef MC_MEM_TRACES - mobicore_log_read(); -#endif - - return (int)ret; -} - - -/*----------------------------------------------------------------------------*/ -/** - * This function will be called from user space as read(...). - * The read function is blocking until a interrupt occurs. In that case the - * event counter is copied into user space and the function is finished. - * @param *file - * @param *buffer buffer where to copy to(userspace) - * @param buffer_len number of requested data - * @param *pos not used - * @return ssize_t ok case: number of copied data - * error case: return errno - */ -static ssize_t mc_kernel_module_read( - struct file *file, - char *buffer, - size_t buffer_len, - loff_t *pos -) -{ - int ret = 0, ssiq_counter; - size_t retLen = 0; - struct mc_instance *instance = get_instance(file); - - MCDRV_ASSERT(instance != NULL); - - /* avoid debug output on non-error, because this is call quite often */ - MCDRV_DBG_VERBOSE("enter\n"); - - do { - /* only the MobiCore Daemon is allowed to call this function */ - if (!is_caller_mc_daemon(instance)) { - MCDRV_DBG_ERROR("caller not MobiCore Daemon\n"); - ret = -EFAULT; - break; - } - - if (buffer_len < sizeof(unsigned int)) { - MCDRV_DBG_ERROR("invalid length\n"); - ret = (ssize_t)(-EINVAL); - break; - } - - for (;;) { - if (down_interruptible( - &mc_drv_kmod_ctx.daemon_ctx.sem)) { - MCDRV_DBG_VERBOSE("read interrupted\n"); - ret = (ssize_t)-ERESTARTSYS; - break; - } - - ssiq_counter = atomic_read( - &(mc_drv_kmod_ctx.ssiq_ctx.counter)); - MCDRV_DBG_VERBOSE("ssiq_counter=%i, ctx.counter=%i\n", - ssiq_counter, - mc_drv_kmod_ctx.daemon_ctx.ssiq_counter); - - if (ssiq_counter != - mc_drv_kmod_ctx.daemon_ctx.ssiq_counter) { - /* read data and exit loop without - error */ - mc_drv_kmod_ctx.daemon_ctx.ssiq_counter = - ssiq_counter; - ret = 0; - break; - } - - /* end loop if non-blocking */ - if ((file->f_flags & O_NONBLOCK) != 0) { - MCDRV_DBG_ERROR("non-blocking read\n"); - ret = (ssize_t)(-EAGAIN); - break; - } - - if (signal_pending(current) != 0) { - MCDRV_DBG_VERBOSE("received signal.\n"); - ret = (ssize_t)(-ERESTARTSYS); - break; - } - - } - - /* we are here if an event occurred or we had an - error.*/ - if (ret != 0) - break; - - /* read data and exit loop */ - ret = copy_to_user( - buffer, - &(mc_drv_kmod_ctx.daemon_ctx.ssiq_counter), - sizeof(unsigned int)); - - - if (ret != 0) { - MCDRV_DBG_ERROR("copy_to_user failed\n"); - ret = (ssize_t)(-EFAULT); - break; - } - - retLen = sizeof(s32); - - } while (FALSE); - - /* avoid debug on non-error. */ - if (ret == 0) - ret = (size_t)retLen; - else - MCDRV_DBG("exit with %d/0x%08X\n", ret, ret); - - return (ssize_t)ret; -} - -/*----------------------------------------------------------------------------*/ -/** - * Allocate WSM for given instance - * - * @param instance instance - * @param requested_size size of the WSM - * @param handle pointer where the handle will be saved - * @param virt_kernel_addr pointer for the kernel virtual address - * @param phys_addr pointer for the physical address - * - * @return error code or 0 for success - */ -int mobicore_allocate_wsm( - struct mc_instance *instance, - unsigned long requested_size, - uint32_t *handle, - void **virt_kernel_addr, - void **phys_addr -) -{ - unsigned int i; - unsigned int order; - unsigned long allocated_size; - int ret = 0; - struct mc_contg_buffer *contg_buffer = 0; - void *virt_kernel_addr_stack; - void *phys_addr_stack; - - MCDRV_ASSERT(instance != NULL); - MCDRV_DBG("%s (size=%ld)\n", __func__, requested_size); - - order = size_to_order(requested_size); - if (order == INVALID_ORDER) { - MCDRV_DBG_ERROR( - "size to order converting failed for size %ld\n", - requested_size); - return INVALID_ORDER; - } - - allocated_size = (1< order %d --> %ld (2^n pages)\n", - requested_size, order, allocated_size); - - do { - /* Usual Wsm request, allocate contigous buffer. */ - /* search for a free entry in the wsm buffer list - * REV axh: serialize this over multiple instances. */ - for (i = 0; i < MC_DRV_KMOD_CONTG_BUFFER_MAX; i++) { - contg_buffer = &(instance->contg_buffers[i]); - if (contg_buffer->handle == 0) { - contg_buffer->handle = get_mc_kmod_unique_id(); - break; - } - } - if (i == MC_DRV_KMOD_CONTG_BUFFER_MAX) { - MCDRV_DBG_ERROR("no free contigous buffer\n"); - ret = -EFAULT; - break; - } - - /* Common code for all allocation paths */ - virt_kernel_addr_stack = (void *)__get_free_pages( - GFP_USER | __GFP_COMP, - order); - if (virt_kernel_addr_stack == NULL) { - MCDRV_DBG_ERROR("get_free_pages failed\n"); - ret = -ENOMEM; - break; - } - - /* Get physical address to instance data */ - phys_addr_stack = (void *)virt_to_phys(virt_kernel_addr_stack); - /* TODO: check for INVALID_ADDRESS? */ - - MCDRV_DBG( - "allocated phys=0x%p - 0x%p, " - "size=%ld, kernel_virt=0x%p, handle=%d\n", - phys_addr_stack, - (void *)((unsigned int)phys_addr_stack+allocated_size), - allocated_size, - virt_kernel_addr_stack, - contg_buffer->handle); - - /* Usual Wsm request, allocate contg_buffer. - * Also, we never free a persistent Tci */ - contg_buffer->phys_addr = phys_addr_stack; - contg_buffer->virt_kernel_addr = virt_kernel_addr_stack; - contg_buffer->virt_user_addr = virt_kernel_addr_stack; - contg_buffer->num_pages = (1U << order); - *handle = contg_buffer->handle; - *virt_kernel_addr = virt_kernel_addr_stack; - *phys_addr = phys_addr_stack; - - } while (FALSE); - - MCDRV_DBG_VERBOSE("%s: exit with 0x%08X\n", __func__, ret); - - return ret; -} -EXPORT_SYMBOL(mobicore_allocate_wsm); - - -/*----------------------------------------------------------------------------*/ -/** - * This function will be called from user space as address = mmap(...). - * - * @param file - * @param vmarea - * vmarea.pg_offset != 0 is mapping of MCI is requested - * - * @return 0 if OK or -ENOMEM in case of error. - */ -static int mc_kernel_module_mmap( - struct file *file, - struct vm_area_struct *vmarea -) -{ - unsigned int i; - unsigned int order; - void *virt_kernel_addr_stack = 0; - void *phys_addr = 0; - unsigned long requested_size = - vmarea->vm_end - vmarea->vm_start; - unsigned long allocated_size; - int ret = 0; - struct mc_contg_buffer *contg_buffer = 0; - unsigned int handle = 0; - struct mc_instance *instance = get_instance(file); - unsigned int request = vmarea->vm_pgoff * 4096; -#if defined(DEBUG) - bool release = false; -#else - bool release = true; -#endif - - MCDRV_ASSERT(instance != NULL); - MCDRV_DBG("enter (vmaStart=0x%p, size=%ld, request=0x%x, mci=0x%x)\n", - (void *)vmarea->vm_start, - requested_size, - request, - mci_base); - - order = size_to_order(requested_size); - if (order == INVALID_ORDER) { - MCDRV_DBG_ERROR( - "size to order converting failed for size %ld\n", - requested_size); - return -ENOMEM; - } - - allocated_size = (1< order %d --> %ld (2^n pages)\n", - requested_size, order, allocated_size); - - do { - /* Daemon tries to get an existing MCI */ - if ((request == MC_DRV_KMOD_MMAP_MCI) && (mci_base != 0)) { - MCDRV_DBG("Request MCI, it is at (%x)\n", mci_base); - - if (!is_caller_mc_daemon(instance)) { - ret = -EPERM; - break; - } - virt_kernel_addr_stack = (void *)mci_base; - phys_addr = - (void *)virt_to_phys(virt_kernel_addr_stack); - } else { - /* Usual Wsm request, allocate buffer. */ - if (request == MC_DRV_KMOD_MMAP_WSM) { - /* search for a free entry in the buffer list - REV axh: serialize this over multiple instances. - */ - for (i = 0; i < MC_DRV_KMOD_CONTG_BUFFER_MAX; - i++) { - contg_buffer = - &(instance->contg_buffers[i]); - if (contg_buffer->handle == 0) { - contg_buffer->handle = - get_mc_kmod_unique_id(); - break; - } - } - if (i == MC_DRV_KMOD_CONTG_BUFFER_MAX) { - MCDRV_DBG_ERROR( - "no free contigous buffer\n"); - ret = -EFAULT; - break; - } - } else { - if (request <= MC_DRV_KMOD_MMAP_PERSISTENTWSM - || release) { - /* Special Wsm request - --> only Daemon is allowed */ - if (!is_caller_mc_daemon(instance)) { - ret = -EPERM; - break; - } - } - } - if (request <= MC_DRV_KMOD_MMAP_PERSISTENTWSM) { - /* Common code for all allocation paths - * get physical address, */ - virt_kernel_addr_stack = - (void *)__get_free_pages( - GFP_USER | __GFP_COMP, - order); - if (virt_kernel_addr_stack == NULL) { - MCDRV_DBG_ERROR( - "get_free_pages failed\n"); - ret = -ENOMEM; - break; - } - if (request == MC_DRV_KMOD_MMAP_WSM) - handle = contg_buffer->handle; - /* Get physical address to instance data */ - /* TODO: check for INVALID_ADDRESS? */ - phys_addr = (void *)virt_to_phys( - virt_kernel_addr_stack); - } else { -#if defined(DEBUG) - phys_addr = (void *)request; - virt_kernel_addr_stack = phys_to_virt(request); -#endif - } - } - /* Common code for all mmap calls: - * map page to user - * store data in page */ - - MCDRV_DBG("allocated phys=0x%p - 0x%p, " - "size=%ld, kernel_virt=0x%p, handle=%d\n", - phys_addr, - (void *)((unsigned int)phys_addr+allocated_size), - allocated_size, virt_kernel_addr_stack, handle); - - vmarea->vm_flags |= VM_RESERVED; - /* convert Kernel address to User Address. Kernel address begins - at PAGE_OFFSET, user Address range is below PAGE_OFFSET. - Remapping the area is always done, so multiple mappings - of one region are possible. Now remap kernel address - space into user space */ - ret = (int)remap_pfn_range( - vmarea, - (vmarea->vm_start), - addr_to_pfn(phys_addr), - requested_size, - vmarea->vm_page_prot); - if (ret != 0) { - MCDRV_DBG_ERROR("remapPfnRange failed\n"); - - /* free allocated pages when mmap fails, however, do not - do it, when daemon tried to get an MCI that - existed */ - if (!((request == MC_DRV_KMOD_MMAP_MCI) && - (mci_base != 0))) - free_continguous_pages(virt_kernel_addr_stack, - (1U << order)); - break; - } - - /* Usual Wsm request, allocate contg_buffer. - When requesting Mci, we do not associate the page with - the process. - Note: we also never free the Mci - Also, we never free a persistent Tci */ - if (request == MC_DRV_KMOD_MMAP_WSM) { - contg_buffer->phys_addr = phys_addr; - contg_buffer->virt_kernel_addr = virt_kernel_addr_stack; - contg_buffer->virt_user_addr = - (void *)(vmarea->vm_start); - contg_buffer->num_pages = (1U << order); - } - - /* set response in allocated buffer */ - { - struct mc_mmap_resp *mmap_resp = - (struct mc_mmap_resp *)virt_kernel_addr_stack; - /* TODO: do this for daemon only, otherwise set NULL */ - mmap_resp->phys_addr = (uint32_t)phys_addr; - mmap_resp->handle = handle; - if ((request == MC_DRV_KMOD_MMAP_MCI) && - (mci_base != 0)) { - mmap_resp->is_reused = 1; - } else - mmap_resp->is_reused = 0; - } - - /* store MCI pointer */ - if ((request == MC_DRV_KMOD_MMAP_MCI) && (mci_base == 0)) { - mci_base = (uint32_t)virt_kernel_addr_stack; - MCDRV_DBG("MCI base set to 0x%x\n", mci_base); - } - } while (FALSE); - - MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret); - - return (int)ret; -} - -#ifdef CONFIG_SMP -/*----------------------------------------------------------------------------*/ -/** - * Force migration of current task to CPU0(where the monitor resides) - * - * @return Error code or 0 for success - */ -static int goto_cpu0( - void -) -{ - int ret = 0; - struct cpumask mask = CPU_MASK_CPU0; - - MCDRV_DBG_VERBOSE("System has %d CPU's, we are on CPU #%d\n" - "\tBinding this process to CPU #0.\n" - "\tactive mask is %lx, setting it to mask=%lx\n", - nr_cpu_ids, - raw_smp_processor_id(), - cpu_active_mask->bits[0], - mask.bits[0]); - ret = set_cpus_allowed_ptr(current, &mask); - if (ret != 0) - MCDRV_DBG_ERROR("set_cpus_allowed_ptr=%d.\n", ret); - MCDRV_DBG_VERBOSE("And now we are on CPU #%d\n", - raw_smp_processor_id()); - - return ret; -} - -/*----------------------------------------------------------------------------*/ -/** - * Restore CPU mask for current to ALL Cpus(reverse of goto_cpu0) - * - * @return Error code or 0 for success - */ -static int goto_all_cpu( - void -) -{ - int ret = 0; - - struct cpumask mask = CPU_MASK_ALL; - - MCDRV_DBG_VERBOSE("System has %d CPU's, we are on CPU #%d\n" - "\tBinding this process to CPU #0.\n" - "\tactive mask is %lx, setting it to mask=%lx\n", - nr_cpu_ids, - raw_smp_processor_id(), - cpu_active_mask->bits[0], - mask.bits[0]); - ret = set_cpus_allowed_ptr(current, &mask); - if (ret != 0) - MCDRV_DBG_ERROR("set_cpus_allowed_ptr=%d.\n", ret); - MCDRV_DBG_VERBOSE("And now we are on CPU #%d\n", - raw_smp_processor_id()); - - return ret; -} - -#else -static int goto_cpu0(void) -{ - return 0; -} - -static int goto_all_cpu(void) -{ - return 0; -} -#endif - -/*----------------------------------------------------------------------------*/ -/** - * Initialize a new mobicore API instance object - * - * @return Instance or NULL if no allocation was possible. - */ -struct mc_instance *mobicore_open( - void -) { - struct mc_instance *instance; - pid_t pid_vnr; - - instance = kzalloc(sizeof(*instance), GFP_KERNEL); - if (instance == NULL) - return NULL; - - /* get a unique ID for this instance (PIDs are not unique) */ - instance->handle = get_mc_kmod_unique_id(); - - /* get the PID of the calling process. We avoid using - * current->pid directly, as 2.6.24 introduced PID - * namespaces. See also http://lwn.net/Articles/259217 */ - pid_vnr = task_pid_vnr(current); - instance->pid_vnr = pid_vnr; - - return instance; -} -EXPORT_SYMBOL(mobicore_open); - -/*----------------------------------------------------------------------------*/ -/** - * This function will be called from user space as fd = open(...). - * A set of internal instance data are created and initialized. - * - * @param inode - * @param file - * @return 0 if OK or -ENOMEM if no allocation was possible. - */ -static int mc_kernel_module_open( - struct inode *inode, - struct file *file -) -{ - struct mc_instance *instance; - int ret = 0; - - MCDRV_DBG_VERBOSE("enter\n"); - - do { - instance = mobicore_open(); - if (instance == NULL) - return -ENOMEM; - - /* check if Daemon. We simply assume that the first to open us - with root privileges must be the daemon. */ - if ((is_userland_caller_privileged()) - && (mc_drv_kmod_ctx.daemon_inst == NULL)) { - MCDRV_DBG("accept this as MobiCore Daemon\n"); - - /* Set the caller's CPU mask to CPU0*/ - ret = goto_cpu0(); - if (ret != 0) { - mobicore_release(instance); - file->private_data = NULL; - MCDRV_DBG("changing core failed!\n"); - break; - } - - mc_drv_kmod_ctx.daemon_inst = instance; - sema_init(&mc_drv_kmod_ctx.daemon_ctx.sem, - DAEMON_SEM_VAL); - /* init ssiq event counter */ - mc_drv_kmod_ctx.daemon_ctx.ssiq_counter = - atomic_read( - &(mc_drv_kmod_ctx.ssiq_ctx.counter)); - -#ifdef MC_MEM_TRACES - /* The traces have to be setup on CPU-0 since we must - * do a fastcall to MobiCore. */ - if (!mci_base) - /* Do the work only if MCI base is not - * initialized properly */ - work_on_cpu(0, mobicore_log_setup, NULL); -#endif - } - - /* store instance data reference */ - file->private_data = instance; - - /* TODO axh: link all instances to allow clean up? */ - - } while (FALSE); - - MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret); - - return (int)ret; - -} - -/*----------------------------------------------------------------------------*/ -/** - * Release a mobicore instance object and all objects related to it - * @param instance instance - * @return 0 if Ok or -E ERROR - */ -int mobicore_release( - struct mc_instance *instance -) -{ - int ret = 0; - int i; - struct mc_used_l2_table *used_l2table, *used_l2table_temp; - - do { - /* try to get the semaphore */ - ret = down_interruptible(&(mc_drv_kmod_ctx.wsm_l2_sem)); - if (ret != 0) { - MCDRV_DBG_ERROR( - "down_interruptible() failed with %d\n", ret); - /* TODO: can be block here? */ - ret = -ERESTARTSYS; - } else { - /* Check if some WSM is still in use. */ - list_for_each_entry_safe( - used_l2table, - used_l2table_temp, - &(mc_drv_kmod_ctx.mc_used_l2_tables), - list - ) { - if (used_l2table->owner == instance) { - MCDRV_DBG_WARN( - "trying to release WSM L2: " - "physBase=%p ,nr_of_pages=%d\n", - get_l2_table_phys(used_l2table), - used_l2table->nr_of_pages); - - /* unlock app usage and free if MobiCore - does not use it */ - delete_used_l2_table(used_l2table, - FREE_FROM_NWD); - } - } /* end while */ - - /* release semaphore */ - up(&(mc_drv_kmod_ctx.wsm_l2_sem)); - } - - - /* release all mapped data */ - for (i = 0; i < MC_DRV_KMOD_CONTG_BUFFER_MAX; i++) { - struct mc_contg_buffer *contg_buffer = - &(instance->contg_buffers[i]); - - if (contg_buffer->virt_user_addr != 0) { - free_continguous_pages( - contg_buffer->virt_kernel_addr, - contg_buffer->num_pages); - } - } - - /* release instance context */ - kfree(instance); - } while (FALSE); - - return ret; -} -EXPORT_SYMBOL(mobicore_release); - -/*----------------------------------------------------------------------------*/ -/** - * This function will be called from user space as close(...). - * The instance data are freed and the associated memory pages are unreserved. - * - * @param inode - * @param file - * - * @return 0 - */ -static int mc_kernel_module_release( - struct inode *inode, - struct file *file -) -{ - int ret = 0; - struct mc_instance *instance = get_instance(file); - - MCDRV_DBG_VERBOSE("enter\n"); - - do { - /* check if daemon closes us. */ - if (is_caller_mc_daemon(instance)) { - /* TODO: cleanup? - * mc_drv_kmod_ctx.mc_used_l2_tables remains */ - MCDRV_DBG_WARN("WARNING: MobiCore Daemon died\n"); - mc_drv_kmod_ctx.daemon_inst = NULL; - } - - ret = mobicore_release(instance); - - } while (FALSE); - - MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret); - - return (int)ret; -} - - -/*----------------------------------------------------------------------------*/ -/** - * This function represents the interrupt function of the mcDrvModule. - * It signals by incrementing of an event counter and the start of the read - * waiting queue, the read function a interrupt has occurred. - * - * @param intr - * @param *context pointer to registered device data - * - * @return IRQ_HANDLED - */ -static irqreturn_t mc_kernel_module_intr_ssiq( - int intr, - void *context -) -{ - irqreturn_t ret = IRQ_NONE; - - /* we know the context. */ - MCDRV_ASSERT(&mc_drv_kmod_ctx == context); - - do { - if (intr != MC_INTR_SSIQ) { - /* this should not happen, as we did no register for any - other interrupt. For debugging, we print a - message, but continue */ - MCDRV_DBG_WARN( - "unknown interrupt %d, expecting only %d\n", - intr, MC_INTR_SSIQ); - } - MCDRV_DBG_VERBOSE("received interrupt %d\n", - intr); - - /* increment interrupt event counter */ - atomic_inc(&(mc_drv_kmod_ctx.ssiq_ctx.counter)); - - /* signal the daemon */ - up(&mc_drv_kmod_ctx.daemon_ctx.sem); - - - ret = IRQ_HANDLED; - - } while (FALSE); - - return ret; -} - -/*----------------------------------------------------------------------------*/ -/** function table structure of this device driver. */ -static const struct file_operations mc_kernel_module_file_operations = { - .owner = THIS_MODULE, /**< driver owner */ - .open = mc_kernel_module_open, /**< driver open function */ - .release = mc_kernel_module_release, /**< driver release function*/ - .unlocked_ioctl = mc_kernel_module_ioctl, /**< driver ioctl function */ - .mmap = mc_kernel_module_mmap, /**< driver mmap function */ - .read = mc_kernel_module_read, /**< driver read function */ -}; - -/*----------------------------------------------------------------------------*/ -/** registration structure as miscdevice. */ -static struct miscdevice mc_kernel_module_device = { - .name = MC_DRV_MOD_DEVNODE, /**< device name */ - .minor = MISC_DYNAMIC_MINOR, /**< device minor number */ - /** device interface function structure */ - .fops = &mc_kernel_module_file_operations, -}; - - -/*----------------------------------------------------------------------------*/ -/** - * This function is called the kernel during startup or by a insmod command. - * This device is installed and registered as miscdevice, then interrupt and - * queue handling is set up - * - * @return 0 for no error or -EIO if registration fails - */ -static int __init mc_kernel_module_init( - void -) -{ - int ret = 0; - - MCDRV_DBG("enter (Build " __TIMESTAMP__ ")\n"); - MCDRV_DBG("mcDrvModuleApi version is %i.%i\n", - MCDRVMODULEAPI_VERSION_MAJOR, - MCDRVMODULEAPI_VERSION_MINOR); -#ifdef MOBICORE_COMPONENT_BUILD_TAG - MCDRV_DBG("%s\n", MOBICORE_COMPONENT_BUILD_TAG); -#endif - do { - /* Hardware does not support ARM TrustZone - -> Cannot continue! */ - if (!has_security_extensions()) { - MCDRV_DBG_ERROR( - "Hardware does't support ARM TrustZone!\n"); - ret = -ENODEV; - break; - } - - /* Running in secure mode -> Cannot load the driver! */ - if (is_secure_mode()) { - MCDRV_DBG_ERROR("Running in secure MODE!\n"); - ret = -ENODEV; - break; - } - - sema_init(&mc_drv_kmod_ctx.daemon_ctx.sem, DAEMON_SEM_VAL); - /* set up S-SIQ interrupt handler */ - ret = request_irq( - MC_INTR_SSIQ, - mc_kernel_module_intr_ssiq, - IRQF_TRIGGER_RISING, - MC_DRV_MOD_DEVNODE, - &mc_drv_kmod_ctx); - if (ret != 0) { - MCDRV_DBG_ERROR("interrupt request failed\n"); - break; - } - - ret = misc_register(&mc_kernel_module_device); - if (ret != 0) { - MCDRV_DBG_ERROR("device register failed\n"); - break; - } - - /* initialize event counter for signaling of an IRQ to zero */ - atomic_set(&(mc_drv_kmod_ctx.ssiq_ctx.counter), 0); - - /* init list for WSM L2 chunks. */ - INIT_LIST_HEAD(&(mc_drv_kmod_ctx.mc_l2_tables_sets)); - - /* L2 table descriptor list. */ - INIT_LIST_HEAD(&(mc_drv_kmod_ctx.mc_used_l2_tables)); - - sema_init(&(mc_drv_kmod_ctx.wsm_l2_sem), 1); - - /* initialize unique number counter which we can use for - handles. It is limited to 2^32, but this should be - enough to be roll-over safe for us. We start with 1 - instead of 0. */ - atomic_set(&(mc_drv_kmod_ctx.unique_counter), 1); - - mci_base = 0; - MCDRV_DBG("initialized\n"); - - ret = 0; - - } while (FALSE); - - MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret); - - return (int)ret; -} - - - -/*----------------------------------------------------------------------------*/ -/** - * This function removes this device driver from the Linux device manager . - */ -static void __exit mc_kernel_module_exit( - void -) -{ - struct mc_used_l2_table *used_l2table; - - MCDRV_DBG_VERBOSE("enter\n"); - - mobicore_log_free(); - - /* Check if some WSM is still in use. */ - list_for_each_entry( - used_l2table, - &(mc_drv_kmod_ctx.mc_used_l2_tables), - list - ) { - MCDRV_DBG_WARN( - "WSM L2 still in use: physBase=%p ,nr_of_pages=%d\n", - get_l2_table_phys(used_l2table), - used_l2table->nr_of_pages); - } /* end while */ - - free_irq(MC_INTR_SSIQ, &mc_drv_kmod_ctx); - - misc_deregister(&mc_kernel_module_device); - MCDRV_DBG_VERBOSE("exit"); -} - - -/*----------------------------------------------------------------------------*/ -/* Linux Driver Module Macros */ -module_init(mc_kernel_module_init); -module_exit(mc_kernel_module_exit); -MODULE_AUTHOR("Giesecke & Devrient GmbH"); -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("MobiCore driver"); - -/** @} */ - diff --git a/drivers/gud/mobicore_driver/mc_drv_module.h b/drivers/gud/mobicore_driver/mc_drv_module.h deleted file mode 100644 index 8b402d6ff371..000000000000 --- a/drivers/gud/mobicore_driver/mc_drv_module.h +++ /dev/null @@ -1,238 +0,0 @@ -/** - * Header file of MobiCore Driver Kernel Module. - * - * @addtogroup MCD_MCDIMPL_KMOD_IMPL - * @{ - * Internal structures of the McDrvModule - * @file - * - * Header file the MobiCore Driver Kernel Module, - * its internal structures and defines. - * - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _MC_DRV_KMOD_H_ -#define _MC_DRV_KMOD_H_ - -#include "mc_drv_module_linux_api.h" -#include "public/mc_drv_module_api.h" -/** Platform specific settings */ -#include "platform.h" - -/** ARM Specific masks and modes */ -#define ARM_CPSR_MASK 0x1F -#define ARM_MONITOR_MODE 0b10110 -#define ARM_SECURITY_EXTENSION_MASK 0x30 - -/** - * Number of page table entries in one L2 table. This is ARM specific, an - * L2 table covers 1 MiB by using 256 entry referring to 4KiB pages each. - */ -#define MC_ARM_L2_TABLE_ENTRIES 256 - -/** Maximum number of contiguous buffer allocations for one driver instance. */ -#define MC_DRV_KMOD_CONTG_BUFFER_MAX 16 - -/** Number of pages for L2 tables. There are 4 table in each page. */ -#define MC_DRV_KMOD_L2_TABLE_PER_PAGES 4 - -/** ARM level 2 (L2) table with 256 entries. Size: 1k */ -struct l2table { - pte_t table_entries[MC_ARM_L2_TABLE_ENTRIES]; -}; - -#define INVALID_ADDRESS ((void *)(-1)) - -/** ARM L2 PTE bits */ -#define L2_FLAG_SMALL_XN (1U << 0) -#define L2_FLAG_SMALL (1U << 1) -#define L2_FLAG_B (1U << 2) -#define L2_FLAG_C (1U << 3) -#define L2_FLAG_AP0 (1U << 4) -#define L2_FLAG_AP1 (1U << 5) -#define L2_FLAG_SMALL_TEX0 (1U << 6) -#define L2_FLAG_SMALL_TEX1 (1U << 7) -#define L2_FLAG_SMALL_TEX2 (1U << 8) -#define L2_FLAG_APX (1U << 9) -#define L2_FLAG_S (1U << 10) -#define L2_FLAG_NG (1U << 11) - -/** - * Contiguous buffer allocated to TLCs. - * These buffers are uses as world shared memory (wsm) and shared with - * secure world. - * The virtual kernel address is added for a simpler search algorithm. - */ -struct mc_contg_buffer { - unsigned int handle; /* unique handle */ - void *virt_user_addr; /**< virtual User start address */ - void *virt_kernel_addr; /**< virtual Kernel start address */ - void *phys_addr; /**< physical start address */ - unsigned int num_pages; /**< number of pages */ -}; - -/** Instance data for MobiCore Daemon and TLCs. */ -struct mc_instance { - /** unique handle */ - unsigned int handle; - /** process that opened this instance */ - pid_t pid_vnr; - /** buffer list for mmap generated address space and - its virtual client address */ - struct mc_contg_buffer contg_buffers[MC_DRV_KMOD_CONTG_BUFFER_MAX]; -}; - -/** Store for four L2 tables in one 4kb page*/ -struct mc_l2_table_store { - struct l2table table[MC_DRV_KMOD_L2_TABLE_PER_PAGES]; -}; - -/** Usage and maintenance information about mc_l2_table_store */ -struct mc_l2_tables_set { - struct list_head list; - unsigned int usage_bitmap; /**< usage bitmap */ - struct mc_l2_table_store *kernel_virt; /**< kernel virtual address */ - struct mc_l2_table_store *phys; /**< physical address */ - struct page *page; /**< pointer to page struct */ -}; - -/** - * L2 table allocated to the Daemon or a TLC describing a world shared buffer. - * When users map a malloc()ed area into SWd, a L2 table is allocated. - * In addition, the area of maximum 1MB virtual address space is mapped into - * the L2 table and a handle for this table is returned to the user. - */ -struct mc_used_l2_table { - struct list_head list; - - /** handle as communicated to user mode */ - unsigned int handle; - unsigned int flags; - - /** owner of this L2 table */ - struct mc_instance *owner; - - /** set describing where our L2 table is stored */ - struct mc_l2_tables_set *set; - - /** index into L2 table set */ - unsigned int idx; - - /** size of buffer */ - unsigned int nr_of_pages; -}; - -#define MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_APP (1U << 0) -#define MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC (1U << 1) - - -/** MobiCore S-SIQ interrupt context data. */ -struct mc_ssiq_ctx { - /** S-SIQ interrupt counter */ - atomic_t counter; -}; - -/** MobiCore Daemon context data. */ -struct mc_daemon_ctx { - /** event semaphore */ - struct semaphore sem; - struct fasync_struct *async_queue; - /** event counter */ - unsigned int ssiq_counter; -}; - -/** MobiCore Driver Kernel Module context data. */ -struct mc_drv_kmod_ctx { - - /** ever incrementing counter */ - atomic_t unique_counter; - - /** S-SIQ interrupt context */ - struct mc_ssiq_ctx ssiq_ctx; - - /** MobiCore Daemon context */ - struct mc_daemon_ctx daemon_ctx; - - /** pointer to instance of daemon */ - struct mc_instance *daemon_inst; - - /** Backing store for L2 tables */ - struct list_head mc_l2_tables_sets; - - /** Bookkeeping for used L2 tables */ - struct list_head mc_used_l2_tables; - - /** semaphore to synchronize access to above lists */ - struct semaphore wsm_l2_sem; -}; - -/** MobiCore internal trace buffer structure. */ -struct mc_trace_buf { - uint32_t version; /**< version of trace buffer */ - uint32_t length; /**< length of allocated buffer(includes header) */ - uint32_t write_pos; /**< last write position */ - char buff[1]; /**< start of the log buffer */ -}; - -/*** MobiCore internal trace log setup. */ -void mobicore_log_read(void); -long mobicore_log_setup(void *); -void mobicore_log_free(void); - -#define MCDRV_DBG_ERROR(txt, ...) \ - printk(KERN_ERR "mcDrvKMod [%d] %s() ### ERROR: " txt, \ - task_pid_vnr(current), \ - __func__, \ - ##__VA_ARGS__) - -/* dummy function helper macro. */ -#define DUMMY_FUNCTION() do {} while (0) - -#if defined(DEBUG) - -/* #define DEBUG_VERBOSE */ -#if defined(DEBUG_VERBOSE) -#define MCDRV_DBG_VERBOSE MCDRV_DBG -#else -#define MCDRV_DBG_VERBOSE(...) DUMMY_FUNCTION() -#endif - -#define MCDRV_DBG(txt, ...) \ - printk(KERN_INFO "mcDrvKMod [%d on CPU%d] %s(): " txt, \ - task_pid_vnr(current), \ - raw_smp_processor_id(), \ - __func__, \ - ##__VA_ARGS__) - -#define MCDRV_DBG_WARN(txt, ...) \ - printk(KERN_WARNING "mcDrvKMod [%d] %s() WARNING: " txt, \ - task_pid_vnr(current), \ - __func__, \ - ##__VA_ARGS__) - -#define MCDRV_ASSERT(cond) \ - do { \ - if (unlikely(!(cond))) { \ - panic("mcDrvKMod Assertion failed: %s:%d\n", \ - __FILE__, __LINE__); \ - } \ - } while (0) - -#else - -#define MCDRV_DBG_VERBOSE(...) DUMMY_FUNCTION() -#define MCDRV_DBG(...) DUMMY_FUNCTION() -#define MCDRV_DBG_WARN(...) DUMMY_FUNCTION() - -#define MCDRV_ASSERT(...) DUMMY_FUNCTION() - -#endif /* [not] defined(DEBUG) */ - - -#endif /* _MC_DRV_KMOD_H_ */ -/** @} */ diff --git a/drivers/gud/mobicore_driver/mc_drv_module_android.h b/drivers/gud/mobicore_driver/mc_drv_module_android.h deleted file mode 100644 index 319509f34456..000000000000 --- a/drivers/gud/mobicore_driver/mc_drv_module_android.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Header file of MobiCore Driver Kernel Module. - * - * @addtogroup MobiCore_Driver_Kernel_Module - * @{ - * Android specific defines - * @file - * - * Android specific defines - * - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _MC_DRV_MODULE_ANDROID_H_ -#define _MC_DRV_MODULE_ANDROID_H_ - -/* Defines needed to identify the Daemon in Android systems - * For the full list see: - * platform_system_core/include/private/android_filesystem_config.h in the - * Android source tree - */ -/* traditional unix root user */ -#define AID_ROOT 0 -/* system server */ -#define AID_SYSTEM 1000 -/* access to misc storage */ -#define AID_MISC 9998 -#define AID_NOBODY 9999 -/* first app user */ -#define AID_APP 10000 - -#endif /* _MC_DRV_MODULE_ANDROID_H_ */ -/** @} */ diff --git a/drivers/gud/mobicore_driver/mc_drv_module_fastcalls.h b/drivers/gud/mobicore_driver/mc_drv_module_fastcalls.h deleted file mode 100644 index d05804324912..000000000000 --- a/drivers/gud/mobicore_driver/mc_drv_module_fastcalls.h +++ /dev/null @@ -1,227 +0,0 @@ -/** - * Header file of MobiCore Driver Kernel Module. - * - * @addtogroup MobiCore_Driver_Kernel_Module - * @{ - * Internal structures of the McDrvModule - * @file - * - * MobiCore Fast Call interface - * - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _MC_DRV_MODULE_FC_H_ -#define _MC_DRV_MODULE_FC_H_ - -#include "mc_drv_module.h" - -/** - * MobiCore SMCs - */ -enum mc_smc_codes { - MC_SMC_N_YIELD = 0x3, /**< Yield to switch from NWd to SWd. */ - MC_SMC_N_SIQ = 0x4 /**< SIQ to switch from NWd to SWd. */ -}; - -/** - * MobiCore fast calls. See MCI documentation - */ -enum mc_fast_call_codes { - MC_FC_INIT = -1, - MC_FC_INFO = -2, - MC_FC_POWER = -3, - MC_FC_DUMP = -4, - MC_FC_NWD_TRACE = -31 /**< Mem trace setup fastcall */ -}; - -/** - * return code for fast calls - */ -enum mc_fast_calls_result { - MC_FC_RET_OK = 0, - MC_FC_RET_ERR_INVALID = 1, - MC_FC_RET_ERR_ALREADY_INITIALIZED = 5 -}; - - - -/*------------------------------------------------------------------------------ - structure wrappers for specific fastcalls -------------------------------------------------------------------------------*/ - -/** generic fast call parameters */ -union fc_generic { - struct { - uint32_t cmd; - uint32_t param[3]; - } as_in; - struct { - uint32_t resp; - uint32_t ret; - uint32_t param[2]; - } as_out; -}; - - -/** fast call init */ -union mc_fc_init { - union fc_generic as_generic; - struct { - uint32_t cmd; - uint32_t base; - uint32_t nq_info; - uint32_t mcp_info; - } as_in; - struct { - uint32_t resp; - uint32_t ret; - uint32_t rfu[2]; - } as_out; -}; - - -/** fast call info parameters */ -union mc_fc_info { - union fc_generic as_generic; - struct { - uint32_t cmd; - uint32_t ext_info_id; - uint32_t rfu[2]; - } as_in; - struct { - uint32_t resp; - uint32_t ret; - uint32_t state; - uint32_t ext_info; - } as_out; -}; - - -/** fast call S-Yield parameters */ -union mc_fc_s_yield { - union fc_generic as_generic; - struct { - uint32_t cmd; - uint32_t rfu[3]; - } as_in; - struct { - uint32_t resp; - uint32_t ret; - uint32_t rfu[2]; - } as_out; -}; - - -/** fast call N-SIQ parameters */ -union mc_fc_nsiq { - union fc_generic as_generic; - struct { - uint32_t cmd; - uint32_t rfu[3]; - } as_in; - struct { - uint32_t resp; - uint32_t ret; - uint32_t rfu[2]; - } as_out; -}; - - -/*----------------------------------------------------------------------------*/ -/** - * fast call to MobiCore - * - * @param fc_generic pointer to fast call data - */ -static inline void mc_fastcall( - union fc_generic *fc_generic -) -{ - MCDRV_ASSERT(fc_generic != NULL); - /* We only expect to make smc calls on CPU0 otherwise something wrong - * will happen */ - MCDRV_ASSERT(raw_smp_processor_id() == 0); - mb(); -#ifdef MC_SMC_FASTCALL - { - int ret = 0; - MCDRV_DBG("Going into SCM()"); - ret = smc_fastcall((void *)fc_generic, sizeof(*fc_generic)); - MCDRV_DBG("Coming from SCM, scm_call=%i, resp=%d/0x%x\n", - ret, - fc_generic->as_out.resp, fc_generic->as_out.resp); - } -#else - { - /* SVC expect values in r0-r3 */ - register u32 reg0 __asm__("r0") = fc_generic->as_in.cmd; - register u32 reg1 __asm__("r1") = fc_generic->as_in.param[0]; - register u32 reg2 __asm__("r2") = fc_generic->as_in.param[1]; - register u32 reg3 __asm__("r3") = fc_generic->as_in.param[2]; - - /* one of the famous preprocessor hacks to stingitize things.*/ -#define __STR2(x) #x -#define __STR(x) __STR2(x) - - /* compiler does not support certain instructions - "SMC": secure monitor call.*/ -#define ASM_ARM_SMC 0xE1600070 - /* "BPKT": debugging breakpoint. We keep this, as is comes - quite handy for debugging. */ -#define ASM_ARM_BPKT 0xE1200070 -#define ASM_THUMB_BPKT 0xBE00 - - - __asm__ volatile ( - ".word " __STR(ASM_ARM_SMC) "\n" - : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3) - ); - - /* set response */ - fc_generic->as_out.resp = reg0; - fc_generic->as_out.ret = reg1; - fc_generic->as_out.param[0] = reg2; - fc_generic->as_out.param[1] = reg3; - } -#endif -} - - -/*----------------------------------------------------------------------------*/ -/** - * convert fast call return code to linux driver module error code - * - */ -static inline int convert_fc_ret( - uint32_t sret -) -{ - int ret = -EFAULT; - - switch (sret) { - - case MC_FC_RET_OK: - ret = 0; - break; - - case MC_FC_RET_ERR_INVALID: - ret = -EINVAL; - break; - - case MC_FC_RET_ERR_ALREADY_INITIALIZED: - ret = -EBUSY; - break; - - default: - break; - } /* end switch( sret ) */ - return ret; -} - -#endif /* _MC_DRV_MODULE_FC_H_ */ -/** @} */ diff --git a/drivers/gud/mobicore_driver/mc_drv_module_linux_api.h b/drivers/gud/mobicore_driver/mc_drv_module_linux_api.h deleted file mode 100644 index b2a99f17355d..000000000000 --- a/drivers/gud/mobicore_driver/mc_drv_module_linux_api.h +++ /dev/null @@ -1,187 +0,0 @@ -/** - * Header file of MobiCore Driver Kernel Module. - * - * @addtogroup MobiCore_Driver_Kernel_Module - * @{ - * Wrapper for Linux API - * @file - * - * Some convenient wrappers for memory functions - * - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _MC_DRV_MODULE_LINUX_API_H_ -#define _MC_DRV_MODULE_LINUX_API_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* make some nice types */ -#if !defined(TRUE) -#define TRUE (1 == 1) -#endif - -#if !defined(FALSE) -#define FALSE (1 != 1) -#endif - - -/* Linux GCC modifiers */ -#if !defined(__init) -#warning "missing definition: __init" -/* define a dummy */ -#define __init -#endif - - -#if !defined(__exit) -#warning "missing definition: __exit" -/* define a dummy */ -#define __exit -#endif - - -#if !defined(__must_check) -#warning "missing definition: __must_check" -/* define a dummy */ -#define __must_check -#endif - - -#if !defined(__user) -#warning "missing definition: __user" -/* define a dummy */ -#define __user -#endif - -#define INVALID_ORDER ((unsigned int)(-1)) - -/*----------------------------------------------------------------------------*/ -/* get start address of the 4 KiB page where the given addres is located in. */ -static inline void *get_page_start( - void *addr -) -{ - return (void *)(((unsigned long)(addr)) & PAGE_MASK); -} - -/*----------------------------------------------------------------------------*/ -/* get offset into the 4 KiB page where the given addres is located in. */ -static inline unsigned int get_offset_in_page( - void *addr -) -{ - return (unsigned int)(((unsigned long)(addr)) & (~PAGE_MASK)); -} - -/*----------------------------------------------------------------------------*/ -/* get number of pages for a given buffer. */ -static inline unsigned int get_nr_of_pages_for_buffer( - void *addr_start, /* may be null */ - unsigned int len -) -{ - /* calculate used number of pages. Example: - offset+size newSize+PAGE_SIZE-1 nr_of_pages - 0 4095 0 - 1 4096 1 - 4095 8190 1 - 4096 8191 1 - 4097 8192 2 */ - - return (get_offset_in_page(addr_start) + len + PAGE_SIZE-1) / PAGE_SIZE; -} - - -/*----------------------------------------------------------------------------*/ -/** - * convert a given size to page order, which is equivalent to finding log_2(x). - * The maximum for order was 5 in Linux 2.0 corresponding to 32 pages. - * Later versions allow 9 corresponding to 512 pages, which is 2 MB on - * most platforms). Anyway, the bigger order is, the more likely it is - * that the allocation will fail. - * Size 0 1 4097 8193 12289 24577 28673 40961 61441 - * Pages - 1 2 3 4 7 8 15 16 - * Order INVALID_ORDER 0 1 1 2 2 3 3 4 - * - * @param size - * @return order - */ -static inline unsigned int size_to_order( - unsigned int size -) -{ - unsigned int order = INVALID_ORDER; - - if (size != 0) { - /* ARMv5 as a CLZ instruction which count the leading zeros of - the binary representation of a value. It return a value - between 0 and 32. - Value 0 1 2 3 4 5 6 7 8 9 10 ... - CLZ 32 31 30 30 29 29 29 29 28 28 28 ... - - We have excluded Size==0 before, so this is safe. */ - order = __builtin_clz( - get_nr_of_pages_for_buffer(NULL, size)); - - /* there is a size overflow in get_nr_of_pages_for_buffer when - * the size is too large */ - if (unlikely(order > 31)) - return INVALID_ORDER; - order = 31 - order; - - /* above algorithm rounds down: clz(5)=2 instead of 3 */ - /* quick correction to fix it: */ - if (((1<> PAGE_SHIFT; -} - - -/*----------------------------------------------------------------------------*/ -/* return the address of a page frame number */ -static inline void *pfn_to_addr( - unsigned int pfn -) -{ - /* there is no real API for this */ - return (void *)(pfn << PAGE_SHIFT); -} - -#endif /* _MC_DRV_MODULE_LINUX_API_H_ */ -/** @} */ diff --git a/drivers/gud/mobicore_driver/platforms/msm8960_surf_std/platform.h b/drivers/gud/mobicore_driver/platforms/msm8960_surf_std/platform.h deleted file mode 100644 index 070222e39f96..000000000000 --- a/drivers/gud/mobicore_driver/platforms/msm8960_surf_std/platform.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Header file of MobiCore Driver Kernel Module Platform - * specific structures - * - * @addtogroup MobiCore_Driver_Kernel_Module - * @{ - * Internal structures of the McDrvModule - * @file - * - * Header file the MobiCore Driver Kernel Module, - * its internal structures and defines. - * - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _MC_DRV_PLATFORM_H_ -#define _MC_DRV_PLATFORM_H_ - -/** MobiCore Interrupt for Qualcomm */ -#define MC_INTR_SSIQ 280 - -/** Use SMC for fastcalls */ -#define MC_SMC_FASTCALL - - -/*--------------- Implementation -------------- */ -#include -/* from following file */ -#define SCM_SVC_MOBICORE 250 -#define SCM_CMD_MOBICORE 1 - -extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len, - void *resp_buf, size_t resp_len); - -static inline int smc_fastcall(void *fc_generic, size_t size) -{ - return scm_call(SCM_SVC_MOBICORE, SCM_CMD_MOBICORE, - fc_generic, size, - fc_generic, size); -} - -/** Enable mobicore mem traces */ -#define MC_MEM_TRACES - -#endif /* _MC_DRV_PLATFORM_H_ */ -/** @} */ diff --git a/drivers/gud/mobicore_driver/public/mc_drv_module_api.h b/drivers/gud/mobicore_driver/public/mc_drv_module_api.h deleted file mode 100644 index 59366f35f2a6..000000000000 --- a/drivers/gud/mobicore_driver/public/mc_drv_module_api.h +++ /dev/null @@ -1,311 +0,0 @@ -/** @addtogroup MCD_MCDIMPL_KMOD_API Mobicore Driver Module API - * @ingroup MCD_MCDIMPL_KMOD - * @{ - * Interface to Mobicore Driver Kernel Module. - * @file - * - *

Introduction

- * The MobiCore Driver Kernel Module is a Linux device driver, which represents - * the command proxy on the lowest layer to the secure world (Swd). Additional - * services like memory allocation via mmap and generation of a L2 tables for - * given virtual memory are also supported. IRQ functionallity receives - * information from the SWd in the non secure world (NWd). - * As customary the driver is handled as linux device driver with "open", - * "close" and "ioctl" commands. Access to the driver is possible after the - * device "/dev/mobicore" has been opened. - * The MobiCore Driver Kernel Module must be installed via - * "insmod mcDrvModule.ko". - * - * - *

Version history

- * - * - * - * - *
DateVersionChanges
2010-05-250.1Initial Release
- * - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _MC_DRV_MODULEAPI_H_ -#define _MC_DRV_MODULEAPI_H_ - -#include "version.h" - -#define MC_DRV_MOD_DEVNODE "mobicore" -#define MC_DRV_MOD_DEVNODE_FULLPATH "/dev/" MC_DRV_MOD_DEVNODE - -/** - * Data exchange structure of the MC_DRV_MODULE_INIT ioctl command. - * INIT request data to SWD - */ -union mc_ioctl_init_params { - struct { - /** base address of mci buffer 4KB align */ - uint32_t base; - /** notification buffer start/length [16:16] [start, length] */ - uint32_t nq_offset; - /** length of notification queue */ - uint32_t nq_length; - /** mcp buffer start/length [16:16] [start, length] */ - uint32_t mcp_offset; - /** length of mcp buffer */ - uint32_t mcp_length; - } in; - struct { - /* nothing */ - } out; -}; - - -/** - * Data exchange structure of the MC_DRV_MODULE_INFO ioctl command. - * INFO request data to the SWD - */ -union mc_ioctl_info_params { - struct { - uint32_t ext_info_id; /**< extended info ID */ - } in; - struct { - uint32_t state; /**< state */ - uint32_t ext_info; /**< extended info */ - } out; -}; - -/** - * Mmap allocates and maps contiguous memory into a process. - * We use the third parameter, void *offset, to distinguish between some cases - * offset = MC_DRV_KMOD_MMAP_WSM usual operation, pages are registered in - device structure and freed later. - * offset = MC_DRV_KMOD_MMAP_MCI get Instance of MCI, allocates or mmaps - the MCI to daemon - * offset = MC_DRV_KMOD_MMAP_PERSISTENTWSM special operation, without - registration of pages - * - * In mmap(), the offset specifies which of several device I/O pages is - * requested. Linux only transfers the page number, i.e. the upper 20 bits to - * kernel module. Therefore we define our special offsets as multiples of page - * size. - */ -enum mc_mmap_memtype { - MC_DRV_KMOD_MMAP_WSM = 0, - MC_DRV_KMOD_MMAP_MCI = 4096, - MC_DRV_KMOD_MMAP_PERSISTENTWSM = 8192 -}; - -struct mc_mmap_resp { - uint32_t handle; /**< WSN handle */ - uint32_t phys_addr; /**< physical address of WSM (or NULL) */ - bool is_reused; /**< if WSM memory was reused, or new allocated */ -}; - -/** - * Data exchange structure of the MC_DRV_KMOD_IOCTL_FREE ioctl command. - */ -union mc_ioctl_free_params { - struct { - uint32_t handle; /**< driver handle */ - uint32_t pid; /**< process id */ - } in; - struct { - /* nothing */ - } out; -}; - - -/** - * Data exchange structure of the MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2 command. - * - * Allocates a physical L2 table and maps the buffer into this page. - * Returns the physical address of the L2 table. - * The page alignment will be created and the appropriated pSize and pOffsetL2 - * will be modified to the used values. - */ -union mc_ioctl_app_reg_wsm_l2_params { - struct { - uint32_t buffer; /**< base address of the virtual address */ - uint32_t len; /**< size of the virtual address space */ - uint32_t pid; /**< process id */ - } in; - struct { - uint32_t handle; /**< driver handle for locked memory */ - uint32_t phys_wsm_l2_table; /* physical address of the L2 table */ - } out; -}; - - -/** - * Data exchange structure of the MC_DRV_KMOD_IOCTL_APP_UNREGISTER_WSM_L2 - * command. - */ -struct mc_ioctl_app_unreg_wsm_l2_params { - struct { - uint32_t handle; /**< driver handle for locked memory */ - uint32_t pid; /**< process id */ - } in; - struct { - /* nothing */ - } out; -}; - - -/** - * Data exchange structure of the MC_DRV_KMOD_IOCTL_DAEMON_LOCK_WSM_L2 command. - */ -struct mc_ioctl_daemon_lock_wsm_l2_params { - struct { - uint32_t handle; /**< driver handle for locked memory */ - } in; - struct { - uint32_t phys_wsm_l2_table; - } out; -}; - - -/** - * Data exchange structure of the MC_DRV_KMOD_IOCTL_DAEMON_UNLOCK_WSM_L2 - * command. - */ -struct mc_ioctl_daemon_unlock_wsm_l2_params { - struct { - uint32_t handle; /**< driver handle for locked memory */ - } in; - struct { - /* nothing */ - } out; -}; - -/** - * Data exchange structure of the MC_DRV_MODULE_FC_EXECUTE ioctl command. - */ -union mc_ioctl_fc_execute_params { - struct { - /**< base address of mobicore binary */ - uint32_t phys_start_addr; - /**< length of DDR area */ - uint32_t length; - } in; - struct { - /* nothing */ - } out; -}; - -/** - * Data exchange structure of the MC_DRV_MODULE_GET_VERSION ioctl command. - */ -struct mc_ioctl_get_version_params { - struct { - uint32_t kernel_module_version; - } out; -}; - -/* @defgroup Mobicore_Driver_Kernel_Module_Interface IOCTL */ - - - - -/* TODO: use IOCTL macros like _IOWR. See Documentation/ioctl/ioctl-number.txt, - Documentation/ioctl/ioctl-decoding.txt */ -/** - * defines for the ioctl mobicore driver module function call from user space. - */ -enum mc_kmod_ioctl { - - /* - * get detailed MobiCore Status - */ - MC_DRV_KMOD_IOCTL_DUMP_STATUS = 200, - - /* - * initialize MobiCore - */ - MC_DRV_KMOD_IOCTL_FC_INIT = 201, - - /* - * get MobiCore status - */ - MC_DRV_KMOD_IOCTL_FC_INFO = 202, - - /** - * ioctl parameter to send the YIELD command to the SWD. - * Only possible in Privileged Mode. - * ioctl(fd, MC_DRV_MODULE_YIELD) - */ - MC_DRV_KMOD_IOCTL_FC_YIELD = 203, - /** - * ioctl parameter to send the NSIQ signal to the SWD. - * Only possible in Privileged Mode - * ioctl(fd, MC_DRV_MODULE_NSIQ) - */ - MC_DRV_KMOD_IOCTL_FC_NSIQ = 204, - /** - * ioctl parameter to tzbsp to start Mobicore binary from DDR. - * Only possible in Privileged Mode - * ioctl(fd, MC_DRV_KMOD_IOCTL_FC_EXECUTE) - */ - MC_DRV_KMOD_IOCTL_FC_EXECUTE = 205, - - /** - * Free's memory which is formerly allocated by the driver's mmap - * command. The parameter must be this mmaped address. - * The internal instance data regarding to this address are deleted as - * well as each according memory page and its appropriated reserved bit - * is cleared (ClearPageReserved). - * Usage: ioctl(fd, MC_DRV_MODULE_FREE, &address) with address beeing of - * type long address - */ - MC_DRV_KMOD_IOCTL_FREE = 218, - - /** - * Creates a L2 Table of the given base address and the size of the - * data. - * Parameter: mc_ioctl_app_reg_wsm_l2_params - */ - MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2 = 220, - - /** - * Frees the L2 table created by a MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2 - * ioctl. - * Parameter: mc_ioctl_app_unreg_wsm_l2_params - */ - MC_DRV_KMOD_IOCTL_APP_UNREGISTER_WSM_L2 = 221, - - - /* TODO: comment this. */ - MC_DRV_KMOD_IOCTL_DAEMON_LOCK_WSM_L2 = 222, - MC_DRV_KMOD_IOCTL_DAEMON_UNLOCK_WSM_L2 = 223, - - /** - * Return kernel driver version. - * Parameter: mc_ioctl_get_version_params - */ - MC_DRV_KMOD_IOCTL_GET_VERSION = 224, -}; - - -#endif /* _MC_DRV_MODULEAPI_H_ */ -/** @} */ diff --git a/drivers/gud/mobicore_driver/public/mc_kernel_api.h b/drivers/gud/mobicore_driver/public/mc_kernel_api.h deleted file mode 100644 index fdfc61876aad..000000000000 --- a/drivers/gud/mobicore_driver/public/mc_kernel_api.h +++ /dev/null @@ -1,100 +0,0 @@ -/** @addtogroup MCD_MCDIMPL_KMOD_KAPI Mobicore Driver Module API inside Kernel. - * @ingroup MCD_MCDIMPL_KMOD - * @{ - * Interface to Mobicore Driver Kernel Module inside Kernel. - * @file - * - * Interface to be used by module MobiCoreKernelAPI. - * - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _MOBICORE_KERNELMODULE_API_H_ -#define _MOBICORE_KERNELMODULE_API_H_ - -struct mc_instance; - -/** - * Initialize a new mobicore API instance object - * - * @return Instance or NULL if no allocation was possible. - */ -struct mc_instance *mobicore_open( - void -); - -/** - * Release a mobicore instance object and all objects related to it - * @param instance instance - * @return 0 if Ok or -E ERROR - */ -int mobicore_release( - struct mc_instance *instance -); - -/** - * Free a WSM buffer allocated with mobicore_allocate_wsm - * @param instance - * @param handle handle of the buffer - * - * @return 0 if no error - * - */ -int mobicore_allocate_wsm( - struct mc_instance *instance, - unsigned long requested_size, - uint32_t *handle, - void **kernel_virt_addr, - void **phys_addr -); - -/** - * Free a WSM buffer allocated with mobicore_allocate_wsm - * @param instance - * @param handle handle of the buffer - * - * @return 0 if no error - * - */ -int mobicore_free( - struct mc_instance *instance, - uint32_t handle -); - -/** - * Map a virtual memory buffer structure to Mobicore - * @param instance - * @param addr address of the buffer(NB it must be kernel virtual!) - * @param len buffer length - * @param handle pointer to handle - * @param phys_wsm_l2_table pointer to physical L2 table(?) - * - * @return 0 if no error - * - */ -int mobicore_map_vmem( - struct mc_instance *instance, - void *addr, - uint32_t len, - uint32_t *handle, - void **phys_wsm_l2_table -); - -/** - * Unmap a virtual memory buffer from mobicore - * @param instance - * @param handle - * - * @return 0 if no error - * - */ -int mobicore_unmap_vmem( - struct mc_instance *instance, - uint32_t handle -); -#endif /* _MOBICORE_KERNELMODULE_API_H_ */ -/** @} */ diff --git a/drivers/gud/mobicore_driver/public/version.h b/drivers/gud/mobicore_driver/public/version.h deleted file mode 100644 index 9b2dbcadb9d6..000000000000 --- a/drivers/gud/mobicore_driver/public/version.h +++ /dev/null @@ -1,36 +0,0 @@ -/** @addtogroup MCD_MCDIMPL_KMOD - * @{ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _MC_DRV_VERSION_H_ -#define _MC_DRV_VERSION_H_ - -#define MCDRVMODULEAPI_VERSION_MAJOR 0 -#define MCDRVMODULEAPI_VERSION_MINOR 1 - -#endif /* _MC_DRV_VERSION_H_ */ diff --git a/drivers/gud/mobicore_kernelapi/clientlib.c b/drivers/gud/mobicore_kernelapi/clientlib.c deleted file mode 100644 index 13826f281b22..000000000000 --- a/drivers/gud/mobicore_kernelapi/clientlib.c +++ /dev/null @@ -1,1093 +0,0 @@ -/** - * MobiCore KernelApi module - * - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "public/mobicore_driver_api.h" -#include "public/mobicore_driver_cmd.h" -#include "device.h" -#include "session.h" - -/* device list */ -LIST_HEAD(devices); - -/*----------------------------------------------------------------------------*/ -static struct mcore_device_t *resolve_device_id( - uint32_t device_id -) { - struct mcore_device_t *tmp; - struct list_head *pos; - - /* Get mcore_device_t for device_id */ - list_for_each(pos, &devices) { - tmp = list_entry(pos, struct mcore_device_t, list); - if (tmp->device_id == device_id) - return tmp; - } - return NULL; -} - - -/*----------------------------------------------------------------------------*/ -static void add_device( - struct mcore_device_t *device -) { - list_add_tail(&(device->list), &devices); -} - - -/*----------------------------------------------------------------------------*/ -static bool remove_device( - uint32_t device_id -) { - struct mcore_device_t *tmp; - struct list_head *pos, *q; - - list_for_each_safe(pos, q, &devices) { - tmp = list_entry(pos, struct mcore_device_t, list); - if (tmp->device_id == device_id) { - list_del(pos); - mcore_device_cleanup(tmp); - return true; - } - } - return false; -} - - -/*----------------------------------------------------------------------------*/ -enum mc_result mc_open_device( - uint32_t device_id -) { - enum mc_result mc_result = MC_DRV_OK; - struct connection *dev_con = NULL; - - MCDRV_DBG_VERBOSE("===%s()===", __func__); - - /* Enter critical section */ - - do { - struct mcore_device_t *device = resolve_device_id(device_id); - if (device != NULL) { - MCDRV_DBG_ERROR("Device %d already opened", device_id); - mc_result = MC_DRV_ERR_INVALID_OPERATION; - break; - } - - /* Open new connection to device */ - dev_con = connection_new(); - if (!connection_connect(dev_con, MC_DAEMON_PID)) { - MCDRV_DBG_ERROR( - "Could not setup netlink connection to PID %u", - MC_DAEMON_PID); - mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE; - break; - } - - /* Forward device open to the daemon and read result */ - struct mc_drv_cmd_open_device_t mc_drv_cmd_open_device = { - /* C++ does not support C99 designated initializers */ - /* .header = */ { - /* .command_id = */ MC_DRV_CMD_OPEN_DEVICE - }, - /* .payload = */ { - /* .device_id = */ device_id - } - }; - - int len = connection_write_data( - dev_con, - &mc_drv_cmd_open_device, - sizeof(struct mc_drv_cmd_open_device_t)); - if (len < 0) { - MCDRV_DBG_ERROR("CMD_OPEN_DEVICE writeCmd failed " - "ret=%d", len); - mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE; - break; - } - - struct mc_drv_response_header_t rsp_header; - len = connection_read_datablock( - dev_con, - &rsp_header, - sizeof(rsp_header)); - if (len != sizeof(rsp_header)) { - MCDRV_DBG_ERROR("CMD_OPEN_DEVICE readRsp failed " - "ret=%d", len); - mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE; - break; - } - if (rsp_header.response_id != MC_DRV_RSP_OK) { - MCDRV_DBG_ERROR("CMD_OPEN_DEVICE failed, respId=%d", - rsp_header.response_id); - switch (rsp_header.response_id) { - case MC_DRV_RSP_PAYLOAD_LENGTH_ERROR: - mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE; - break; - case MC_DRV_INVALID_DEVICE_NAME: - mc_result = MC_DRV_ERR_UNKNOWN_DEVICE; - break; - case MC_DRV_RSP_DEVICE_ALREADY_OPENED: - default: - mc_result = MC_DRV_ERR_INVALID_OPERATION; - break; - } - break; - } - - /* there is no payload to read */ - - device = mcore_device_create(device_id, dev_con); - if (!mcore_device_open(device, MC_DRV_MOD_DEVNODE_FULLPATH)) { - mcore_device_cleanup(device); - MCDRV_DBG_ERROR("could not open device file: %s", - MC_DRV_MOD_DEVNODE_FULLPATH); - mc_result = MC_DRV_ERR_INVALID_DEVICE_FILE; - break; - } - - add_device(device); - - } while (false); - - if (mc_result != MC_DRV_OK) - connection_cleanup(dev_con); - - /* Exit critical section */ - - return mc_result; -} -EXPORT_SYMBOL(mc_open_device); - -/*----------------------------------------------------------------------------*/ -enum mc_result mc_close_device( - uint32_t device_id -) { - enum mc_result mc_result = MC_DRV_OK; - - MCDRV_DBG_VERBOSE("===%s()===", __func__); - - /* Enter critical section */ - do { - struct mcore_device_t *device = resolve_device_id(device_id); - if (device == NULL) { - MCDRV_DBG_ERROR("Device not found"); - mc_result = MC_DRV_ERR_UNKNOWN_DEVICE; - break; - } - struct connection *dev_con = device->connection; - - /* Return if not all sessions have been closed */ - if (mcore_device_has_sessions(device)) { - MCDRV_DBG_ERROR("cannot close with sessions pending"); - mc_result = MC_DRV_ERR_SESSION_PENDING; - break; - } - - struct mc_drv_cmd_close_device_t mc_drv_cmd_close_device = { - /* C++ does not support C99 designated initializers */ - /* .header = */ { - /* .command_id = */ MC_DRV_CMD_CLOSE_DEVICE - } - }; - int len = connection_write_data( - dev_con, - &mc_drv_cmd_close_device, - sizeof(struct mc_drv_cmd_close_device_t)); - /* ignore error, but log details */ - if (len < 0) { - MCDRV_DBG_ERROR("CMD_CLOSE_DEVICE writeCmd failed " - "ret=%d", len); - mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE; - } - - struct mc_drv_response_header_t rsp_header; - len = connection_read_datablock( - dev_con, - &rsp_header, - sizeof(rsp_header)); - if (len != sizeof(rsp_header)) { - MCDRV_DBG_ERROR("CMD_CLOSE_DEVICE readResp failed " - " ret=%d", len); - mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE; - break; - } - - if (rsp_header.response_id != MC_DRV_RSP_OK) { - MCDRV_DBG_ERROR("CMD_CLOSE_DEVICE failed, respId=%d", - rsp_header.response_id); - mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE; - break; - } - - remove_device(device_id); - - } while (false); - - /* Exit critical section */ - - return mc_result; -} -EXPORT_SYMBOL(mc_close_device); - -/*----------------------------------------------------------------------------*/ -enum mc_result mc_open_session( - struct mc_session_handle *session, - const struct mc_uuid_t *uuid, - uint8_t *tci, - uint32_t len -) { - enum mc_result mc_result = MC_DRV_OK; - - MCDRV_DBG_VERBOSE("===%s()===", __func__); - - /* Enter critical section */ - - do { - if (session == NULL) { - MCDRV_DBG_ERROR("Session is null"); - mc_result = MC_DRV_ERR_INVALID_PARAMETER; - break; - } - if (uuid == NULL) { - MCDRV_DBG_ERROR("UUID is null"); - mc_result = MC_DRV_ERR_INVALID_PARAMETER; - break; - } - if (tci == NULL) { - MCDRV_DBG_ERROR("TCI is null"); - mc_result = MC_DRV_ERR_INVALID_PARAMETER; - break; - } - if (len > MC_MAX_TCI_LEN) { - MCDRV_DBG_ERROR("TCI length is longer than %d", - MC_MAX_TCI_LEN); - mc_result = MC_DRV_ERR_INVALID_PARAMETER; - break; - } - - /* Get the device associated with the given session */ - struct mcore_device_t *device = - resolve_device_id(session->device_id); - if (device == NULL) { - MCDRV_DBG_ERROR("Device not found"); - mc_result = MC_DRV_ERR_UNKNOWN_DEVICE; - break; - } - struct connection *dev_con = device->connection; - - /* Get the physical address of the given TCI */ - struct wsm *wsm = - mcore_device_find_contiguous_wsm(device, tci); - if (wsm == NULL) { - MCDRV_DBG_ERROR("Could not resolve TCI phy address "); - mc_result = MC_DRV_ERR_INVALID_PARAMETER; - break; - } - - if (wsm->len < len) { - MCDRV_DBG_ERROR("length is more than allocated TCI"); - mc_result = MC_DRV_ERR_INVALID_PARAMETER; - break; - } - - /* Prepare open session command */ - struct mc_drv_cmd_open_session_t cmdOpenSession = { - /* C++ does not support C99 designated initializers */ - /* .header = */ { - /* .command_id = */ MC_DRV_CMD_OPEN_SESSION - }, - /* .payload = */ { - /* .device_id = */ session->device_id, - /* .uuid = */ *uuid, - /* .tci = */ (uint32_t)wsm->phys_addr, - /* .len = */ len - } - }; - - /* Transmit command data */ - - int len = connection_write_data( - dev_con, - &cmdOpenSession, - sizeof(cmdOpenSession)); - if (len != sizeof(cmdOpenSession)) { - MCDRV_DBG_ERROR("CMD_OPEN_SESSION writeData failed " - "ret=%d", len); - mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE; - break; - } - - /* Read command response */ - - /* read header first */ - struct mc_drv_response_header_t rsp_header; - len = connection_read_datablock( - dev_con, - &rsp_header, - sizeof(rsp_header)); - if (len != sizeof(rsp_header)) { - MCDRV_DBG_ERROR("CMD_OPEN_SESSION readResp failed " - " ret=%d", len); - mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE; - break; - } - - if (rsp_header.response_id != MC_DRV_RSP_OK) { - MCDRV_DBG_ERROR("CMD_OPEN_SESSION failed, respId=%d", - rsp_header.response_id); - switch (rsp_header.response_id) { - case MC_DRV_RSP_TRUSTLET_NOT_FOUND: - mc_result = MC_DRV_ERR_INVALID_DEVICE_FILE; - break; - case MC_DRV_RSP_PAYLOAD_LENGTH_ERROR: - case MC_DRV_RSP_DEVICE_NOT_OPENED: - case MC_DRV_RSP_FAILED: - default: - mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE; - break; - } - break; - } - - /* read payload */ - struct mc_drv_rsp_open_session_payload_t - rsp_open_session_payload; - len = connection_read_datablock( - dev_con, - &rsp_open_session_payload, - sizeof(rsp_open_session_payload)); - if (len != sizeof(rsp_open_session_payload)) { - MCDRV_DBG_ERROR("CMD_OPEN_SESSION readPayload failed " - "ret=%d", len); - mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE; - break; - } - - /* Register session with handle */ - session->session_id = rsp_open_session_payload.session_id; - - /* Set up second channel for notifications */ - struct connection *session_connection = connection_new(); - /*TODO: no real need to connect here? */ - if (!connection_connect(session_connection, MC_DAEMON_PID)) { - MCDRV_DBG_ERROR( - "Could not setup netlink connection to PID %u", - MC_DAEMON_PID); - connection_cleanup(session_connection); - mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE; - break; - } - - /*TODO CONTINOUE HERE !!!! FIX RW RETURN HANDLING!!!! */ - - /* Write command to use channel for notifications */ - struct mc_drv_cmd_nqconnect_t cmd_nqconnect = { - /* C++ does not support C99 designated initializers */ - /* .header = */ { - /* .command_id = */ MC_DRV_CMD_NQ_CONNECT - }, - /* .payload = */ { - /* .device_id = */ session->device_id, - /* .session_id = */ session->session_id, - /* .device_session_id = */ - rsp_open_session_payload.device_session_id, - /* .session_magic = */ - rsp_open_session_payload.session_magic - } - }; - connection_write_data(session_connection, - &cmd_nqconnect, - sizeof(cmd_nqconnect)); - - /* Read command response, header first */ - len = connection_read_datablock( - session_connection, - &rsp_header, - sizeof(rsp_header)); - if (len != sizeof(rsp_header)) { - MCDRV_DBG_ERROR("CMD_NQ_CONNECT readRsp failed " - "ret=%d", len); - connection_cleanup(session_connection); - mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE; - break; - } - - if (rsp_header.response_id != MC_DRV_RSP_OK) { - MCDRV_DBG_ERROR("CMD_NQ_CONNECT failed, respId=%d", - rsp_header.response_id); - connection_cleanup(session_connection); - mc_result = MC_DRV_ERR_NQ_FAILED; - break; - } - - /* there is no payload. */ - - /* Session established, new session object must be created */ - mcore_device_create_new_session( - device, - session->session_id, - session_connection); - - } while (false); - - /* Exit critical section */ - - return mc_result; -} -EXPORT_SYMBOL(mc_open_session); - -/*----------------------------------------------------------------------------*/ -enum mc_result mc_close_session( - struct mc_session_handle *session -) { - enum mc_result mc_result = MC_DRV_OK; - - MCDRV_DBG_VERBOSE("===%s()===", __func__); - - /* Enter critical section */ - - do { - if (session == NULL) { - MCDRV_DBG_ERROR("Session is null"); - mc_result = MC_DRV_ERR_INVALID_PARAMETER; - break; - } - - struct mcore_device_t *device = - resolve_device_id(session->device_id); - if (device == NULL) { - MCDRV_DBG_ERROR("Device not found"); - mc_result = MC_DRV_ERR_UNKNOWN_DEVICE; - break; - } - struct connection *dev_con = device->connection; - - struct session *nq_session = - mcore_device_resolve_session_id(device, session->session_id); - if (nq_session == NULL) { - MCDRV_DBG_ERROR("Session not found"); - mc_result = MC_DRV_ERR_UNKNOWN_SESSION; - break; - } - - /* Write close session command */ - struct mc_drv_cmd_close_session_t cmd_close_session = { - /* C++ does not support C99 designated initializers */ - /* .header = */ { - /* .command_id = */ MC_DRV_CMD_CLOSE_SESSION - }, - /* .payload = */ { - /* .session_id = */ session->session_id, - } - }; - connection_write_data( - dev_con, - &cmd_close_session, - sizeof(cmd_close_session)); - - /* Read command response */ - struct mc_drv_response_header_t rsp_header; - int len = connection_read_datablock( - dev_con, - &rsp_header, - sizeof(rsp_header)); - if (len != sizeof(rsp_header)) { - MCDRV_DBG_ERROR("CMD_CLOSE_SESSION readRsp failed " - "ret=%d", len); - mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE; - break; - } - - if (rsp_header.response_id != MC_DRV_RSP_OK) { - MCDRV_DBG_ERROR("CMD_CLOSE_SESSION failed, respId=%d", - rsp_header.response_id); - mc_result = MC_DRV_ERR_UNKNOWN_DEVICE; - break; - } - - mcore_device_remove_session(device, session->session_id); - mc_result = MC_DRV_OK; - - } while (false); - - /* Exit critical section */ - - return mc_result; -} -EXPORT_SYMBOL(mc_close_session); - -/*----------------------------------------------------------------------------*/ -enum mc_result mc_notify( - struct mc_session_handle *session -) { - enum mc_result mc_result = MC_DRV_OK; - - MCDRV_DBG_VERBOSE("===%s()===", __func__); - - do { - if (session == NULL) { - MCDRV_DBG_ERROR("Session is null"); - mc_result = MC_DRV_ERR_INVALID_PARAMETER; - break; - } - - struct mcore_device_t *device = - resolve_device_id(session->device_id); - if (device == NULL) { - MCDRV_DBG_ERROR("Device not found"); - mc_result = MC_DRV_ERR_UNKNOWN_DEVICE; - break; - } - struct connection *dev_con = device->connection; - - struct session *nqsession = - mcore_device_resolve_session_id(device, session->session_id); - if (nqsession == NULL) { - MCDRV_DBG_ERROR("Session not found"); - mc_result = MC_DRV_ERR_UNKNOWN_SESSION; - break; - } - - struct mc_drv_cmd_notify_t cmd_notify = { - /* C++ does not support C99 designated initializers */ - /* .header = */ { - /* .command_id = */ MC_DRV_CMD_NOTIFY - }, - /* .payload = */ { - /* .session_id = */ session->session_id, - } - }; - - connection_write_data( - dev_con, - &cmd_notify, - sizeof(cmd_notify)); - - /* Daemon will not return a response */ - - } while (false); - - return mc_result; -} -EXPORT_SYMBOL(mc_notify); - -/*----------------------------------------------------------------------------*/ -enum mc_result mc_wait_notification( - struct mc_session_handle *session, - int32_t timeout -) { - enum mc_result mc_result = MC_DRV_OK; - - MCDRV_DBG_VERBOSE("===%s()===", __func__); - - do { - if (session == NULL) { - mc_result = MC_DRV_ERR_INVALID_PARAMETER; - break; - } - - struct mcore_device_t *device = - resolve_device_id(session->device_id); - if (device == NULL) { - MCDRV_DBG_ERROR("Device not found"); - mc_result = MC_DRV_ERR_UNKNOWN_DEVICE; - break; - } - - struct session *nq_session = - mcore_device_resolve_session_id(device, session->session_id); - if (nq_session == NULL) { - MCDRV_DBG_ERROR("Session not found"); - mc_result = MC_DRV_ERR_UNKNOWN_SESSION; - break; - } - - struct connection *nqconnection = - nq_session->notification_connection; - uint32_t count = 0; - - /* Read notification queue till it's empty */ - for (;;) { - struct notification notification; - ssize_t num_read = connection_read_data( - nqconnection, - ¬ification, - sizeof(notification), - timeout); - /* Exit on timeout in first run. Later runs have - * timeout set to 0. - * -2 means, there is no more data. */ - if (count == 0 && num_read == -2) { - MCDRV_DBG_ERROR("read timeout"); - mc_result = MC_DRV_ERR_TIMEOUT; - break; - } - /* After first notification the queue will be - * drained, Thus we set no timeout for the - * following reads */ - timeout = 0; - - if (num_read != sizeof(struct notification)) { - if (count == 0) { - /* failure in first read, notify it */ - mc_result = MC_DRV_ERR_NOTIFICATION; - MCDRV_DBG_ERROR( - "read notification failed, " - "%i bytes received", (int)num_read); - break; - } else { - /* Read of the n-th notification - failed/timeout. We don't tell the - caller, as we got valid notifications - before. */ - mc_result = MC_DRV_OK; - break; - } - } - - count++; - MCDRV_DBG_VERBOSE("readNq count=%d, SessionID=%d, " - "Payload=%d", count, - notification.session_id, notification.payload); - - if (notification.payload != 0) { - /* Session end point died -> store exit code */ - session_set_error_info(nq_session, - notification.payload); - - mc_result = MC_DRV_INFO_NOTIFICATION; - break; - } - } /* for(;;) */ - - } while (false); - - return mc_result; -} -EXPORT_SYMBOL(mc_wait_notification); - -/*----------------------------------------------------------------------------*/ -enum mc_result mc_malloc_wsm( - uint32_t device_id, - uint32_t align, - uint32_t len, - uint8_t **wsm, - uint32_t wsm_flags -) { - enum mc_result mc_result = MC_DRV_ERR_UNKNOWN; - - MCDRV_DBG_VERBOSE("===%s()===", __func__); - - /* Enter critical section */ - - do { - struct mcore_device_t *device = resolve_device_id(device_id); - if (device == NULL) { - MCDRV_DBG_ERROR("Device not found"); - mc_result = MC_DRV_ERR_UNKNOWN_DEVICE; - break; - } - if (wsm == NULL) { - mc_result = MC_DRV_ERR_INVALID_PARAMETER; - break; - } - - struct wsm *wsm_stack = - mcore_device_allocate_contiguous_wsm(device, len); - if (wsm_stack == NULL) { - MCDRV_DBG_ERROR("Allocation of WSM failed"); - mc_result = MC_DRV_ERR_NO_FREE_MEMORY; - break; - } - - *wsm = (uint8_t *)wsm_stack->virt_addr; - mc_result = MC_DRV_OK; - - } while (false); - - /* Exit critical section */ - - return mc_result; -} -EXPORT_SYMBOL(mc_malloc_wsm); - -/*----------------------------------------------------------------------------*/ -enum mc_result mc_free_wsm( - uint32_t device_id, - uint8_t *wsm -) { - enum mc_result mc_result = MC_DRV_ERR_UNKNOWN; - struct mcore_device_t *device; - - - MCDRV_DBG_VERBOSE("===%s()===", __func__); - - /* Enter critical section */ - - do { - - /* Get the device associated wit the given session */ - device = resolve_device_id(device_id); - if (device == NULL) { - MCDRV_DBG_ERROR("Device not found"); - mc_result = MC_DRV_ERR_UNKNOWN_DEVICE; - break; - } - - /* find WSM object */ - struct wsm *wsm_stack = - mcore_device_find_contiguous_wsm(device, wsm); - if (wsm_stack == NULL) { - MCDRV_DBG_ERROR("unknown address"); - mc_result = MC_DRV_ERR_INVALID_PARAMETER; - break; - } - - /* Free the given virtual address */ - if (!mcore_device_free_contiguous_wsm(device, wsm_stack)) { - MCDRV_DBG_ERROR("Free of virtual address failed"); - mc_result = MC_DRV_ERR_FREE_MEMORY_FAILED; - break; - } - mc_result = MC_DRV_OK; - - } while (false); - - /* Exit critical section */ - - return mc_result; -} -EXPORT_SYMBOL(mc_free_wsm); - -/*----------------------------------------------------------------------------*/ -enum mc_result mc_map( - struct mc_session_handle *session_handle, - void *buf, - uint32_t buf_len, - struct mc_bulk_map *map_info -) { - enum mc_result mc_result = MC_DRV_ERR_UNKNOWN; - - MCDRV_DBG_VERBOSE("===%s()===", __func__); - - /* Enter critical section */ - - do { - if (session_handle == NULL) { - MCDRV_DBG_ERROR("session_handle is null"); - mc_result = MC_DRV_ERR_INVALID_PARAMETER; - break; - } - if (map_info == NULL) { - MCDRV_DBG_ERROR("map_info is null"); - mc_result = MC_DRV_ERR_INVALID_PARAMETER; - break; - } - if (buf == NULL) { - MCDRV_DBG_ERROR("buf is null"); - mc_result = MC_DRV_ERR_INVALID_PARAMETER; - break; - } - - /* Determine device the session belongs to */ - struct mcore_device_t *device = resolve_device_id( - session_handle->device_id); - if (device == NULL) { - MCDRV_DBG_ERROR("Device not found"); - mc_result = MC_DRV_ERR_UNKNOWN_DEVICE; - break; - } - struct connection *dev_con = device->connection; - - /* Get session */ - struct session *session = - mcore_device_resolve_session_id(device, - session_handle->session_id); - if (session == NULL) { - MCDRV_DBG_ERROR("Session not found"); - mc_result = MC_DRV_ERR_UNKNOWN_SESSION; - break; - } - - /* Register mapped bulk buffer to Kernel Module and keep mapped - bulk buffer in mind */ - struct bulk_buffer_descriptor *bulk_buf = session_add_bulk_buf( - session, buf, buf_len); - if (bulk_buf == NULL) { - MCDRV_DBG_ERROR("Error mapping bulk buffer"); - mc_result = MC_DRV_ERR_BULK_MAPPING; - break; - } - - /* Prepare map command */ - struct mc_drv_cmd_map_bulk_mem_t mc_drv_cmd_map_bulk_mem = { - /* C++ does not support C99 designated initializers */ - /* .header = */ { - /* .command_id = */ MC_DRV_CMD_MAP_BULK_BUF - }, - /* .payload = */ { - /* .session_id = */ session->session_id, - /* .phys_addr_l2; = */ - (uint32_t)bulk_buf->phys_addr_wsm_l2, - /* .offset_payload = */ - (uint32_t)(bulk_buf->virt_addr) & 0xFFF, - /* .len_bulk_mem = */ bulk_buf->len - } - }; - - /* Transmit map command to MobiCore device */ - connection_write_data( - dev_con, - &mc_drv_cmd_map_bulk_mem, - sizeof(mc_drv_cmd_map_bulk_mem)); - - /* Read command response */ - struct mc_drv_response_header_t rsp_header; - int len = connection_read_datablock( - dev_con, - &rsp_header, - sizeof(rsp_header)); - if (len != sizeof(rsp_header)) { - MCDRV_DBG_ERROR("CMD_MAP_BULK_BUF readRsp failed, " - "ret=%d", len); - mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE; - break; - } - - if (rsp_header.response_id != MC_DRV_RSP_OK) { - MCDRV_DBG_ERROR("CMD_MAP_BULK_BUF failed, respId=%d", - rsp_header.response_id); - /* REV We ignore Daemon Error code because client cannot - handle it anyhow. */ - mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE; - - /* Unregister mapped bulk buffer from Kernel Module and - remove mapped bulk buffer from session maintenance */ - if (!session_remove_bulk_buf(session, buf)) { - /* Removing of bulk buffer not possible */ - MCDRV_DBG_ERROR("Unregistering of bulk memory" - "from Kernel Module failed"); - } - break; - } - - struct mc_drv_rsp_map_bulk_mem_payload_t - rsp_map_bulk_mem_payload; - connection_read_datablock( - dev_con, - &rsp_map_bulk_mem_payload, - sizeof(rsp_map_bulk_mem_payload)); - - /* Set mapping info for Trustlet */ - map_info->secure_virt_addr = - (void *)(rsp_map_bulk_mem_payload.secure_virtual_adr); - map_info->secure_virt_len = buf_len; - mc_result = MC_DRV_OK; - - } while (false); - - /* Exit critical section */ - - return mc_result; -} -EXPORT_SYMBOL(mc_map); - -/*----------------------------------------------------------------------------*/ -enum mc_result mc_unmap( - struct mc_session_handle *session_handle, - void *buf, - struct mc_bulk_map *map_info -) { - enum mc_result mc_result = MC_DRV_ERR_UNKNOWN; - - MCDRV_DBG_VERBOSE("===%s()===", __func__); - - /* Enter critical section */ - - do { - if (session_handle == NULL) { - MCDRV_DBG_ERROR("session_handle is null"); - mc_result = MC_DRV_ERR_INVALID_PARAMETER; - break; - } - if (map_info == NULL) { - MCDRV_DBG_ERROR("map_info is null"); - mc_result = MC_DRV_ERR_INVALID_PARAMETER; - break; - } - if (buf == NULL) { - MCDRV_DBG_ERROR("buf is null"); - mc_result = MC_DRV_ERR_INVALID_PARAMETER; - break; - } - - /* Determine device the session belongs to */ - struct mcore_device_t *device = - resolve_device_id(session_handle->device_id); - if (device == NULL) { - MCDRV_DBG_ERROR("Device not found"); - mc_result = MC_DRV_ERR_UNKNOWN_DEVICE; - break; - } - struct connection *dev_con = device->connection; - - /* Get session */ - struct session *session = - mcore_device_resolve_session_id(device, - session_handle->session_id); - if (session == NULL) { - MCDRV_DBG_ERROR("Session not found"); - mc_result = MC_DRV_ERR_UNKNOWN_SESSION; - break; - } - - /* Prepare unmap command */ - struct mc_drv_cmd_unmap_bulk_mem_t cmd_unmap_bulk_mem = { - /* .header = */ { - /* .command_id = */ - MC_DRV_CMD_UNMAP_BULK_BUF - }, - /* .payload = */ { - /* .session_id = */ session->session_id, - /* .secure_virtual_adr = */ - (uint32_t)(map_info->secure_virt_addr), - /* .len_bulk_mem = - map_info->secure_virt_len*/ - } - }; - - connection_write_data( - dev_con, - &cmd_unmap_bulk_mem, - sizeof(cmd_unmap_bulk_mem)); - - /* Read command response */ - struct mc_drv_response_header_t rsp_header; - int len = connection_read_datablock( - dev_con, - &rsp_header, - sizeof(rsp_header)); - if (len != sizeof(rsp_header)) { - MCDRV_DBG_ERROR("CMD_UNMAP_BULK_BUF readRsp failed, " - "ret=%d", len); - mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE; - break; - } - - if (rsp_header.response_id != MC_DRV_RSP_OK) { - MCDRV_DBG_ERROR("CMD_UNMAP_BULK_BUF failed, respId=%d", - rsp_header.response_id); - /* REV We ignore Daemon Error code because client - cannot handle it anyhow. */ - mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE; - break; - } - - struct mc_drv_rsp_unmap_bulk_mem_payload_t - rsp_unmap_bulk_mem_payload; - connection_read_datablock( - dev_con, - &rsp_unmap_bulk_mem_payload, - sizeof(rsp_unmap_bulk_mem_payload)); - - /* REV axh: what about check the payload? */ - - /* Unregister mapped bulk buffer from Kernel Module and - * remove mapped bulk buffer from session maintenance */ - if (!session_remove_bulk_buf(session, buf)) { - /* Removing of bulk buffer not possible */ - MCDRV_DBG_ERROR("Unregistering of bulk memory from " - "Kernel Module failed"); - mc_result = MC_DRV_ERR_BULK_UNMAPPING; - break; - } - - mc_result = MC_DRV_OK; - - } while (false); - - /* Exit critical section */ - - return mc_result; -} -EXPORT_SYMBOL(mc_unmap); - -/*----------------------------------------------------------------------------*/ -enum mc_result mc_get_session_error_code( - struct mc_session_handle *session, - int32_t *last_error -) { - enum mc_result mc_result = MC_DRV_OK; - - MCDRV_DBG_VERBOSE("===%s()===", __func__); - - do { - if (session == NULL || last_error == NULL) { - mc_result = MC_DRV_ERR_INVALID_PARAMETER; - break; - } - - /* Get device */ - struct mcore_device_t *device = - resolve_device_id(session->device_id); - if (device == NULL) { - MCDRV_DBG_ERROR("Device not found"); - mc_result = MC_DRV_ERR_UNKNOWN_DEVICE; - break; - } - - /* Get session */ - struct session *nqsession = - mcore_device_resolve_session_id(device, session->session_id); - if (nqsession == NULL) { - MCDRV_DBG_ERROR("Session not found"); - mc_result = MC_DRV_ERR_UNKNOWN_SESSION; - break; - } - - /* get session error code from session */ - *last_error = session_get_last_err(nqsession); - - } while (false); - - return mc_result; -} -EXPORT_SYMBOL(mc_get_session_error_code); - -/*----------------------------------------------------------------------------*/ -enum mc_result mc_driver_ctrl( - enum mc_driver_ctrl param, - uint8_t *data, - uint32_t len -) { - MCDRV_DBG_WARN("not implemented"); - return MC_DRV_ERR_NOT_IMPLEMENTED; -} -EXPORT_SYMBOL(mc_driver_ctrl); - -/*----------------------------------------------------------------------------*/ -enum mc_result mc_manage( - uint32_t device_id, - uint8_t *data, - uint32_t len -) { - MCDRV_DBG_WARN("not implemented"); - return MC_DRV_ERR_NOT_IMPLEMENTED; -} -EXPORT_SYMBOL(mc_manage); - diff --git a/drivers/gud/mobicore_kernelapi/common.h b/drivers/gud/mobicore_kernelapi/common.h deleted file mode 100644 index 2a7347487040..000000000000 --- a/drivers/gud/mobicore_kernelapi/common.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * - * Common data types - * - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef COMMON_H -#define COMMON_H - -#include "connection.h" -#include "mcinq.h" - -void mcapi_insert_connection( - struct connection *connection -); - -void mcapi_remove_connection( - uint32_t seq -); - -unsigned int mcapi_unique_id( - void -); - - -#define MC_DAEMON_PID 0xFFFFFFFF -#define MC_DRV_MOD_DEVNODE_FULLPATH "/dev/mobicore" - -/* dummy function helper macro. */ -#define DUMMY_FUNCTION() do {} while (0) - -#define MCDRV_ERROR(txt, ...) \ - printk(KERN_ERR "mcKernelApi %s() ### ERROR: " txt, \ - __func__, \ - ##__VA_ARGS__) - -#if defined(DEBUG) - -/* #define DEBUG_VERBOSE */ -#if defined(DEBUG_VERBOSE) -#define MCDRV_DBG_VERBOSE MCDRV_DBG -#else -#define MCDRV_DBG_VERBOSE(...) DUMMY_FUNCTION() -#endif - -#define MCDRV_DBG(txt, ...) \ - printk(KERN_INFO "mcKernelApi %s(): " txt, \ - __func__, \ - ##__VA_ARGS__) - -#define MCDRV_DBG_WARN(txt, ...) \ - printk(KERN_WARNING "mcKernelApi %s() WARNING: " txt, \ - __func__, \ - ##__VA_ARGS__) - -#define MCDRV_DBG_ERROR(txt, ...) \ - printk(KERN_ERR "mcKernelApi %s() ### ERROR: " txt, \ - __func__, \ - ##__VA_ARGS__) - - -#define MCDRV_ASSERT(cond) \ - do { \ - if (unlikely(!(cond))) { \ - panic("mcKernelApi Assertion failed: %s:%d\n", \ - __FILE__, __LINE__); \ - } \ - } while (0) - -#elif defined(NDEBUG) - -#define MCDRV_DBG_VERBOSE(...) DUMMY_FUNCTION() -#define MCDRV_DBG(...) DUMMY_FUNCTION() -#define MCDRV_DBG_WARN(...) DUMMY_FUNCTION() -#define MCDRV_DBG_ERROR(...) DUMMY_FUNCTION() - -#define MCDRV_ASSERT(...) DUMMY_FUNCTION() - -#else -#error "Define DEBUG or NDEBUG" -#endif /* [not] defined(DEBUG_MCMODULE) */ - - -#define LOG_I MCDRV_DBG_VERBOSE -#define LOG_W MCDRV_DBG_WARN -#define LOG_E MCDRV_DBG_ERROR - - -#define assert(expr) MCDRV_ASSERT(expr) - -#endif /* COMMON_H */ - -/** @} */ diff --git a/drivers/gud/mobicore_kernelapi/connection.c b/drivers/gud/mobicore_kernelapi/connection.c deleted file mode 100644 index 9048ae87a5a1..000000000000 --- a/drivers/gud/mobicore_kernelapi/connection.c +++ /dev/null @@ -1,229 +0,0 @@ -/** @addtogroup MCD_MCDIMPL_DAEMON_SRV - * @{ - * @file - * - * Connection data. - * - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "connection.h" -#include "common.h" - -/* Define the initial state of the Data Available Semaphore */ -#define SEM_NO_DATA_AVAILABLE 0 - -/*----------------------------------------------------------------------------*/ -struct connection *connection_new( - void -) { - struct connection *conn = kzalloc(sizeof(struct connection), - GFP_KERNEL); - conn->sequence_magic = mcapi_unique_id(); - mutex_init(&conn->data_lock); - /* No data available */ - sema_init(&conn->data_available_sem, SEM_NO_DATA_AVAILABLE); - - mcapi_insert_connection(conn); - return conn; -} - -/*----------------------------------------------------------------------------*/ -struct connection *connection_create( - int socket_descriptor, - pid_t dest -) { - struct connection *conn = connection_new(); - - conn->peer_pid = dest; - return conn; -} - - -/*----------------------------------------------------------------------------*/ -void connection_cleanup( - struct connection *conn -) { - if (!conn) - return; - - kfree_skb(conn->skb); - - mcapi_remove_connection(conn->sequence_magic); - kfree(conn); -} - - -/*----------------------------------------------------------------------------*/ -bool connection_connect( - struct connection *conn, - pid_t dest -) { - /* Nothing to connect */ - conn->peer_pid = dest; - return true; -} - -/*----------------------------------------------------------------------------*/ -size_t connection_readDataMsg( - struct connection *conn, - void *buffer, - uint32_t len -) { - size_t ret = -1; - MCDRV_DBG_VERBOSE("reading connection data %u, connection data left %u", - len, conn->data_len); - /* trying to read more than the left data */ - if (len > conn->data_len) { - ret = conn->data_len; - memcpy(buffer, conn->data_start, conn->data_len); - conn->data_len = 0; - } else { - ret = len; - memcpy(buffer, conn->data_start, len); - conn->data_len -= len; - conn->data_start += len; - } - - if (conn->data_len == 0) { - conn->data_start = NULL; - kfree_skb(conn->skb); - conn->skb = NULL; - } - MCDRV_DBG_VERBOSE("read %u", ret); - return ret; -} - -/*----------------------------------------------------------------------------*/ -size_t connection_read_datablock( - struct connection *conn, - void *buffer, - uint32_t len -) { - return connection_read_data(conn, buffer, len, -1); -} - - -/*----------------------------------------------------------------------------*/ -size_t connection_read_data( - struct connection *conn, - void *buffer, - uint32_t len, - int32_t timeout -) { - size_t ret = 0; - - MCDRV_ASSERT(buffer != NULL); - MCDRV_ASSERT(conn->socket_descriptor != NULL); - - MCDRV_DBG_VERBOSE("read data len = %u for PID = %u", - len, conn->sequence_magic); - do { - /* Wait until data is available or timeout - msecs_to_jiffies(-1) -> wait forever for the sem */ - if (down_timeout(&(conn->data_available_sem), - msecs_to_jiffies(timeout))) { - MCDRV_DBG_VERBOSE("Timeout reading the data sem"); - ret = -2; - break; - } - - if (mutex_lock_interruptible(&(conn->data_lock))) { - MCDRV_DBG_ERROR("interrupted reading the data sem"); - ret = -1; - break; - } - /* Have data, use it */ - if (conn->data_len > 0) - ret = connection_readDataMsg(conn, buffer, len); - - mutex_unlock(&(conn->data_lock)); - - /* There is still some data left */ - if (conn->data_len > 0) - up(&conn->data_available_sem); - } while (0); - - return ret; -} - -/*----------------------------------------------------------------------------*/ -size_t connection_write_data( - struct connection *conn, - void *buffer, - uint32_t len -) { - struct sk_buff *skb = NULL; - struct nlmsghdr *nlh; - int ret = 0; - - MCDRV_DBG_VERBOSE("buffer length %u from pid %u\n", - len, conn->sequence_magic); - do { - skb = nlmsg_new(NLMSG_SPACE(len), GFP_KERNEL); - if (!skb) { - ret = -1; - break; - } - - nlh = nlmsg_put(skb, 0, conn->sequence_magic, 2, - NLMSG_LENGTH(len), NLM_F_REQUEST); - if (!nlh) { - ret = -1; - break; - } - memcpy(NLMSG_DATA(nlh), buffer, len); - - netlink_unicast(conn->socket_descriptor, skb, - conn->peer_pid, MSG_DONTWAIT); - ret = len; - } while (0); - - if (!ret && skb != NULL) - kfree_skb(skb); - - return ret; -} - -int connection_process( - struct connection *conn, - struct sk_buff *skb -) -{ - int ret = 0; - do { - if (mutex_lock_interruptible(&(conn->data_lock))) { - MCDRV_DBG_ERROR("Interrupted getting data semaphore!"); - ret = -1; - break; - } - - kfree_skb(conn->skb); - - /* Get a reference to the incomming skb */ - conn->skb = skb_get(skb); - if (conn->skb) { - conn->data_msg = nlmsg_hdr(conn->skb); - conn->data_len = NLMSG_PAYLOAD(conn->data_msg, 0); - conn->data_start = NLMSG_DATA(conn->data_msg); - up(&(conn->data_available_sem)); - } - mutex_unlock(&(conn->data_lock)); - ret = 0; - } while (0); - return ret; -} -/** @} */ diff --git a/drivers/gud/mobicore_kernelapi/connection.h b/drivers/gud/mobicore_kernelapi/connection.h deleted file mode 100644 index 0b468e6c7b43..000000000000 --- a/drivers/gud/mobicore_kernelapi/connection.h +++ /dev/null @@ -1,122 +0,0 @@ -/** @addtogroup MCD_MCDIMPL_DAEMON_SRV - * @{ - * @file - * - * Connection data. - * - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef CONNECTION_H_ -#define CONNECTION_H_ - -#include - -#include -#include - -#define MAX_PAYLOAD_SIZE 128 - -struct connection { - struct sock *socket_descriptor; /**< Netlink socket */ - uint32_t sequence_magic; /**< Random? magic to match requests/answers */ - - struct nlmsghdr *data_msg; - uint32_t data_len; /**< How much connection data is left */ - void *data_start; /**< Start pointer of remaining data */ - struct sk_buff *skb; - - struct mutex data_lock; /**< Data protection lock */ - struct semaphore data_available_sem; /**< Data protection semaphore */ - - pid_t self_pid; /**< PID address used for local connection */ - pid_t peer_pid; /**< Remote PID for connection */ - - struct list_head list; /**< The list param for using the kernel lists*/ -}; - -struct connection *connection_new( - void -); - -struct connection *connection_create( - int socket_descriptor, - pid_t dest -); - -void connection_cleanup( - struct connection *conn -); - -/** - * Connect to destination. - * - * @param Destination pointer. - * @return true on success. - */ -bool connection_connect( - struct connection *conn, - pid_t dest -); - - -/** - * Read bytes from the connection. - * - * @param buffer Pointer to destination buffer. - * @param len Number of bytes to read. - * @return Number of bytes read. - */ -size_t connection_read_datablock( - struct connection *conn, - void *buffer, - uint32_t len -); -/** - * Read bytes from the connection. - * - * @param buffer Pointer to destination buffer. - * @param len Number of bytes to read. - * @param timeout Timeout in milliseconds - * @return Number of bytes read. - * @return -1 if select() failed (returned -1) - * @return -2 if no data available, i.e. timeout - */ -size_t connection_read_data( - struct connection *conn, - void *buffer, - uint32_t len, - int32_t timeout -); - -/** - * Write bytes to the connection. - * - * @param buffer Pointer to source buffer. - * @param len Number of bytes to read. - * @return Number of bytes written. - */ -size_t connection_write_data( - struct connection *conn, - void *buffer, - uint32_t len -); - -/** - * Write bytes to the connection. - * - * @param buffer Pointer to source buffer. - * @param len Number of bytes to read. - * @return Number of bytes written. - */ -int connection_process( - struct connection *conn, - struct sk_buff *skb -); - -#endif /* CONNECTION_H_ */ - -/** @} */ diff --git a/drivers/gud/mobicore_kernelapi/device.c b/drivers/gud/mobicore_kernelapi/device.c deleted file mode 100644 index dbeee6a81190..000000000000 --- a/drivers/gud/mobicore_kernelapi/device.c +++ /dev/null @@ -1,257 +0,0 @@ -/** @addtogroup MCD_IMPL_LIB - * @{ - * @file - * - * Client library device management. - * - * Device and Trustlet Session management Funtions. - * - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include "mc_kernel_api.h" -#include "public/mobicore_driver_api.h" - -#include "device.h" -#include "common.h" - -/*----------------------------------------------------------------------------*/ -struct wsm *wsm_create( - void *virt_addr, - uint32_t len, - uint32_t handle, - void *phys_addr /*= NULL this may be unknown, so is can be omitted.*/ - ) -{ - struct wsm *wsm = kzalloc(sizeof(struct wsm), GFP_KERNEL); - wsm->virt_addr = virt_addr; - wsm->len = len; - wsm->handle = handle; - wsm->phys_addr = phys_addr; - return wsm; -} - - -/*----------------------------------------------------------------------------*/ -struct mcore_device_t *mcore_device_create( - uint32_t device_id, - struct connection *connection -) { - struct mcore_device_t *dev = - kzalloc(sizeof(struct mcore_device_t), GFP_KERNEL); - dev->device_id = device_id; - dev->connection = connection; - - INIT_LIST_HEAD(&dev->session_vector); - INIT_LIST_HEAD(&dev->wsm_l2_vector); - - return dev; -} - - -/*----------------------------------------------------------------------------*/ -void mcore_device_cleanup( - struct mcore_device_t *dev -) { - struct session *tmp; - struct wsm *wsm; - struct list_head *pos, *q; - - /* Delete all session objects. Usually this should not be needed - * as closeDevice()requires that all sessions have been closed before.*/ - list_for_each_safe(pos, q, &dev->session_vector) { - tmp = list_entry(pos, struct session, list); - list_del(pos); - session_cleanup(tmp); - } - - /* Free all allocated WSM descriptors */ - list_for_each_safe(pos, q, &dev->wsm_l2_vector) { - wsm = list_entry(pos, struct wsm, list); - /* mcKMod_free(dev->instance, wsm->handle); */ - list_del(pos); - kfree(wsm); - } - connection_cleanup(dev->connection); - - mcore_device_close(dev); - kfree(dev); -} - - -/*----------------------------------------------------------------------------*/ -bool mcore_device_open( - struct mcore_device_t *dev, - const char *deviceName -) { - dev->instance = mobicore_open(); - return (dev->instance != NULL); -} - - -/*----------------------------------------------------------------------------*/ -void mcore_device_close( - struct mcore_device_t *dev -) { - mobicore_release(dev->instance); -} - - -/*----------------------------------------------------------------------------*/ -bool mcore_device_has_sessions( - struct mcore_device_t *dev -) { - return !list_empty(&dev->session_vector); -} - - -/*----------------------------------------------------------------------------*/ -bool mcore_device_create_new_session( - struct mcore_device_t *dev, - uint32_t session_id, - struct connection *connection -) { - /* Check if session_id already exists */ - if (mcore_device_resolve_session_id(dev, session_id)) { - MCDRV_DBG_ERROR(" session %u already exists", session_id); - return false; - } - struct session *session = session_create(session_id, dev->instance, - connection); - list_add_tail(&(session->list), &(dev->session_vector)); - return true; -} - - -/*----------------------------------------------------------------------------*/ -bool mcore_device_remove_session( - struct mcore_device_t *dev, - uint32_t session_id -) { - bool ret = false; - struct session *tmp; - struct list_head *pos, *q; - - list_for_each_safe(pos, q, &dev->session_vector) { - tmp = list_entry(pos, struct session, list); - if (tmp->session_id == session_id) { - list_del(pos); - session_cleanup(tmp); - ret = true; - break; - } - } - return ret; -} - - -/*----------------------------------------------------------------------------*/ -struct session *mcore_device_resolve_session_id( - struct mcore_device_t *dev, - uint32_t session_id -) { - struct session *ret = NULL; - struct session *tmp; - struct list_head *pos; - - - /* Get session for session_id */ - list_for_each(pos, &dev->session_vector) { - tmp = list_entry(pos, struct session, list); - if (tmp->session_id == session_id) { - ret = tmp; - break; - } - } - return ret; -} - - -/*----------------------------------------------------------------------------*/ -struct wsm *mcore_device_allocate_contiguous_wsm( - struct mcore_device_t *dev, - uint32_t len -) { - struct wsm *wsm = NULL; - do { - if (len == 0) - break; - - /* Allocate shared memory */ - void *virt_addr; - uint32_t handle; - void *phys_addr; - int ret = mobicore_allocate_wsm(dev->instance, - len, - &handle, - &virt_addr, - &phys_addr); - if (ret != 0) - break; - - /* Register (vaddr,paddr) with device */ - wsm = wsm_create(virt_addr, len, handle, phys_addr); - - list_add_tail(&(wsm->list), &(dev->wsm_l2_vector)); - - } while (0); - - /* Return pointer to the allocated memory */ - return wsm; -} - - -/*----------------------------------------------------------------------------*/ -bool mcore_device_free_contiguous_wsm( - struct mcore_device_t *dev, - struct wsm *wsm -) { - bool ret = false; - struct wsm *tmp; - struct list_head *pos; - - list_for_each(pos, &dev->wsm_l2_vector) { - tmp = list_entry(pos, struct wsm, list); - if (tmp == wsm) { - ret = true; - break; - } - } - - if (ret) { - MCDRV_DBG_VERBOSE("freeWsm virt_addr=0x%p, handle=%d", - wsm->virt_addr, wsm->handle); - - /* ignore return code */ - mobicore_free(dev->instance, wsm->handle); - - list_del(pos); - kfree(wsm); - } - return ret; -} - - -/*----------------------------------------------------------------------------*/ -struct wsm *mcore_device_find_contiguous_wsm( - struct mcore_device_t *dev, - void *virt_addr -) { - struct wsm *wsm; - struct list_head *pos; - - list_for_each(pos, &dev->wsm_l2_vector) { - wsm = list_entry(pos, struct wsm, list); - if (virt_addr == wsm->virt_addr) - return wsm; - } - - return NULL; -} - -/** @} */ diff --git a/drivers/gud/mobicore_kernelapi/device.h b/drivers/gud/mobicore_kernelapi/device.h deleted file mode 100644 index f40d9936714a..000000000000 --- a/drivers/gud/mobicore_kernelapi/device.h +++ /dev/null @@ -1,139 +0,0 @@ -/** @addtogroup MCD_IMPL_LIB - * @{ - * @file - * - * Client library device management. - * - * Device and Trustlet Session management Functions. - * - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef DEVICE_H_ -#define DEVICE_H_ - -#include - -#include "connection.h" -#include "session.h" -#include "wsm.h" - - -struct mcore_device_t { - struct list_head session_vector; /**< MobiCore Trustlet session - associated with the device */ - struct list_head wsm_l2_vector; /**< WSM L2 Table */ - - uint32_t device_id; /**< Device identifier */ - struct connection *connection; /**< The device connection */ - struct mc_instance *instance; /**< MobiCore Driver instance */ - - struct list_head list; /**< The list param for using the kernel lists*/ -}; - -struct mcore_device_t *mcore_device_create( - uint32_t device_id, - struct connection *connection -); - -void mcore_device_cleanup( - struct mcore_device_t *dev -); - -/** - * Open the device. - * @param deviceName Name of the kernel modules device file. - * @return true if the device has been opened successfully - */ -bool mcore_device_open( - struct mcore_device_t *dev, - const char *deviceName -); - -/** - * Closes the device. - */ -void mcore_device_close( - struct mcore_device_t *dev -); - -/** - * Check if the device has open sessions. - * @return true if the device has one or more open sessions. - */ -bool mcore_device_has_sessions( - struct mcore_device_t *dev -); - -/** - * Add a session to the device. - * @param session_id session ID - * @param connection session connection - */ -bool mcore_device_create_new_session( - struct mcore_device_t *dev, - uint32_t session_id, - struct connection *connection -); - -/** - * Remove the specified session from the device. - * The session object will be destroyed and all resources associated with it - * will be freed. - * - * @param session_id Session of the session to remove. - * @return true if a session has been found and removed. - */ -bool mcore_device_remove_session( - struct mcore_device_t *dev, - uint32_t session_id -); - -/** - * Get as session object for a given session ID. - * @param session_id Identified of a previously opened session. - * @return Session object if available or NULL if no session has been found. - */ -struct session *mcore_device_resolve_session_id( - struct mcore_device_t *dev, - uint32_t session_id -); - -/** - * Allocate a block of contiguous WSM. - * @param len The virtual address to be registered. - * @return The virtual address of the allocated memory or NULL if no memory - * is available. - */ -struct wsm *mcore_device_allocate_contiguous_wsm( - struct mcore_device_t *dev, - uint32_t len -); - -/** - * Unregister a vaddr from a device. - * @param vaddr The virtual address to be registered. - * @param paddr The physical address to be registered. - */ -bool mcore_device_free_contiguous_wsm( - struct mcore_device_t *dev, - struct wsm *wsm -); - -/** - * Get a WSM object for a given virtual address. - * @param vaddr The virtual address which has been allocate with mc_malloc_wsm() - * in advance. - * @return the WSM object or NULL if no address has been found. - */ -struct wsm *mcore_device_find_contiguous_wsm( - struct mcore_device_t *dev, - void *virt_addr -); - -#endif /* DEVICE_H_ */ - -/** @} */ diff --git a/drivers/gud/mobicore_kernelapi/include/mcinq.h b/drivers/gud/mobicore_kernelapi/include/mcinq.h deleted file mode 100644 index 3cb82be8a32d..000000000000 --- a/drivers/gud/mobicore_kernelapi/include/mcinq.h +++ /dev/null @@ -1,125 +0,0 @@ -/** @addtogroup NQ - * @{ - * Notifications inform the MobiCore runtime environment that information is - * pending in a WSM buffer. - * The Trustlet Connector (TLC) and the corresponding trustlet also utilize - * this buffer to notify each other about new data within the - * Trustlet Connector Interface (TCI). - * - * The buffer is set up as a queue, which means that more than one - * notification can be written to the buffer before the switch to the other - * world is performed. Each side therefore facilitates an incoming and an - * outgoing queue for communication with the other side. - * - * Notifications hold the session ID, which is used to reference the - * communication partner in the other world. - * So if, e.g., the TLC in the normal world wants to notify his trustlet - * about new data in the TLC buffer - * - * @file - * Notification queue declarations. - * - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef NQ_H_ -#define NQ_H_ - -/** \name NQ Size Defines - * Minimum and maximum count of elements in the notification queue. - * @{ */ -#define MIN_NQ_ELEM 1 /**< Minimum notification queue elements. */ -#define MAX_NQ_ELEM 64 /**< Maximum notification queue elements. */ -/** @} */ - -/** \name NQ Length Defines - * Minimum and maximum notification queue length. - * @{ */ -/**< Minimum notification length (in bytes). */ -#define MIN_NQ_LEN (MIN_NQ_ELEM * sizeof(notification)) -/**< Maximum notification length (in bytes). */ -#define MAX_NQ_LEN (MAX_NQ_ELEM * sizeof(notification)) -/** @} */ - -/** \name Session ID Defines - * Standard Session IDs. - * @{ */ -/**< MCP session ID is used when directly communicating with the MobiCore - * (e.g. for starting and stopping of trustlets). */ -#define SID_MCP 0 -/**< Invalid session id is returned in case of an error. */ -#define SID_INVALID 0xffffffff -/** @} */ - -/** Notification data structure. */ -struct notification { - uint32_t session_id; /**< Session ID. */ - int32_t payload; /**< Additional notification information. */ -}; - -/** Notification payload codes. - * 0 indicated a plain simple notification, - * a positive value is a termination reason from the task, - * a negative value is a termination reason from MobiCore. - * Possible negative values are given below. - */ -enum notification_payload { - /**< task terminated, but exit code is invalid */ - ERR_INVALID_EXIT_CODE = -1, - /**< task terminated due to session end, no exit code available */ - ERR_SESSION_CLOSE = -2, - /**< task terminated due to invalid operation */ - ERR_INVALID_OPERATION = -3, - /**< session ID is unknown */ - ERR_INVALID_SID = -4, - /**< session is not active */ - ERR_SID_NOT_ACTIVE = -5 -}; - -/** Declaration of the notification queue header. - * layout as specified in the data structure specification. - */ -struct notification_queue_header { - uint32_t write_cnt; /**< Write counter. */ - uint32_t read_cnt; /**< Read counter. */ - uint32_t queue_size; /**< Queue size. */ -}; - -/** Queue struct which defines a queue object. - * The queue struct is accessed by the queue type of - * function. elementCnt must be a power of two and the power needs - * to be smaller than power of uint32_t (obviously 32). - */ -struct notification_queue { - /**< Queue header. */ - struct notification_queue_header hdr; - /**< Notification elements. */ - struct notification notification[MIN_NQ_ELEM]; -} ; - -#endif /** NQ_H_ */ - -/** @} */ diff --git a/drivers/gud/mobicore_kernelapi/include/mcuuid.h b/drivers/gud/mobicore_kernelapi/include/mcuuid.h deleted file mode 100644 index b72acb8a002e..000000000000 --- a/drivers/gud/mobicore_kernelapi/include/mcuuid.h +++ /dev/null @@ -1,74 +0,0 @@ -/** - * @addtogroup MC_UUID mcUuid - Universally Unique Identifier. - * - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @ingroup MC_DATA_TYPES - * @{ - */ - -#ifndef MC_UUID_H_ -#define MC_UUID_H_ - -#define UUID_TYPE - -/** Universally Unique Identifier (UUID) according to ISO/IEC 11578. */ -struct mc_uuid_t { - uint8_t value[16]; /**< Value of the UUID. */ -}; - -/** UUID value used as free marker in service provider containers. */ -#define MC_UUID_FREE_DEFINE \ - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } - -static const struct mc_uuid_t MC_UUID_FREE = { - MC_UUID_FREE_DEFINE -}; - -/** Reserved UUID. */ -#define MC_UUID_RESERVED_DEFINE \ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } - -static const struct mc_uuid_t MC_UUID_RESERVED = { - MC_UUID_RESERVED_DEFINE -}; - -/** UUID for system applications. */ -#define MC_UUID_SYSTEM_DEFINE \ - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE } - -static const struct mc_uuid_t MC_UUID_SYSTEM = { - MC_UUID_SYSTEM_DEFINE -}; - -#endif /* MC_UUID_H_ */ - -/** @} */ - diff --git a/drivers/gud/mobicore_kernelapi/main.c b/drivers/gud/mobicore_kernelapi/main.c deleted file mode 100644 index 62997f725e62..000000000000 --- a/drivers/gud/mobicore_kernelapi/main.c +++ /dev/null @@ -1,181 +0,0 @@ -/** - * MobiCore KernelApi module - * - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "connection.h" -#include "common.h" - -#define MC_DAEMON_NETLINK 17 - -struct mc_kernelapi_ctx { - struct sock *sk; - struct list_head peers; - atomic_t counter; -}; - -struct mc_kernelapi_ctx *mod_ctx; /* = NULL; */ - -/*----------------------------------------------------------------------------*/ -/* get a unique ID */ -unsigned int mcapi_unique_id( - void -) -{ - return (unsigned int)atomic_inc_return( - &(mod_ctx->counter)); -} - - -/*----------------------------------------------------------------------------*/ -static struct connection *mcapi_find_connection( - uint32_t seq -) -{ - struct connection *tmp; - struct list_head *pos; - - /* Get session for session_id */ - list_for_each(pos, &mod_ctx->peers) { - tmp = list_entry(pos, struct connection, list); - if (tmp->sequence_magic == seq) - return tmp; - } - - return NULL; -} - -/*----------------------------------------------------------------------------*/ -void mcapi_insert_connection( - struct connection *connection -) -{ - list_add_tail(&(connection->list), &(mod_ctx->peers)); - connection->socket_descriptor = mod_ctx->sk; -} - -void mcapi_remove_connection( - uint32_t seq -) -{ - struct connection *tmp; - struct list_head *pos, *q; - - /* Delete all session objects. Usually this should not be needed as - closeDevice() requires that all sessions have been closed before.*/ - list_for_each_safe(pos, q, &mod_ctx->peers) { - tmp = list_entry(pos, struct connection, list); - if (tmp->sequence_magic == seq) { - list_del(pos); - break; - } - } -} - -/*----------------------------------------------------------------------------*/ -static int mcapi_process( - struct sk_buff *skb, - struct nlmsghdr *nlh -) -{ - struct connection *c; - int length; - int seq; - pid_t pid; - int ret; - - pid = nlh->nlmsg_pid; - length = nlh->nlmsg_len; - seq = nlh->nlmsg_seq; - MCDRV_DBG_VERBOSE("nlmsg len %d type %d pid 0x%X seq %d\n", - length, nlh->nlmsg_type, pid, seq); - do { - c = mcapi_find_connection(seq); - if (!c) { - MCDRV_ERROR("Invalid incomming connection - seq=%u!", - seq); - ret = -1; - break; - } - - /* Pass the buffer to the appropriate connection */ - connection_process(c, skb); - - ret = 0; - } while (false); - return ret; -} - -/*----------------------------------------------------------------------------*/ -static void mcapi_callback( - struct sk_buff *skb -) -{ - struct nlmsghdr *nlh = nlmsg_hdr(skb); - int len = skb->len; - int err = 0; - - while (NLMSG_OK(nlh, len)) { - err = mcapi_process(skb, nlh); - - /* if err or if this message says it wants a response */ - if (err || (nlh->nlmsg_flags & NLM_F_ACK)) - netlink_ack(skb, nlh, err); - - nlh = NLMSG_NEXT(nlh, len); - } -} - -/*----------------------------------------------------------------------------*/ -static int __init mcapi_init(void) -{ - printk(KERN_INFO "Mobicore API module initialized!\n"); - - mod_ctx = kzalloc(sizeof(struct mc_kernelapi_ctx), GFP_KERNEL); - - /* start kernel thread */ - mod_ctx->sk = netlink_kernel_create(&init_net, MC_DAEMON_NETLINK, 0, - mcapi_callback, NULL, THIS_MODULE); - - if (!mod_ctx->sk) { - MCDRV_ERROR("register of recieve handler failed"); - return -EFAULT; - } - - INIT_LIST_HEAD(&mod_ctx->peers); - return 0; -} - -static void __exit mcapi_exit(void) -{ - printk(KERN_INFO "Unloading Mobicore API module.\n"); - - if (mod_ctx->sk != NULL) { - netlink_kernel_release(mod_ctx->sk); - mod_ctx->sk = NULL; - } - kfree(mod_ctx); - mod_ctx = NULL; -} - -module_init(mcapi_init); -module_exit(mcapi_exit); - -MODULE_AUTHOR("Giesecke & Devrient GmbH"); -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("MobiCore API driver"); diff --git a/drivers/gud/mobicore_kernelapi/public/mobicore_driver_api.h b/drivers/gud/mobicore_kernelapi/public/mobicore_driver_api.h deleted file mode 100644 index ccfb2e5e9de9..000000000000 --- a/drivers/gud/mobicore_kernelapi/public/mobicore_driver_api.h +++ /dev/null @@ -1,483 +0,0 @@ -/** - * @defgroup MCD_API MobiCore Driver API - * @addtogroup MCD_API - * @{ - * - * @if DOXYGEN_MCDRV_API - * @mainpage MobiCore Driver API. - * @endif - * - * MobiCore Driver API. - * - * The MobiCore (MC) Driver API provides access functions to the MobiCore - * runtime environment and the contained Trustlets. - * - * @image html DoxyOverviewDrvApi500x.png - * @image latex DoxyOverviewDrvApi500x.png "MobiCore Overview" width=12cm - * - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef MCDRIVER_H_ -#define MCDRIVER_H_ - -#define __MC_CLIENT_LIB_API - -#include "mcuuid.h" - -/** - * Return values of MobiCore driver functions. - */ -enum mc_result { - /**< Function call succeeded. */ - MC_DRV_OK = 0, - /**< No notification available. */ - MC_DRV_NO_NOTIFICATION = 1, - /**< Error during notification on communication level. */ - MC_DRV_ERR_NOTIFICATION = 2, - /**< Function not implemented. */ - MC_DRV_ERR_NOT_IMPLEMENTED = 3, - /**< No more resources available. */ - MC_DRV_ERR_OUT_OF_RESOURCES = 4, - /**< Driver initialization failed. */ - MC_DRV_ERR_INIT = 5, - /**< Unknown error. */ - MC_DRV_ERR_UNKNOWN = 6, - /**< The specified device is unknown. */ - MC_DRV_ERR_UNKNOWN_DEVICE = 7, - /**< The specified session is unknown.*/ - MC_DRV_ERR_UNKNOWN_SESSION = 8, - /**< The specified operation is not allowed. */ - MC_DRV_ERR_INVALID_OPERATION = 9, - /**< The response header from the MC is invalid. */ - MC_DRV_ERR_INVALID_RESPONSE = 10, - /**< Function call timed out. */ - MC_DRV_ERR_TIMEOUT = 11, - /**< Can not allocate additional memory. */ - MC_DRV_ERR_NO_FREE_MEMORY = 12, - /**< Free memory failed. */ - MC_DRV_ERR_FREE_MEMORY_FAILED = 13, - /**< Still some open sessions pending. */ - MC_DRV_ERR_SESSION_PENDING = 14, - /**< MC daemon not reachable */ - MC_DRV_ERR_DAEMON_UNREACHABLE = 15, - /**< The device file of the kernel module could not be opened. */ - MC_DRV_ERR_INVALID_DEVICE_FILE = 16, - /**< Invalid parameter. */ - MC_DRV_ERR_INVALID_PARAMETER = 17, - /**< Unspecified error from Kernel Module*/ - MC_DRV_ERR_KERNEL_MODULE = 18, - /**< Error during mapping of additional bulk memory to session. */ - MC_DRV_ERR_BULK_MAPPING = 19, - /**< Error during unmapping of additional bulk memory to session. */ - MC_DRV_ERR_BULK_UNMAPPING = 20, - /**< Notification received, exit code available. */ - MC_DRV_INFO_NOTIFICATION = 21, - /**< Set up of NWd connection failed. */ - MC_DRV_ERR_NQ_FAILED = 22 -}; - - -/** - * Driver control command. - */ -enum mc_driver_ctrl { - MC_CTRL_GET_VERSION = 1 /**< Return the driver version */ -}; - - -/** Structure of Session Handle, includes the Session ID and the Device ID the - * Session belongs to. - * The session handle will be used for session-based MobiCore communication. - * It will be passed to calls which address a communication end point in the - * MobiCore environment. - */ -struct mc_session_handle { - uint32_t session_id; /**< MobiCore session ID */ - uint32_t device_id; /**< Device ID the session belongs to */ -}; - -/** Information structure about additional mapped Bulk buffer between the - * Trustlet Connector (Nwd) and the Trustlet (Swd). This structure is - * initialized from a Trustlet Connector by calling mc_map(). - * In order to use the memory within a Trustlet the Trustlet Connector has to - * inform the Trustlet with the content of this structure via the TCI. - */ -struct mc_bulk_map { - /**< The virtual address of the Bulk buffer regarding the address space - * of the Trustlet, already includes a possible offset! */ - void *secure_virt_addr; - uint32_t secure_virt_len; /**< Length of the mapped Bulk buffer */ -}; - - -/**< The default device ID */ -#define MC_DEVICE_ID_DEFAULT 0 -/**< Wait infinite for a response of the MC. */ -#define MC_INFINITE_TIMEOUT ((int32_t)(-1)) -/**< Do not wait for a response of the MC. */ -#define MC_NO_TIMEOUT 0 -/**< TCI/DCI must not exceed 1MiB */ -#define MC_MAX_TCI_LEN 0x100000 - - - -/** Open a new connection to a MobiCore device. - * - * mc_open_device() initializes all device specific resources required to - * communicate with an MobiCore instance located on the specified device in the - * system. If the device does not exist the function will return - * MC_DRV_ERR_UNKNOWN_DEVICE. - * - * @param [in] device_id Identifier for the MobiCore device to be used. - * MC_DEVICE_ID_DEFAULT refers to the default device. - * - * @return MC_DRV_OK if operation has been successfully completed. - * @return MC_DRV_ERR_INVALID_OPERATION if device already opened. - * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur. - * @return MC_DRV_ERR_UNKNOWN_DEVICE when device_id is unknown. - * @return MC_DRV_ERR_INVALID_DEVICE_FILE if kernel module under - * /dev/mobicore cannot be opened - * - * Uses a Mutex. - */ -__MC_CLIENT_LIB_API enum mc_result mc_open_device( - uint32_t device_id -); - -/** Close the connection to a MobiCore device. - * When closing a device, active sessions have to be closed beforehand. - * Resources associated with the device will be released. - * The device may be opened again after it has been closed. - * - * @param [in] device_id Identifier for the MobiCore device. - * MC_DEVICE_ID_DEFAULT refers to the default device. - * - * @return MC_DRV_OK if operation has been successfully completed. - * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid. - * @return MC_DRV_ERR_SESSION_PENDING when a session is still open. - * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur. - * - * Uses a Mutex. - */ -__MC_CLIENT_LIB_API enum mc_result mc_close_device( - uint32_t device_id -); - -/** Open a new session to a Trustlet. The trustlet with the given UUID has - * to be available in the flash filesystem. - * - * Write MCP open message to buffer and notify MobiCore about the availability - * of a new command. - * Waits till the MobiCore responses with the new session ID (stored in the MCP - * buffer). - * - * @param [in,out] session On success, the session data will be returned. - * Note that session.device_id has to be the device id of an opened device. - * @param [in] uuid UUID of the Trustlet to be opened. - * @param [in] tci TCI buffer for communicating with the trustlet. - * @param [in] tci_len Length of the TCI buffer. Maximum allowed value - * is MC_MAX_TCI_LEN. - * - * @return MC_DRV_OK if operation has been successfully completed. - * @return MC_DRV_INVALID_PARAMETER if session parameter is invalid. - * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid. - * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon socket occur. - * @return MC_DRV_ERR_UNKNOWN_DEVICE when daemon returns an error. - * - * Uses a Mutex. - */ -__MC_CLIENT_LIB_API enum mc_result mc_open_session( - struct mc_session_handle *session, - const struct mc_uuid_t *uuid, - uint8_t *tci, - uint32_t tci_len -); - -/** Close a Trustlet session. - * - * Closes the specified MobiCore session. The call will block until the - * session has been closed. - * - * @pre Device device_id has to be opened in advance. - * - * @param [in] session Session to be closed. - * - * @return MC_DRV_OK if operation has been successfully completed. - * @return MC_DRV_INVALID_PARAMETER if session parameter is invalid. - * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid. - * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid. - * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur. - * @return MC_DRV_ERR_INVALID_DEVICE_FILE when daemon cannot open trustlet file. - * - * Uses a Mutex. - */ -__MC_CLIENT_LIB_API enum mc_result mc_close_session( - struct mc_session_handle *session -); - -/** Notify a session. - * Notifies the session end point about available message data. - * If the session parameter is correct, notify will always succeed. - * Corresponding errors can only be received by mc_wait_notification(). - * @pre A session has to be opened in advance. - * - * @param session The session to be notified. - * - * @return MC_DRV_OK if operation has been successfully completed. - * @return MC_DRV_INVALID_PARAMETER if session parameter is invalid. - * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid. - * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid. - */ -__MC_CLIENT_LIB_API enum mc_result mc_notify( - struct mc_session_handle *session -); - -/** Wait for a notification. - * - * Wait for a notification issued by the MobiCore for a specific session. - * The timeout parameter specifies the number of milliseconds the call will wait - * for a notification. - * If the caller passes 0 as timeout value the call will immediately return. - * If timeout value is below 0 the call will block until a notification for the - session has been received. - * - * @attention if timeout is below 0, call will block: - * Caller has to trust the other side to send a notification to wake him up - * again. - * - * @param [in] session The session the notification should correspond to. - * @param [in] timeout Time in milliseconds to wait - * (MC_NO_TIMEOUT : direct return, > 0 : milliseconds, - * MC_INFINITE_TIMEOUT : wait infinitely) - * - * @return MC_DRV_OK if notification is available. - * @return MC_DRV_ERR_TIMEOUT if no notification arrived in time. - * @return MC_DRV_INFO_NOTIFICATION if a problem with the session was - * encountered. Get more details with mc_get_session_error_code(). - * @return MC_DRV_ERR_NOTIFICATION if a problem with the socket occurred. - * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid. - * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid. - * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid. - */ -__MC_CLIENT_LIB_API enum mc_result mc_wait_notification( - struct mc_session_handle *session, - int32_t timeout -); - -/** - * Allocate a block of world shared memory (WSM). - * The MC driver allocates a contiguous block of memory which can be used as - * WSM. - * This implicates that the allocated memory is aligned according to the - * alignment parameter. - * Always returns a buffer of size WSM_SIZE aligned to 4K. - * - * @param [in] device_id The ID of an opened device to retrieve the WSM from. - * @param [in] align The alignment (number of pages) of the memory block - * (e.g. 0x00000001 for 4kb). - * @param [in] len Length of the block in bytes. - * @param [out] wsm Virtual address of the world shared memory block. - * @param [in] wsm_flags Platform specific flags describing the memory to - * be allocated. - * - * @attention: align and wsm_flags are currently ignored - * - * @return MC_DRV_OK if operation has been successfully completed. - * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid. - * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid. - * @return MC_DRV_ERR_NO_FREE_MEMORY if no more contiguous memory is available - * in this size or for this process. - * - * Uses a Mutex. - */ -__MC_CLIENT_LIB_API enum mc_result mc_malloc_wsm( - uint32_t device_id, - uint32_t align, - uint32_t len, - uint8_t **wsm, - uint32_t wsm_flags -); - -/** - * Free a block of world shared memory (WSM). - * The MC driver will free a block of world shared memory (WSM) previously - * allocated with mc_malloc_wsm(). The caller has to assure that the address - * handed over to the driver is a valid WSM address. - * - * @param [in] device_id The ID to which the given address belongs. - * @param [in] wsm Address of WSM block to be freed. - * - * @return MC_DRV_OK if operation has been successfully completed. - * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid. - * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid. - * @return MC_DRV_ERR_FREE_MEMORY_FAILED on failures. - * - * Uses a Mutex. - */ -__MC_CLIENT_LIB_API enum mc_result mc_free_wsm( - uint32_t device_id, - uint8_t *wsm -); - -/** - * Map additional bulk buffer between a Trustlet Connector (TLC) and - * the Trustlet (TL) for a session. - * Memory allocated in user space of the TLC can be mapped as additional - * communication channel (besides TCI) to the Trustlet. Limitation of the - * Trustlet memory structure apply: only 6 chunks can be mapped with a maximum - * chunk size of 1 MiB each. - * - * @attention It is up to the application layer (TLC) to inform the Trustlet - * about the additional mapped bulk memory. - * - * @param [in] session Session handle with information of the device_id and - * the session_id. The - * given buffer is mapped to the session specified in the sessionHandle. - * @param [in] buf Virtual address of a memory portion (relative to TLC) - * to be shared with the Trustlet, already includes a possible offset! - * @param [in] len length of buffer block in bytes. - * @param [out] map_info Information structure about the mapped Bulk buffer - * between the TLC (Nwd) and - * the TL (Swd). - * - * @return MC_DRV_OK if operation has been successfully completed. - * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid. - * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid. - * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid. - * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur. - * @return MC_DRV_ERR_BULK_MAPPING when buf is already uses as bulk buffer or - * when registering the buffer failed. - * - * Uses a Mutex. - */ -__MC_CLIENT_LIB_API enum mc_result mc_map( - struct mc_session_handle *session, - void *buf, - uint32_t len, - struct mc_bulk_map *map_info -); - -/** - * Remove additional mapped bulk buffer between Trustlet Connector (TLC) - * and the Trustlet (TL) for a session. - * - * @attention The bulk buffer will immediately be unmapped from the session - * context. - * @attention The application layer (TLC) must inform the TL about unmapping - * of the additional bulk memory before calling mc_unmap! - * - * @param [in] session Session handle with information of the device_id and - * the session_id. The given buffer is unmapped from the session specified - * in the sessionHandle. - * @param [in] buf Virtual address of a memory portion (relative to TLC) - * shared with the TL, already includes a possible offset! - * @param [in] map_info Information structure about the mapped Bulk buffer - * between the TLC (Nwd) and - * the TL (Swd). - * @attention The clientlib currently ignores the len field in map_info. - * - * @return MC_DRV_OK if operation has been successfully completed. - * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid. - * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid. - * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid. - * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur. - * @return MC_DRV_ERR_BULK_UNMAPPING when buf was not registered earlier - * or when unregistering failed. - * - * Uses a Mutex. - */ -__MC_CLIENT_LIB_API enum mc_result mc_unmap( - struct mc_session_handle *session, - void *buf, - struct mc_bulk_map *map_info -); - - -/** - * @attention: Not implemented. - * Execute driver specific command. - * mc_driver_ctrl() can be used to execute driver specific commands. - * Besides the control command MC_CTRL_GET_VERSION commands are implementation - * specific. - * Please refer to the corresponding specification of the driver manufacturer. - * - * @param [in] param Command ID of the command to be executed. - * @param [in, out] data Command data and response depending on command. - * @param [in] len Length of the data block. - * - * @return MC_DRV_ERR_NOT_IMPLEMENTED. - */ -__MC_CLIENT_LIB_API enum mc_result mc_driver_ctrl( - enum mc_driver_ctrl param, - uint8_t *data, - uint32_t len -); - -/** - * @attention: Not implemented. - * Execute application management command. - * mc_manage() shall be used to exchange application management commands with - * the MobiCore. - * The MobiCore Application Management Protocol is described in [MCAMP]. - * - * @param [in] device_id Identifier for the MobiCore device to be used. - * NULL refers to the default device. - * @param [in, out] data Command data/response data depending on command. - * @param [in] len Length of the data block. - * - * @return MC_DRV_ERR_NOT_IMPLEMENTED. - */ -__MC_CLIENT_LIB_API enum mc_result mc_manage( - uint32_t device_id, - uint8_t *data, - uint32_t len -); - -/** - * Get additional error information of the last error that occured on a session. - * After the request the stored error code will be deleted. - * - * @param [in] session Session handle with information of the device_id and - * the session_id. - * @param [out] last_error >0 Trustlet has terminated itself with this value, - * <0 Trustlet is dead because of an error within the MobiCore - * (e.g. Kernel exception). - * See also MCI definition. - * - * @return MC_DRV_OK if operation has been successfully completed. - * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid. - * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid. - * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid. - */ -__MC_CLIENT_LIB_API enum mc_result mc_get_session_error_code( - struct mc_session_handle *session, - int32_t *last_error -); - -#endif /** MCDRIVER_H_ */ - -/** @} */ diff --git a/drivers/gud/mobicore_kernelapi/public/mobicore_driver_cmd.h b/drivers/gud/mobicore_kernelapi/public/mobicore_driver_cmd.h deleted file mode 100644 index 9ff798927dc4..000000000000 --- a/drivers/gud/mobicore_kernelapi/public/mobicore_driver_cmd.h +++ /dev/null @@ -1,289 +0,0 @@ -/** @addtogroup MCD_MCDIMPL_DAEMON - * @{ - * @file - * - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef MCDAEMON_H_ -#define MCDAEMON_H_ - - - - -#include "mcuuid.h" - -enum mc_drv_cmd_t { - MC_DRV_CMD_PING = 0, - MC_DRV_CMD_GET_INFO = 1, - MC_DRV_CMD_OPEN_DEVICE = 2, - MC_DRV_CMD_CLOSE_DEVICE = 3, - MC_DRV_CMD_NQ_CONNECT = 4, - MC_DRV_CMD_OPEN_SESSION = 5, - MC_DRV_CMD_CLOSE_SESSION = 6, - MC_DRV_CMD_NOTIFY = 7, - MC_DRV_CMD_MAP_BULK_BUF = 8, - MC_DRV_CMD_UNMAP_BULK_BUF = 9 -}; - - -enum mc_drv_rsp_t { - MC_DRV_RSP_OK = 0, - MC_DRV_RSP_FAILED = 1, - MC_DRV_RSP_DEVICE_NOT_OPENED = 2, - MC_DRV_RSP_DEVICE_ALREADY_OPENED = 3, - MC_DRV_RSP_COMMAND_NOT_ALLOWED = 4, - MC_DRV_INVALID_DEVICE_NAME = 5, - MC_DRV_RSP_MAP_BULK_ERRO = 6, - MC_DRV_RSP_TRUSTLET_NOT_FOUND = 7, - MC_DRV_RSP_PAYLOAD_LENGTH_ERROR = 8, -}; - - -struct mc_drv_command_header_t { - uint32_t command_id; -}; - -struct mc_drv_response_header_t { - uint32_t response_id; -}; - -#define MC_DEVICE_ID_DEFAULT 0 /**< The default device ID */ - - -/*****************************************************************************/ -struct mc_drv_cmd_open_device_payload_t { - uint32_t device_id; -}; - -struct mc_drv_cmd_open_device_t { - struct mc_drv_command_header_t header; - struct mc_drv_cmd_open_device_payload_t payload; -}; - - -struct mc_drv_rsp_open_device_payload_t { - /* empty */ -}; - -struct mc_drv_rsp_open_device_t { - struct mc_drv_response_header_t header; - struct mc_drv_rsp_open_device_payload_t payload; -}; - - -/*****************************************************************************/ -struct mc_drv_cmd_close_device_t { - struct mc_drv_command_header_t header; - /* no payload here because close has none. - If we use an empty struct, C++ will count it as 4 bytes. - This will write too much into the socket at write(cmd,sizeof(cmd)) */ -}; - - -struct mc_drv_rsp_close_device_payload_t { - /* empty */ -}; - -struct mc_drv_rsp_close_device_t { - struct mc_drv_response_header_t header; - struct mc_drv_rsp_close_device_payload_t payload; -}; - - -/*****************************************************************************/ -struct mc_drv_cmd_open_session_payload_t { - uint32_t device_id; - struct mc_uuid_t uuid; - uint32_t tci; - uint32_t len; -}; - -struct mc_drv_cmd_open_session_t { - struct mc_drv_command_header_t header; - struct mc_drv_cmd_open_session_payload_t payload; -}; - - -struct mc_drv_rsp_open_session_payload_t { - uint32_t device_id; - uint32_t session_id; - uint32_t device_session_id; - uint32_t mc_result; - uint32_t session_magic; -}; - -struct mc_drv_rsp_open_session_t { - struct mc_drv_response_header_t header; - struct mc_drv_rsp_open_session_payload_t payload; -}; - - -/*****************************************************************************/ -struct mc_drv_cmd_close_session_payload_t { - uint32_t session_id; -}; - -struct mc_drv_cmd_close_session_t { - struct mc_drv_command_header_t header; - struct mc_drv_cmd_close_session_payload_t payload; -}; - - -struct mc_drv_rsp_close_session_payload_t { - /* empty */ -}; - -struct mc_drv_rsp_close_session_t { - struct mc_drv_response_header_t header; - struct mc_drv_rsp_close_session_payload_t payload; -}; - - -/*****************************************************************************/ -struct mc_drv_cmd_notify_payload_t { - uint32_t session_id; -}; - -struct mc_drv_cmd_notify_t { - struct mc_drv_command_header_t header; - struct mc_drv_cmd_notify_payload_t payload; -}; - - -struct mc_drv_rsp_notify_payload_t { - /* empty */ -}; - -struct mc_drv_rsp_notify_t { - struct mc_drv_response_header_t header; - struct mc_drv_rsp_notify_payload_t payload; -}; - - -/*****************************************************************************/ -struct mc_drv_cmd_map_bulk_mem_payload_t { - uint32_t session_id; - uint32_t phys_addr_l2; - uint32_t offset_payload; - uint32_t len_bulk_mem; -}; - -struct mc_drv_cmd_map_bulk_mem_t { - struct mc_drv_command_header_t header; - struct mc_drv_cmd_map_bulk_mem_payload_t payload; -}; - - -struct mc_drv_rsp_map_bulk_mem_payload_t { - uint32_t session_id; - uint32_t secure_virtual_adr; - uint32_t mc_result; -}; - -struct mc_drv_rsp_map_bulk_mem_t { - struct mc_drv_response_header_t header; - struct mc_drv_rsp_map_bulk_mem_payload_t payload; -}; - - -/*****************************************************************************/ -struct mc_drv_cmd_unmap_bulk_mem_payload_t { - uint32_t session_id; - uint32_t secure_virtual_adr; - uint32_t len_bulk_mem; -}; - -struct mc_drv_cmd_unmap_bulk_mem_t { - struct mc_drv_command_header_t header; - struct mc_drv_cmd_unmap_bulk_mem_payload_t payload; -}; - - -struct mc_drv_rsp_unmap_bulk_mem_payload_t { - uint32_t response_id; - uint32_t session_id; - uint32_t mc_result; -}; - -struct mc_drv_rsp_unmap_bulk_mem_t { - struct mc_drv_response_header_t header; - struct mc_drv_rsp_unmap_bulk_mem_payload_t payload; -}; - - -/*****************************************************************************/ -struct mc_drv_cmd_nqconnect_payload_t { - uint32_t device_id; - uint32_t session_id; - uint32_t device_session_id; - uint32_t session_magic; /* Random data */ -}; - -struct mc_drv_cmd_nqconnect_t { - struct mc_drv_command_header_t header; - struct mc_drv_cmd_nqconnect_payload_t payload; -}; - - -struct mc_drv_rsp_nqconnect_payload_t { - /* empty; */ -}; - -struct mc_drv_rsp_nqconnect_t { - struct mc_drv_response_header_t header; - struct mc_drv_rsp_nqconnect_payload_t payload; -}; - - -/*****************************************************************************/ -union mc_drv_command_t { - struct mc_drv_command_header_t header; - struct mc_drv_cmd_open_device_t mc_drv_cmd_open_device; - struct mc_drv_cmd_close_device_t mc_drv_cmd_close_device; - struct mc_drv_cmd_open_session_t mc_drv_cmd_open_session; - struct mc_drv_cmd_close_session_t mc_drv_cmd_close_session; - struct mc_drv_cmd_nqconnect_t mc_drv_cmd_nqconnect; - struct mc_drv_cmd_notify_t mc_drv_cmd_notify; - struct mc_drv_cmd_map_bulk_mem_t mc_drv_cmd_map_bulk_mem; - struct mc_drv_cmd_unmap_bulk_mem_t mc_drv_cmd_unmap_bulk_mem; -}; - -union mc_drv_response_t { - struct mc_drv_response_header_t header; - struct mc_drv_rsp_open_device_t mc_drv_rsp_open_device; - struct mc_drv_rsp_close_device_t mc_drv_rsp_close_device; - struct mc_drv_rsp_open_session_t mc_drv_rsp_open_session; - struct mc_drv_rsp_close_session_t mc_drv_rsp_close_session; - struct mc_drv_rsp_nqconnect_t mc_drv_rsp_nqconnect; - struct mc_drv_rsp_notify_t mc_drv_rsp_notify; - struct mc_drv_rsp_map_bulk_mem_t mc_drv_rsp_map_bulk_mem; - struct mc_drv_rsp_unmap_bulk_mem_t mc_drv_rsp_unmap_bulk_mem; -}; - -#endif /* MCDAEMON_H_ */ - -/** @} */ diff --git a/drivers/gud/mobicore_kernelapi/session.c b/drivers/gud/mobicore_kernelapi/session.c deleted file mode 100644 index e62b4b3efc73..000000000000 --- a/drivers/gud/mobicore_kernelapi/session.c +++ /dev/null @@ -1,202 +0,0 @@ -/** @addtogroup MCD_IMPL_LIB - * @{ - * @file - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include "mc_kernel_api.h" -#include "public/mobicore_driver_api.h" - -#include "session.h" - -/*****************************************************************************/ -struct bulk_buffer_descriptor *bulk_buffer_descriptor_create( - void *virt_addr, - uint32_t len, - uint32_t handle, - void *phys_addr_wsm_l2 -) { - struct bulk_buffer_descriptor *desc = - kzalloc(sizeof(struct bulk_buffer_descriptor), GFP_KERNEL); - desc->virt_addr = virt_addr; - desc->len = len; - desc->handle = handle; - desc->phys_addr_wsm_l2 = phys_addr_wsm_l2; - return desc; -} - -/*****************************************************************************/ -struct session *session_create( - uint32_t session_id, - void *instance, - struct connection *connection -) { - struct session *session = - kzalloc(sizeof(struct session), GFP_KERNEL); - session->session_id = session_id; - session->instance = instance; - session->notification_connection = connection; - - session->session_info.last_error = SESSION_ERR_NO; - session->session_info.state = SESSION_STATE_INITIAL; - - INIT_LIST_HEAD(&(session->bulk_buffer_descriptors)); - return session; -} - - -/*****************************************************************************/ -void session_cleanup( - struct session *session -) { - struct bulk_buffer_descriptor *bulk_buf_descr; - struct list_head *pos, *q; - - /* Unmap still mapped buffers */ - list_for_each_safe(pos, q, &session->bulk_buffer_descriptors) { - bulk_buf_descr = - list_entry(pos, struct bulk_buffer_descriptor, list); - - MCDRV_DBG_VERBOSE("Physical Address of L2 Table = 0x%X, " - "handle= %d", - (unsigned int)bulk_buf_descr->phys_addr_wsm_l2, - bulk_buf_descr->handle); - - /* ignore any error, as we cannot do anything in this case. */ - int ret = mobicore_unmap_vmem(session->instance, - bulk_buf_descr->handle); - if (ret != 0) - MCDRV_DBG_ERROR("mobicore_unmap_vmem failed: %d", ret); - - list_del(pos); - kfree(bulk_buf_descr); - } - - /* Finally delete notification connection */ - connection_cleanup(session->notification_connection); - kfree(session); -} - - -/*****************************************************************************/ -void session_set_error_info( - struct session *session, - int32_t err -) { - session->session_info.last_error = err; -} - - -/*****************************************************************************/ -int32_t session_get_last_err( - struct session *session -) { - return session->session_info.last_error; -} - - -/*****************************************************************************/ -struct bulk_buffer_descriptor *session_add_bulk_buf( - struct session *session, - void *buf, - uint32_t len -) { - struct bulk_buffer_descriptor *bulk_buf_descr = NULL; - struct bulk_buffer_descriptor *tmp; - struct list_head *pos; - - /* Search bulk buffer descriptors for existing vAddr - At the moment a virtual address can only be added one time */ - list_for_each(pos, &session->bulk_buffer_descriptors) { - tmp = list_entry(pos, struct bulk_buffer_descriptor, list); - if (tmp->virt_addr == buf) - return NULL; - } - - do { - /* Prepare the interface structure for memory registration in - Kernel Module */ - void *l2_table_phys; - uint32_t handle; - - int ret = mobicore_map_vmem(session->instance, - buf, - len, - &handle, - &l2_table_phys); - - if (ret != 0) { - MCDRV_DBG_ERROR("mobicore_map_vmem failed, ret=%d", - ret); - break; - } - - MCDRV_DBG_VERBOSE("Physical Address of L2 Table = 0x%X, " - "handle=%d", - (unsigned int)l2_table_phys, - handle); - - /* Create new descriptor */ - bulk_buf_descr = bulk_buffer_descriptor_create( - buf, - len, - handle, - l2_table_phys); - - /* Add to vector of descriptors */ - list_add_tail(&(bulk_buf_descr->list), - &(session->bulk_buffer_descriptors)); - } while (0); - - return bulk_buf_descr; -} - - -/*****************************************************************************/ -bool session_remove_bulk_buf( - struct session *session, - void *virt_addr -) { - bool ret = true; - struct bulk_buffer_descriptor *bulk_buf_descr = NULL; - struct bulk_buffer_descriptor *tmp; - struct list_head *pos, *q; - - MCDRV_DBG_VERBOSE("Virtual Address = 0x%X", (unsigned int) virt_addr); - - /* Search and remove bulk buffer descriptor */ - list_for_each_safe(pos, q, &session->bulk_buffer_descriptors) { - tmp = list_entry(pos, struct bulk_buffer_descriptor, list); - if (tmp->virt_addr == virt_addr) { - bulk_buf_descr = tmp; - list_del(pos); - break; - } - } - - if (bulk_buf_descr == NULL) { - MCDRV_DBG_ERROR("Virtual Address not found"); - ret = false; - } else { - MCDRV_DBG_VERBOSE("WsmL2 phys=0x%X, handle=%d", - (unsigned int)bulk_buf_descr->phys_addr_wsm_l2, - bulk_buf_descr->handle); - - /* ignore any error, as we cannot do anything */ - int ret = mobicore_unmap_vmem(session->instance, - bulk_buf_descr->handle); - if (ret != 0) - MCDRV_DBG_ERROR("mobicore_unmap_vmem failed: %d", ret); - - kfree(bulk_buf_descr); - } - - return ret; -} - -/** @} */ diff --git a/drivers/gud/mobicore_kernelapi/session.h b/drivers/gud/mobicore_kernelapi/session.h deleted file mode 100644 index 9a5374027335..000000000000 --- a/drivers/gud/mobicore_kernelapi/session.h +++ /dev/null @@ -1,136 +0,0 @@ -/** @addtogroup MCD_IMPL_LIB - * @{ - * @file - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef SESSION_H_ -#define SESSION_H_ - -#include "common.h" - -#include -#include "connection.h" - - -struct bulk_buffer_descriptor { - void *virt_addr;/**< The virtual address of the Bulk buffer*/ - uint32_t len; /**< Length of the Bulk buffer*/ - uint32_t handle; - void *phys_addr_wsm_l2; /**< The physical address of the - L2 table of the Bulk buffer*/ - struct list_head list; /**< The list param for using the kernel lists*/ -}; - -struct bulk_buffer_descriptor *bulk_buffer_descriptor_create( - void *virt_addr, - uint32_t len, - uint32_t handle, - void *phys_addr_wsm_l2 -); - -/** Session states. - * At the moment not used !!. - */ -enum session_state { - SESSION_STATE_INITIAL, - SESSION_STATE_OPEN, - SESSION_STATE_TRUSTLET_DEAD -}; - -#define SESSION_ERR_NO 0 /**< No session error */ - -/** Session information structure. - * The information structure is used to hold the state of the session, which - * will limit further actions for the session. - * Also the last error code will be stored till it's read. - */ -struct session_information { - enum session_state state; /**< Session state */ - int32_t last_error; /**< Last error of session */ -}; - - -struct session { - struct mc_instance *instance; - /**< Descriptors of additional bulk buffer of a session */ - struct list_head bulk_buffer_descriptors; - /**< Informations about session */ - struct session_information session_info; - - uint32_t session_id; - struct connection *notification_connection; - - /**< The list param for using the kernel lists*/ - struct list_head list; -}; - -struct session *session_create( - uint32_t session_id, - void *instance, - struct connection *connection -); - -void session_cleanup( - struct session *session -); - -/** - * Add address information of additional bulk buffer memory to session and - * register virtual memory in kernel module. - * - * @attention The virtual address can only be added one time. If the virtual - * address already exist, NULL is returned. - * - * @param buf The virtual address of bulk buffer. - * @param len Length of bulk buffer. - * - * @return On success the actual Bulk buffer descriptor with all address - * information is retured, NULL if an error occurs. - */ -struct bulk_buffer_descriptor *session_add_bulk_buf( - struct session *session, - void *buf, - uint32_t len -); - -/** - * Remove address information of additional bulk buffer memory from session and - * unregister virtual memory in kernel module - * - * @param buf The virtual address of the bulk buffer. - * - * @return true on success. - */ -bool session_remove_bulk_buf( - struct session *session, - void *buf -); - -/** - * Set additional error information of the last error that occured. - * - * @param errorCode The actual error. - */ -void session_set_error_info( - struct session *session, - int32_t err -); - -/** - * Get additional error information of the last error that occured. - * - * @attention After request the information is set to SESSION_ERR_NO. - * - * @return Last stored error code or SESSION_ERR_NO. - */ -int32_t session_get_last_err( - struct session *session -); - -#endif /* SESSION_H_ */ - -/** @} */ diff --git a/drivers/gud/mobicore_kernelapi/wsm.h b/drivers/gud/mobicore_kernelapi/wsm.h deleted file mode 100644 index 6877c53768b2..000000000000 --- a/drivers/gud/mobicore_kernelapi/wsm.h +++ /dev/null @@ -1,35 +0,0 @@ -/** @addtogroup MCD_MCDIMPL_DAEMON_SRV - * @{ - * @file - * - * World shared memory definitions. - * - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef WSM_H_ -#define WSM_H_ - -#include "common.h" -#include - -struct wsm { - void *virt_addr; - uint32_t len; - uint32_t handle; - void *phys_addr; - struct list_head list; -}; - -struct wsm *wsm_create( - void *virt_addr, - uint32_t len, - uint32_t handle, - void *phys_addr /*= NULL this may be unknown, so is can be omitted.*/ -); -#endif /* WSM_H_ */ - -/** @} */