mirror of
https://github.com/apache/nuttx.git
synced 2026-05-24 16:11:56 +08:00
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:
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 \
|
||||
{ \
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user