From ffff51c1b10df479856d1bed73bfdb70b6e788b6 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 14 Sep 2014 09:10:09 -0600 Subject: [PATCH] Rename everything associated with the dynamic process stack to ustack to make room in the name space for a kstack --- arch/Kconfig | 47 +++++++++++++++---- arch/arm/include/armv7-a/irq.h | 17 ++++++- arch/arm/src/a1x/Make.defs | 5 +- arch/arm/src/armv7-a/arm_addrenv.c | 8 ++-- ...m_addrenv_stack.c => arm_addrenv_ustack.c} | 42 ++++++++--------- arch/arm/src/sama5/Make.defs | 5 +- 6 files changed, 87 insertions(+), 37 deletions(-) rename arch/arm/src/armv7-a/{arm_addrenv_stack.c => arm_addrenv_ustack.c} (88%) diff --git a/arch/Kconfig b/arch/Kconfig index 76daa18100..e552869e44 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -224,10 +224,9 @@ config ARCH_HEAP_NPAGES the heap virtual address space. Default is 1. config ARCH_STACK_DYNAMIC - bool "Dynamic stack" - default n if !BUILD_KERNEL || !LIBC_EXECFUNCS - default y if BUILD_KERNEL && LIBC_EXECFUNCS - depends on EXPERIMENTAL + bool "Dynamic user stack" + default n + depends on BUILD_KERNEL && EXPERIMENTAL ---help--- Select this option if the user process stack resides in its own address space. The naming of this selection implies that dynamic @@ -236,10 +235,9 @@ config ARCH_STACK_DYNAMIC general meaning of this configuration environment is simply that the stack has its own address space. - NOTE: This option is also *required* if BUILD_KERNEL and - LIBC_EXECFUNCS are selected. Why? Because the caller's stack must - be preserved in its own address space when we instantiate the - environment of the new process in order to initialize it. + NOTE: This option not yet fully implemented in the code base. + Hence, it is marked EXPERIMENTAL: Do not enable it unless you plan + finish the implementation. if ARCH_STACK_DYNAMIC @@ -258,6 +256,39 @@ config ARCH_STACK_NPAGES endif # ARCH_STACK_DYNAMIC +config ARCH_KERNEL_STACK + bool "Kernel process stack" + default n if !LIBC_EXECFUNCS + default y if LIBC_EXECFUNCS + depends on BUILD_KERNEL + ---help--- + It this option is selected, then every user process will have two + stacks: A large, potentially dynamically sized user stack and small + kernel stack that is used during system call process. + + If this option is not selected, then kernel system calls will simply + use the caller's user stack. So, in most cases, this option is not + required. However, this option is *required* if both BUILD_KERNEL + and LIBC_EXECFUNCS are selected. Why? Because when we instantiate + and initialize the address environment of the new user process, we + will temporarily lose the address environment of the old user + process, including its stack contents. The kernel C logic will + crash immediately with no valid stack in place. + + When this option is selected, the smaller kernel stack stays in + place during system call processing event though the original user + stack may or may not be accessible. + +if ARCH_KERNEL_STACK + +config ARCH_KERNEL_STACKSIZE + int "Kernel stack size" + default 1568 + ---help--- + The common size of each process' kernel stack + +endif # ARCH_KERNEL_STACK + config ARCH_PGPOOL_MAPPING bool "Have page pool mapping" default n diff --git a/arch/arm/include/armv7-a/irq.h b/arch/arm/include/armv7-a/irq.h index f9d5225b3a..612f4cbeae 100755 --- a/arch/arm/include/armv7-a/irq.h +++ b/arch/arm/include/armv7-a/irq.h @@ -274,14 +274,27 @@ struct xcptcontext struct xcpt_syscall_s syscall[CONFIG_SYS_NNEST]; #endif -#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_ARCH_STACK_DYNAMIC) +#ifdef CONFIG_ARCH_ADDRENV +#ifdef CONFIG_ARCH_STACK_DYNAMIC /* This table holds the physical address of the level 2 page table used * to map the thread's stack memory. This array will be initially of * zeroed and would be back-up up with pages during page fault exception * handling to support dynamically sized stacks for each thread. */ - FAR uintptr_t *stack[ARCH_STACK_NSECTS]; + FAR uintptr_t *ustack[ARCH_STACK_NSECTS]; +#endif +#ifdef CONFIG_ARCH_KERNEL_STACK + /* In this configuration, all syscalls execute from an internal kernel + * stack. Why? Because when we instantiate and initialize the address + * environment of the new user process, we will temporarily lose the + * address environment of the old user process, including its stack + * contents. The kernel C logic will crash immediately with no valid + * stack in place. + */ + + FAR uintptr_t *kstack; +#endif #endif }; #endif diff --git a/arch/arm/src/a1x/Make.defs b/arch/arm/src/a1x/Make.defs index 22f5065446..d7d5dfbc45 100644 --- a/arch/arm/src/a1x/Make.defs +++ b/arch/arm/src/a1x/Make.defs @@ -93,7 +93,10 @@ endif ifeq ($(CONFIG_ARCH_ADDRENV),y) CMN_CSRCS += arm_addrenv.c arm_addrenv_utils.c arm_pgalloc.c ifeq ($(CONFIG_ARCH_STACK_DYNAMIC),y) -CMN_CSRCS += arm_addrenv_stack.c +CMN_CSRCS += arm_addrenv_ustack.c +endif +ifeq ($(CONFIG_ARCH_KERNEL_STACK),y) +CMN_CSRCS += arm_addrenv_kstack.c endif endif diff --git a/arch/arm/src/armv7-a/arm_addrenv.c b/arch/arm/src/armv7-a/arm_addrenv.c index 257a14a36a..fcc1eb1f15 100644 --- a/arch/arm/src/armv7-a/arm_addrenv.c +++ b/arch/arm/src/armv7-a/arm_addrenv.c @@ -79,10 +79,10 @@ * If CONFIG_ARCH_STACK_DYNAMIC=y is selected then the platform specific * code must export these additional interfaces: * - * up_addrenv_stackalloc - Create a stack address environment - * up_addrenv_stackfree - Destroy a stack address environment. - * up_addrenv_vstack - Returns the virtual base address of the stack - * up_addrenv_stackselect - Instantiate a stack address environment + * up_addrenv_ustackalloc - Create a stack address environment + * up_addrenv_ustackfree - Destroy a stack address environment. + * up_addrenv_vustack - Returns the virtual base address of the stack + * up_addrenv_ustackselect - Instantiate a stack address environment * ****************************************************************************/ diff --git a/arch/arm/src/armv7-a/arm_addrenv_stack.c b/arch/arm/src/armv7-a/arm_addrenv_ustack.c similarity index 88% rename from arch/arm/src/armv7-a/arm_addrenv_stack.c rename to arch/arm/src/armv7-a/arm_addrenv_ustack.c index 225906f817..e30dfa4e37 100644 --- a/arch/arm/src/armv7-a/arm_addrenv_stack.c +++ b/arch/arm/src/armv7-a/arm_addrenv_ustack.c @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/arm/src/armv7/arm_addrenv_stack.c + * arch/arm/src/armv7/arm_addrenv_ustack.c * * Copyright (C) 2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -79,10 +79,10 @@ * If CONFIG_ARCH_STACK_DYNAMIC=y is selected then the platform specific * code must export these additional interfaces: * - * up_addrenv_stackalloc - Create a stack address environment - * up_addrenv_stackfree - Destroy a stack address environment. - * up_addrenv_vstack - Returns the virtual base address of the stack - * up_addrenv_stackselect - Instantiate a stack address environment + * up_addrenv_ustackalloc - Create a stack address environment + * up_addrenv_ustackfree - Destroy a stack address environment. + * up_addrenv_vustack - Returns the virtual base address of the stack + * up_addrenv_ustackselect - Instantiate a stack address environment * ****************************************************************************/ @@ -129,12 +129,12 @@ ****************************************************************************/ /**************************************************************************** - * Name: up_addrenv_stackalloc + * Name: up_addrenv_ustackalloc * * Description: * This function is called when a new thread is created in order to * instantiate an address environment for the new thread's stack. - * up_addrenv_stackalloc() is essentially the allocator of the physical + * up_addrenv_ustackalloc() is essentially the allocator of the physical * memory for the new task's stack. * * Input Parameters: @@ -147,7 +147,7 @@ * ****************************************************************************/ -int up_addrenv_stackalloc(FAR struct tcb_s *tcb, size_t stacksize) +int up_addrenv_ustackalloc(FAR struct tcb_s *tcb, size_t stacksize) { int ret; @@ -157,7 +157,7 @@ int up_addrenv_stackalloc(FAR struct tcb_s *tcb, size_t stacksize) /* Initialize the address environment list to all zeroes */ - memset(tcb->xcp.stack, 0, ARCH_STACK_NSECTS * sizeof(uintptr_t *)); + memset(tcb->xcp.ustack, 0, ARCH_STACK_NSECTS * sizeof(uintptr_t *)); /* Back the allocation up with physical pages and set up the level 2 mapping * (which of course does nothing until the L2 page table is hooked into @@ -166,13 +166,13 @@ int up_addrenv_stackalloc(FAR struct tcb_s *tcb, size_t stacksize) /* Allocate .text space pages */ - ret = arm_addrenv_create_region(tcb->xcp.stack, ARCH_STACK_NSECTS, + ret = arm_addrenv_create_region(tcb->xcp.ustack, ARCH_STACK_NSECTS, CONFIG_ARCH_STACK_VBASE, stacksize, MMU_L2_UDATAFLAGS); if (ret < 0) { bdbg("ERROR: Failed to create stack region: %d\n", ret); - up_addrenv_stackfree(tcb); + up_addrenv_ustackfree(tcb); return ret; } @@ -180,7 +180,7 @@ int up_addrenv_stackalloc(FAR struct tcb_s *tcb, size_t stacksize) } /**************************************************************************** - * Name: up_addrenv_stackfree + * Name: up_addrenv_ustackfree * * Description: * This function is called when any thread exits. This function then @@ -196,22 +196,22 @@ int up_addrenv_stackalloc(FAR struct tcb_s *tcb, size_t stacksize) * ****************************************************************************/ -int up_addrenv_stackfree(FAR struct tcb_s *tcb) +int up_addrenv_ustackfree(FAR struct tcb_s *tcb) { bvdbg("tcb=%p\n", tcb); DEBUGASSERT(tcb); /* Destroy the stack region */ - arm_addrenv_destroy_region(tcb->xcp.stack, ARCH_STACK_NSECTS, + arm_addrenv_destroy_region(tcb->xcp.ustack, ARCH_STACK_NSECTS, CONFIG_ARCH_STACK_VBASE); - memset(tcb->xcp.stack, 0, ARCH_STACK_NSECTS * sizeof(uintptr_t *)); + memset(tcb->xcp.ustack, 0, ARCH_STACK_NSECTS * sizeof(uintptr_t *)); return OK; } /**************************************************************************** - * Name: up_addrenv_vstack + * Name: up_addrenv_vustack * * Description: * Return the virtual address associated with the newly create stack @@ -227,7 +227,7 @@ int up_addrenv_stackfree(FAR struct tcb_s *tcb) * ****************************************************************************/ -int up_addrenv_vstack(FAR const struct tcb_s *tcb, FAR void **vstack) +int up_addrenv_vustack(FAR const struct tcb_s *tcb, FAR void **vstack) { bvdbg("Return=%p\n", (FAR void *)CONFIG_ARCH_STACK_VBASE); @@ -239,11 +239,11 @@ int up_addrenv_vstack(FAR const struct tcb_s *tcb, FAR void **vstack) } /**************************************************************************** - * Name: up_addrenv_stackselect + * Name: up_addrenv_ustackselect * * Description: * After an address environment has been established for a task's stack - * (via up_addrenv_stackalloc(). This function may be called to instantiate + * (via up_addrenv_ustackalloc(). This function may be called to instantiate * that address environment in the virtual address space. This is a * necessary step before each context switch to the newly created thread * (including the initial thread startup). @@ -257,7 +257,7 @@ int up_addrenv_vstack(FAR const struct tcb_s *tcb, FAR void **vstack) * ****************************************************************************/ -int up_addrenv_stackselect(FAR const struct tcb_s *tcb) +int up_addrenv_ustackselect(FAR const struct tcb_s *tcb) { uintptr_t vaddr; uintptr_t paddr; @@ -271,7 +271,7 @@ int up_addrenv_stackselect(FAR const struct tcb_s *tcb) { /* Set (or clear) the new page table entry */ - paddr = (uintptr_t)tcb->xcp.stack[i]; + paddr = (uintptr_t)tcb->xcp.ustack[i]; if (paddr) { mmu_l1_setentry(paddr, vaddr, MMU_L1_PGTABFLAGS); diff --git a/arch/arm/src/sama5/Make.defs b/arch/arm/src/sama5/Make.defs index 59654e5e3c..748ebf9870 100644 --- a/arch/arm/src/sama5/Make.defs +++ b/arch/arm/src/sama5/Make.defs @@ -95,7 +95,10 @@ endif ifeq ($(CONFIG_ARCH_ADDRENV),y) CMN_CSRCS += arm_addrenv.c arm_addrenv_utils.c arm_pgalloc.c ifeq ($(CONFIG_ARCH_STACK_DYNAMIC),y) -CMN_CSRCS += arm_addrenv_stack.c +CMN_CSRCS += arm_addrenv_ustack.c +endif +ifeq ($(CONFIG_ARCH_KERNEL_STACK),y) +CMN_CSRCS += arm_addrenv_kstack.c endif endif