-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] Dynamic shared memory implementation. #1232
Conversation
Checkpatch have failed two times. But one error looks like a bug in checkpatch (or I don't understand what it wants from me). Another message is about long line. But there are string constants, which should not be divided into two parts (because string constant division also triggers checkpatch error). |
@@ -69,7 +69,7 @@ | |||
#define TEE_MMU_L1_ALIGNMENT TEE_MMU_L1_SIZE | |||
|
|||
#define TEE_MMU_L2_NUM_ENTRIES (TEE_MMU_L2_SIZE / 4) | |||
#define TEE_MMU_L2_SIZE (1 << 10) | |||
#define TEE_MMU_L2_SIZE (1 << 13) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RES_VASPACE_SIZE is 10MB, so the L2 entries is not enough here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the size of a nonlpae L2 table. should remain 1KByte.
core/arch/arm/mm/shmem.c
Outdated
unsigned int idx; | ||
|
||
while (true) { | ||
if (!core_mmu_find_table(vaddr, 99, &tbl_info)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use UINT_MAX instead of 99.
core/arch/arm/mm/shmem.c
Outdated
* TEE_ERROR_XXX - on error | ||
*/ | ||
|
||
int shmem_map_buffer(paddr_t pa, size_t size, paddr_t *pages, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The page list dynamic mapping is a common function, can we introduce a new function like map_page_list, and the shmem_map_buffer is a wrapper function of the map_page_list here?
Please create a new PR for the first 6 patches. They look quite easy and shouldn't take much time to review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some comment.
This changes enables registered shm for the core, but not yet the TAs, right?
core/arch/arm/mm/shmem.c
Outdated
bool shmem_contains_region_pa(paddr_t pa, size_t size) | ||
{ | ||
bool result = false; | ||
struct shmem_mapping *area = NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: no need to init area
core/arch/arm/mm/shmem.c
Outdated
{ | ||
while (size) { | ||
if (shmem_contains_region_pa(pa, (size < SMALL_PAGE_SIZE) ? size | ||
: SMALL_PAGE_SIZE)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor style?: :
before newline.
core/arch/arm/mm/core_mmu.c
Outdated
va = map_pa2va(find_map_by_type_and_pa(m, pa), pa); | ||
if (!va) | ||
va = shmem_pa2va(pa); | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you really need this ? not simply case MEM_AREA_SHM_VASPACE: va = shmem_pa2va(pa); break;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
core/arch/arm/mm/shmem.c
Outdated
|
||
/** | ||
* struct shmem_mapping - informaion about shared buffer | ||
* @next: next elemein in linked list |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: s/elemein/element/
core/arch/arm/mm/shmem.c
Outdated
* @pages_cnt: Number of mapped pages | ||
* @pages: Addresses of pages that hold this buffer. Actually we are not | ||
* obligued to store page addresses there, because we can get them | ||
* from MMU. But this aproach simplifies code a lot. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: s/obligued/obliged/ + s/aproach/approach/
core/arch/arm/mm/shmem.c
Outdated
/* Special case for last page */ | ||
if (area->pages_cnt > 1 && | ||
pa >= area->pages[area->pages_cnt-1] && | ||
pa < (area->pages[area->pages_cnt-1] + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: spaces around -
in the 2 lines above.
core/arch/arm/mm/shmem.c
Outdated
return area; | ||
|
||
/* All other cases are trivial */ | ||
for (int i = 1; i < area->pages_cnt-1; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: move 'int i' definition to block top, spaces around -
core/arch/arm/mm/shmem.c
Outdated
core_mmu_set_entry(&tbl_info, idx, 0, TEE_MATTR_HIDDEN_BLOCK); | ||
vaddr += SMALL_PAGE_SIZE; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mapping table allocated at map stage are never freed here.
there sould rather be a generic core_mmu.c routine for runtime mapping+table(s) alloc and unmapping+table(s) release.
core/include/mm/tee_mm.h
Outdated
@@ -62,6 +62,9 @@ extern tee_mm_pool_t tee_mm_sec_ddr; | |||
/* Virtual eSRAM pool */ | |||
extern tee_mm_pool_t tee_mm_vcore; | |||
|
|||
/* Shared memory pool */ | |||
extern tee_mm_pool_t tee_mm_shm __early_bss; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: __early_bss
not needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
@@ -69,7 +69,7 @@ | |||
#define TEE_MMU_L1_ALIGNMENT TEE_MMU_L1_SIZE | |||
|
|||
#define TEE_MMU_L2_NUM_ENTRIES (TEE_MMU_L2_SIZE / 4) | |||
#define TEE_MMU_L2_SIZE (1 << 10) | |||
#define TEE_MMU_L2_SIZE (1 << 13) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the size of a nonlpae L2 table. should remain 1KByte.
Please rebase this now that all prerequisites are in place. |
e1117ee
to
623fb56
Compare
Patches was rebased on master branch. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this looks good. I suspect that it depends on CFG_SMALL_PAGE_USER_TA=y
for mapping of TA parameters.
It looks like struct shmem_mapping
and struct mobj_reg_shm
overlaps a bit. What if all shared memory dealings where based on MOBJS? We could have yet another MOBJ class adding what's missing from struct shmem_mapping
to struct mobj_reg_shm
or some other base class.
core/arch/arm/kernel/thread.c
Outdated
} | ||
|
||
if (!check_alloced_shm(pa, size, sizeof(uint64_t))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function will return false
if core_pbuf_is(CORE_MEM_NSEC_SHM, pa, size)
returns false
.
core/arch/arm/mm/core_mmu.c
Outdated
core_mmu_find_table(vaddr, UINT_MAX, &tbl_info); | ||
idx = core_mmu_va2idx(&tbl_info, vaddr); | ||
core_mmu_set_entry(&tbl_info, idx, 0, | ||
TEE_MATTR_HIDDEN_BLOCK); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0
would be more appropriate than TEE_MATTR_HIDDEN_BLOCK
. Hidden block is something used by the pager.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0
would be more appropriate than TEE_MATTR_HIDDEN_BLOCK
. Hidden block is something used by the pager.
core/arch/arm/mm/core_mmu.c
Outdated
va = map_pa2va(find_map_by_type_and_pa(m, pa), pa); | ||
if (!va) | ||
va = shmem_pa2va(pa); | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
core/arch/arm/tee/entry_std.c
Outdated
if (arg == NULL) | ||
goto err; | ||
|
||
num_params = arg->num_params; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
num_params
will be read once again in tee_entry_std()
below after this function has returned. What if normal world succeeds in using this window to increase num_params
?
core/include/mm/tee_mm.h
Outdated
@@ -62,6 +62,9 @@ extern tee_mm_pool_t tee_mm_sec_ddr; | |||
/* Virtual eSRAM pool */ | |||
extern tee_mm_pool_t tee_mm_vcore; | |||
|
|||
/* Shared memory pool */ | |||
extern tee_mm_pool_t tee_mm_shm __early_bss; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
core/include/optee_msg.h
Outdated
* Special parameter type denoting that command buffer continues on | ||
* specified page | ||
*/ | ||
#define OPTEE_MSG_ATTR_TYPE_NEXT_FRAGMENT 0xc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This together with OPTEE_MSG_ATTR_NESTED
is quite complicated. To make it easier to understand please describe how they can be used in one or two example use cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This provides ability to map discontiguous SHM (registered or rpc-allocated) into OP-TEE core but not into TAs. Do you plan to support such SHM in TA ? or I am wrong?
core/arch/arm/kernel/thread.c
Outdated
thread_rpc_free_arg(co); | ||
pa = 0; | ||
co = 0; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If needing to call a RPC to allocate discontiguous buffer, I think RPC should rather have NonSecure allocating the buffer, registering it to OP-TEE core and then returning to RPC allocation caller with the registered buffer ID. For the RPC basic communication, default SHM is ok, no real need to complexify with pure "registered" SHM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be the use case where a TA is loaded.
For normal world to call back and register an SHM, it would need yet another thread in secure world as we don't support calling back from an RPC on the same thread.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, understood.
@jenswi-linaro , I tried to dump all Also, I don't know what to do with checks like |
@lorc & @jenswi-linaro, regarding For example, at core entry, nonsecure provides a buffer location (eventually a list of physical chunks) to be handled as a shm buffer. The core must verify each physical location against authorized SHM locations before creating a "mobj" for the buffer. |
I agree, |
Sorry for late answer, I was on sick leave. @etienne-lms, my idea was to put I'm asking because I had removed Anyway, code in |
hi @lorc , hope you feel better.
I agree, This is the best way. Get a mobj and once ok only rely on the mobj API. With your proposal, you plan to create a mobj for each of the physically contiguous chunks of the registered shm ? I rather like the proposal from Jens to extend mobj to support physically discontiguous memory and hide this complexity behind inside the mobj layer (easy to say but I'm not sure it is less complex to implement/maintain :). |
Hi all, There is a new version of registered SHM. I get rid of shmem.c and moved all code to mobjs, including code in |
@@ -221,7 +221,7 @@ | |||
#endif | |||
|
|||
#define DRAM0_BASE UINTPTR_C(0x40000000) | |||
#define DRAM0_SIZE (UINTPTR_C(0x40000000) - CFG_SHMEM_SIZE) | |||
#define DRAM0_SIZE (UINTPTR_C(0x42100000) - CFG_SHMEM_SIZE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather update build/qemu_v8.mk
.
Long term we could read (or supplement) the DRAM config from DT on the QEMU platforms.
core/arch/arm/include/sm/optee_smc.h
Outdated
* Privileged call flag. Used by supplicant. Asks OP-TEE to use reserved | ||
* thread if all regular threads are used. | ||
*/ | ||
#define OPTEE_SMC_FLAGS_PRIVILEGED BIT(0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't waste that much memory for this. There has to be some other way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean that you don't want to allocate whole register for flags? Possibly we can pass flag in r0 then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I'm concerned about the stack.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see. We need 3 pages per thread for stack, right? This feature will require one extra thread, so additional 12Kb of memory will be used. Is this too much?
I can imagine another approach: save context (and stack) of a suspended thread to dynamically allocated buffer and use that thread for a privileged call. But what if we couldn't allocate buffer for context? There will be deadlock.
Another approach is to try to squeeze privileged thread stack into one of the suspended thread's stack. But this is also prone to problems with the stack size.
Probably we can forbid STD SMC calls from a RPC call. Then there will be no need to a privileged thread. But in that case we will need another call path to register SHM in a RPC request. I had that solution (maybe you remember OPTEE_MSG_ATTR_TYPE_NEXT_NESTED
) in earlier versions of the pacthes. But there was the extra param type (NESTED
one), additional logic, etc, etc. I didn't liked it, so I choose simpler approach with existing shared memory calls.
Maybe you have ideas on how to avoid deadlock?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One extra privileged thread isn't enough, one extra privileged thread per normal thread is actually needed to avoid deadlocks. That also lead me into the idea that if during RPC registering of SHM is needed it can be done using the suspended thread currently doing the RPC. If we only allow registration of SHM in this case I don't think we'll have a problem with stack overruns.
However, it will result in some extra ping-pong and it may be a bit complicated to find out which thread did the RPC and do a call inside that.
I'm afraid I've forgotten how OPTEE_MSG_ATTR_TYPE_NEXT_NESTED
worked, but I think the best solution would be to let the return of OPTEE_MSG_RPC_CMD_SHM_ALLOC
to carry the information needed to register the shared memory. Do you really needed OPTEE_MSG_ATTR_TYPE_NEXT_NESTED
for that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose it's possible with careful programming to avoid needing more than one reserved thread, but that means constantly being aware of this restriction and thus accumulating technical debt. Since this will affect the ABI it's important to get it right from the start.
But regardless wasting 8k for this is too much, especially since there's other options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I can see it, one thread will be enough in all cases except case when privileged thread will issue own RPC. That is the biggest problem in my opinion.
Can we allocate stack dynamically with malloc()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that it's a big problem as it can occur when taking a mutex. :-)
To allocate the stack with malloc()
is likely to fail due to fragmented heap (8k is a significant part of ~32k).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, point taken. Generally speaking, RPC handling code should not issue OP-TEE calls because this calls can lead to more RPCs.
But in this particular situation with SHM we can:
a) make exception for special register_shm
call
b) rework the way how results are returned from RPC
Variant a) leads to alterations to tasker/scheduler code. Variant b) leads to more complex ABI between OP-TEE, kernel driver and supplicant. I prefer b) because I did it once.
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer b) too.
@jenswi-linaro I had reworked this in a way you asked. I have added a new parameter type and corresponding logic in |
core/arch/arm/include/kernel/misc.h
Outdated
size_t get_core_pos(void); | ||
|
||
uint32_t read_mode_sp(int cpu_mode); | ||
uint32_t read_mode_lr(int cpu_mode); | ||
|
||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These functions should go into a .h file with a better name, they should also have a proper prefix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please suggest file name and prefix? They used in both std_entry.c
and thread.c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
msg_param
could be used as both prefix and basename of the file.
extract_pages_from_params()
would then become msg_param_extract_pages()
and so on.
core/arch/arm/kernel/misc.c
Outdated
@@ -0,0 +1,242 @@ | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please choose a better file name for these functions.
core/arch/arm/kernel/thread.c
Outdated
args->a0 = OPTEE_SMC_RETURN_ENOMEM; | ||
return; | ||
} | ||
|
||
arg = mobj_get_va(mobj, 0); | ||
if (!arg || !mobj_is_nonsec(mobj)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be enough to assert this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
core/arch/arm/kernel/thread.c
Outdated
if (!parg || !ALIGNMENT_IS_OK(parg, struct optee_msg_arg) || | ||
!(arg = phys_to_virt(parg, MEM_AREA_NSEC_SHM))) { | ||
thread_rpc_free_arg(carg); | ||
&carg); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps the cookie should be stored inside the mobj, but that can be done later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I thought about that. But I don't want to make this change in current PR.
core/arch/arm/kernel/thread.c
Outdated
goto free_first; | ||
} | ||
num_pages = (nested_params[0].u.tmem.size + page_offset - 1) | ||
/ SMALL_PAGE_SIZE + 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please keep the /
on the line above and indent this line properly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
core/arch/arm/tee/entry_std.c
Outdated
return; | ||
} | ||
|
||
arg = mobj_get_va(mobj, 0); | ||
if (!arg || !mobj_is_nonsec(mobj)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't an assert be enough?
core/arch/arm/kernel/misc.c
Outdated
if (!mobj) | ||
goto err; | ||
|
||
params = (struct optee_msg_param *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cast not needed.
core/arch/arm/kernel/misc.c
Outdated
params = (struct optee_msg_param *) | ||
mobj_get_va(mobj, pa_params & SMALL_PAGE_MASK); | ||
pages_cnt = 1; | ||
for (uint32_t i = 0; i < num_params; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please declare local variables at the beginning of a block.
core/arch/arm/kernel/misc.c
Outdated
goto err; | ||
|
||
pages_cnt++; | ||
params = (struct optee_msg_param *)mobj_get_va(mobj, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cast not needed
core/arch/arm/kernel/misc.c
Outdated
params = (struct optee_msg_param *)mobj_get_va(mobj, 0); | ||
} else { | ||
params++; | ||
if (((vaddr_t)params & SMALL_PAGE_MASK) == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It wouldn't hurt with a comment stating that we're checking that we're not overflowing into the next page.
Preferred style is if (!((vaddr_t)params & SMALL_PAGE_MASK))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm agree about comment, but disagree about style in this particular place.
I want to emphasis that we are getting 0
after applying the mask. I think, it is more obvious with == 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree, but it's no big deal. Keep it as is if you think it's important.
Please create a new PR for "spinlock: add cpu_spin_lock_xsave()/xrestore() functions" and |
@jenswi-linaro Thank you for review. Regarding that two patches, there are PR for them: #1356 |
Wouldn't it be more easy if registering SHM reference was using a buffer from the default physically contiguous SHM negotiated at OP-TEE init ? |
I have another idea. As you pointed out we can't use the user space pages to carry the physical pointers. We scrap What this This model isn't too complicated it's the same as what's in use today except that with I think it's important (especially for the virtualization use case) to be able to get rid of the shared memory pool we're using today completely. We can still support the shared memory pool, but it's not a requirement. So how can we deal with a normal invoke with Does it make sense? Can it be simplified further? Am I missing any corner case? |
@jenswi-linaro, thanks for the idea. I'm currently implementing it. Do deal with non-page aligned shared buffer I prefer to store beginning of the shared buffer as the first element of the array. So But I see another problem there: RPC calls. It is easy to allocate buffer for pages array in |
It's not so important where the offset is stored, but I think at least one special case can be removed if it's coded into the lower bits of Regarding the buffer for the pages array for RPC: |
Okay, so I decided to do as you say and store offset in So, there are v5 delta. To produce #1527 I had to squash v1-v4 deltas and rebase to the master branch. Patch for the kernel is on the way. |
Looks good. :-) I've added a few comments in the "v5 delta". Only misunderstanding is that I'd like
|
@jenswi-linaro, thanks for the review. I had pushed v6 delta. I want to clarify |
Yes, |
@jenswi-linaro, thanks for the clarification.
|
Issue 1: Issue 2: |
Hi @jenswi-linaro, As for that two issues: Issue 1: I also think that pointer value should not be updated, but optee driver does this for some reason. |
Thanks @lorc Issue 2: sounds good. I'll not be able to do much reviewing this week, but next week I'll prioritize this. |
This patch adds various helper functions to manipulate with parameters passed to/from normal world. Also it introduces new optee_param type which is used to pass long lists of parameters. Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
This is quite large patch, that enables registered shared memory support. Main idea is that normal world can provide own pages for shared memory. So there are two new calls: OPTEE_MSG_CMD_REGISTER_SHM and OPTEE_MSG_CMD_UNREGISTER_SHM. Also, OPTEE_MSG_RPC_CMD_SHM_ALLOC can return registered shared buffer. To ease up use of such buffers all code that uses them is moved to mobjs. That means that TA loader, fs_rpc, sockets, etc all use mobjs to represent shared buffers instead of simple paddr_t. Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
reworked ABI for registered SHM and RPC calls. Removed OPTEE_MSG_ATTR_TYPE_NESTED and OPTEE_MSG_ATTR_FRAGMENT, added OPTEE_MSG_ATTR_TYPE_NONCONTIG. Now "register SHM" and "alloc mem" RPC are handled in the same way. List of pages is stored as plain array of 64 bit values. Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
- OPTEE_MSG_ATTR_TYPE_NONCONTIG converted to OPTEE_MSG_ATTR_NONCONTIG: This is flag now, rather than a type. - removed OPTEE_MSG_ATTR_FRAGMENT (forgot to remove in prev commit). Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
- fixed dump mistake with (OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT | OPTEE_MSG_ATTR_TYPE_MASK) instead of (OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT | OPTEE_MSG_ATTR_NONCONTIG) in thread.c - added support for non-contig TMEM references - removed duplicate code that constructed mobjs from non-contig buffers: added msg_param_mobj_from_noncontig_param() function that does the job. Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
mobj_shm represents buffer in predefined SHM region. It is used as fallback, when dynamic SHM is disabled. also removed "#ifdef CFG_SMALL_PAGE_USER_TA" check Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
There was bug in offset calculation: invalid variable was used. Also division remainder was replaced with bitwise and to speed up things a bit. Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. It would be very good if you could break out the part
Also, OPTEE_MSG_RPC_CMD_SHM_ALLOC can return registered shared
buffer. To ease up use of such buffers all code that uses them
is moved to mobjs. That means that TA loader, fs_rpc, sockets, etc
all use mobjs to represent shared buffers instead of simple paddr_t.
And take that in a separate pull request, only the core part of the non-contiguous shared memory would remain after that.
} | ||
|
||
/* We don't need mobj there, we only care if it was created */ | ||
if (!msg_param_mobj_from_noncontig_param(arg->params, false)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update the comment with why this doesn't cause mobj leakage.
|
||
arg = (struct optee_msg_arg *)mobj_get_va(mobj, 0); | ||
if (arg == NULL) { | ||
mobj_free(mobj); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use a cleanup label instead, as:
if (arg)
goto error;
.
.
.
error:
mobj_free(mobj);
return NULL;
@@ -140,15 +144,29 @@ struct optee_msg_param_value { | |||
}; | |||
|
|||
/** | |||
* struct optee_msg_param_nested - nested params |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The nested stuff can be removed
Okay, I created #1582. It includes three patches that I took from this PR. |
During review this PR evolved into something completely different, multiple PRs were detached from it. Current code base does not resemble what was pushed originally. So I decided to close it and push new patches for registered shm in new PRs. |
Hello,
I want to propose new approach for shared memory. Idea is not to use carveout in memory, but to use memory provided by Normal World. Normal World allocates memory at its side and provided list of pages to OP-TEE, so OP-TEE kernel can map them into its virtual space.
This is not the final version, because it should be merged with @jenswi-linaro MOBJs framework. But anyway, it was tested on simple tests. With this approach I was able to number allocate large shared buffers (e.g. 2M each).
There are number of patches in this PR. First patches are quite generic and I can create separate PRs to merge them if maintainers wish. Most important are two last patches: one of them adds shared memory subsystem and second one puts it into use.
There are one problem that is not resolved at this time - we need to list of shared pages to TA memory manager. I hope MOBJs will help with this.
There are corresponding kernel and client changes based on @jenswi-linaro patches for registering shared memory. I'll present them later.