hc
2024-11-01 2f529f9b558ca1c1bd74be7437a84e4711743404
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
/* SPDX-License-Identifier: GPL-2.0 */
/* thread_info.h: low-level thread information
 *
 * Copyright (C) 2002  David Howells (dhowells@redhat.com)
 * - Incorporating suggestions made by Linus Torvalds and Dave Miller
 */
 
#ifndef _ASM_X86_THREAD_INFO_H
#define _ASM_X86_THREAD_INFO_H
 
#include <linux/compiler.h>
#include <asm/page.h>
#include <asm/percpu.h>
#include <asm/types.h>
 
/*
 * TOP_OF_KERNEL_STACK_PADDING is a number of unused bytes that we
 * reserve at the top of the kernel stack.  We do it because of a nasty
 * 32-bit corner case.  On x86_32, the hardware stack frame is
 * variable-length.  Except for vm86 mode, struct pt_regs assumes a
 * maximum-length frame.  If we enter from CPL 0, the top 8 bytes of
 * pt_regs don't actually exist.  Ordinarily this doesn't matter, but it
 * does in at least one case:
 *
 * If we take an NMI early enough in SYSENTER, then we can end up with
 * pt_regs that extends above sp0.  On the way out, in the espfix code,
 * we can read the saved SS value, but that value will be above sp0.
 * Without this offset, that can result in a page fault.  (We are
 * careful that, in this case, the value we read doesn't matter.)
 *
 * In vm86 mode, the hardware frame is much longer still, so add 16
 * bytes to make room for the real-mode segments.
 *
 * x86_64 has a fixed-length stack frame.
 */
#ifdef CONFIG_X86_32
# ifdef CONFIG_VM86
#  define TOP_OF_KERNEL_STACK_PADDING 16
# else
#  define TOP_OF_KERNEL_STACK_PADDING 8
# endif
#else
# define TOP_OF_KERNEL_STACK_PADDING 0
#endif
 
/*
 * low level task data that entry.S needs immediate access to
 * - this struct should fit entirely inside of one cache line
 * - this struct shares the supervisor stack pages
 */
#ifndef __ASSEMBLY__
struct task_struct;
#include <asm/cpufeature.h>
#include <linux/atomic.h>
#include <dovetail/thread_info.h>
 
struct thread_info {
   unsigned long        flags;        /* low level flags */
   u32            status;        /* thread synchronous flags */
   struct oob_thread_state    oob_state;    /* co-kernel thread state */
};
 
#define INIT_THREAD_INFO(tsk)            \
{                        \
   .flags        = 0,            \
}
 
#define ti_local_flags(__ti)    ((__ti)->status)
 
#else /* !__ASSEMBLY__ */
 
#include <asm/asm-offsets.h>
 
#endif
 
/*
 * thread information flags
 * - these are process state flags that various assembly files
 *   may need to access
 */
#define TIF_SYSCALL_TRACE    0    /* syscall trace active */
#define TIF_NOTIFY_RESUME    1    /* callback before returning to user */
#define TIF_SIGPENDING        2    /* signal pending */
#define TIF_NEED_RESCHED    3    /* rescheduling necessary */
#define TIF_SINGLESTEP        4    /* reenable singlestep on user return*/
#define TIF_SSBD        5    /* Speculative store bypass disable */
#define TIF_SYSCALL_EMU        6    /* syscall emulation active */
#define TIF_SYSCALL_AUDIT    7    /* syscall auditing active */
#define TIF_SECCOMP        8    /* secure computing */
#define TIF_SPEC_IB        9    /* Indirect branch speculation mitigation */
#define TIF_SPEC_FORCE_UPDATE    10    /* Force speculation MSR update in context switch */
#define TIF_USER_RETURN_NOTIFY    11    /* notify kernel of userspace return */
#define TIF_UPROBE        12    /* breakpointed or singlestepping */
#define TIF_PATCH_PENDING    13    /* pending live patching update */
#define TIF_NEED_FPU_LOAD    14    /* load FPU on return to userspace */
#define TIF_NOCPUID        15    /* CPUID is not accessible in userland */
#define TIF_NOTSC        16    /* TSC is not accessible in userland */
#define TIF_IA32        17    /* IA32 compatibility process */
#define TIF_SLD            18    /* Restore split lock detection on context switch */
#define TIF_NOTIFY_SIGNAL    19    /* signal notifications exist */
#define TIF_MEMDIE        20    /* is terminating due to OOM killer */
#define TIF_POLLING_NRFLAG    21    /* idle is polling for TIF_NEED_RESCHED */
#define TIF_IO_BITMAP        22    /* uses I/O bitmap */
#define TIF_RETUSER        23    /* INBAND_TASK_RETUSER is pending */
#define TIF_FORCED_TF        24    /* true if TF in eflags artificially */
#define TIF_BLOCKSTEP        25    /* set when we want DEBUGCTLMSR_BTF */
#define TIF_MAYDAY        26    /* emergency trap pending */
#define TIF_LAZY_MMU_UPDATES    27    /* task is updating the mmu lazily */
#define TIF_SYSCALL_TRACEPOINT    28    /* syscall tracepoint instrumentation */
#define TIF_ADDR32        29    /* 32-bit address space on 64 bits */
#define TIF_X32            30    /* 32-bit native x86-64 binary */
 
#define _TIF_SYSCALL_TRACE    (1 << TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME    (1 << TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING        (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED    (1 << TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP        (1 << TIF_SINGLESTEP)
#define _TIF_SSBD        (1 << TIF_SSBD)
#define _TIF_SYSCALL_EMU    (1 << TIF_SYSCALL_EMU)
#define _TIF_SYSCALL_AUDIT    (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP        (1 << TIF_SECCOMP)
#define _TIF_SPEC_IB        (1 << TIF_SPEC_IB)
#define _TIF_SPEC_FORCE_UPDATE    (1 << TIF_SPEC_FORCE_UPDATE)
#define _TIF_USER_RETURN_NOTIFY    (1 << TIF_USER_RETURN_NOTIFY)
#define _TIF_UPROBE        (1 << TIF_UPROBE)
#define _TIF_PATCH_PENDING    (1 << TIF_PATCH_PENDING)
#define _TIF_NEED_FPU_LOAD    (1 << TIF_NEED_FPU_LOAD)
#define _TIF_NOCPUID        (1 << TIF_NOCPUID)
#define _TIF_NOTSC        (1 << TIF_NOTSC)
#define _TIF_IA32        (1 << TIF_IA32)
#define _TIF_NOTIFY_SIGNAL    (1 << TIF_NOTIFY_SIGNAL)
#define _TIF_SLD        (1 << TIF_SLD)
#define _TIF_POLLING_NRFLAG    (1 << TIF_POLLING_NRFLAG)
#define _TIF_IO_BITMAP        (1 << TIF_IO_BITMAP)
#define _TIF_RETUSER        (1 << TIF_RETUSER)
#define _TIF_FORCED_TF        (1 << TIF_FORCED_TF)
#define _TIF_MAYDAY        (1 << TIF_MAYDAY)
#define _TIF_BLOCKSTEP        (1 << TIF_BLOCKSTEP)
#define _TIF_LAZY_MMU_UPDATES    (1 << TIF_LAZY_MMU_UPDATES)
#define _TIF_SYSCALL_TRACEPOINT    (1 << TIF_SYSCALL_TRACEPOINT)
#define _TIF_ADDR32        (1 << TIF_ADDR32)
#define _TIF_X32        (1 << TIF_X32)
 
/* flags to check in __switch_to() */
#define _TIF_WORK_CTXSW_BASE                    \
   (_TIF_NOCPUID | _TIF_NOTSC | _TIF_BLOCKSTEP |        \
    _TIF_SSBD | _TIF_SPEC_FORCE_UPDATE | _TIF_SLD)
 
/*
 * Avoid calls to __switch_to_xtra() on UP as STIBP is not evaluated.
 */
#ifdef CONFIG_SMP
# define _TIF_WORK_CTXSW    (_TIF_WORK_CTXSW_BASE | _TIF_SPEC_IB)
#else
# define _TIF_WORK_CTXSW    (_TIF_WORK_CTXSW_BASE)
#endif
 
#ifdef CONFIG_X86_IOPL_IOPERM
# define _TIF_WORK_CTXSW_PREV    (_TIF_WORK_CTXSW| _TIF_USER_RETURN_NOTIFY | \
                _TIF_IO_BITMAP)
#else
# define _TIF_WORK_CTXSW_PREV    (_TIF_WORK_CTXSW| _TIF_USER_RETURN_NOTIFY)
#endif
 
#define _TIF_WORK_CTXSW_NEXT    (_TIF_WORK_CTXSW)
 
#define STACK_WARN        (THREAD_SIZE/8)
 
/*
 * macros/functions for gaining access to the thread information structure
 *
 * preempt_count needs to be 1 initially, until the scheduler is functional.
 */
#ifndef __ASSEMBLY__
 
/*
 * Walks up the stack frames to make sure that the specified object is
 * entirely contained by a single stack frame.
 *
 * Returns:
 *    GOOD_FRAME    if within a frame
 *    BAD_STACK    if placed across a frame boundary (or outside stack)
 *    NOT_STACK    unable to determine (no frame pointers, etc)
 */
static inline int arch_within_stack_frames(const void * const stack,
                      const void * const stackend,
                      const void *obj, unsigned long len)
{
#if defined(CONFIG_FRAME_POINTER)
   const void *frame = NULL;
   const void *oldframe;
 
   oldframe = __builtin_frame_address(1);
   if (oldframe)
       frame = __builtin_frame_address(2);
   /*
    * low ----------------------------------------------> high
    * [saved bp][saved ip][args][local vars][saved bp][saved ip]
    *                     ^----------------^
    *               allow copies only within here
    */
   while (stack <= frame && frame < stackend) {
       /*
        * If obj + len extends past the last frame, this
        * check won't pass and the next frame will be 0,
        * causing us to bail out and correctly report
        * the copy as invalid.
        */
       if (obj + len <= frame)
           return obj >= oldframe + 2 * sizeof(void *) ?
               GOOD_FRAME : BAD_STACK;
       oldframe = frame;
       frame = *(const void * const *)frame;
   }
   return BAD_STACK;
#else
   return NOT_STACK;
#endif
}
 
#else /* !__ASSEMBLY__ */
 
#ifdef CONFIG_X86_64
# define cpu_current_top_of_stack (cpu_tss_rw + TSS_sp1)
#endif
 
#endif
 
/*
 * Thread-synchronous status.
 *
 * This is different from the flags in that nobody else
 * ever touches our thread-synchronous status, so we don't
 * have to worry about atomic accesses.
 */
#define TS_COMPAT        0x0002    /* 32bit syscall active (64BIT)*/
/* bits 2 and 3 reserved for compat */
#define TS_OOB            0x0010    /* Thread is running out-of-band */
#define TS_DOVETAIL        0x0020  /* Dovetail notifier enabled */
#define TS_OFFSTAGE        0x0040    /* Thread is in-flight to OOB context */
#define TS_OOBTRAP        0x0080    /* Handling a trap from OOB context */
 
#define _TLF_OOB        TS_OOB
#define _TLF_DOVETAIL        TS_DOVETAIL
#define _TLF_OFFSTAGE        TS_OFFSTAGE
#define _TLF_OOBTRAP        TS_OOBTRAP
 
#ifndef __ASSEMBLY__
#ifdef CONFIG_COMPAT
#define TS_I386_REGS_POKED    0x0004    /* regs poked by 32-bit ptracer */
#define TS_COMPAT_RESTART    0x0008
 
#define arch_set_restart_data    arch_set_restart_data
 
static inline void arch_set_restart_data(struct restart_block *restart)
{
   struct thread_info *ti = current_thread_info();
   if (ti->status & TS_COMPAT)
       ti->status |= TS_COMPAT_RESTART;
   else
       ti->status &= ~TS_COMPAT_RESTART;
}
#endif
 
#ifdef CONFIG_X86_32
#define in_ia32_syscall() true
#else
#define in_ia32_syscall() (IS_ENABLED(CONFIG_IA32_EMULATION) && \
              current_thread_info()->status & TS_COMPAT)
#endif
 
extern void arch_task_cache_init(void);
extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
extern void arch_release_task_struct(struct task_struct *tsk);
extern void arch_setup_new_exec(void);
#define arch_setup_new_exec arch_setup_new_exec
#endif    /* !__ASSEMBLY__ */
 
#endif /* _ASM_X86_THREAD_INFO_H */