blob: d1fc51c026fbf2102e99e7590268a1502cfc9d16 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2016, Linaro Limited
*/
#include <kernel/thread.h>
#include <mm/core_memprot.h>
#include <mm/core_mmu.h>
#include <mm/mobj.h>
#include <tee/tee_fs_rpc.h>
void tee_fs_rpc_cache_clear(struct thread_specific_data *tsd)
{
if (tsd->rpc_fs_payload) {
thread_rpc_free_payload(tsd->rpc_fs_payload_cookie,
tsd->rpc_fs_payload_mobj);
tsd->rpc_fs_payload = NULL;
tsd->rpc_fs_payload_cookie = 0;
tsd->rpc_fs_payload_size = 0;
tsd->rpc_fs_payload_mobj = NULL;
}
}
void *tee_fs_rpc_cache_alloc(size_t size, struct mobj **mobj, uint64_t *cookie)
{
struct thread_specific_data *tsd = thread_get_tsd();
size_t sz = size;
uint64_t c = 0;
paddr_t p;
void *va;
if (!size)
return NULL;
/*
* Always allocate in page chunks as normal world allocates payload
* memory as complete pages.
*/
sz = ROUNDUP(size, SMALL_PAGE_SIZE);
if (sz > tsd->rpc_fs_payload_size) {
tee_fs_rpc_cache_clear(tsd);
*mobj = thread_rpc_alloc_payload(sz, &c);
if (!*mobj)
return NULL;
if (mobj_get_pa(*mobj, 0, 0, &p))
goto err;
if (!ALIGNMENT_IS_OK(p, uint64_t))
goto err;
va = mobj_get_va(*mobj, 0);
if (!va)
goto err;
tsd->rpc_fs_payload = va;
tsd->rpc_fs_payload_mobj = *mobj;
tsd->rpc_fs_payload_cookie = c;
tsd->rpc_fs_payload_size = sz;
} else
*mobj = tsd->rpc_fs_payload_mobj;
*cookie = tsd->rpc_fs_payload_cookie;
return tsd->rpc_fs_payload;
err:
thread_rpc_free_payload(c, *mobj);
return NULL;
}
|