Many of the Morello helper functions are implemented in assembly due to historical reasons. This patch rewrites the following helpers in C to improve their readability:
- __morello_cap_lo_hi_tag - __morello_cap_has_executive - __morello_merge_c_x - __morello_thread_init_user
Signed-off-by: Akram Ahmad Akram.Ahmad@arm.com --- arch/arm64/kernel/morello.c | 44 ++++++++++++++++++++++++---- arch/arm64/lib/morello.S | 58 ------------------------------------- 2 files changed, 39 insertions(+), 63 deletions(-)
diff --git a/arch/arm64/kernel/morello.c b/arch/arm64/kernel/morello.c index e3f732f4c52d..644edfd44b46 100644 --- a/arch/arm64/kernel/morello.c +++ b/arch/arm64/kernel/morello.c @@ -20,12 +20,46 @@ #include <asm/morello.h> #include <asm/ptrace.h>
-/* Private functions implemented in morello.S */ void __morello_cap_lo_hi_tag(uintcap_t cap, u64 *lo_val, u64 *hi_val, - u8 *tag); -void __morello_merge_c_x(uintcap_t *creg, u64 xreg); -bool __morello_cap_has_executive(uintcap_t cap); -void __morello_thread_init_user(struct task_struct *tsk, uintcap_t ddc); + u8 *tag) +{ + *lo_val = cap; + *hi_val = __builtin_cheri_copy_from_high((void __capability *)cap); + *tag = cheri_tag_get((void __capability *)&cap); +} + +void __morello_merge_c_x(uintcap_t *creg, u64 xreg) +{ + if (cheri_address_get(*creg) != xreg) + *creg = (uintcap_t)cheri_address_set(*creg, xreg); +} + +bool __morello_cap_has_executive(uintcap_t cap) +{ + return cheri_perms_get((void __capability *)cap) & MORELLO_CAP_PERM_EXECUTIVE_MASK; +} + +void __morello_thread_init_user(struct task_struct *tsk, uintcap_t ddc) +{ + tsk->thread.morello_user_state.ddc = ddc; + tsk->thread.morello_user_state.rddc = (uintcap_t)as_user_ptr(0); + tsk->thread.morello_user_state.cid = (uintcap_t)as_user_ptr(0); + tsk->thread.morello_user_state.cctlr = 0; + + /* + * tls_thread_flush() does not touch rctpidr_el0 so this must be zeroed + * here. We do not need to initialise its value in morello_user_state. + * Only the ddc_el0 register must be initialised to the specific value; + * RDDC is set to a null capability as processes are always started in + * Executive. + */ + asm("msr rctpidr_el0, czr\n\t" + "msr ddc_el0, %0\n\t" + "msr rddc_el0, czr\n\t" + "msr cid_el0, czr\n\t" + "msr cctlr_el0, xzr" + : /* outputs */ :/* inputs */ "r"(ddc) : /*clobbers */); +}
static uintcap_t morello_sentry_unsealcap __ro_after_init;
diff --git a/arch/arm64/lib/morello.S b/arch/arm64/lib/morello.S index 0800375ef33d..5a4a39badfe2 100644 --- a/arch/arm64/lib/morello.S +++ b/arch/arm64/lib/morello.S @@ -46,38 +46,6 @@ SYM_FUNC_START(morello_build_any_user_cap) ret SYM_FUNC_END(morello_build_any_user_cap)
-SYM_FUNC_START(__morello_thread_init_user) - mov x9, #THREAD_MORELLO_USER_STATE - add x0, x0, x9 // x0 = tsk->thread.morello_user_state - - /* - * CTPIDR doesn't need to be initialised explicitly: - * - tls_thread_flush() already zeroes tpidr_el0, zeroing ctpidr_el0 as - * well - * - The value stored in thread.morello_user_state will be set the next - * time task_save_user_tls() is called, like thread_struct.uw.tp_value. - * - * tls_thread_flush() does not touch rcsp_el0, so we need to zero it - * here, but its value in morello_user_state does not need to be - * initialised here either. - */ - msr rctpidr_el0, czr - - /* DDC: initialised to the specified value */ - msr ddc_el0, c1 - /* RDDC: null capability (processes are always started in Executive) */ - msr rddc_el0, czr - stp c1, czr, [x0, #MORELLO_STATE_DDC] - /* CID: null capability */ - msr cid_el0, czr - str czr, [x0, #MORELLO_STATE_CID] - /* CCTLR: all bits cleared */ - msr cctlr_el0, xzr - str xzr, [x0, #MORELLO_STATE_CCTLR] - - ret -SYM_FUNC_END(__morello_thread_init_user) - SYM_FUNC_START(morello_thread_save_user_state) mov x9, #THREAD_MORELLO_USER_STATE add x0, x0, x9 // x0 = tsk->thread.morello_user_state @@ -177,29 +145,3 @@ SYM_FUNC_START(morello_task_restore_user_tls) ret SYM_FUNC_END(morello_task_restore_user_tls)
- -SYM_FUNC_START(__morello_cap_lo_hi_tag) - str x0, [x1] - cfhi x4, c0 // Extract upper 64 bits - str x4, [x2] - gctag x4, c0 - strb w4, [x3] - - ret -SYM_FUNC_END(__morello_cap_lo_hi_tag) - -SYM_FUNC_START(__morello_merge_c_x) - ldr c2, [x0] - cmp x2, x1 - b.eq 1f - scvalue c2, c2, x1 - str c2, [x0] -1: - ret -SYM_FUNC_END(__morello_merge_c_x) - -SYM_FUNC_START(__morello_cap_has_executive) - gcperm x0, c0 - ubfx x0, x0, #MORELLO_CAP_PERM_EXECUTIVE_BIT, #1 - ret -SYM_FUNC_END(__morello_cap_has_executive)