linux/drivers/tee/tee_core.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2015-2016, Linaro Limited
   3 *
   4 * This software is licensed under the terms of the GNU General Public
   5 * License version 2, as published by the Free Software Foundation, and
   6 * may be copied, distributed, and modified under those terms.
   7 *
   8 * This program is distributed in the hope that it will be useful,
   9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11 * GNU General Public License for more details.
  12 *
  13 */
  14
  15#define pr_fmt(fmt) "%s: " fmt, __func__
  16
  17#include <linux/cdev.h>
  18#include <linux/device.h>
  19#include <linux/fs.h>
  20#include <linux/idr.h>
  21#include <linux/module.h>
  22#include <linux/slab.h>
  23#include <linux/tee_drv.h>
  24#include <linux/uaccess.h>
  25#include "tee_private.h"
  26
  27#define TEE_NUM_DEVICES 32
  28
  29#define TEE_IOCTL_PARAM_SIZE(x) (sizeof(struct tee_param) * (x))
  30
  31/*
  32 * Unprivileged devices in the lower half range and privileged devices in
  33 * the upper half range.
  34 */
  35static DECLARE_BITMAP(dev_mask, TEE_NUM_DEVICES);
  36static DEFINE_SPINLOCK(driver_lock);
  37
  38static struct class *tee_class;
  39static dev_t tee_devt;
  40
  41static int tee_open(struct inode *inode, struct file *filp)
  42{
  43        int rc;
  44        struct tee_device *teedev;
  45        struct tee_context *ctx;
  46
  47        teedev = container_of(inode->i_cdev, struct tee_device, cdev);
  48        if (!tee_device_get(teedev))
  49                return -EINVAL;
  50
  51        ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
  52        if (!ctx) {
  53                rc = -ENOMEM;
  54                goto err;
  55        }
  56
  57        ctx->teedev = teedev;
  58        INIT_LIST_HEAD(&ctx->list_shm);
  59        filp->private_data = ctx;
  60        rc = teedev->desc->ops->open(ctx);
  61        if (rc)
  62                goto err;
  63
  64        return 0;
  65err:
  66        kfree(ctx);
  67        tee_device_put(teedev);
  68        return rc;
  69}
  70
  71static int tee_release(struct inode *inode, struct file *filp)
  72{
  73        struct tee_context *ctx = filp->private_data;
  74        struct tee_device *teedev = ctx->teedev;
  75        struct tee_shm *shm;
  76
  77        ctx->teedev->desc->ops->release(ctx);
  78        mutex_lock(&ctx->teedev->mutex);
  79        list_for_each_entry(shm, &ctx->list_shm, link)
  80                shm->ctx = NULL;
  81        mutex_unlock(&ctx->teedev->mutex);
  82        kfree(ctx);
  83        tee_device_put(teedev);
  84        return 0;
  85}
  86
  87static int tee_ioctl_version(struct tee_context *ctx,
  88                             struct tee_ioctl_version_data __user *uvers)
  89{
  90        struct tee_ioctl_version_data vers;
  91
  92        ctx->teedev->desc->ops->get_version(ctx->teedev, &vers);
  93
  94        if (ctx->teedev->desc->flags & TEE_DESC_PRIVILEGED)
  95                vers.gen_caps |= TEE_GEN_CAP_PRIVILEGED;
  96
  97        if (copy_to_user(uvers, &vers, sizeof(vers)))
  98                return -EFAULT;
  99
 100        return 0;
 101}
 102
 103static int tee_ioctl_shm_alloc(struct tee_context *ctx,
 104                               struct tee_ioctl_shm_alloc_data __user *udata)
 105{
 106        long ret;
 107        struct tee_ioctl_shm_alloc_data data;
 108        struct tee_shm *shm;
 109
 110        if (copy_from_user(&data, udata, sizeof(data)))
 111                return -EFAULT;
 112
 113        /* Currently no input flags are supported */
 114        if (data.flags)
 115                return -EINVAL;
 116
 117        data.id = -1;
 118
 119        shm = tee_shm_alloc(ctx, data.size, TEE_SHM_MAPPED | TEE_SHM_DMA_BUF);
 120        if (IS_ERR(shm))
 121                return PTR_ERR(shm);
 122
 123        data.id = shm->id;
 124        data.flags = shm->flags;
 125        data.size = shm->size;
 126
 127        if (copy_to_user(udata, &data, sizeof(data)))
 128                ret = -EFAULT;
 129        else
 130                ret = tee_shm_get_fd(shm);
 131
 132        /*
 133         * When user space closes the file descriptor the shared memory
 134         * should be freed or if tee_shm_get_fd() failed then it will
 135         * be freed immediately.
 136         */
 137        tee_shm_put(shm);
 138        return ret;
 139}
 140
 141static int params_from_user(struct tee_context *ctx, struct tee_param *params,
 142                            size_t num_params,
 143                            struct tee_ioctl_param __user *uparams)
 144{
 145        size_t n;
 146
 147        for (n = 0; n < num_params; n++) {
 148                struct tee_shm *shm;
 149                struct tee_ioctl_param ip;
 150
 151                if (copy_from_user(&ip, uparams + n, sizeof(ip)))
 152                        return -EFAULT;
 153
 154                /* All unused attribute bits has to be zero */
 155                if (ip.attr & ~TEE_IOCTL_PARAM_ATTR_TYPE_MASK)
 156                        return -EINVAL;
 157
 158                params[n].attr = ip.attr;
 159                switch (ip.attr) {
 160                case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
 161                case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
 162                        break;
 163                case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
 164                case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
 165                        params[n].u.value.a = ip.a;
 166                        params[n].u.value.b = ip.b;
 167                        params[n].u.value.c = ip.c;
 168                        break;
 169                case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
 170                case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
 171                case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
 172                        /*
 173                         * If we fail to get a pointer to a shared memory
 174                         * object (and increase the ref count) from an
 175                         * identifier we return an error. All pointers that
 176                         * has been added in params have an increased ref
 177                         * count. It's the callers responibility to do
 178                         * tee_shm_put() on all resolved pointers.
 179                         */
 180                        shm = tee_shm_get_from_id(ctx, ip.c);
 181                        if (IS_ERR(shm))
 182                                return PTR_ERR(shm);
 183
 184                        params[n].u.memref.shm_offs = ip.a;
 185                        params[n].u.memref.size = ip.b;
 186                        params[n].u.memref.shm = shm;
 187                        break;
 188                default:
 189                        /* Unknown attribute */
 190                        return -EINVAL;
 191                }
 192        }
 193        return 0;
 194}
 195
 196static int params_to_user(struct tee_ioctl_param __user *uparams,
 197                          size_t num_params, struct tee_param *params)
 198{
 199        size_t n;
 200
 201        for (n = 0; n < num_params; n++) {
 202                struct tee_ioctl_param __user *up = uparams + n;
 203                struct tee_param *p = params + n;
 204
 205                switch (p->attr) {
 206                case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
 207                case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
 208                        if (put_user(p->u.value.a, &up->a) ||
 209                            put_user(p->u.value.b, &up->b) ||
 210                            put_user(p->u.value.c, &up->c))
 211                                return -EFAULT;
 212                        break;
 213                case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
 214                case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
 215                        if (put_user((u64)p->u.memref.size, &up->b))
 216                                return -EFAULT;
 217                default:
 218                        break;
 219                }
 220        }
 221        return 0;
 222}
 223
 224static bool param_is_memref(struct tee_param *param)
 225{
 226        switch (param->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
 227        case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
 228        case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
 229        case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
 230                return true;
 231        default:
 232                return false;
 233        }
 234}
 235
 236static int tee_ioctl_open_session(struct tee_context *ctx,
 237                                  struct tee_ioctl_buf_data __user *ubuf)
 238{
 239        int rc;
 240        size_t n;
 241        struct tee_ioctl_buf_data buf;
 242        struct tee_ioctl_open_session_arg __user *uarg;
 243        struct tee_ioctl_open_session_arg arg;
 244        struct tee_ioctl_param __user *uparams = NULL;
 245        struct tee_param *params = NULL;
 246        bool have_session = false;
 247
 248        if (!ctx->teedev->desc->ops->open_session)
 249                return -EINVAL;
 250
 251        if (copy_from_user(&buf, ubuf, sizeof(buf)))
 252                return -EFAULT;
 253
 254        if (buf.buf_len > TEE_MAX_ARG_SIZE ||
 255            buf.buf_len < sizeof(struct tee_ioctl_open_session_arg))
 256                return -EINVAL;
 257
 258        uarg = u64_to_user_ptr(buf.buf_ptr);
 259        if (copy_from_user(&arg, uarg, sizeof(arg)))
 260                return -EFAULT;
 261
 262        if (sizeof(arg) + TEE_IOCTL_PARAM_SIZE(arg.num_params) != buf.buf_len)
 263                return -EINVAL;
 264
 265        if (arg.num_params) {
 266                params = kcalloc(arg.num_params, sizeof(struct tee_param),
 267                                 GFP_KERNEL);
 268                if (!params)
 269                        return -ENOMEM;
 270                uparams = uarg->params;
 271                rc = params_from_user(ctx, params, arg.num_params, uparams);
 272                if (rc)
 273                        goto out;
 274        }
 275
 276        rc = ctx->teedev->desc->ops->open_session(ctx, &arg, params);
 277        if (rc)
 278                goto out;
 279        have_session = true;
 280
 281        if (put_user(arg.session, &uarg->session) ||
 282            put_user(arg.ret, &uarg->ret) ||
 283            put_user(arg.ret_origin, &uarg->ret_origin)) {
 284                rc = -EFAULT;
 285                goto out;
 286        }
 287        rc = params_to_user(uparams, arg.num_params, params);
 288out:
 289        /*
 290         * If we've succeeded to open the session but failed to communicate
 291         * it back to user space, close the session again to avoid leakage.
 292         */
 293        if (rc && have_session && ctx->teedev->desc->ops->close_session)
 294                ctx->teedev->desc->ops->close_session(ctx, arg.session);
 295
 296        if (params) {
 297                /* Decrease ref count for all valid shared memory pointers */
 298                for (n = 0; n < arg.num_params; n++)
 299                        if (param_is_memref(params + n) &&
 300                            params[n].u.memref.shm)
 301                                tee_shm_put(params[n].u.memref.shm);
 302                kfree(params);
 303        }
 304
 305        return rc;
 306}
 307
 308static int tee_ioctl_invoke(struct tee_context *ctx,
 309                            struct tee_ioctl_buf_data __user *ubuf)
 310{
 311        int rc;
 312        size_t n;
 313        struct tee_ioctl_buf_data buf;
 314        struct tee_ioctl_invoke_arg __user *uarg;
 315        struct tee_ioctl_invoke_arg arg;
 316        struct tee_ioctl_param __user *uparams = NULL;
 317        struct tee_param *params = NULL;
 318
 319        if (!ctx->teedev->desc->ops->invoke_func)
 320                return -EINVAL;
 321
 322        if (copy_from_user(&buf, ubuf, sizeof(buf)))
 323                return -EFAULT;
 324
 325        if (buf.buf_len > TEE_MAX_ARG_SIZE ||
 326            buf.buf_len < sizeof(struct tee_ioctl_invoke_arg))
 327                return -EINVAL;
 328
 329        uarg = u64_to_user_ptr(buf.buf_ptr);
 330        if (copy_from_user(&arg, uarg, sizeof(arg)))
 331                return -EFAULT;
 332
 333        if (sizeof(arg) + TEE_IOCTL_PARAM_SIZE(arg.num_params) != buf.buf_len)
 334                return -EINVAL;
 335
 336        if (arg.num_params) {
 337                params = kcalloc(arg.num_params, sizeof(struct tee_param),
 338                                 GFP_KERNEL);
 339                if (!params)
 340                        return -ENOMEM;
 341                uparams = uarg->params;
 342                rc = params_from_user(ctx, params, arg.num_params, uparams);
 343                if (rc)
 344                        goto out;
 345        }
 346
 347        rc = ctx->teedev->desc->ops->invoke_func(ctx, &arg, params);
 348        if (rc)
 349                goto out;
 350
 351        if (put_user(arg.ret, &uarg->ret) ||
 352            put_user(arg.ret_origin, &uarg->ret_origin)) {
 353                rc = -EFAULT;
 354                goto out;
 355        }
 356        rc = params_to_user(uparams, arg.num_params, params);
 357out:
 358        if (params) {
 359                /* Decrease ref count for all valid shared memory pointers */
 360                for (n = 0; n < arg.num_params; n++)
 361                        if (param_is_memref(params + n) &&
 362                            params[n].u.memref.shm)
 363                                tee_shm_put(params[n].u.memref.shm);
 364                kfree(params);
 365        }
 366        return rc;
 367}
 368
 369static int tee_ioctl_cancel(struct tee_context *ctx,
 370                            struct tee_ioctl_cancel_arg __user *uarg)
 371{
 372        struct tee_ioctl_cancel_arg arg;
 373
 374        if (!ctx->teedev->desc->ops->cancel_req)
 375                return -EINVAL;
 376
 377        if (copy_from_user(&arg, uarg, sizeof(arg)))
 378                return -EFAULT;
 379
 380        return ctx->teedev->desc->ops->cancel_req(ctx, arg.cancel_id,
 381                                                  arg.session);
 382}
 383
 384static int
 385tee_ioctl_close_session(struct tee_context *ctx,
 386                        struct tee_ioctl_close_session_arg __user *uarg)
 387{
 388        struct tee_ioctl_close_session_arg arg;
 389
 390        if (!ctx->teedev->desc->ops->close_session)
 391                return -EINVAL;
 392
 393        if (copy_from_user(&arg, uarg, sizeof(arg)))
 394                return -EFAULT;
 395
 396        return ctx->teedev->desc->ops->close_session(ctx, arg.session);
 397}
 398
 399static int params_to_supp(struct tee_context *ctx,
 400                          struct tee_ioctl_param __user *uparams,
 401                          size_t num_params, struct tee_param *params)
 402{
 403        size_t n;
 404
 405        for (n = 0; n < num_params; n++) {
 406                struct tee_ioctl_param ip;
 407                struct tee_param *p = params + n;
 408
 409                ip.attr = p->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK;
 410                switch (p->attr) {
 411                case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
 412                case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
 413                        ip.a = p->u.value.a;
 414                        ip.b = p->u.value.b;
 415                        ip.c = p->u.value.c;
 416                        break;
 417                case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
 418                case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
 419                case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
 420                        ip.b = p->u.memref.size;
 421                        if (!p->u.memref.shm) {
 422                                ip.a = 0;
 423                                ip.c = (u64)-1; /* invalid shm id */
 424                                break;
 425                        }
 426                        ip.a = p->u.memref.shm_offs;
 427                        ip.c = p->u.memref.shm->id;
 428                        break;
 429                default:
 430                        ip.a = 0;
 431                        ip.b = 0;
 432                        ip.c = 0;
 433                        break;
 434                }
 435
 436                if (copy_to_user(uparams + n, &ip, sizeof(ip)))
 437                        return -EFAULT;
 438        }
 439
 440        return 0;
 441}
 442
 443static int tee_ioctl_supp_recv(struct tee_context *ctx,
 444                               struct tee_ioctl_buf_data __user *ubuf)
 445{
 446        int rc;
 447        struct tee_ioctl_buf_data buf;
 448        struct tee_iocl_supp_recv_arg __user *uarg;
 449        struct tee_param *params;
 450        u32 num_params;
 451        u32 func;
 452
 453        if (!ctx->teedev->desc->ops->supp_recv)
 454                return -EINVAL;
 455
 456        if (copy_from_user(&buf, ubuf, sizeof(buf)))
 457                return -EFAULT;
 458
 459        if (buf.buf_len > TEE_MAX_ARG_SIZE ||
 460            buf.buf_len < sizeof(struct tee_iocl_supp_recv_arg))
 461                return -EINVAL;
 462
 463        uarg = u64_to_user_ptr(buf.buf_ptr);
 464        if (get_user(num_params, &uarg->num_params))
 465                return -EFAULT;
 466
 467        if (sizeof(*uarg) + TEE_IOCTL_PARAM_SIZE(num_params) != buf.buf_len)
 468                return -EINVAL;
 469
 470        params = kcalloc(num_params, sizeof(struct tee_param), GFP_KERNEL);
 471        if (!params)
 472                return -ENOMEM;
 473
 474        rc = ctx->teedev->desc->ops->supp_recv(ctx, &func, &num_params, params);
 475        if (rc)
 476                goto out;
 477
 478        if (put_user(func, &uarg->func) ||
 479            put_user(num_params, &uarg->num_params)) {
 480                rc = -EFAULT;
 481                goto out;
 482        }
 483
 484        rc = params_to_supp(ctx, uarg->params, num_params, params);
 485out:
 486        kfree(params);
 487        return rc;
 488}
 489
 490static int params_from_supp(struct tee_param *params, size_t num_params,
 491                            struct tee_ioctl_param __user *uparams)
 492{
 493        size_t n;
 494
 495        for (n = 0; n < num_params; n++) {
 496                struct tee_param *p = params + n;
 497                struct tee_ioctl_param ip;
 498
 499                if (copy_from_user(&ip, uparams + n, sizeof(ip)))
 500                        return -EFAULT;
 501
 502                /* All unused attribute bits has to be zero */
 503                if (ip.attr & ~TEE_IOCTL_PARAM_ATTR_TYPE_MASK)
 504                        return -EINVAL;
 505
 506                p->attr = ip.attr;
 507                switch (ip.attr) {
 508                case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
 509                case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
 510                        /* Only out and in/out values can be updated */
 511                        p->u.value.a = ip.a;
 512                        p->u.value.b = ip.b;
 513                        p->u.value.c = ip.c;
 514                        break;
 515                case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
 516                case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
 517                        /*
 518                         * Only the size of the memref can be updated.
 519                         * Since we don't have access to the original
 520                         * parameters here, only store the supplied size.
 521                         * The driver will copy the updated size into the
 522                         * original parameters.
 523                         */
 524                        p->u.memref.shm = NULL;
 525                        p->u.memref.shm_offs = 0;
 526                        p->u.memref.size = ip.b;
 527                        break;
 528                default:
 529                        memset(&p->u, 0, sizeof(p->u));
 530                        break;
 531                }
 532        }
 533        return 0;
 534}
 535
 536static int tee_ioctl_supp_send(struct tee_context *ctx,
 537                               struct tee_ioctl_buf_data __user *ubuf)
 538{
 539        long rc;
 540        struct tee_ioctl_buf_data buf;
 541        struct tee_iocl_supp_send_arg __user *uarg;
 542        struct tee_param *params;
 543        u32 num_params;
 544        u32 ret;
 545
 546        /* Not valid for this driver */
 547        if (!ctx->teedev->desc->ops->supp_send)
 548                return -EINVAL;
 549
 550        if (copy_from_user(&buf, ubuf, sizeof(buf)))
 551                return -EFAULT;
 552
 553        if (buf.buf_len > TEE_MAX_ARG_SIZE ||
 554            buf.buf_len < sizeof(struct tee_iocl_supp_send_arg))
 555                return -EINVAL;
 556
 557        uarg = u64_to_user_ptr(buf.buf_ptr);
 558        if (get_user(ret, &uarg->ret) ||
 559            get_user(num_params, &uarg->num_params))
 560                return -EFAULT;
 561
 562        if (sizeof(*uarg) + TEE_IOCTL_PARAM_SIZE(num_params) > buf.buf_len)
 563                return -EINVAL;
 564
 565        params = kcalloc(num_params, sizeof(struct tee_param), GFP_KERNEL);
 566        if (!params)
 567                return -ENOMEM;
 568
 569        rc = params_from_supp(params, num_params, uarg->params);
 570        if (rc)
 571                goto out;
 572
 573        rc = ctx->teedev->desc->ops->supp_send(ctx, ret, num_params, params);
 574out:
 575        kfree(params);
 576        return rc;
 577}
 578
 579static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 580{
 581        struct tee_context *ctx = filp->private_data;
 582        void __user *uarg = (void __user *)arg;
 583
 584        switch (cmd) {
 585        case TEE_IOC_VERSION:
 586                return tee_ioctl_version(ctx, uarg);
 587        case TEE_IOC_SHM_ALLOC:
 588                return tee_ioctl_shm_alloc(ctx, uarg);
 589        case TEE_IOC_OPEN_SESSION:
 590                return tee_ioctl_open_session(ctx, uarg);
 591        case TEE_IOC_INVOKE:
 592                return tee_ioctl_invoke(ctx, uarg);
 593        case TEE_IOC_CANCEL:
 594                return tee_ioctl_cancel(ctx, uarg);
 595        case TEE_IOC_CLOSE_SESSION:
 596                return tee_ioctl_close_session(ctx, uarg);
 597        case TEE_IOC_SUPPL_RECV:
 598                return tee_ioctl_supp_recv(ctx, uarg);
 599        case TEE_IOC_SUPPL_SEND:
 600                return tee_ioctl_supp_send(ctx, uarg);
 601        default:
 602                return -EINVAL;
 603        }
 604}
 605
 606static const struct file_operations tee_fops = {
 607        .owner = THIS_MODULE,
 608        .open = tee_open,
 609        .release = tee_release,
 610        .unlocked_ioctl = tee_ioctl,
 611        .compat_ioctl = tee_ioctl,
 612};
 613
 614static void tee_release_device(struct device *dev)
 615{
 616        struct tee_device *teedev = container_of(dev, struct tee_device, dev);
 617
 618        spin_lock(&driver_lock);
 619        clear_bit(teedev->id, dev_mask);
 620        spin_unlock(&driver_lock);
 621        mutex_destroy(&teedev->mutex);
 622        idr_destroy(&teedev->idr);
 623        kfree(teedev);
 624}
 625
 626/**
 627 * tee_device_alloc() - Allocate a new struct tee_device instance
 628 * @teedesc:    Descriptor for this driver
 629 * @dev:        Parent device for this device
 630 * @pool:       Shared memory pool, NULL if not used
 631 * @driver_data: Private driver data for this device
 632 *
 633 * Allocates a new struct tee_device instance. The device is
 634 * removed by tee_device_unregister().
 635 *
 636 * @returns a pointer to a 'struct tee_device' or an ERR_PTR on failure
 637 */
 638struct tee_device *tee_device_alloc(const struct tee_desc *teedesc,
 639                                    struct device *dev,
 640                                    struct tee_shm_pool *pool,
 641                                    void *driver_data)
 642{
 643        struct tee_device *teedev;
 644        void *ret;
 645        int rc;
 646        int offs = 0;
 647
 648        if (!teedesc || !teedesc->name || !teedesc->ops ||
 649            !teedesc->ops->get_version || !teedesc->ops->open ||
 650            !teedesc->ops->release || !pool)
 651                return ERR_PTR(-EINVAL);
 652
 653        teedev = kzalloc(sizeof(*teedev), GFP_KERNEL);
 654        if (!teedev) {
 655                ret = ERR_PTR(-ENOMEM);
 656                goto err;
 657        }
 658
 659        if (teedesc->flags & TEE_DESC_PRIVILEGED)
 660                offs = TEE_NUM_DEVICES / 2;
 661
 662        spin_lock(&driver_lock);
 663        teedev->id = find_next_zero_bit(dev_mask, TEE_NUM_DEVICES, offs);
 664        if (teedev->id < TEE_NUM_DEVICES)
 665                set_bit(teedev->id, dev_mask);
 666        spin_unlock(&driver_lock);
 667
 668        if (teedev->id >= TEE_NUM_DEVICES) {
 669                ret = ERR_PTR(-ENOMEM);
 670                goto err;
 671        }
 672
 673        snprintf(teedev->name, sizeof(teedev->name), "tee%s%d",
 674                 teedesc->flags & TEE_DESC_PRIVILEGED ? "priv" : "",
 675                 teedev->id - offs);
 676
 677        teedev->dev.class = tee_class;
 678        teedev->dev.release = tee_release_device;
 679        teedev->dev.parent = dev;
 680
 681        teedev->dev.devt = MKDEV(MAJOR(tee_devt), teedev->id);
 682
 683        rc = dev_set_name(&teedev->dev, "%s", teedev->name);
 684        if (rc) {
 685                ret = ERR_PTR(rc);
 686                goto err_devt;
 687        }
 688
 689        cdev_init(&teedev->cdev, &tee_fops);
 690        teedev->cdev.owner = teedesc->owner;
 691        teedev->cdev.kobj.parent = &teedev->dev.kobj;
 692
 693        dev_set_drvdata(&teedev->dev, driver_data);
 694        device_initialize(&teedev->dev);
 695
 696        /* 1 as tee_device_unregister() does one final tee_device_put() */
 697        teedev->num_users = 1;
 698        init_completion(&teedev->c_no_users);
 699        mutex_init(&teedev->mutex);
 700        idr_init(&teedev->idr);
 701
 702        teedev->desc = teedesc;
 703        teedev->pool = pool;
 704
 705        return teedev;
 706err_devt:
 707        unregister_chrdev_region(teedev->dev.devt, 1);
 708err:
 709        pr_err("could not register %s driver\n",
 710               teedesc->flags & TEE_DESC_PRIVILEGED ? "privileged" : "client");
 711        if (teedev && teedev->id < TEE_NUM_DEVICES) {
 712                spin_lock(&driver_lock);
 713                clear_bit(teedev->id, dev_mask);
 714                spin_unlock(&driver_lock);
 715        }
 716        kfree(teedev);
 717        return ret;
 718}
 719EXPORT_SYMBOL_GPL(tee_device_alloc);
 720
 721static ssize_t implementation_id_show(struct device *dev,
 722                                      struct device_attribute *attr, char *buf)
 723{
 724        struct tee_device *teedev = container_of(dev, struct tee_device, dev);
 725        struct tee_ioctl_version_data vers;
 726
 727        teedev->desc->ops->get_version(teedev, &vers);
 728        return scnprintf(buf, PAGE_SIZE, "%d\n", vers.impl_id);
 729}
 730static DEVICE_ATTR_RO(implementation_id);
 731
 732static struct attribute *tee_dev_attrs[] = {
 733        &dev_attr_implementation_id.attr,
 734        NULL
 735};
 736
 737static const struct attribute_group tee_dev_group = {
 738        .attrs = tee_dev_attrs,
 739};
 740
 741/**
 742 * tee_device_register() - Registers a TEE device
 743 * @teedev:     Device to register
 744 *
 745 * tee_device_unregister() need to be called to remove the @teedev if
 746 * this function fails.
 747 *
 748 * @returns < 0 on failure
 749 */
 750int tee_device_register(struct tee_device *teedev)
 751{
 752        int rc;
 753
 754        if (teedev->flags & TEE_DEVICE_FLAG_REGISTERED) {
 755                dev_err(&teedev->dev, "attempt to register twice\n");
 756                return -EINVAL;
 757        }
 758
 759        rc = cdev_add(&teedev->cdev, teedev->dev.devt, 1);
 760        if (rc) {
 761                dev_err(&teedev->dev,
 762                        "unable to cdev_add() %s, major %d, minor %d, err=%d\n",
 763                        teedev->name, MAJOR(teedev->dev.devt),
 764                        MINOR(teedev->dev.devt), rc);
 765                return rc;
 766        }
 767
 768        rc = device_add(&teedev->dev);
 769        if (rc) {
 770                dev_err(&teedev->dev,
 771                        "unable to device_add() %s, major %d, minor %d, err=%d\n",
 772                        teedev->name, MAJOR(teedev->dev.devt),
 773                        MINOR(teedev->dev.devt), rc);
 774                goto err_device_add;
 775        }
 776
 777        rc = sysfs_create_group(&teedev->dev.kobj, &tee_dev_group);
 778        if (rc) {
 779                dev_err(&teedev->dev,
 780                        "failed to create sysfs attributes, err=%d\n", rc);
 781                goto err_sysfs_create_group;
 782        }
 783
 784        teedev->flags |= TEE_DEVICE_FLAG_REGISTERED;
 785        return 0;
 786
 787err_sysfs_create_group:
 788        device_del(&teedev->dev);
 789err_device_add:
 790        cdev_del(&teedev->cdev);
 791        return rc;
 792}
 793EXPORT_SYMBOL_GPL(tee_device_register);
 794
 795void tee_device_put(struct tee_device *teedev)
 796{
 797        mutex_lock(&teedev->mutex);
 798        /* Shouldn't put in this state */
 799        if (!WARN_ON(!teedev->desc)) {
 800                teedev->num_users--;
 801                if (!teedev->num_users) {
 802                        teedev->desc = NULL;
 803                        complete(&teedev->c_no_users);
 804                }
 805        }
 806        mutex_unlock(&teedev->mutex);
 807}
 808
 809bool tee_device_get(struct tee_device *teedev)
 810{
 811        mutex_lock(&teedev->mutex);
 812        if (!teedev->desc) {
 813                mutex_unlock(&teedev->mutex);
 814                return false;
 815        }
 816        teedev->num_users++;
 817        mutex_unlock(&teedev->mutex);
 818        return true;
 819}
 820
 821/**
 822 * tee_device_unregister() - Removes a TEE device
 823 * @teedev:     Device to unregister
 824 *
 825 * This function should be called to remove the @teedev even if
 826 * tee_device_register() hasn't been called yet. Does nothing if
 827 * @teedev is NULL.
 828 */
 829void tee_device_unregister(struct tee_device *teedev)
 830{
 831        if (!teedev)
 832                return;
 833
 834        if (teedev->flags & TEE_DEVICE_FLAG_REGISTERED) {
 835                sysfs_remove_group(&teedev->dev.kobj, &tee_dev_group);
 836                cdev_del(&teedev->cdev);
 837                device_del(&teedev->dev);
 838        }
 839
 840        tee_device_put(teedev);
 841        wait_for_completion(&teedev->c_no_users);
 842
 843        /*
 844         * No need to take a mutex any longer now since teedev->desc was
 845         * set to NULL before teedev->c_no_users was completed.
 846         */
 847
 848        teedev->pool = NULL;
 849
 850        put_device(&teedev->dev);
 851}
 852EXPORT_SYMBOL_GPL(tee_device_unregister);
 853
 854/**
 855 * tee_get_drvdata() - Return driver_data pointer
 856 * @teedev:     Device containing the driver_data pointer
 857 * @returns the driver_data pointer supplied to tee_register().
 858 */
 859void *tee_get_drvdata(struct tee_device *teedev)
 860{
 861        return dev_get_drvdata(&teedev->dev);
 862}
 863EXPORT_SYMBOL_GPL(tee_get_drvdata);
 864
 865static int __init tee_init(void)
 866{
 867        int rc;
 868
 869        tee_class = class_create(THIS_MODULE, "tee");
 870        if (IS_ERR(tee_class)) {
 871                pr_err("couldn't create class\n");
 872                return PTR_ERR(tee_class);
 873        }
 874
 875        rc = alloc_chrdev_region(&tee_devt, 0, TEE_NUM_DEVICES, "tee");
 876        if (rc) {
 877                pr_err("failed to allocate char dev region\n");
 878                class_destroy(tee_class);
 879                tee_class = NULL;
 880        }
 881
 882        return rc;
 883}
 884
 885static void __exit tee_exit(void)
 886{
 887        class_destroy(tee_class);
 888        tee_class = NULL;
 889        unregister_chrdev_region(tee_devt, TEE_NUM_DEVICES);
 890}
 891
 892subsys_initcall(tee_init);
 893module_exit(tee_exit);
 894
 895MODULE_AUTHOR("Linaro");
 896MODULE_DESCRIPTION("TEE Driver");
 897MODULE_VERSION("1.0");
 898MODULE_LICENSE("GPL v2");
 899