| /* 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> | 
|   | 
| struct thread_info { | 
|     unsigned long        flags;        /* low level flags */ | 
|     u32            status;        /* thread synchronous flags */ | 
| }; | 
|   | 
| #define INIT_THREAD_INFO(tsk)            \ | 
| {                        \ | 
|     .flags        = 0,            \ | 
| } | 
|   | 
| #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_FORCED_TF        24    /* true if TF in eflags artificially */ | 
| #define TIF_BLOCKSTEP        25    /* set when we want DEBUGCTLMSR_BTF */ | 
| #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_FORCED_TF        (1 << TIF_FORCED_TF) | 
| #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)*/ | 
|   | 
| #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 */ |