Loading drivers/gud/MobiCoreDriver/Makefile +16 −8 Original line number Diff line number Diff line Loading @@ -2,24 +2,32 @@ # Makefile for the <t-base core driver # GUD_ROOT_FOLDER := drivers/gud GUD_ROOT_FOLDER := drivers/gud/ # add our modules to kernel. obj-$(CONFIG_MOBICORE_DRIVER) += mcDrvModule.o mcDrvModule-y := admin.o api.o client.o clientlib.o fastcall.o logging.o \ main.o mcp.o mmu.o nqueue.o pm.o scheduler.o session.o mcDrvModule-y := \ admin.o \ api.o \ client.o \ clientlib.o \ clock.o \ fastcall.o \ logging.o \ main.o \ mcp.o \ mmu.o \ pm.o \ scheduler.o \ session.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 $(srctree)/$(GUD_ROOT_FOLDER)/MobiCoreDriver/platforms | tail -1)) # Use the available platform folder ccflags-y += -I$(GUD_ROOT_FOLDER)/MobiCoreDriver/platforms/$(MOBICORE_PLATFORM) # MobiCore Driver includes ccflags-y += -I$(GUD_ROOT_FOLDER)/MobiCoreDriver drivers/gud/MobiCoreDriver/admin.c +94 −40 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include <asm/atomic.h> #include <linux/slab.h> #include <linux/device.h> Loading @@ -24,6 +25,7 @@ #include <linux/vmalloc.h> #include <linux/module.h> #include <linux/random.h> #include <linux/delay.h> #include "public/mc_linux.h" #include "public/mc_admin.h" Loading @@ -33,12 +35,13 @@ #include "main.h" #include "debug.h" #include "mmu.h" /* For load_check and load_token */ #include "scheduler.h" /* For mc_dev_get_version */ #include "logging.h" #include "mcp.h" #include "client.h" #include "api.h" #include "admin.h" #define DRIVER_TCI_LEN PAGE_SIZE /* We need 2 devices for admin and user interface*/ #define MC_DEV_MAX 2 static struct admin_ctx { struct device *dev; Loading @@ -47,6 +50,7 @@ static struct admin_ctx { struct device_driver mc_dev_name; dev_t mc_dev_admin; struct cdev mc_admin_cdev; int (*tee_start_cb)(void); } g_admin_ctx; static struct mc_admin_driver_request { Loading Loading @@ -146,10 +150,18 @@ static int request_send(uint32_t command, const struct mc_uuid_t *uuid, uint32_t is_gp, uint32_t spid) { struct device *dev = g_admin_ctx.dev; int counter = 10; int ret; /* Prepare request */ mutex_lock(&g_request.states_mutex); /* Wait a little for daemon to connect */ while ((g_request.server_state == NOT_CONNECTED) && counter--) { mutex_unlock(&g_request.states_mutex); ssleep(1); mutex_lock(&g_request.states_mutex); } BUG_ON(g_request.client_state != IDLE); if (g_request.server_state != READY) { mutex_unlock(&g_request.states_mutex); Loading Loading @@ -194,14 +206,8 @@ static int request_send(uint32_t command, const struct mc_uuid_t *uuid, ret = -EPIPE; break; case READY: /* Length was 0, expect error */ if (!g_request.response.error_no) { dev_err(dev, "%s: length is 0 but no error reported\n", __func__); ret = -EPIPE; } else { /* No data to come, likely an error */ ret = -g_request.response.error_no; } break; case RESPONSE_SENT: case DATA_SENT: Loading Loading @@ -376,7 +382,7 @@ end: static struct tbase_object *admin_get_trustlet(const struct mc_uuid_t *uuid, uint32_t is_gp, uint32_t *spid) { struct tbase_object *obj; struct tbase_object *obj = NULL; bool is_sp_tl; int ret = 0; Loading Loading @@ -409,6 +415,25 @@ end: return obj; } static void mc_admin_sendcrashdump(void) { int ret = 0; /* Lock communication channel */ mutex_lock(&g_request.mutex); /* Send request and wait for header */ ret = request_send(MC_DRV_SIGNAL_CRASH, NULL, false, 0); if (ret) goto end; /* Done */ request_cancel(); end: mutex_unlock(&g_request.mutex); } static int tbase_object_make(uint32_t spid, struct tbase_object *obj) { struct mc_blob_len_info *l_info = (struct mc_blob_len_info *)obj->data; Loading Loading @@ -550,7 +575,12 @@ static inline int load_driver(struct tbase_client *client, struct mc_admin_load_info *info) { struct tbase_object *obj; void *dci; struct mclf_header_v2 *thdr; struct mc_identity identity = { .login_type = TEEC_LOGIN_PUBLIC, }; uintptr_t dci = 0; uint32_t dci_len = 0; uint32_t sid; int ret; Loading @@ -558,13 +588,21 @@ static inline int load_driver(struct tbase_client *client, if (IS_ERR(obj)) return PTR_ERR(obj); /* Create a driver */ ret = api_malloc_cbuf(client, DRIVER_TCI_LEN, &dci, NULL); thdr = (struct mclf_header_v2 *)&obj->data[obj->header_length]; if (!(thdr->flags & MC_SERVICE_HEADER_FLAGS_NO_CONTROL_INTERFACE)) { /* * The driver requires a DCI, although we won't be able to use * it to communicate. */ dci_len = PAGE_SIZE; ret = api_malloc_cbuf(client, dci_len, &dci, NULL); if (ret) goto end; } /* Open session */ ret = client_add_session(client, obj, dci, DRIVER_TCI_LEN, &sid, false); ret = client_add_session(client, obj, dci, dci_len, &sid, false, &identity); if (ret) api_free_cbuf(client, dci); else Loading @@ -578,6 +616,7 @@ end: static inline int load_token(struct mc_admin_load_info *token) { struct tbase_mmu *mmu; struct mcp_buffer_map map; int ret; mmu = tbase_mmu_create(current, (void *)(uintptr_t)token->address, Loading @@ -585,7 +624,8 @@ static inline int load_token(struct mc_admin_load_info *token) if (IS_ERR(mmu)) return PTR_ERR(mmu); ret = mcp_load_token(token->address, token->length, mmu); tbase_mmu_buffer(mmu, &map); ret = mcp_load_token(token->address, &map); tbase_mmu_delete(mmu); return ret; } Loading @@ -594,6 +634,7 @@ static inline int load_check(struct mc_admin_load_info *info) { struct tbase_object *obj; struct tbase_mmu *mmu; struct mcp_buffer_map map; int ret; obj = tbase_object_read(info->spid, info->address, info->length); Loading @@ -604,7 +645,8 @@ static inline int load_check(struct mc_admin_load_info *info) if (IS_ERR(mmu)) return PTR_ERR(mmu); ret = mcp_load_check(obj, mmu); tbase_mmu_buffer(mmu, &map); ret = mcp_load_check(obj, &map); tbase_mmu_delete(mmu); return ret; } Loading Loading @@ -709,10 +751,8 @@ static long admin_ioctl(struct file *file, unsigned int cmd, MCDRV_DBG("%u from %s", _IOC_NR(cmd), current->comm); if (WARN(!client, "No client data available")) { ret = -EFAULT; goto out; } if (WARN(!client, "No client data available")) return -EFAULT; switch (cmd) { case MC_ADMIN_IO_GET_DRIVER_REQUEST: { Loading Loading @@ -747,7 +787,8 @@ static long admin_ioctl(struct file *file, unsigned int cmd, case MC_ADMIN_IO_GET_INFO: { struct mc_admin_driver_info info; info.drv_version = mc_dev_get_version(); info.drv_version = MC_VERSION(MCDRVMODULEAPI_VERSION_MAJOR, MCDRVMODULEAPI_VERSION_MINOR); info.initial_cmd_id = g_request.request_id; ret = copy_to_user(uarg, &info, sizeof(info)); break; Loading @@ -755,19 +796,12 @@ static long admin_ioctl(struct file *file, unsigned int cmd, case MC_ADMIN_IO_LOAD_DRIVER: { struct mc_admin_load_info info; /* Acquire client */ if (!mc_ref_client(client)) { ret = -ENODEV; break; } ret = copy_from_user(&info, uarg, sizeof(info)); if (ret) ret = -EFAULT; else ret = load_driver(client, &info); mc_unref_client(client); break; } case MC_ADMIN_IO_LOAD_TOKEN: { Loading Loading @@ -796,8 +830,6 @@ static long admin_ioctl(struct file *file, unsigned int cmd, ret = -ENOIOCTLCMD; } out: mobicore_log_read(); return ret; } Loading Loading @@ -844,6 +876,7 @@ static int admin_open(struct inode *inode, struct file *file) { struct device *dev = g_admin_ctx.dev; struct tbase_client *client; int err; /* * If the daemon is already set we can't allow anybody else to open Loading @@ -860,11 +893,23 @@ static int admin_open(struct inode *inode, struct file *file) /* Setup the usual variables */ MCDRV_DBG("accept %s as tbase daemon", current->comm); /* * daemon is connected so now we can safely suppose * the secure world is loaded too */ if (!IS_ERR_OR_NULL(g_admin_ctx.tee_start_cb)) g_admin_ctx.tee_start_cb = ERR_PTR(g_admin_ctx.tee_start_cb()); if (IS_ERR(g_admin_ctx.tee_start_cb)) { MCDRV_ERROR("Failed initializing the SW"); err = PTR_ERR(g_admin_ctx.tee_start_cb); goto fail_connection; } /* Create client */ client = api_open_device(true); if (!client) { atomic_set(&g_admin_ctx.daemon_counter, 0); return -ENOMEM; err = -ENOMEM; goto fail_connection; } /* Store client in user file */ Loading @@ -875,6 +920,10 @@ static int admin_open(struct inode *inode, struct file *file) dev_info(dev, "%s: daemon connected\n", __func__); return 0; fail_connection: atomic_set(&g_admin_ctx.daemon_counter, 0); return err; } /* function table structure of this device driver. */ Loading @@ -889,7 +938,8 @@ static const struct file_operations mc_admin_fops = { .write = admin_write, }; int admin_dev_init(struct class *mc_device_class, dev_t *out_dev) int mc_admin_init(struct class *mc_device_class, dev_t *out_dev, int (*tee_start_cb)(void)) { int err = 0; Loading @@ -903,11 +953,12 @@ int admin_dev_init(struct class *mc_device_class, dev_t *out_dev) mutex_init(&g_request.states_mutex); init_completion(&g_request.client_complete); init_completion(&g_request.server_complete); mcp_register_crashhandler(mc_admin_sendcrashdump); /* Create char device */ cdev_init(&g_admin_ctx.mc_admin_cdev, &mc_admin_fops); err = alloc_chrdev_region(&g_admin_ctx.mc_dev_admin, 0, MC_DEV_MAX, "mobicore"); "trustonic_tee"); if (err < 0) { MCDRV_ERROR("failed to allocate char dev region"); goto fail_alloc_chrdev_region; Loading @@ -932,6 +983,9 @@ int admin_dev_init(struct class *mc_device_class, dev_t *out_dev) g_admin_ctx.dev->driver = &g_admin_ctx.mc_dev_name; *out_dev = g_admin_ctx.mc_dev_admin; /* Register the call back for starting the secure world */ g_admin_ctx.tee_start_cb = tee_start_cb; MCDRV_DBG("done"); return 0; Loading @@ -946,7 +1000,7 @@ fail_alloc_chrdev_region: return err; } void admin_dev_cleanup(struct class *mc_device_class) void mc_admin_exit(struct class *mc_device_class) { device_destroy(mc_device_class, g_admin_ctx.mc_dev_admin); cdev_del(&g_admin_ctx.mc_admin_cdev); Loading drivers/gud/MobiCoreDriver/admin.h +6 −10 Original line number Diff line number Diff line /* * Copyright (c) 2013-2014 TRUSTONIC LIMITED * Copyright (c) 2013-2015 TRUSTONIC LIMITED * All Rights Reserved. * * This program is free software; you can redistribute it and/or Loading @@ -15,16 +15,12 @@ #ifndef ADMIN_FD_H_ #define ADMIN_FD_H_ #include <public/mc_linux.h> struct mc_uuid_t; struct tbase_object; struct tbase_object { uint32_t length; /* Total length */ uint32_t header_length; /* Length of header before payload */ uint8_t data[]; /* Header followed by payload */ }; int admin_dev_init(struct class *mc_device_class, dev_t *out_dev); void admin_dev_cleanup(struct class *mc_device_class); int mc_admin_init(struct class *mc_device_class, dev_t *out_dev, int (*tee_start_cb)(void)); void mc_admin_exit(struct class *mc_device_class); struct tbase_object *tbase_object_select(const struct mc_uuid_t *uuid); struct tbase_object *tbase_object_get(const struct mc_uuid_t *uuid, Loading drivers/gud/MobiCoreDriver/api.c +110 −156 Original line number Diff line number Diff line Loading @@ -15,12 +15,23 @@ #include <linux/device.h> #include <linux/slab.h> #include <linux/err.h> #include <linux/cred.h> #include <linux/sched.h> #include <public/mc_linux.h> /* MC_MAP_MAX */ #include "main.h" #include "debug.h" #include "mcp.h" #include "admin.h" #include "session.h" #include "client.h" #include "api.h" static struct api_ctx { struct mutex clients_lock; /* Clients list + temp notifs */ struct list_head clients; /* List of user-space clients */ } api_ctx; /* * Initialize a new tbase client object * @return client pointer or NULL if no allocation was possible. Loading @@ -37,9 +48,11 @@ struct tbase_client *api_open_device(bool is_from_kernel) } /* Add client to list of clients */ mc_add_client(client); mutex_lock(&api_ctx.clients_lock); list_add_tail(&client->list, &api_ctx.clients); mutex_unlock(&api_ctx.clients_lock); MCDRV_DBG("Created client 0x%p", client); MCDRV_DBG("created client %p", client); return client; } Loading @@ -51,17 +64,10 @@ int api_freeze_device(struct tbase_client *client) { int err = 0; if (!mc_ref_client(client)) { err = -ENODEV; goto end; } if (!client_set_closing(client)) err = -ENOTEMPTY; mc_unref_client(client); end: MCDRV_DBG("client 0x%p, exit with %d\n", client, err); MCDRV_DBG("client %p, exit with %d\n", client, err); return err; } Loading @@ -70,18 +76,16 @@ end: * @param client_t client * @return tbase driver error code */ int api_close_device(struct tbase_client *client) void api_close_device(struct tbase_client *client) { /* Remove client from list of active clients */ int err = mc_remove_client(client); if (!err) { mutex_lock(&api_ctx.clients_lock); list_del(&client->list); mutex_unlock(&api_ctx.clients_lock); /* Close all remaining sessions */ client_close_sessions(client); mc_unref_client(client); } MCDRV_DBG("client 0x%p, exit with %d\n\n", client, err); return err; client_put(client); MCDRV_DBG("client %p closed\n", client); } /* Loading @@ -94,7 +98,8 @@ int api_open_session(struct tbase_client *client, const struct mc_uuid_t *uuid, uintptr_t tci, size_t tci_len, bool is_gp_uuid) bool is_gp_uuid, struct mc_identity *identity) { int err = 0; uint32_t sid = 0; Loading @@ -107,10 +112,6 @@ int api_open_session(struct tbase_client *client, if (!uuid) return -EINVAL; /* Acquire client */ if (!mc_ref_client(client)) return -ENODEV; /* Get secure object */ obj = tbase_object_get(uuid, is_gp_uuid); if (IS_ERR(obj)) { Loading @@ -125,8 +126,8 @@ int api_open_session(struct tbase_client *client, } /* Open session */ err = client_add_session(client, obj, (void *)tci, tci_len, &sid, is_gp_uuid); err = client_add_session(client, obj, tci, tci_len, &sid, is_gp_uuid, identity); /* Fill in return parameter */ if (!err) *p_session_id = sid; Loading @@ -135,8 +136,6 @@ int api_open_session(struct tbase_client *client, tbase_object_free(obj); end: /* Release client */ mc_unref_client(client); MCDRV_DBG("session %x, exit with %d\n", sid, err); return err; Loading @@ -155,18 +154,17 @@ int api_open_trustlet(struct tbase_client *client, uintptr_t tci, size_t tci_len) { int err = 0; uint32_t sid = 0; struct tbase_object *obj; struct mc_identity identity = { .login_type = TEEC_LOGIN_PUBLIC, }; uint32_t sid = 0; int err = 0; /* Check parameters */ if (!p_session_id) return -EINVAL; /* Acquire client */ if (!mc_ref_client(client)) return -ENODEV; /* Create secure object from user-space trustlet binary */ obj = tbase_object_read(spid, trustlet, trustlet_len); if (IS_ERR(obj)) { Loading @@ -175,8 +173,8 @@ int api_open_trustlet(struct tbase_client *client, } /* Open session */ err = client_add_session(client, obj, (void *)tci, tci_len, &sid, false); err = client_add_session(client, obj, tci, tci_len, &sid, false, &identity); /* Fill in return parameter */ if (!err) *p_session_id = sid; Loading @@ -185,9 +183,6 @@ int api_open_trustlet(struct tbase_client *client, tbase_object_free(obj); end: /* Release client */ mc_unref_client(client); MCDRV_DBG("session %x, exit with %d\n", sid, err); return err; } Loading @@ -199,23 +194,10 @@ end: */ int api_close_session(struct tbase_client *client, uint32_t session_id) { int err = 0; /* Acquire client */ if (!mc_ref_client(client)) { err = -ENODEV; goto end; } /* Close session */ err = client_remove_session(client, session_id); int ret = client_remove_session(client, session_id); /* Release client */ mc_unref_client(client); end: MCDRV_DBG("session %x, exit with %d\n", session_id, err); return err; MCDRV_DBG("session %x, exit with %d\n", session_id, ret); return ret; } /* Loading @@ -227,10 +209,6 @@ int api_notify(struct tbase_client *client, uint32_t session_id) int err = 0; struct tbase_session *session = NULL; /* Acquire client */ if (!mc_ref_client(client)) return -ENODEV; /* Acquire session */ session = client_ref_session(client, session_id); Loading @@ -244,9 +222,6 @@ int api_notify(struct tbase_client *client, uint32_t session_id) client_unref_session(session); } /* Release client */ mc_unref_client(client); MCDRV_DBG("session %x, exit with %d\n", session_id, err); return err; } Loading @@ -262,10 +237,6 @@ int api_wait_notification(struct tbase_client *client, int err = 0; struct tbase_session *session = NULL; /* Acquire client */ if (!mc_ref_client(client)) return -ENODEV; /* Acquire session */ session = client_ref_session(client, session_id); Loading @@ -273,15 +244,12 @@ int api_wait_notification(struct tbase_client *client, if (!session) { err = -ENXIO; } else { err = session_wait(session, timeout); err = session_waitnotif(session, timeout); /* Release session */ client_unref_session(session); } /* Release client */ mc_unref_client(client); MCDRV_DBG("session %x, exit with %d\n", session_id, err); return err; } Loading @@ -295,19 +263,9 @@ int api_wait_notification(struct tbase_client *client, * @return tbase driver error code */ int api_malloc_cbuf(struct tbase_client *client, uint32_t len, void **p_addr, struct vm_area_struct *vmarea) uintptr_t *addr, struct vm_area_struct *vmarea) { int err = 0; /* Acquire client */ if (!mc_ref_client(client)) return -ENODEV; /* Allocate buffer */ err = tbase_cbuf_alloc(client, len, p_addr, vmarea); /* Release client */ mc_unref_client(client); int err = tbase_cbuf_alloc(client, len, addr, vmarea); MCDRV_DBG("exit with %d\n", err); return err; Loading @@ -320,49 +278,33 @@ int api_malloc_cbuf(struct tbase_client *client, uint32_t len, * * @return tbase driver error code */ int api_free_cbuf(struct tbase_client *client, void *addr) int api_free_cbuf(struct tbase_client *client, uintptr_t addr) { int err = 0; /* Acquire client */ if (!mc_ref_client(client)) return -ENODEV; /* Free buffer */ err = tbase_cbuf_free(client, addr); /* Release client */ mc_unref_client(client); int err = tbase_cbuf_free(client, addr); MCDRV_DBG("@ 0x%p, exit with %d\n", addr, err); MCDRV_DBG("@ 0x%lx, exit with %d\n", addr, err); return err; } /* * Share a buffer with given TA in SWd * @return tbase driver error code */ int api_map_wsm(struct tbase_client *client, uint32_t session_id, void *buf, uint32_t len, uint32_t *p_sva, uint32_t *p_slen) /* Share a buffer with given TA in SWd */ int api_map_wsms(struct tbase_client *client, uint32_t session_id, struct mc_ioctl_buffer *bufs) { int err = 0; struct tbase_session *session = NULL; uint32_t sva; int err = 0; /* Check parameters */ if (!buf || !len || !p_sva || !p_slen) if (!client) return -EINVAL; /* Acquire client */ if (!mc_ref_client(client)) return -ENODEV; if (!bufs) return -EINVAL; /* Acquire session */ session = client_ref_session(client, session_id); if (session) { /* Add buffer to the session */ err = session_add_wsm(session, buf, len, &sva); err = session_wsms_add(session, bufs); /* Release session */ client_unref_session(session); Loading @@ -370,43 +312,22 @@ int api_map_wsm(struct tbase_client *client, uint32_t session_id, void *buf, err = -ENXIO; } if (err) { *p_sva = 0; *p_slen = 0; MCDRV_ERROR("code %d", err); } else { *p_sva = sva; *p_slen = len; } /* Release client */ mc_unref_client(client); MCDRV_DBG("0x%p, exit with %d\n", buf, err); MCDRV_DBG("exit with %d\n", err); return err; } /* * Stop sharing a buffer with SWd * @param client * @param session_id * @param buf * @param map_info * @return tbase driver error code */ int api_unmap_wsm(struct tbase_client *client, uint32_t session_id, void *buf, uint32_t sva, uint32_t slen) /* Stop sharing a buffer with SWd */ int api_unmap_wsms(struct tbase_client *client, uint32_t session_id, const struct mc_ioctl_buffer *bufs) { int err = 0; struct tbase_session *session = NULL; int err = 0; /* Check parameters */ if (!client) return -EINVAL; /* Acquire client */ if (!mc_ref_client(client)) return -ENODEV; if (!bufs) return -EINVAL; /* Acquire session */ session = client_ref_session(client, session_id); Loading @@ -415,33 +336,24 @@ int api_unmap_wsm(struct tbase_client *client, uint32_t session_id, err = -ENXIO; } else { /* Remove buffer from session */ err = session_remove_wsm(session, buf, sva, slen); err = session_wsms_remove(session, bufs); /* Release session */ client_unref_session(session); } /* Release client */ mc_unref_client(client); MCDRV_DBG("0x%p, exit with %d\n", buf, err); MCDRV_DBG("exit with %d\n", err); return err; } /* * Read last error from received notifications * @return tbase driver error code * Read session exit/termination code */ int api_get_session_error(struct tbase_client *client, uint32_t session_id, int32_t *last_error) int api_get_session_exitcode(struct tbase_client *client, uint32_t session_id, int32_t *exit_code) { int err = 0; struct tbase_session *session; /* Acquire client */ if (!mc_ref_client(client)) return -ENODEV; /* Acquire session */ session = client_ref_session(client, session_id); Loading @@ -449,7 +361,7 @@ int api_get_session_error(struct tbase_client *client, uint32_t session_id, err = -ENXIO; } else { /* Retrieve error */ *last_error = session_get_err(session); *exit_code = session_exitcode(session); /* Release session */ client_unref_session(session); Loading @@ -457,9 +369,51 @@ int api_get_session_error(struct tbase_client *client, uint32_t session_id, err = 0; } /* Release client */ mc_unref_client(client); MCDRV_DBG("session %x, exit with %d\n", session_id, err); return err; } void api_init(void) { INIT_LIST_HEAD(&api_ctx.clients); mutex_init(&api_ctx.clients_lock); INIT_LIST_HEAD(&g_ctx.closing_sess); mutex_init(&g_ctx.closing_lock); } int api_info(struct kasnprintf_buf *buf) { struct tbase_client *client; struct tbase_session *session; ssize_t ret = 0; mutex_lock(&api_ctx.clients_lock); if (list_empty(&api_ctx.clients)) goto done; list_for_each_entry(client, &api_ctx.clients, list) { ret = client_info(client, buf); if (ret < 0) break; } done: mutex_unlock(&api_ctx.clients_lock); if (ret >= 0) { mutex_lock(&g_ctx.closing_lock); if (!list_empty(&g_ctx.closing_sess)) ret = kasnprintf(buf, "closing sessions:\n"); list_for_each_entry(session, &g_ctx.closing_sess, list) { ret = session_info(session, buf); if (ret < 0) break; } mutex_unlock(&g_ctx.closing_lock); } return ret; } drivers/gud/MobiCoreDriver/api.h +19 −38 Original line number Diff line number Diff line Loading @@ -15,51 +15,32 @@ #ifndef _API_H_ #define _API_H_ #include "public/mc_linux.h" #include "client.h" #include "session.h" struct tbase_client; struct tbase_client *api_open_device(bool is_from_kernel); int api_freeze_device(struct tbase_client *client); int api_close_device(struct tbase_client *client); int api_open_session(struct tbase_client *client, uint32_t *session_id, void api_close_device(struct tbase_client *client); int api_open_session(struct tbase_client *client, uint32_t *session_id, const struct mc_uuid_t *uuid, uintptr_t tci, size_t tci_len, bool is_gp_uuid); int api_open_trustlet(struct tbase_client *client, uint32_t *p_sid, uint32_t spid, uintptr_t trustlet, size_t trustlet_len, uintptr_t tci, size_t tci_len); uintptr_t tci, size_t tci_len, bool is_gp_uuid, struct mc_identity *identity); int api_open_trustlet(struct tbase_client *client, uint32_t *session_id, uint32_t spid, uintptr_t trustlet, size_t trustlet_len, uintptr_t tci, size_t tci_len); int api_close_session(struct tbase_client *client, uint32_t session_id); int api_notify(struct tbase_client *client, uint32_t session_id); int api_wait_notification(struct tbase_client *client, uint32_t session_id, int32_t timeout); int api_malloc_cbuf(struct tbase_client *client, uint32_t len, void **p_addr, int api_malloc_cbuf(struct tbase_client *client, uint32_t len, uintptr_t *addr, struct vm_area_struct *vmarea); int api_free_cbuf(struct tbase_client *client, void *addr); int api_map_wsm(struct tbase_client *client, uint32_t session_id, void *buf, uint32_t len, uint32_t *p_sva, uint32_t *p_slen); int api_unmap_wsm(struct tbase_client *client, uint32_t session_id, void *buf, uint32_t sva, uint32_t slen); int api_get_session_error(struct tbase_client *client, uint32_t session_id, int32_t *last_error); int api_free_cbuf(struct tbase_client *client, uintptr_t addr); int api_map_wsms(struct tbase_client *client, uint32_t session_id, struct mc_ioctl_buffer *bufs); int api_unmap_wsms(struct tbase_client *client, uint32_t session_id, const struct mc_ioctl_buffer *bufs); int api_get_session_exitcode(struct tbase_client *client, uint32_t session_id, int32_t *exit_code); void api_init(void); int api_info(struct kasnprintf_buf *buf); #endif /* _API_H_ */ Loading
drivers/gud/MobiCoreDriver/Makefile +16 −8 Original line number Diff line number Diff line Loading @@ -2,24 +2,32 @@ # Makefile for the <t-base core driver # GUD_ROOT_FOLDER := drivers/gud GUD_ROOT_FOLDER := drivers/gud/ # add our modules to kernel. obj-$(CONFIG_MOBICORE_DRIVER) += mcDrvModule.o mcDrvModule-y := admin.o api.o client.o clientlib.o fastcall.o logging.o \ main.o mcp.o mmu.o nqueue.o pm.o scheduler.o session.o mcDrvModule-y := \ admin.o \ api.o \ client.o \ clientlib.o \ clock.o \ fastcall.o \ logging.o \ main.o \ mcp.o \ mmu.o \ pm.o \ scheduler.o \ session.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 $(srctree)/$(GUD_ROOT_FOLDER)/MobiCoreDriver/platforms | tail -1)) # Use the available platform folder ccflags-y += -I$(GUD_ROOT_FOLDER)/MobiCoreDriver/platforms/$(MOBICORE_PLATFORM) # MobiCore Driver includes ccflags-y += -I$(GUD_ROOT_FOLDER)/MobiCoreDriver
drivers/gud/MobiCoreDriver/admin.c +94 −40 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include <asm/atomic.h> #include <linux/slab.h> #include <linux/device.h> Loading @@ -24,6 +25,7 @@ #include <linux/vmalloc.h> #include <linux/module.h> #include <linux/random.h> #include <linux/delay.h> #include "public/mc_linux.h" #include "public/mc_admin.h" Loading @@ -33,12 +35,13 @@ #include "main.h" #include "debug.h" #include "mmu.h" /* For load_check and load_token */ #include "scheduler.h" /* For mc_dev_get_version */ #include "logging.h" #include "mcp.h" #include "client.h" #include "api.h" #include "admin.h" #define DRIVER_TCI_LEN PAGE_SIZE /* We need 2 devices for admin and user interface*/ #define MC_DEV_MAX 2 static struct admin_ctx { struct device *dev; Loading @@ -47,6 +50,7 @@ static struct admin_ctx { struct device_driver mc_dev_name; dev_t mc_dev_admin; struct cdev mc_admin_cdev; int (*tee_start_cb)(void); } g_admin_ctx; static struct mc_admin_driver_request { Loading Loading @@ -146,10 +150,18 @@ static int request_send(uint32_t command, const struct mc_uuid_t *uuid, uint32_t is_gp, uint32_t spid) { struct device *dev = g_admin_ctx.dev; int counter = 10; int ret; /* Prepare request */ mutex_lock(&g_request.states_mutex); /* Wait a little for daemon to connect */ while ((g_request.server_state == NOT_CONNECTED) && counter--) { mutex_unlock(&g_request.states_mutex); ssleep(1); mutex_lock(&g_request.states_mutex); } BUG_ON(g_request.client_state != IDLE); if (g_request.server_state != READY) { mutex_unlock(&g_request.states_mutex); Loading Loading @@ -194,14 +206,8 @@ static int request_send(uint32_t command, const struct mc_uuid_t *uuid, ret = -EPIPE; break; case READY: /* Length was 0, expect error */ if (!g_request.response.error_no) { dev_err(dev, "%s: length is 0 but no error reported\n", __func__); ret = -EPIPE; } else { /* No data to come, likely an error */ ret = -g_request.response.error_no; } break; case RESPONSE_SENT: case DATA_SENT: Loading Loading @@ -376,7 +382,7 @@ end: static struct tbase_object *admin_get_trustlet(const struct mc_uuid_t *uuid, uint32_t is_gp, uint32_t *spid) { struct tbase_object *obj; struct tbase_object *obj = NULL; bool is_sp_tl; int ret = 0; Loading Loading @@ -409,6 +415,25 @@ end: return obj; } static void mc_admin_sendcrashdump(void) { int ret = 0; /* Lock communication channel */ mutex_lock(&g_request.mutex); /* Send request and wait for header */ ret = request_send(MC_DRV_SIGNAL_CRASH, NULL, false, 0); if (ret) goto end; /* Done */ request_cancel(); end: mutex_unlock(&g_request.mutex); } static int tbase_object_make(uint32_t spid, struct tbase_object *obj) { struct mc_blob_len_info *l_info = (struct mc_blob_len_info *)obj->data; Loading Loading @@ -550,7 +575,12 @@ static inline int load_driver(struct tbase_client *client, struct mc_admin_load_info *info) { struct tbase_object *obj; void *dci; struct mclf_header_v2 *thdr; struct mc_identity identity = { .login_type = TEEC_LOGIN_PUBLIC, }; uintptr_t dci = 0; uint32_t dci_len = 0; uint32_t sid; int ret; Loading @@ -558,13 +588,21 @@ static inline int load_driver(struct tbase_client *client, if (IS_ERR(obj)) return PTR_ERR(obj); /* Create a driver */ ret = api_malloc_cbuf(client, DRIVER_TCI_LEN, &dci, NULL); thdr = (struct mclf_header_v2 *)&obj->data[obj->header_length]; if (!(thdr->flags & MC_SERVICE_HEADER_FLAGS_NO_CONTROL_INTERFACE)) { /* * The driver requires a DCI, although we won't be able to use * it to communicate. */ dci_len = PAGE_SIZE; ret = api_malloc_cbuf(client, dci_len, &dci, NULL); if (ret) goto end; } /* Open session */ ret = client_add_session(client, obj, dci, DRIVER_TCI_LEN, &sid, false); ret = client_add_session(client, obj, dci, dci_len, &sid, false, &identity); if (ret) api_free_cbuf(client, dci); else Loading @@ -578,6 +616,7 @@ end: static inline int load_token(struct mc_admin_load_info *token) { struct tbase_mmu *mmu; struct mcp_buffer_map map; int ret; mmu = tbase_mmu_create(current, (void *)(uintptr_t)token->address, Loading @@ -585,7 +624,8 @@ static inline int load_token(struct mc_admin_load_info *token) if (IS_ERR(mmu)) return PTR_ERR(mmu); ret = mcp_load_token(token->address, token->length, mmu); tbase_mmu_buffer(mmu, &map); ret = mcp_load_token(token->address, &map); tbase_mmu_delete(mmu); return ret; } Loading @@ -594,6 +634,7 @@ static inline int load_check(struct mc_admin_load_info *info) { struct tbase_object *obj; struct tbase_mmu *mmu; struct mcp_buffer_map map; int ret; obj = tbase_object_read(info->spid, info->address, info->length); Loading @@ -604,7 +645,8 @@ static inline int load_check(struct mc_admin_load_info *info) if (IS_ERR(mmu)) return PTR_ERR(mmu); ret = mcp_load_check(obj, mmu); tbase_mmu_buffer(mmu, &map); ret = mcp_load_check(obj, &map); tbase_mmu_delete(mmu); return ret; } Loading Loading @@ -709,10 +751,8 @@ static long admin_ioctl(struct file *file, unsigned int cmd, MCDRV_DBG("%u from %s", _IOC_NR(cmd), current->comm); if (WARN(!client, "No client data available")) { ret = -EFAULT; goto out; } if (WARN(!client, "No client data available")) return -EFAULT; switch (cmd) { case MC_ADMIN_IO_GET_DRIVER_REQUEST: { Loading Loading @@ -747,7 +787,8 @@ static long admin_ioctl(struct file *file, unsigned int cmd, case MC_ADMIN_IO_GET_INFO: { struct mc_admin_driver_info info; info.drv_version = mc_dev_get_version(); info.drv_version = MC_VERSION(MCDRVMODULEAPI_VERSION_MAJOR, MCDRVMODULEAPI_VERSION_MINOR); info.initial_cmd_id = g_request.request_id; ret = copy_to_user(uarg, &info, sizeof(info)); break; Loading @@ -755,19 +796,12 @@ static long admin_ioctl(struct file *file, unsigned int cmd, case MC_ADMIN_IO_LOAD_DRIVER: { struct mc_admin_load_info info; /* Acquire client */ if (!mc_ref_client(client)) { ret = -ENODEV; break; } ret = copy_from_user(&info, uarg, sizeof(info)); if (ret) ret = -EFAULT; else ret = load_driver(client, &info); mc_unref_client(client); break; } case MC_ADMIN_IO_LOAD_TOKEN: { Loading Loading @@ -796,8 +830,6 @@ static long admin_ioctl(struct file *file, unsigned int cmd, ret = -ENOIOCTLCMD; } out: mobicore_log_read(); return ret; } Loading Loading @@ -844,6 +876,7 @@ static int admin_open(struct inode *inode, struct file *file) { struct device *dev = g_admin_ctx.dev; struct tbase_client *client; int err; /* * If the daemon is already set we can't allow anybody else to open Loading @@ -860,11 +893,23 @@ static int admin_open(struct inode *inode, struct file *file) /* Setup the usual variables */ MCDRV_DBG("accept %s as tbase daemon", current->comm); /* * daemon is connected so now we can safely suppose * the secure world is loaded too */ if (!IS_ERR_OR_NULL(g_admin_ctx.tee_start_cb)) g_admin_ctx.tee_start_cb = ERR_PTR(g_admin_ctx.tee_start_cb()); if (IS_ERR(g_admin_ctx.tee_start_cb)) { MCDRV_ERROR("Failed initializing the SW"); err = PTR_ERR(g_admin_ctx.tee_start_cb); goto fail_connection; } /* Create client */ client = api_open_device(true); if (!client) { atomic_set(&g_admin_ctx.daemon_counter, 0); return -ENOMEM; err = -ENOMEM; goto fail_connection; } /* Store client in user file */ Loading @@ -875,6 +920,10 @@ static int admin_open(struct inode *inode, struct file *file) dev_info(dev, "%s: daemon connected\n", __func__); return 0; fail_connection: atomic_set(&g_admin_ctx.daemon_counter, 0); return err; } /* function table structure of this device driver. */ Loading @@ -889,7 +938,8 @@ static const struct file_operations mc_admin_fops = { .write = admin_write, }; int admin_dev_init(struct class *mc_device_class, dev_t *out_dev) int mc_admin_init(struct class *mc_device_class, dev_t *out_dev, int (*tee_start_cb)(void)) { int err = 0; Loading @@ -903,11 +953,12 @@ int admin_dev_init(struct class *mc_device_class, dev_t *out_dev) mutex_init(&g_request.states_mutex); init_completion(&g_request.client_complete); init_completion(&g_request.server_complete); mcp_register_crashhandler(mc_admin_sendcrashdump); /* Create char device */ cdev_init(&g_admin_ctx.mc_admin_cdev, &mc_admin_fops); err = alloc_chrdev_region(&g_admin_ctx.mc_dev_admin, 0, MC_DEV_MAX, "mobicore"); "trustonic_tee"); if (err < 0) { MCDRV_ERROR("failed to allocate char dev region"); goto fail_alloc_chrdev_region; Loading @@ -932,6 +983,9 @@ int admin_dev_init(struct class *mc_device_class, dev_t *out_dev) g_admin_ctx.dev->driver = &g_admin_ctx.mc_dev_name; *out_dev = g_admin_ctx.mc_dev_admin; /* Register the call back for starting the secure world */ g_admin_ctx.tee_start_cb = tee_start_cb; MCDRV_DBG("done"); return 0; Loading @@ -946,7 +1000,7 @@ fail_alloc_chrdev_region: return err; } void admin_dev_cleanup(struct class *mc_device_class) void mc_admin_exit(struct class *mc_device_class) { device_destroy(mc_device_class, g_admin_ctx.mc_dev_admin); cdev_del(&g_admin_ctx.mc_admin_cdev); Loading
drivers/gud/MobiCoreDriver/admin.h +6 −10 Original line number Diff line number Diff line /* * Copyright (c) 2013-2014 TRUSTONIC LIMITED * Copyright (c) 2013-2015 TRUSTONIC LIMITED * All Rights Reserved. * * This program is free software; you can redistribute it and/or Loading @@ -15,16 +15,12 @@ #ifndef ADMIN_FD_H_ #define ADMIN_FD_H_ #include <public/mc_linux.h> struct mc_uuid_t; struct tbase_object; struct tbase_object { uint32_t length; /* Total length */ uint32_t header_length; /* Length of header before payload */ uint8_t data[]; /* Header followed by payload */ }; int admin_dev_init(struct class *mc_device_class, dev_t *out_dev); void admin_dev_cleanup(struct class *mc_device_class); int mc_admin_init(struct class *mc_device_class, dev_t *out_dev, int (*tee_start_cb)(void)); void mc_admin_exit(struct class *mc_device_class); struct tbase_object *tbase_object_select(const struct mc_uuid_t *uuid); struct tbase_object *tbase_object_get(const struct mc_uuid_t *uuid, Loading
drivers/gud/MobiCoreDriver/api.c +110 −156 Original line number Diff line number Diff line Loading @@ -15,12 +15,23 @@ #include <linux/device.h> #include <linux/slab.h> #include <linux/err.h> #include <linux/cred.h> #include <linux/sched.h> #include <public/mc_linux.h> /* MC_MAP_MAX */ #include "main.h" #include "debug.h" #include "mcp.h" #include "admin.h" #include "session.h" #include "client.h" #include "api.h" static struct api_ctx { struct mutex clients_lock; /* Clients list + temp notifs */ struct list_head clients; /* List of user-space clients */ } api_ctx; /* * Initialize a new tbase client object * @return client pointer or NULL if no allocation was possible. Loading @@ -37,9 +48,11 @@ struct tbase_client *api_open_device(bool is_from_kernel) } /* Add client to list of clients */ mc_add_client(client); mutex_lock(&api_ctx.clients_lock); list_add_tail(&client->list, &api_ctx.clients); mutex_unlock(&api_ctx.clients_lock); MCDRV_DBG("Created client 0x%p", client); MCDRV_DBG("created client %p", client); return client; } Loading @@ -51,17 +64,10 @@ int api_freeze_device(struct tbase_client *client) { int err = 0; if (!mc_ref_client(client)) { err = -ENODEV; goto end; } if (!client_set_closing(client)) err = -ENOTEMPTY; mc_unref_client(client); end: MCDRV_DBG("client 0x%p, exit with %d\n", client, err); MCDRV_DBG("client %p, exit with %d\n", client, err); return err; } Loading @@ -70,18 +76,16 @@ end: * @param client_t client * @return tbase driver error code */ int api_close_device(struct tbase_client *client) void api_close_device(struct tbase_client *client) { /* Remove client from list of active clients */ int err = mc_remove_client(client); if (!err) { mutex_lock(&api_ctx.clients_lock); list_del(&client->list); mutex_unlock(&api_ctx.clients_lock); /* Close all remaining sessions */ client_close_sessions(client); mc_unref_client(client); } MCDRV_DBG("client 0x%p, exit with %d\n\n", client, err); return err; client_put(client); MCDRV_DBG("client %p closed\n", client); } /* Loading @@ -94,7 +98,8 @@ int api_open_session(struct tbase_client *client, const struct mc_uuid_t *uuid, uintptr_t tci, size_t tci_len, bool is_gp_uuid) bool is_gp_uuid, struct mc_identity *identity) { int err = 0; uint32_t sid = 0; Loading @@ -107,10 +112,6 @@ int api_open_session(struct tbase_client *client, if (!uuid) return -EINVAL; /* Acquire client */ if (!mc_ref_client(client)) return -ENODEV; /* Get secure object */ obj = tbase_object_get(uuid, is_gp_uuid); if (IS_ERR(obj)) { Loading @@ -125,8 +126,8 @@ int api_open_session(struct tbase_client *client, } /* Open session */ err = client_add_session(client, obj, (void *)tci, tci_len, &sid, is_gp_uuid); err = client_add_session(client, obj, tci, tci_len, &sid, is_gp_uuid, identity); /* Fill in return parameter */ if (!err) *p_session_id = sid; Loading @@ -135,8 +136,6 @@ int api_open_session(struct tbase_client *client, tbase_object_free(obj); end: /* Release client */ mc_unref_client(client); MCDRV_DBG("session %x, exit with %d\n", sid, err); return err; Loading @@ -155,18 +154,17 @@ int api_open_trustlet(struct tbase_client *client, uintptr_t tci, size_t tci_len) { int err = 0; uint32_t sid = 0; struct tbase_object *obj; struct mc_identity identity = { .login_type = TEEC_LOGIN_PUBLIC, }; uint32_t sid = 0; int err = 0; /* Check parameters */ if (!p_session_id) return -EINVAL; /* Acquire client */ if (!mc_ref_client(client)) return -ENODEV; /* Create secure object from user-space trustlet binary */ obj = tbase_object_read(spid, trustlet, trustlet_len); if (IS_ERR(obj)) { Loading @@ -175,8 +173,8 @@ int api_open_trustlet(struct tbase_client *client, } /* Open session */ err = client_add_session(client, obj, (void *)tci, tci_len, &sid, false); err = client_add_session(client, obj, tci, tci_len, &sid, false, &identity); /* Fill in return parameter */ if (!err) *p_session_id = sid; Loading @@ -185,9 +183,6 @@ int api_open_trustlet(struct tbase_client *client, tbase_object_free(obj); end: /* Release client */ mc_unref_client(client); MCDRV_DBG("session %x, exit with %d\n", sid, err); return err; } Loading @@ -199,23 +194,10 @@ end: */ int api_close_session(struct tbase_client *client, uint32_t session_id) { int err = 0; /* Acquire client */ if (!mc_ref_client(client)) { err = -ENODEV; goto end; } /* Close session */ err = client_remove_session(client, session_id); int ret = client_remove_session(client, session_id); /* Release client */ mc_unref_client(client); end: MCDRV_DBG("session %x, exit with %d\n", session_id, err); return err; MCDRV_DBG("session %x, exit with %d\n", session_id, ret); return ret; } /* Loading @@ -227,10 +209,6 @@ int api_notify(struct tbase_client *client, uint32_t session_id) int err = 0; struct tbase_session *session = NULL; /* Acquire client */ if (!mc_ref_client(client)) return -ENODEV; /* Acquire session */ session = client_ref_session(client, session_id); Loading @@ -244,9 +222,6 @@ int api_notify(struct tbase_client *client, uint32_t session_id) client_unref_session(session); } /* Release client */ mc_unref_client(client); MCDRV_DBG("session %x, exit with %d\n", session_id, err); return err; } Loading @@ -262,10 +237,6 @@ int api_wait_notification(struct tbase_client *client, int err = 0; struct tbase_session *session = NULL; /* Acquire client */ if (!mc_ref_client(client)) return -ENODEV; /* Acquire session */ session = client_ref_session(client, session_id); Loading @@ -273,15 +244,12 @@ int api_wait_notification(struct tbase_client *client, if (!session) { err = -ENXIO; } else { err = session_wait(session, timeout); err = session_waitnotif(session, timeout); /* Release session */ client_unref_session(session); } /* Release client */ mc_unref_client(client); MCDRV_DBG("session %x, exit with %d\n", session_id, err); return err; } Loading @@ -295,19 +263,9 @@ int api_wait_notification(struct tbase_client *client, * @return tbase driver error code */ int api_malloc_cbuf(struct tbase_client *client, uint32_t len, void **p_addr, struct vm_area_struct *vmarea) uintptr_t *addr, struct vm_area_struct *vmarea) { int err = 0; /* Acquire client */ if (!mc_ref_client(client)) return -ENODEV; /* Allocate buffer */ err = tbase_cbuf_alloc(client, len, p_addr, vmarea); /* Release client */ mc_unref_client(client); int err = tbase_cbuf_alloc(client, len, addr, vmarea); MCDRV_DBG("exit with %d\n", err); return err; Loading @@ -320,49 +278,33 @@ int api_malloc_cbuf(struct tbase_client *client, uint32_t len, * * @return tbase driver error code */ int api_free_cbuf(struct tbase_client *client, void *addr) int api_free_cbuf(struct tbase_client *client, uintptr_t addr) { int err = 0; /* Acquire client */ if (!mc_ref_client(client)) return -ENODEV; /* Free buffer */ err = tbase_cbuf_free(client, addr); /* Release client */ mc_unref_client(client); int err = tbase_cbuf_free(client, addr); MCDRV_DBG("@ 0x%p, exit with %d\n", addr, err); MCDRV_DBG("@ 0x%lx, exit with %d\n", addr, err); return err; } /* * Share a buffer with given TA in SWd * @return tbase driver error code */ int api_map_wsm(struct tbase_client *client, uint32_t session_id, void *buf, uint32_t len, uint32_t *p_sva, uint32_t *p_slen) /* Share a buffer with given TA in SWd */ int api_map_wsms(struct tbase_client *client, uint32_t session_id, struct mc_ioctl_buffer *bufs) { int err = 0; struct tbase_session *session = NULL; uint32_t sva; int err = 0; /* Check parameters */ if (!buf || !len || !p_sva || !p_slen) if (!client) return -EINVAL; /* Acquire client */ if (!mc_ref_client(client)) return -ENODEV; if (!bufs) return -EINVAL; /* Acquire session */ session = client_ref_session(client, session_id); if (session) { /* Add buffer to the session */ err = session_add_wsm(session, buf, len, &sva); err = session_wsms_add(session, bufs); /* Release session */ client_unref_session(session); Loading @@ -370,43 +312,22 @@ int api_map_wsm(struct tbase_client *client, uint32_t session_id, void *buf, err = -ENXIO; } if (err) { *p_sva = 0; *p_slen = 0; MCDRV_ERROR("code %d", err); } else { *p_sva = sva; *p_slen = len; } /* Release client */ mc_unref_client(client); MCDRV_DBG("0x%p, exit with %d\n", buf, err); MCDRV_DBG("exit with %d\n", err); return err; } /* * Stop sharing a buffer with SWd * @param client * @param session_id * @param buf * @param map_info * @return tbase driver error code */ int api_unmap_wsm(struct tbase_client *client, uint32_t session_id, void *buf, uint32_t sva, uint32_t slen) /* Stop sharing a buffer with SWd */ int api_unmap_wsms(struct tbase_client *client, uint32_t session_id, const struct mc_ioctl_buffer *bufs) { int err = 0; struct tbase_session *session = NULL; int err = 0; /* Check parameters */ if (!client) return -EINVAL; /* Acquire client */ if (!mc_ref_client(client)) return -ENODEV; if (!bufs) return -EINVAL; /* Acquire session */ session = client_ref_session(client, session_id); Loading @@ -415,33 +336,24 @@ int api_unmap_wsm(struct tbase_client *client, uint32_t session_id, err = -ENXIO; } else { /* Remove buffer from session */ err = session_remove_wsm(session, buf, sva, slen); err = session_wsms_remove(session, bufs); /* Release session */ client_unref_session(session); } /* Release client */ mc_unref_client(client); MCDRV_DBG("0x%p, exit with %d\n", buf, err); MCDRV_DBG("exit with %d\n", err); return err; } /* * Read last error from received notifications * @return tbase driver error code * Read session exit/termination code */ int api_get_session_error(struct tbase_client *client, uint32_t session_id, int32_t *last_error) int api_get_session_exitcode(struct tbase_client *client, uint32_t session_id, int32_t *exit_code) { int err = 0; struct tbase_session *session; /* Acquire client */ if (!mc_ref_client(client)) return -ENODEV; /* Acquire session */ session = client_ref_session(client, session_id); Loading @@ -449,7 +361,7 @@ int api_get_session_error(struct tbase_client *client, uint32_t session_id, err = -ENXIO; } else { /* Retrieve error */ *last_error = session_get_err(session); *exit_code = session_exitcode(session); /* Release session */ client_unref_session(session); Loading @@ -457,9 +369,51 @@ int api_get_session_error(struct tbase_client *client, uint32_t session_id, err = 0; } /* Release client */ mc_unref_client(client); MCDRV_DBG("session %x, exit with %d\n", session_id, err); return err; } void api_init(void) { INIT_LIST_HEAD(&api_ctx.clients); mutex_init(&api_ctx.clients_lock); INIT_LIST_HEAD(&g_ctx.closing_sess); mutex_init(&g_ctx.closing_lock); } int api_info(struct kasnprintf_buf *buf) { struct tbase_client *client; struct tbase_session *session; ssize_t ret = 0; mutex_lock(&api_ctx.clients_lock); if (list_empty(&api_ctx.clients)) goto done; list_for_each_entry(client, &api_ctx.clients, list) { ret = client_info(client, buf); if (ret < 0) break; } done: mutex_unlock(&api_ctx.clients_lock); if (ret >= 0) { mutex_lock(&g_ctx.closing_lock); if (!list_empty(&g_ctx.closing_sess)) ret = kasnprintf(buf, "closing sessions:\n"); list_for_each_entry(session, &g_ctx.closing_sess, list) { ret = session_info(session, buf); if (ret < 0) break; } mutex_unlock(&g_ctx.closing_lock); } return ret; }
drivers/gud/MobiCoreDriver/api.h +19 −38 Original line number Diff line number Diff line Loading @@ -15,51 +15,32 @@ #ifndef _API_H_ #define _API_H_ #include "public/mc_linux.h" #include "client.h" #include "session.h" struct tbase_client; struct tbase_client *api_open_device(bool is_from_kernel); int api_freeze_device(struct tbase_client *client); int api_close_device(struct tbase_client *client); int api_open_session(struct tbase_client *client, uint32_t *session_id, void api_close_device(struct tbase_client *client); int api_open_session(struct tbase_client *client, uint32_t *session_id, const struct mc_uuid_t *uuid, uintptr_t tci, size_t tci_len, bool is_gp_uuid); int api_open_trustlet(struct tbase_client *client, uint32_t *p_sid, uint32_t spid, uintptr_t trustlet, size_t trustlet_len, uintptr_t tci, size_t tci_len); uintptr_t tci, size_t tci_len, bool is_gp_uuid, struct mc_identity *identity); int api_open_trustlet(struct tbase_client *client, uint32_t *session_id, uint32_t spid, uintptr_t trustlet, size_t trustlet_len, uintptr_t tci, size_t tci_len); int api_close_session(struct tbase_client *client, uint32_t session_id); int api_notify(struct tbase_client *client, uint32_t session_id); int api_wait_notification(struct tbase_client *client, uint32_t session_id, int32_t timeout); int api_malloc_cbuf(struct tbase_client *client, uint32_t len, void **p_addr, int api_malloc_cbuf(struct tbase_client *client, uint32_t len, uintptr_t *addr, struct vm_area_struct *vmarea); int api_free_cbuf(struct tbase_client *client, void *addr); int api_map_wsm(struct tbase_client *client, uint32_t session_id, void *buf, uint32_t len, uint32_t *p_sva, uint32_t *p_slen); int api_unmap_wsm(struct tbase_client *client, uint32_t session_id, void *buf, uint32_t sva, uint32_t slen); int api_get_session_error(struct tbase_client *client, uint32_t session_id, int32_t *last_error); int api_free_cbuf(struct tbase_client *client, uintptr_t addr); int api_map_wsms(struct tbase_client *client, uint32_t session_id, struct mc_ioctl_buffer *bufs); int api_unmap_wsms(struct tbase_client *client, uint32_t session_id, const struct mc_ioctl_buffer *bufs); int api_get_session_exitcode(struct tbase_client *client, uint32_t session_id, int32_t *exit_code); void api_init(void); int api_info(struct kasnprintf_buf *buf); #endif /* _API_H_ */