This post discusses how user space stack grows.
reference code base
linux 4.3
kernel config assumption
# CONFIG_STACK_GROWSUP is not set
how does user space stack grow
As discussed in kernel: mm: task->mm->mmap_sem, virtual address space is represented by intervals of VMAs. The stack itself corresponding to a VMA whose vm_flags has flag VM_GROWSDOWN set.
If a stack grows below its corresponding VMA’s scope, then a page fault will be triggered. __do_page_fault() calls expand_stack() to extend the corresponding VMA downward. Then, it calls -> handle_mm_fault() to allocate a page and modify page tables.
do_page_fault() -> __do_page_fault() -> expand_stack() -> expand_downwards() -> handle_mm_fault() -> __handle_mm_fault()
__do_page_fault
If vma->vm_start > addr, then __do_page_fault() checks if VM_GROWSDOWN flag is set in vma->vm_flags. If true, then it calls expand_stack(vma, addr) to expand the VMA by 1 page. If successful, it calls handle_mm_fault() to allocate a page and modify page tables.
157 static int __do_page_fault(struct mm_struct *mm, unsigned long addr, 158 unsigned int mm_flags, unsigned long vm_flags, 159 struct task_struct *tsk) 160 { 161 struct vm_area_struct *vma; 162 int fault; 163 164 vma = find_vma(mm, addr); 165 fault = VM_FAULT_BADMAP; 166 if (unlikely(!vma)) 167 goto out; 168 if (unlikely(vma->vm_start > addr)) 169 goto check_stack; 170 171 /* 172 * Ok, we have a good vm_area for this memory access, so we can handle 173 * it. 174 */ 175 good_area: 176 /* 177 * Check that the permissions on the VMA allow for the fault which 178 * occurred. If we encountered a write or exec fault, we must have 179 * appropriate permissions, otherwise we allow any permission. 180 */ 181 if (!(vma->vm_flags & vm_flags)) { 182 fault = VM_FAULT_BADACCESS; 183 goto out; 184 } 185 186 return handle_mm_fault(mm, vma, addr & PAGE_MASK, mm_flags); 187 188 check_stack: 189 if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr)) 190 goto good_area; 191 out: 192 return fault; 193 }
conclusion
This post discusses how user space stack grows. While stack is below its lowest address defined by VMA. A page fault is triggered to extend the corresponding VMA downward by 1 page, allocate a page, and modify page tables.