cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

tee_shm_pool.c (2276B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (c) 2015, 2017, 2022 Linaro Limited
      4 */
      5#include <linux/device.h>
      6#include <linux/dma-buf.h>
      7#include <linux/genalloc.h>
      8#include <linux/slab.h>
      9#include <linux/tee_drv.h>
     10#include "tee_private.h"
     11
     12static int pool_op_gen_alloc(struct tee_shm_pool *pool, struct tee_shm *shm,
     13			     size_t size, size_t align)
     14{
     15	unsigned long va;
     16	struct gen_pool *genpool = pool->private_data;
     17	size_t a = max_t(size_t, align, BIT(genpool->min_alloc_order));
     18	struct genpool_data_align data = { .align = a };
     19	size_t s = roundup(size, a);
     20
     21	va = gen_pool_alloc_algo(genpool, s, gen_pool_first_fit_align, &data);
     22	if (!va)
     23		return -ENOMEM;
     24
     25	memset((void *)va, 0, s);
     26	shm->kaddr = (void *)va;
     27	shm->paddr = gen_pool_virt_to_phys(genpool, va);
     28	shm->size = s;
     29	/*
     30	 * This is from a static shared memory pool so no need to register
     31	 * each chunk, and no need to unregister later either.
     32	 */
     33	shm->flags &= ~TEE_SHM_DYNAMIC;
     34	return 0;
     35}
     36
     37static void pool_op_gen_free(struct tee_shm_pool *pool, struct tee_shm *shm)
     38{
     39	gen_pool_free(pool->private_data, (unsigned long)shm->kaddr,
     40		      shm->size);
     41	shm->kaddr = NULL;
     42}
     43
     44static void pool_op_gen_destroy_pool(struct tee_shm_pool *pool)
     45{
     46	gen_pool_destroy(pool->private_data);
     47	kfree(pool);
     48}
     49
     50static const struct tee_shm_pool_ops pool_ops_generic = {
     51	.alloc = pool_op_gen_alloc,
     52	.free = pool_op_gen_free,
     53	.destroy_pool = pool_op_gen_destroy_pool,
     54};
     55
     56struct tee_shm_pool *tee_shm_pool_alloc_res_mem(unsigned long vaddr,
     57						phys_addr_t paddr, size_t size,
     58						int min_alloc_order)
     59{
     60	const size_t page_mask = PAGE_SIZE - 1;
     61	struct tee_shm_pool *pool;
     62	int rc;
     63
     64	/* Start and end must be page aligned */
     65	if (vaddr & page_mask || paddr & page_mask || size & page_mask)
     66		return ERR_PTR(-EINVAL);
     67
     68	pool = kzalloc(sizeof(*pool), GFP_KERNEL);
     69	if (!pool)
     70		return ERR_PTR(-ENOMEM);
     71
     72	pool->private_data = gen_pool_create(min_alloc_order, -1);
     73	if (!pool->private_data) {
     74		rc = -ENOMEM;
     75		goto err;
     76	}
     77
     78	rc = gen_pool_add_virt(pool->private_data, vaddr, paddr, size, -1);
     79	if (rc) {
     80		gen_pool_destroy(pool->private_data);
     81		goto err;
     82	}
     83
     84	pool->ops = &pool_ops_generic;
     85
     86	return pool;
     87err:
     88	kfree(pool);
     89
     90	return ERR_PTR(rc);
     91}
     92EXPORT_SYMBOL_GPL(tee_shm_pool_alloc_res_mem);