x86: userspace: page in stack before starting user thread
If generic section is not present at boot, the thread stack may not be in physical memory. Unconditionally page in the stack instead of relying on page fault to speed up a little bit on starting the thread. Also, this prevents a double fault during thread setup when setting up stack permission in z_x86_userspace_enter(). Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
parent
ea0f9474f7
commit
7605619c1e
1 changed files with 36 additions and 0 deletions
|
@ -106,6 +106,42 @@ FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry,
|
|||
stack_end -= 8;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DEMAND_PAGING) && \
|
||||
!defined(CONFIG_LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT)
|
||||
/* If generic section is not present at boot,
|
||||
* the thread stack may not be in physical memory.
|
||||
* Unconditionally page in the stack instead of
|
||||
* relying on page fault to speed up a little bit
|
||||
* on starting the thread.
|
||||
*
|
||||
* Note that this also needs to page in the reserved
|
||||
* portion of the stack (which is usually the page just
|
||||
* before the beginning of stack in
|
||||
* _current->stack_info.start.
|
||||
*/
|
||||
uintptr_t stack_start;
|
||||
size_t stack_size;
|
||||
uintptr_t stack_aligned_start;
|
||||
size_t stack_aligned_size;
|
||||
|
||||
stack_start = POINTER_TO_UINT(_current->stack_obj);
|
||||
stack_size = Z_THREAD_STACK_SIZE_ADJUST(_current->stack_info.size);
|
||||
|
||||
#if defined(CONFIG_HW_STACK_PROTECTION)
|
||||
/* With hardware stack protection, the first page of stack
|
||||
* is a guard page. So need to skip it.
|
||||
*/
|
||||
stack_start += CONFIG_MMU_PAGE_SIZE;
|
||||
stack_size -= CONFIG_MMU_PAGE_SIZE;
|
||||
#endif
|
||||
|
||||
(void)k_mem_region_align(&stack_aligned_start, &stack_aligned_size,
|
||||
stack_start, stack_size,
|
||||
CONFIG_MMU_PAGE_SIZE);
|
||||
k_mem_page_in(UINT_TO_POINTER(stack_aligned_start),
|
||||
stack_aligned_size);
|
||||
#endif
|
||||
|
||||
z_x86_userspace_enter(user_entry, p1, p2, p3, stack_end,
|
||||
_current->stack_info.start);
|
||||
CODE_UNREACHABLE;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue