arm64: support protectbuild

Add CONFIG_BUILD_PROTECTED support alongside
CONFIG_BUILD_KERNEL for saved register
pointers and task startup functions. Fix
arm64_fork() to properly handle Thumb bit masking.
Enable weak_function for up_allocate_kheap()
to support board-specific heap allocation.

Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
hujun5
2025-05-13 14:48:05 +08:00
committed by GUIDINGLI
parent de77967144
commit be9d0665e4
11 changed files with 87 additions and 25 deletions
+1 -1
View File
@@ -268,7 +268,7 @@ struct xcptcontext
uint64_t *saved_regs;
#ifdef CONFIG_BUILD_KERNEL
#if defined(CONFIG_BUILD_KERNEL) || defined(CONFIG_BUILD_PROTECTED)
/* This is the saved address to use when returning from a user-space
* signal handler.
*/
+1 -1
View File
@@ -91,7 +91,7 @@ if(CONFIG_SMP)
list(APPEND SRCS arm64_smpcall.c)
endif()
if(CONFIG_BUILD_KERNEL)
if(CONFIG_BUILD_KERNEL OR CONFIG_BUILD_PROTECTED)
list(APPEND SRCS arm64_task_start.c arm64_pthread_start.c)
if(CONFIG_ENABLE_ALL_SIGNALS)
list(APPEND SRCS arm64_signal_dispatch.c)
+1 -1
View File
@@ -100,7 +100,7 @@ CMN_CSRCS += arm64_cpuidlestack.c arm64_cpustart.c
CMN_CSRCS += arm64_smpcall.c
endif
ifeq ($(CONFIG_BUILD_KERNEL),y)
ifeq ($(CONFIG_BUILD_PROTECTED)$(CONFIG_BUILD_KERNEL),y)
CMN_CSRCS += arm64_task_start.c arm64_pthread_start.c
ifeq ($(CONFIG_ENABLE_ALL_SIGNALS),y)
CMN_CSRCS += arm64_signal_dispatch.c
+1 -1
View File
@@ -145,7 +145,7 @@ void up_allocate_heap(void **heap_start, size_t *heap_size)
****************************************************************************/
#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)
void up_allocate_kheap(void **heap_start, size_t *heap_size)
void weak_function up_allocate_kheap(void **heap_start, size_t *heap_size)
{
/* Get the unaligned size and position of the user-space heap.
* This heap begins after the user-space .bss section at an offset
+1 -1
View File
@@ -131,7 +131,7 @@ pid_t arm64_fork(const struct fork_s *context)
/* Allocate and initialize a TCB for the child task. */
child = nxtask_setup_fork((start_t)(context->lr & ~1));
child = nxtask_setup_fork((start_t)context->lr);
if (!child)
{
serr("ERROR: nxtask_setup_fork failed\n");
+3 -1
View File
@@ -252,7 +252,9 @@ EXTERN uint8_t g_idle_topstack[]; /* End+1 of heap */
****************************************************************************/
void arm64_new_task(struct tcb_s *tak_new);
void arm64_jump_to_user(uint64_t entry, uint64_t x0, uint64_t x1,
void arm64_jump_to_user(uint64_t entry, uint64_t x0,
uint64_t x1, uint64_t x2,
uint64_t sp_el0, uint64_t *regs) noreturn_function;
/* Low level initialization provided by chip logic */
+45 -8
View File
@@ -213,12 +213,19 @@
}
#ifdef CONFIG_SMP
# define REGION_RAM_ATTR \
{ \
/* AP, XN, SH */ \
.rbar = (NOT_EXEC | P_RW_U_NA_MSK | INNER_SHAREABLE_MSK) , \
/* Cache-ability */ \
.mair_idx = MPU_MAIR_INDEX_SRAM, \
# define REGION_RAM_ATTR \
{ \
/* AP, XN, SH */ \
.rbar = (NOT_EXEC | P_RW_U_NA_MSK | INNER_SHAREABLE_MSK), \
/* Cache-ability */ \
.mair_idx = MPU_MAIR_INDEX_SRAM, \
}
# define REGION_URAM_ATTR \
{ \
/* AP, XN, SH */ \
.rbar = (NOT_EXEC | P_RW_U_RW_MSK | INNER_SHAREABLE_MSK), \
/* Cache-ability */ \
.mair_idx = MPU_MAIR_INDEX_SRAM, \
}
#else
# define REGION_RAM_ATTR \
@@ -228,15 +235,45 @@
/* Cache-ability */ \
.mair_idx = MPU_MAIR_INDEX_SRAM, \
}
# define REGION_URAM_ATTR \
{ \
/* AP, XN, SH */ \
.rbar = NOT_EXEC | P_RW_U_RW_MSK | NON_SHAREABLE_MSK, \
/* Cache-ability */ \
.mair_idx = MPU_MAIR_INDEX_SRAM, \
}
#endif
#define REGION_RAM_TEXT_ATTR \
#ifdef CONFIG_SMP
# define REGION_RAM_TEXT_ATTR \
{ \
/* AP, XN, SH */ \
.rbar = P_RO_U_NA_MSK | INNER_SHAREABLE_MSK, \
/* Cache-ability */ \
.mair_idx = MPU_MAIR_INDEX_SRAM, \
}
# define REGION_RAM_UTEXT_ATTR \
{ \
/* AP, XN, SH */ \
.rbar = P_RO_U_RO_MSK | INNER_SHAREABLE_MSK, \
/* Cache-ability */ \
.mair_idx = MPU_MAIR_INDEX_SRAM, \
}
#else
# define REGION_RAM_TEXT_ATTR \
{ \
/* AP, XN, SH */ \
/* Cache-ability */ \
.rbar = P_RO_U_NA_MSK | NON_SHAREABLE_MSK, \
.mair_idx = MPU_MAIR_INDEX_SRAM, \
}
# define REGION_RAM_UTEXT_ATTR \
{ \
/* AP, XN, SH */ \
.rbar = P_RO_U_RO_MSK | NON_SHAREABLE_MSK, \
/* Cache-ability */ \
.mair_idx = MPU_MAIR_INDEX_SRAM, \
}
#endif
#define REGION_RAM_RO_ATTR \
{ \
+8 -1
View File
@@ -81,8 +81,15 @@ void up_pthread_start(pthread_trampoline_t startup,
* SPSR = user mode
*/
arm64_jump_to_user((uint64_t)startup, (uint64_t)entrypt, (uint64_t)arg,
#ifdef CONFIG_BUILD_KERNEL
arm64_jump_to_user((uint64_t)startup, (uint64_t)entrypt,
(uint64_t)arg, 0,
(uint64_t)rtcb->xcp.ustkptr, rtcb->xcp.initregs);
#elif defined(CONFIG_BUILD_PROTECTED)
arm64_jump_to_user((uint64_t)USERSPACE->task_startup,
(uint64_t)startup, (uint64_t)entrypt, (uint64_t)arg,
(uint64_t)rtcb->xcp.ustkptr, rtcb->xcp.initregs);
#endif
}
#endif /* !CONFIG_BUILD_FLAT && __KERNEL__ && !CONFIG_DISABLE_PTHREAD */
+8 -2
View File
@@ -159,7 +159,7 @@ uint64_t *arm64_syscall(uint64_t *regs)
struct tcb_s **running_task = &g_running_tasks[cpu];
struct tcb_s *tcb = this_task();
uint64_t cmd;
#ifdef CONFIG_BUILD_KERNEL
#if defined(CONFIG_BUILD_KERNEL) || defined(CONFIG_BUILD_PROTECTED)
uint64_t spsr;
#endif
@@ -217,7 +217,8 @@ uint64_t *arm64_syscall(uint64_t *regs)
restore_critical_section(tcb, cpu);
break;
#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_ENABLE_ALL_SIGNALS)
#if (defined(CONFIG_BUILD_KERNEL) || defined(CONFIG_BUILD_PROTECTED)) \
&& defined(CONFIG_ENABLE_ALL_SIGNALS)
/* R0=SYS_signal_handler: This a user signal handler callback
*
* void signal_handler(_sa_sigaction_t sighand, int signo,
@@ -245,7 +246,12 @@ uint64_t *arm64_syscall(uint64_t *regs)
* unprivileged mode.
*/
#if defined(CONFIG_BUILD_KERNEL)
regs[REG_ELR] = (uint64_t)ARCH_DATA_RESERVE->ar_sigtramp;
#elif defined(CONFIG_BUILD_PROTECTED)
regs[REG_ELR] = (uint64_t)(USERSPACE->signal_handler);
#endif
spsr = regs[REG_SPSR] & ~SPSR_MODE_MASK;
regs[REG_SPSR] = spsr | SPSR_MODE_EL0T;
+14 -5
View File
@@ -72,14 +72,23 @@ void up_task_start(main_t taskentry, int argc, char *argv[])
/* Set up to return to the user-space _start function in
* unprivileged mode. We need:
*
* R0 = argc
* R1 = argv
* ELR = taskentry
* SPSR = user mode
* X0 = REG_ELR
* X1 = param1
* X2 = param2
* X3 = param3
* X4 = SP_EL0
* X5 = REGS
*/
arm64_jump_to_user((uint64_t)taskentry, (uint64_t)argc, (uint64_t)argv,
#ifdef CONFIG_BUILD_KERNEL
arm64_jump_to_user((uint64_t)taskentry, (uint64_t)argc,
(uint64_t)argv, 0,
(uint64_t)rtcb->xcp.ustkptr, rtcb->xcp.initregs);
#elif defined(CONFIG_BUILD_PROTECTED)
arm64_jump_to_user((uint64_t)USERSPACE->task_startup,
(uint64_t)taskentry, (uint64_t)argc, (uint64_t)argv,
(uint64_t)rtcb->xcp.ustkptr, rtcb->xcp.initregs);
#endif
}
#endif /* !CONFIG_BUILD_FLAT */
+4 -3
View File
@@ -105,15 +105,16 @@ SECTION_FUNC(text, up_saveusercontext)
*
****************************************************************************/
#ifndef CONFIG_BUILD_FLAT
#if defined(CONFIG_BUILD_KERNEL) || defined(CONFIG_BUILD_PROTECTED)
GTEXT(arm64_jump_to_user)
SECTION_FUNC(text, arm64_jump_to_user)
msr daifset, #IRQ_DAIF_MASK
mov sp, x4
mov sp, x5
str x0, [sp, #8 * REG_ELR]
str x1, [sp, #8 * REG_X0]
str x2, [sp, #8 * REG_X1]
str x3, [sp, #8 * REG_SP_EL0]
str x3, [sp, #8 * REG_X2]
str x4, [sp, #8 * REG_SP_EL0]
mrs x0, spsr_el1
and x0, x0, #~SPSR_MODE_MASK
#orr x0, x0, #SPSR_MODE_EL0T # EL0T=0x00, out of range for orr