Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4e016077 authored by Oana Medvesan's avatar Oana Medvesan Committed by Puneet Mishra
Browse files

tbase-400: Fix built in feature and merge recent changes from the trustonic trunk base



Change-Id: I2b1ea788794bf3bf224fcf562ac89c18404ec36a
Signed-off-by: default avatarOana Medvesan <medvesan.oana@gmail.com>
Git-commit: 3ca78a233de16402cb09a688ce236f1fcd660d34
Git-repo: https://github.com/TrustonicNwd/tee-mobicore-driver.kernel.git


Acked-by: default avatarTony Hamilton <tonyh@qti.qualcomm.com>
Signed-off-by: default avatarPuneet Mishra <puneetm@codeaurora.org>
parent c312a53c
Loading
Loading
Loading
Loading
+16 −8
Original line number Diff line number Diff line
@@ -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
+94 −40
Original line number Diff line number Diff line
@@ -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>
@@ -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"
@@ -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;
@@ -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 {
@@ -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);
@@ -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:
@@ -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;

@@ -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;
@@ -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;

@@ -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
@@ -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,
@@ -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;
}
@@ -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);
@@ -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;
}
@@ -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: {
@@ -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;
@@ -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: {
@@ -796,8 +830,6 @@ static long admin_ioctl(struct file *file, unsigned int cmd,
		ret = -ENOIOCTLCMD;
	}

out:
	mobicore_log_read();
	return ret;
}

@@ -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
@@ -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 */
@@ -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. */
@@ -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;

@@ -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;
@@ -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;

@@ -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);
+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
@@ -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,
+110 −156
Original line number Diff line number Diff line
@@ -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.
@@ -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;
}

@@ -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;
}

@@ -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);
}

/*
@@ -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;
@@ -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)) {
@@ -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;
@@ -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;
@@ -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)) {
@@ -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;
@@ -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;
}
@@ -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;
}

/*
@@ -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);

@@ -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;
}
@@ -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);

@@ -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;
}
@@ -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;
@@ -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);
@@ -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);
@@ -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);

@@ -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);
@@ -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;
}
+19 −38
Original line number Diff line number Diff line
@@ -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