Skip to content

Commit ec70b2b

Browse files
carlocaionenashif
authored andcommitted
aarch64: userspace: Add support for page tables swapping
Introduce the necessary routines to have the user thread stack correctly mapped and the functions to swap page tables on context switch. Signed-off-by: Carlo Caione <[email protected]>
1 parent b1eefc0 commit ec70b2b

File tree

7 files changed

+86
-1
lines changed

7 files changed

+86
-1
lines changed

arch/arm/core/aarch64/mmu/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
zephyr_library()
44

5-
zephyr_library_sources(arm_mmu.c)
5+
zephyr_library_sources(arm_mmu.c low_level.S)

arch/arm/core/aarch64/mmu/arm_mmu.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <device.h>
1111
#include <init.h>
1212
#include <kernel.h>
13+
#include <kernel_arch_func.h>
1314
#include <kernel_arch_interface.h>
1415
#include <kernel_internal.h>
1516
#include <logging/log.h>
@@ -993,6 +994,10 @@ void arch_mem_domain_thread_add(struct k_thread *thread)
993994
reset_map(old_ptables, __func__, thread->stack_info.start,
994995
thread->stack_info.size);
995996
}
997+
998+
if (thread == _current && !is_ptable_active(domain_ptables)) {
999+
z_arm64_swap_ptables(thread);
1000+
}
9961001
}
9971002

9981003
void arch_mem_domain_thread_remove(struct k_thread *thread)
@@ -1015,4 +1020,30 @@ void arch_mem_domain_thread_remove(struct k_thread *thread)
10151020
thread->stack_info.size);
10161021
}
10171022

1023+
void z_arm64_swap_ptables(struct k_thread *incoming)
1024+
{
1025+
struct arm_mmu_ptables *ptables = incoming->arch.ptables;
1026+
1027+
if (!is_ptable_active(ptables)) {
1028+
z_arm64_set_ttbr0((uintptr_t)ptables->base_xlat_table);
1029+
} else {
1030+
invalidate_tlb_all();
1031+
}
1032+
}
1033+
1034+
void z_arm64_thread_pt_init(struct k_thread *incoming)
1035+
{
1036+
struct arm_mmu_ptables *ptables;
1037+
1038+
if ((incoming->base.user_options & K_USER) == 0)
1039+
return;
1040+
1041+
ptables = incoming->arch.ptables;
1042+
1043+
/* Map the thread stack */
1044+
map_thread_stack(incoming, ptables);
1045+
1046+
z_arm64_swap_ptables(incoming);
1047+
}
1048+
10181049
#endif /* CONFIG_USERSPACE */
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) 2021 Carlo Caione <[email protected]>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <toolchain.h>
8+
#include <linker/sections.h>
9+
#include <arch/cpu.h>
10+
11+
_ASM_FILE_PROLOGUE
12+
13+
/*
14+
* Switch TTBR0
15+
*/
16+
17+
GTEXT(z_arm64_set_ttbr0)
18+
SECTION_FUNC(TEXT, z_arm64_set_ttbr0)
19+
20+
/* Disable all the caches */
21+
mrs x2, sctlr_el1
22+
mov_imm x1, (SCTLR_M_BIT | SCTLR_C_BIT | SCTLR_I_BIT)
23+
and x1, x2, x1
24+
msr sctlr_el1, x1
25+
isb
26+
27+
/* Invalidate the TLBs */
28+
tlbi vmalle1
29+
dsb sy
30+
isb
31+
32+
/* Switch the TTBR0 */
33+
msr ttbr0_el1, x0
34+
isb
35+
36+
/* Restore the saved SCTLR_EL1 */
37+
msr sctlr_el1, x2
38+
isb
39+
40+
ret

arch/arm/core/aarch64/switch.S

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ SECTION_FUNC(TEXT, z_arm64_context_switch)
7676

7777
mov sp, x1
7878

79+
#ifdef CONFIG_USERSPACE
80+
stp xzr, x30, [sp, #-16]!
81+
bl z_arm64_swap_ptables
82+
ldp xzr, x30, [sp], #16
83+
#endif
84+
7985
#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING
8086
stp xzr, x30, [sp, #-16]!
8187
bl z_thread_mark_switched_in

arch/arm/core/aarch64/thread.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry,
8383
z_arch_esf_t *pInitCtx;
8484
uintptr_t stack_ptr;
8585

86+
/* Map the thread stack */
87+
z_arm64_thread_pt_init(_current);
88+
8689
/* Setup the private stack */
8790
_current->arch.priv_stack_start = (uint64_t)(_current->stack_obj);
8891

arch/arm/include/aarch64/kernel_arch_func.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ static inline void arch_switch(void *switch_to, void **switched_from)
4141

4242
extern void z_arm64_fatal_error(z_arch_esf_t *esf, unsigned int reason);
4343
extern void z_arm64_userspace_enter(z_arch_esf_t *esf);
44+
extern void z_arm64_set_ttbr0(uintptr_t ttbr0);
4445

4546
#endif /* _ASMLANGUAGE */
4647

include/arch/arm/aarch64/arm_mmu.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,11 @@ struct arm_mmu_ptables {
194194
*/
195195
extern const struct arm_mmu_config mmu_config;
196196

197+
struct k_thread;
197198
void z_arm64_mmu_init(void);
199+
void z_arm64_thread_pt_init(struct k_thread *thread);
200+
void z_arm64_swap_ptables(struct k_thread *thread);
201+
198202
#endif /* _ASMLANGUAGE */
199203

200204
#endif /* ZEPHYR_INCLUDE_ARCH_ARM64_MMU_ARM_MMU_H_ */

0 commit comments

Comments
 (0)