1 /*
2  * Copyright (c) 2023 EPAM Systems
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/drivers/tee.h>
8 
tee_add_shm(const struct device * dev,void * addr,size_t align,size_t size,uint32_t flags,struct tee_shm ** shmp)9 int tee_add_shm(const struct device *dev, void *addr, size_t align, size_t size,
10 		uint32_t flags, struct tee_shm **shmp)
11 {
12 	int rc;
13 	void *p = addr;
14 	struct tee_shm *shm;
15 
16 	if (!shmp) {
17 		return -EINVAL;
18 	}
19 
20 	if (flags & TEE_SHM_ALLOC) {
21 		if (align) {
22 			p = k_aligned_alloc(align, size);
23 		} else {
24 			p = k_malloc(size);
25 		}
26 	}
27 
28 	if (!p) {
29 		return -ENOMEM;
30 	}
31 
32 	shm = k_malloc(sizeof(struct tee_shm));
33 	if (!shm) {
34 		rc = -ENOMEM;
35 		goto err;
36 	}
37 
38 	shm->addr = p;
39 	shm->size = size;
40 	shm->flags = flags;
41 	shm->dev = dev;
42 
43 	if (flags & TEE_SHM_REGISTER) {
44 		const struct tee_driver_api *api = (const struct tee_driver_api *)dev->api;
45 
46 		if (!api->shm_register) {
47 			rc = -ENOSYS;
48 			goto err;
49 		}
50 
51 		rc = api->shm_register(dev, shm);
52 		if (rc) {
53 			goto err;
54 		}
55 	}
56 
57 	*shmp = shm;
58 
59 	return 0;
60 err:
61 	k_free(shm);
62 	if (flags & TEE_SHM_ALLOC) {
63 		k_free(p);
64 	}
65 
66 	return rc;
67 }
68 
tee_rm_shm(const struct device * dev,struct tee_shm * shm)69 int tee_rm_shm(const struct device *dev, struct tee_shm *shm)
70 {
71 	int rc = 0;
72 
73 	if (!shm) {
74 		return -EINVAL;
75 	}
76 
77 	if (shm->flags & TEE_SHM_REGISTER) {
78 		const struct tee_driver_api *api = (const struct tee_driver_api *)dev->api;
79 
80 		if (api->shm_unregister) {
81 			/*
82 			 * We don't return immediately if callback returned error,
83 			 * just return this code after cleanup.
84 			 */
85 			rc = api->shm_unregister(dev, shm);
86 		} else {
87 			/*
88 			 * Set ENOSYS is SHM_REGISTER flag was set, but callback
89 			 * is not set.
90 			 */
91 			rc = -ENOSYS;
92 		}
93 	}
94 
95 	if (shm->flags & TEE_SHM_ALLOC) {
96 		k_free(shm->addr);
97 	}
98 
99 	k_free(shm);
100 
101 	return rc;
102 }
103