// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015-2016, Linaro Limited
*/
#define pr_fmt(fmt) "%s: " fmt, __func__
#include <linux/cdev.h>
#include <linux/cred.h>
#include <linux/fs.h>
#include <linux/idr.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/tee_drv.h>
#include <linux/uaccess.h>
#include <crypto/hash.h>
#include <crypto/sha.h>
#include "tee_private.h"
#define TEE_NUM_DEVICES 32
#define TEE_IOCTL_PARAM_SIZE(x) (sizeof(struct tee_param) * (x))
#define TEE_UUID_NS_NAME_SIZE 128
/*
* TEE Client UUID name space identifier (UUIDv4)
*
* Value here is random UUID that is allocated as name space identifier for
* forming Client UUID's for TEE environment using UUIDv5 scheme.
*/
static const uuid_t tee_client_uuid_ns = UUID_INIT(0x58ac9ca0, 0x2086, 0x4683,
0xa1, 0xb8, 0xec, 0x4b,
0xc0, 0x8e, 0x01, 0xb6);
/*
* Unprivileged devices in the lower half range and privileged devices in
* the upper half range.
*/
static DECLARE_BITMAP(dev_mask, TEE_NUM_DEVICES);
static DEFINE_SPINLOCK(driver_lock);
static struct class *tee_class;
static dev_t tee_devt;
static struct tee_context *teedev_open(struct tee_device *teedev)
{
int rc;
struct tee_context *ctx;
if (!tee_device_get(teedev))
return ERR_PTR(-EINVAL);
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx) {
rc = -ENOMEM;
goto err;
}
kref_init(&ctx->refcount);
ctx->teedev = teedev;
rc = teedev->desc->ops->open(ctx);
if (rc)
goto err;
return ctx;
err:
kfree(ctx);
tee_device_put(teedev);
return ERR_PTR(rc);
}
void teedev_ctx_get(struct tee_context *ctx)
{
if (ctx->releasing)
return;
kref_get(&ctx->refcount);
}
static void teedev_ctx_release(struct kref *ref)
{
struct tee_context *ctx = container_of(ref, struct tee_context,
refcount);
ctx->releasing = true;
ctx->teedev->desc->ops->release(ctx);
kfree(ctx);
}
void teedev_ctx_put(struct tee_context *ctx)
{
if (ctx->releasing)
return;
kref_put(&ctx->refcount, teedev_ctx_release);
}
static void teedev_close_context(struct tee_context *ctx)
{
tee_device_put(ctx->teedev);
teedev_ctx_put(ctx);
}
static int tee_open(struct inod