Line data Source code
1 0 : /* 2 : * Copyright (c) 2019 Intel Corporation 3 : * 4 : * SPDX-License-Identifier: Apache-2.0 5 : */ 6 : #ifndef ZEPHYR_INCLUDE_ARCH_X86_THREAD_STACK_H 7 : #define ZEPHYR_INCLUDE_ARCH_X86_THREAD_STACK_H 8 : 9 : #include <zephyr/arch/x86/mmustructs.h> 10 : 11 : #ifdef CONFIG_X86_64 12 : #define ARCH_STACK_PTR_ALIGN 16UL 13 : #else 14 0 : #define ARCH_STACK_PTR_ALIGN 4UL 15 : #endif 16 : 17 : #if defined(CONFIG_X86_STACK_PROTECTION) || defined(CONFIG_USERSPACE) \ 18 : || defined(CONFIG_THREAD_STACK_MEM_MAPPED) 19 : #define Z_X86_STACK_BASE_ALIGN CONFIG_MMU_PAGE_SIZE 20 : #else 21 : #define Z_X86_STACK_BASE_ALIGN ARCH_STACK_PTR_ALIGN 22 : #endif 23 : 24 : #if defined(CONFIG_USERSPACE) || defined(CONFIG_THREAD_STACK_MEM_MAPPED) 25 : /* If user mode enabled, expand any stack size to fill a page since that is 26 : * the access control granularity and we don't want other kernel data to 27 : * unintentionally fall in the latter part of the page 28 : * 29 : * This is also true when memory mapped stacks are used with since 30 : * access control applies to one page at a time. 31 : */ 32 : #define Z_X86_STACK_SIZE_ALIGN CONFIG_MMU_PAGE_SIZE 33 : #else 34 : #define Z_X86_STACK_SIZE_ALIGN ARCH_STACK_PTR_ALIGN 35 : #endif 36 : 37 : #ifndef _ASMLANGUAGE 38 : /* With both hardware stack protection and userspace enabled, stacks are 39 : * arranged as follows: 40 : * 41 : * --- Without stack being memory mapped: 42 : * High memory addresses 43 : * +-----------------------------------------+ 44 : * | Thread stack (varies) | 45 : * +-----------------------------------------+ 46 : * | Privilege elevation stack | 47 : * | (CONFIG_PRIVILEGED_STACK_SIZE) | 48 : * +-----------------------------------------+ 49 : * | Guard page (4096 bytes) | 50 : * | - 'guard_page' in struct | 51 : * | z_x86_thread_stack_header | 52 : * +-----------------------------------------+ 53 : * Low Memory addresses 54 : * 55 : * --- With stack being memory mapped: 56 : * High memory addresses 57 : * +-----------------------------------------+ 58 : * | Guard page (empty page) | 59 : * +-----------------------------------------+ 60 : * | Thread stack (varies) | 61 : * +-----------------------------------------+ 62 : * | Privilege elevation stack | 63 : * | (CONFIG_PRIVILEGED_STACK_SIZE) | 64 : * +-----------------------------------------+ 65 : * | Guard page (empty page) | 66 : * +-----------------------------------------+ 67 : * Low Memory addresses 68 : * 69 : * Without memory mapped stacks, the guard page is actually allocated 70 : * as part of the stack struct, which takes up physical memory during 71 : * linking. 72 : * 73 : * Privilege elevation stacks are fixed-size. All the pages containing the 74 : * thread stack are marked as user-accessible. The guard page is marked 75 : * read-only to catch stack overflows in supervisor mode. 76 : * 77 : * If a thread starts in supervisor mode, the page containing the 78 : * privilege elevation stack is also marked read-only. 79 : * 80 : * If a thread starts in, or drops down to user mode, the privilege stack page 81 : * will be marked as present, supervisor-only. 82 : * 83 : * If KPTI is not enabled, the _main_tss.esp0 field will always be updated 84 : * updated to point to the top of the privilege elevation stack. Otherwise 85 : * _main_tss.esp0 always points to the trampoline stack, which handles the 86 : * page table switch to the kernel PDPT and transplants context to the 87 : * privileged mode stack. 88 : */ 89 : struct z_x86_thread_stack_header { 90 : #if defined(CONFIG_X86_STACK_PROTECTION) && !defined(CONFIG_THREAD_STACK_MEM_MAPPED) 91 : char guard_page[CONFIG_MMU_PAGE_SIZE]; 92 : #endif 93 : #ifdef CONFIG_USERSPACE 94 : char privilege_stack[CONFIG_PRIVILEGED_STACK_SIZE]; 95 : #endif /* CONFIG_USERSPACE */ 96 : } __packed __aligned(Z_X86_STACK_BASE_ALIGN); 97 : 98 0 : #define ARCH_THREAD_STACK_OBJ_ALIGN(size) Z_X86_STACK_BASE_ALIGN 99 : 100 0 : #define ARCH_THREAD_STACK_SIZE_ADJUST(size) \ 101 : ROUND_UP((size), Z_X86_STACK_SIZE_ALIGN) 102 : 103 0 : #define ARCH_THREAD_STACK_RESERVED \ 104 : sizeof(struct z_x86_thread_stack_header) 105 : 106 : #ifdef CONFIG_X86_STACK_PROTECTION 107 : #define ARCH_KERNEL_STACK_RESERVED CONFIG_MMU_PAGE_SIZE 108 : #define ARCH_KERNEL_STACK_OBJ_ALIGN CONFIG_MMU_PAGE_SIZE 109 : #else 110 0 : #define ARCH_KERNEL_STACK_RESERVED 0 111 0 : #define ARCH_KERNEL_STACK_OBJ_ALIGN ARCH_STACK_PTR_ALIGN 112 : #endif 113 : 114 : #endif /* !_ASMLANGUAGE */ 115 : #endif /* ZEPHYR_INCLUDE_ARCH_X86_THREAD_STACK_H */