Zephyr API Documentation  2.7.0-rc2
A Scalable Open Source RTOS
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_HW_STACK_PROTECTION) || defined(CONFIG_USERSPACE)
18#define Z_X86_STACK_BASE_ALIGN CONFIG_MMU_PAGE_SIZE
19#else
20#define Z_X86_STACK_BASE_ALIGN ARCH_STACK_PTR_ALIGN
21#endif
22
23#ifdef CONFIG_USERSPACE
24/* If user mode enabled, expand any stack size to fill a page since that is
25 * the access control granularity and we don't want other kernel data to
26 * unintentionally fall in the latter part of the page
27 */
28#define Z_X86_STACK_SIZE_ALIGN CONFIG_MMU_PAGE_SIZE
29#else
30#define Z_X86_STACK_SIZE_ALIGN ARCH_STACK_PTR_ALIGN
31#endif
32
33#ifndef _ASMLANGUAGE
34/* With both hardware stack protection and userspace enabled, stacks are
35 * arranged as follows:
36 *
37 * High memory addresses
38 * +-----------------------------------------+
39 * | Thread stack (varies) |
40 * +-----------------------------------------+
41 * | Privilege elevation stack |
42 * | (4096 bytes) |
43 * +-----------------------------------------+
44 * | Guard page (4096 bytes) |
45 * +-----------------------------------------+
46 * Low Memory addresses
47 *
48 * Privilege elevation stacks are fixed-size. All the pages containing the
49 * thread stack are marked as user-accessible. The guard page is marked
50 * read-only to catch stack overflows in supervisor mode.
51 *
52 * If a thread starts in supervisor mode, the page containing the
53 * privilege elevation stack is also marked read-only.
54 *
55 * If a thread starts in, or drops down to user mode, the privilege stack page
56 * will be marked as present, supervior-only.
57 *
58 * If KPTI is not enabled, the _main_tss.esp0 field will always be updated
59 * updated to point to the top of the privilege elevation stack. Otherwise
60 * _main_tss.esp0 always points to the trampoline stack, which handles the
61 * page table switch to the kernel PDPT and transplants context to the
62 * privileged mode stack.
63 */
64struct z_x86_thread_stack_header {
65#ifdef CONFIG_HW_STACK_PROTECTION
66 char guard_page[CONFIG_MMU_PAGE_SIZE];
67#endif
68#ifdef CONFIG_USERSPACE
69 char privilege_stack[CONFIG_MMU_PAGE_SIZE];
70#endif /* CONFIG_USERSPACE */
71} __packed __aligned(Z_X86_STACK_BASE_ALIGN);
72
73#define ARCH_THREAD_STACK_OBJ_ALIGN(size) Z_X86_STACK_BASE_ALIGN
74
75#define ARCH_THREAD_STACK_SIZE_ADJUST(size) \
76 ROUND_UP((size), Z_X86_STACK_SIZE_ALIGN)
77
78#define ARCH_THREAD_STACK_RESERVED \
79 sizeof(struct z_x86_thread_stack_header)
80
81#ifdef CONFIG_HW_STACK_PROTECTION
82#define ARCH_KERNEL_STACK_RESERVED CONFIG_MMU_PAGE_SIZE
83#define ARCH_KERNEL_STACK_OBJ_ALIGN CONFIG_MMU_PAGE_SIZE
84#else
85#define ARCH_KERNEL_STACK_RESERVED 0
86#define ARCH_KERNEL_STACK_OBJ_ALIGN ARCH_STACK_PTR_ALIGN
87#endif
88
89#endif /* !_ASMLANGUAGE */
90#endif /* ZEPHYR_INCLUDE_ARCH_X86_THREAD_STACK_H */