-
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
Dynamic allocation of mmu translation tables #7192
base: master
Are you sure you want to change the base?
Conversation
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.
- For "core: allow partially unmapped MEM_AREA_TEE_RAM_RW":
Acked-by: Jerome Forissier <[email protected]>
- For "core: boot_mem: allow NULL pointers while relocating":
Reviewed-by: Jerome Forissier <[email protected]>
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.
For commit "core: boot_mem: keep track of padding", with the minor comment below addressed:
Acked-by: Jerome Forissier <[email protected]>
@@ -39,6 +51,7 @@ struct boot_mem_desc { | |||
vaddr_t mem_start; | |||
vaddr_t mem_end; | |||
struct boot_mem_reloc *reloc; | |||
struct boot_mem_padding *padding; |
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.
Add @padding
to the documentation
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'll update
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.
For "core: arm: add boot mem paddings to the heap":
Acked-by: Jerome Forissier <[email protected]>
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.
For "core: mm: extend temporary dummy memory map":
Acked-by: Jerome Forissier <[email protected]>
core/arch/arm/mm/core_mmu_lpae.c
Outdated
* entry1 | ||
* entry2 | ||
* entry3 | ||
* core0: table1: entry (maps only EL0) |
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 mean entry0
here? Or is it on purpose to differentiate from entry0
while entry1
etc. are the same in both tables?
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's a typo, it should be entry0
. I'll update the comment.
|
Unless paging is enabled, |
Ping? |
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.
Reviewed-by: Etienne Carriere <[email protected]>
for commits
"core: allow partially unmapped MEM_AREA_TEE_RAM_RW",
"core: boot_mem: allow NULL pointers while relocating",
"core: boot_mem: keep track of padding" (with a minor comment to address and a free suggestion),
"core: arm: add boot mem paddings to the heap" and
"core: mm: extend temporary dummy memory map".
I'm still looking at the remaining commits.
(edited)
core/mm/boot_mem.c
Outdated
/* | ||
* struct boot_mem_padding - unused memory between allocations | ||
* @start: Start of padding | ||
* @start: Length of padding |
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.
s/start/len/
core/arch/arm/mm/core_mmu_v7.c
Outdated
p = boot_mem_alloc(SMALL_PAGE_SIZE, SMALL_PAGE_SIZE); | ||
if (prtn->last_l2_page) | ||
assert(prtn->last_l2_page + SMALL_PAGE_SIZE == | ||
p); |
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.
at this stage prtn->last_l2_page
is always 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.
Good catch, I'll remove the if and assert. This was a leftover from a previous version.
assert(prtn->last_l2_page + SMALL_PAGE_SIZE == | ||
p); | ||
if (!prtn->tables_used) | ||
boot_mem_add_reloc(&prtn->last_l2_page); |
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.
IIUC this allows only a single chunk of 4 32bit MMU page table references. Isn't it an issue?
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's OK. I'll add this comment:
/*
* L2 tables are allocated four at a time as a 4k
* page. The pointer prtn->last_l2_page keeps track
* of that page until all the l2 tables has been
* used. That pointer may need to be relocated when
* the MMU is enabled so the address of the pointer
* is recorded, but it must only be recorded once.
*
* The already used 4k pages are only referenced
* via recorded physical addresses in the l1 table
* so those pointers don't need to be updated for
* relocation.
*/
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.
Right, crystal clear. Thanks.
s/has been/have been/
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.
Comment addressed.
@@ -214,19 +217,23 @@ static l2_xlat_tbl_t main_mmu_l2_ttb[MAX_XLAT_TABLES] | |||
/* MMU L1 table for TAs, one for each thread */ | |||
static ul1_xlat_tbl_t main_mmu_ul1_ttb[CFG_NUM_THREADS] | |||
__aligned(UL1_ALIGNMENT) __section(".nozi.mmu.ul1"); | |||
#endif | |||
|
|||
struct mmu_partition { |
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.
Would you be ok to add an inline description as you've added in the LPAE implementation, something like:
/*
* struct mmu_partition - core virtual memory tables
* @l1_table: Level 1 translation tables base address
* @l2_table: Level 2 translation tables base address (CFG_DYN_CONFIG=n)
* @last_l2_page: Pre-allocated Level 2 table chunk (CFG_DYN_CONFIG=y)
* @ul1_tables: Level 1 translation tab le for EL0 mapping
* @tables_used: Number of level 2 tables already used
*/
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.
Sure, thanks.
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.
Comment addressed.
@@ -158,6 +200,33 @@ void *boot_mem_alloc_tmp(size_t len, size_t align) | |||
return mem_alloc_tmp(boot_mem_desc, len, align); | |||
} | |||
|
|||
void boot_mem_foreach_padding(bool (*func)(vaddr_t va, size_t len, void *ptr), |
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.
Maybe add a little helper inline description telling that this function call func()
for each registered padding instance and unregisters (consumes) it when the func()
return true
.
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
Update |
Update. |
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.
Comments for commit "core: arm: mm: refactor LPAE translation table handling".
* | ||
* TTBR is assigned a base translation table of NUM_BASE_LEVEL_ENTRIES | ||
* entries. NUM_BASE_LEVEL_ENTRIES is determined based on | ||
* CFG_LPAE_ADDR_SPACE_BITS. CFG_LPAE_ADDR_SPACE_BITS is by default 32 |
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.
nitpicking: 2 space chars
core/arch/arm/mm/core_mmu_lpae.c
Outdated
* EL0 where EL1 is unmapped except for a minimal trampoline needed to | ||
* restore EL1 mappings on exception from EL0. | ||
* | ||
* Each CPU core is assign a unique set of base translation tables as: |
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.
s/assign/assigned/
{ | ||
size_t idx = 0; | ||
|
||
idx = ((vaddr_t)tbl - (vaddr_t)prtn->xlat_tables) / XLAT_TABLE_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.
Previous implementation used &tbl[user_va_idx]
not tbl
.
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, but I think it was incorrect. user_va_idx
is typically 1
so that would give the address of the second entry in the translation table. That difference is lost with the division so it doesn't harm except that it's confusing.
core/arch/arm/mm/core_mmu_lpae.c
Outdated
|
||
idx = ((vaddr_t)tbl - (vaddr_t)prtn->xlat_tables) / XLAT_TABLE_SIZE; | ||
if (idx > MAX_XLAT_TABLES) | ||
panic(); |
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 previous implementation tested idx
index against the number of tables already consumed (prtn->xlat_table_used
). It is intentional to allow up to MAX_XLAT_TABLES
now?
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.
Good catch, I'll restore the assert().
I'm having my doubts about this array of indices. With a hardcoded limit, it's easy to ensure that the index type is wide enough, but with a more dynamic approach, we may be better off with pointers. It's also slightly less complicated and that should be welcome in this file. If you have a VA space larger than 39 bits, you can afford 6-7 extra bytes per CPU (in addition to the extra 4k page needed). The decision can wait until we have a dynamic configuration of the number of cores.
Update |
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.
Reviewed-by: Etienne Carriere <[email protected]>
for commit
"core: arm: mm: dynamic allocation of LPAE translation tables".
Commit "core: arm: mm: dynamic allocation of v7 translation tables" looks good to me once comments are addressed. Feel free to squash all fixes in your next P-R update.
core/arch/arm/mm/core_mmu_v7.c
Outdated
|
||
new_table = prtn->l2_tables[prtn->tables_used]; | ||
prtn->tables_used++; | ||
DMSG("L2 table used: %d/%d", prtn->tables_used, |
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.
Nitpicking: typo in previous implementation, let's fix it?
"L2 table used: %"PRIu32"/%d"
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
assert(prtn->last_l2_page + SMALL_PAGE_SIZE == | ||
p); | ||
if (!prtn->tables_used) | ||
boot_mem_add_reloc(&prtn->last_l2_page); |
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.
Comment addressed.
@@ -214,19 +217,23 @@ static l2_xlat_tbl_t main_mmu_l2_ttb[MAX_XLAT_TABLES] | |||
/* MMU L1 table for TAs, one for each thread */ | |||
static ul1_xlat_tbl_t main_mmu_ul1_ttb[CFG_NUM_THREADS] | |||
__aligned(UL1_ALIGNMENT) __section(".nozi.mmu.ul1"); | |||
#endif | |||
|
|||
struct mmu_partition { |
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.
Comment addressed.
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.
Reviewed-by: Etienne Carriere <[email protected]>
for commit
"core: arm: mm: refactor LPAE translation table handling".
Add special checks in phys_to_virt_tee_ram() to see that a virtual address indeed is mapped before return the address if the memory area is MEM_AREA_TEE_RAM_RW since the VCORE_FREE may be unmapped. Signed-off-by: Jens Wiklander <[email protected]> Acked-by: Jerome Forissier <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
In boot_mem_relocate() when relocating registered pointers, allow the pointer to be NULL. NULL pointers are not relocated. Signed-off-by: Jens Wiklander <[email protected]> Reviewed-by: Jerome Forissier <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
When boot_mem_alloc() allocates memory up to alignment - 1 number of bytes may have be skipped to satisfy the required alignment of the returned pointer. If the skipped bytes, or padding, is large enough, it's recorded in a list of padding. The list of paddings can be processed and consumed with boot_mem_foreach_padding(). This allows sufficiently large paddings to be added to for instance the heap instead of being wasted. Signed-off-by: Jens Wiklander <[email protected]> Acked-by: Jerome Forissier <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
Add the paddings added due to requested alignment in boot mem allocations to the heap. Signed-off-by: Jens Wiklander <[email protected]> Acked-by: Jerome Forissier <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
core_init_mmu_map() uses a temporary dummy memory map for the virt_to_phys() and phys_to_virt() conversions to avoid asserting while setting up translation tables before the MMU is enabled. CFG_DYN_CONFIG will need a larger range of memory since translation tables might not be allocated from .nozi memory only. So for CFG_DYN_CONFIG extend of end of the unused memory range that the boot_mem_*() functions allocate memory from. Introduce CFG_DYN_CONFIG, enabled by default if CFG_BOOT_MEM is enabled and CFG_WITH_PAGER disabled. CFG_DYN_CONFIG conflicts with CFG_WITH_PAGER since the pager uses a different mechanism for memory allocation. Signed-off-by: Jens Wiklander <[email protected]> Acked-by: Jerome Forissier <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
Refactor translation table handling to use a more flexible layout of the translation tables in memory. Instead of relying on multidimensional array use helper functions to calculate the address of each translation table as needed. Preparing for future changes, no change in behaviour. Signed-off-by: Jens Wiklander <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
With CFG_DYN_CONFIG enabled allocate translation tables using the boot_mem_*() functions. Static allocation from global variables is still used with CFG_DYN_CONFIG disabled. Signed-off-by: Jens Wiklander <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
With CFG_DYN_CONFIG enabled allocate translation tables using the boot_mem_*() functions. Static allocation from global variables is still used with CFG_DYN_CONFIG disabled. Signed-off-by: Jens Wiklander <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
12f11a8
to
489a140
Compare
Comments addressed, commits squashed, rebased, and tags applied. |
The PR touches very core parts and although it's stable I don't mind if it's merged after the release to minimize the risk of last-minute problems. |
No description provided.