Zephyr API 3.6.99
Loading...
Searching...
No Matches
thread_stack.h
Go to the documentation of this file.
1/*
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
10
11#ifdef CONFIG_X86_64
12#define ARCH_STACK_PTR_ALIGN 16UL
13#else
14#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 */
89struct 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#define ARCH_THREAD_STACK_OBJ_ALIGN(size) Z_X86_STACK_BASE_ALIGN
99
100#define ARCH_THREAD_STACK_SIZE_ADJUST(size) \
101 ROUND_UP((size), Z_X86_STACK_SIZE_ALIGN)
102
103#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#define ARCH_KERNEL_STACK_RESERVED 0
111#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 */