1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2c767a54bSJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
3c767a54bSJoe Perches
461c4628bSSuresh Siddha #include <linux/errno.h>
561c4628bSSuresh Siddha #include <linux/kernel.h>
661c4628bSSuresh Siddha #include <linux/mm.h>
761c4628bSSuresh Siddha #include <linux/smp.h>
8b4c108d7SPhilippe Mathieu-Daudé #include <linux/cpu.h>
9389d1fb1SJeremy Fitzhardinge #include <linux/prctl.h>
1061c4628bSSuresh Siddha #include <linux/slab.h>
1161c4628bSSuresh Siddha #include <linux/sched.h>
124c822698SIngo Molnar #include <linux/sched/idle.h>
13b17b0153SIngo Molnar #include <linux/sched/debug.h>
1429930025SIngo Molnar #include <linux/sched/task.h>
1568db0cf1SIngo Molnar #include <linux/sched/task_stack.h>
16186f4360SPaul Gortmaker #include <linux/init.h>
17186f4360SPaul Gortmaker #include <linux/export.h>
187f424a8bSPeter Zijlstra #include <linux/pm.h>
19162a688eSThomas Gleixner #include <linux/tick.h>
209d62dcdfSAmerigo Wang #include <linux/random.h>
217c68af6eSAvi Kivity #include <linux/user-return-notifier.h>
22814e2c84SAndy Isaacson #include <linux/dmi.h>
23814e2c84SAndy Isaacson #include <linux/utsname.h>
2490e24014SRichard Weinberger #include <linux/stackprotector.h>
2590e24014SRichard Weinberger #include <linux/cpuidle.h>
2689f579ceSYi Wang #include <linux/acpi.h>
2789f579ceSYi Wang #include <linux/elf-randomize.h>
28aaa3896bSPeter Zijlstra #include <linux/static_call.h>
2961613521SArjan van de Ven #include <trace/events/power.h>
3024f1e32cSFrederic Weisbecker #include <linux/hw_breakpoint.h>
313aec4ecbSBrian Gerst #include <linux/entry-common.h>
3293789b32SBorislav Petkov #include <asm/cpu.h>
33d3ec5caeSIvan Vecera #include <asm/apic.h>
347c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
35b253149bSLen Brown #include <asm/mwait.h>
36db8268dfSChang S. Bae #include <asm/fpu/api.h>
3763e81807SThomas Gleixner #include <asm/fpu/sched.h>
38500afbf6SChang S. Bae #include <asm/fpu/xstate.h>
3966cb5917SK.Prasad #include <asm/debugreg.h>
4090e24014SRichard Weinberger #include <asm/nmi.h>
41375074ccSAndy Lutomirski #include <asm/tlbflush.h>
428838eb6cSAshok Raj #include <asm/mce.h>
439fda6a06SBrian Gerst #include <asm/vm86.h>
447b32aeadSBrian Gerst #include <asm/switch_to.h>
45b7ffc44dSAndy Lutomirski #include <asm/desc.h>
46e9ea1e7fSKyle Huey #include <asm/prctl.h>
47885f82bfSThomas Gleixner #include <asm/spec-ctrl.h>
48577d5cd7SThomas Gleixner #include <asm/io_bitmap.h>
4989f579ceSYi Wang #include <asm/proto.h>
506f9885a3SJosh Poimboeuf #include <asm/frame.h>
515d1ceb39SPeter Zijlstra #include <asm/unwind.h>
52bfe6ed0cSKirill A. Shutemov #include <asm/tdx.h>
5374c228d2SKirill A. Shutemov #include <asm/mmu_context.h>
54b2926a36SRick Edgecombe #include <asm/shstk.h>
5590e24014SRichard Weinberger
56ff16701aSThomas Gleixner #include "process.h"
57ff16701aSThomas Gleixner
5845046892SThomas Gleixner /*
5945046892SThomas Gleixner * per-CPU TSS segments. Threads are completely 'soft' on Linux,
6045046892SThomas Gleixner * no more per-task TSS's. The TSS size is kept cacheline-aligned
6145046892SThomas Gleixner * so they are allowed to end up in the .data..cacheline_aligned
6245046892SThomas Gleixner * section. Since TSS's are completely CPU-local, we want them
6345046892SThomas Gleixner * on exact cacheline boundaries, to eliminate cacheline ping-pong.
6445046892SThomas Gleixner */
652fd9c41aSNick Desaulniers __visible DEFINE_PER_CPU_PAGE_ALIGNED(struct tss_struct, cpu_tss_rw) = {
66d0a0de21SAndy Lutomirski .x86_tss = {
6720bb8344SAndy Lutomirski /*
6820bb8344SAndy Lutomirski * .sp0 is only used when entering ring 0 from a lower
6920bb8344SAndy Lutomirski * privilege level. Since the init task never runs anything
7020bb8344SAndy Lutomirski * but ring 0 code, there is no need for a valid value here.
7120bb8344SAndy Lutomirski * Poison it.
7220bb8344SAndy Lutomirski */
7320bb8344SAndy Lutomirski .sp0 = (1UL << (BITS_PER_LONG-1)) + 1,
749aaefe7bSAndy Lutomirski
751591584eSLai Jiangshan #ifdef CONFIG_X86_32
769aaefe7bSAndy Lutomirski .sp1 = TOP_OF_INIT_STACK,
779aaefe7bSAndy Lutomirski
78d0a0de21SAndy Lutomirski .ss0 = __KERNEL_DS,
79d0a0de21SAndy Lutomirski .ss1 = __KERNEL_CS,
80d0a0de21SAndy Lutomirski #endif
81ecc7e37dSThomas Gleixner .io_bitmap_base = IO_BITMAP_OFFSET_INVALID,
82d0a0de21SAndy Lutomirski },
83d0a0de21SAndy Lutomirski };
84c482feefSAndy Lutomirski EXPORT_PER_CPU_SYMBOL(cpu_tss_rw);
8545046892SThomas Gleixner
86b7ceaec1SAndy Lutomirski DEFINE_PER_CPU(bool, __tss_limit_invalid);
87b7ceaec1SAndy Lutomirski EXPORT_PER_CPU_SYMBOL_GPL(__tss_limit_invalid);
88b7ffc44dSAndy Lutomirski
8955ccf3feSSuresh Siddha /*
9055ccf3feSSuresh Siddha * this gets called so that we can store lazy state into memory and copy the
9155ccf3feSSuresh Siddha * current task into the new thread.
9255ccf3feSSuresh Siddha */
arch_dup_task_struct(struct task_struct * dst,struct task_struct * src)9361c4628bSSuresh Siddha int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
9461c4628bSSuresh Siddha {
955aaeb5c0SIngo Molnar memcpy(dst, src, arch_task_struct_size);
962459ee86SAndy Lutomirski #ifdef CONFIG_VM86
972459ee86SAndy Lutomirski dst->thread.vm86 = NULL;
982459ee86SAndy Lutomirski #endif
99f0cbc8b3SThomas Gleixner /* Drop the copied pointer to current's fpstate */
100f0cbc8b3SThomas Gleixner dst->thread.fpu.fpstate = NULL;
101500afbf6SChang S. Bae
1022d16a187SThomas Gleixner return 0;
10361c4628bSSuresh Siddha }
1047f424a8bSPeter Zijlstra
105500afbf6SChang S. Bae #ifdef CONFIG_X86_64
arch_release_task_struct(struct task_struct * tsk)106500afbf6SChang S. Bae void arch_release_task_struct(struct task_struct *tsk)
107500afbf6SChang S. Bae {
108500afbf6SChang S. Bae if (fpu_state_size_dynamic())
109500afbf6SChang S. Bae fpstate_free(&tsk->thread.fpu);
110500afbf6SChang S. Bae }
111500afbf6SChang S. Bae #endif
112500afbf6SChang S. Bae
11300dba564SThomas Gleixner /*
1144bfe6cceSJay Lang * Free thread data structures etc..
115389d1fb1SJeremy Fitzhardinge */
exit_thread(struct task_struct * tsk)116e6464694SJiri Slaby void exit_thread(struct task_struct *tsk)
117389d1fb1SJeremy Fitzhardinge {
118e6464694SJiri Slaby struct thread_struct *t = &tsk->thread;
119ca6787baSIngo Molnar struct fpu *fpu = &t->fpu;
120389d1fb1SJeremy Fitzhardinge
121ea5f1cd7SThomas Gleixner if (test_thread_flag(TIF_IO_BITMAP))
1224bfe6cceSJay Lang io_bitmap_exit(tsk);
1231dcc8d7bSSuresh Siddha
1249fda6a06SBrian Gerst free_vm86(t);
1259fda6a06SBrian Gerst
126b2926a36SRick Edgecombe shstk_free(tsk);
12750338615SIngo Molnar fpu__drop(fpu);
128389d1fb1SJeremy Fitzhardinge }
129389d1fb1SJeremy Fitzhardinge
set_new_tls(struct task_struct * p,unsigned long tls)1302fff071dSThomas Gleixner static int set_new_tls(struct task_struct *p, unsigned long tls)
1312fff071dSThomas Gleixner {
1322fff071dSThomas Gleixner struct user_desc __user *utls = (struct user_desc __user *)tls;
1332fff071dSThomas Gleixner
1342fff071dSThomas Gleixner if (in_ia32_syscall())
1352fff071dSThomas Gleixner return do_set_thread_area(p, -1, utls, 0);
1362fff071dSThomas Gleixner else
1372fff071dSThomas Gleixner return do_set_thread_area_64(p, ARCH_SET_FS, tls);
1382fff071dSThomas Gleixner }
1392fff071dSThomas Gleixner
ret_from_fork(struct task_struct * prev,struct pt_regs * regs,int (* fn)(void *),void * fn_arg)1403aec4ecbSBrian Gerst __visible void ret_from_fork(struct task_struct *prev, struct pt_regs *regs,
1413aec4ecbSBrian Gerst int (*fn)(void *), void *fn_arg)
1423aec4ecbSBrian Gerst {
1433aec4ecbSBrian Gerst schedule_tail(prev);
1443aec4ecbSBrian Gerst
1453aec4ecbSBrian Gerst /* Is this a kernel thread? */
1463aec4ecbSBrian Gerst if (unlikely(fn)) {
1473aec4ecbSBrian Gerst fn(fn_arg);
1483aec4ecbSBrian Gerst /*
1493aec4ecbSBrian Gerst * A kernel thread is allowed to return here after successfully
1503aec4ecbSBrian Gerst * calling kernel_execve(). Exit to userspace to complete the
1513aec4ecbSBrian Gerst * execve() syscall.
1523aec4ecbSBrian Gerst */
1533aec4ecbSBrian Gerst regs->ax = 0;
1543aec4ecbSBrian Gerst }
1553aec4ecbSBrian Gerst
1563aec4ecbSBrian Gerst syscall_exit_to_user_mode(regs);
1573aec4ecbSBrian Gerst }
1583aec4ecbSBrian Gerst
copy_thread(struct task_struct * p,const struct kernel_clone_args * args)159c5febea0SEric W. Biederman int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
1602fff071dSThomas Gleixner {
161c5febea0SEric W. Biederman unsigned long clone_flags = args->flags;
162c5febea0SEric W. Biederman unsigned long sp = args->stack;
163c5febea0SEric W. Biederman unsigned long tls = args->tls;
1642fff071dSThomas Gleixner struct inactive_task_frame *frame;
1652fff071dSThomas Gleixner struct fork_frame *fork_frame;
1662fff071dSThomas Gleixner struct pt_regs *childregs;
167b2926a36SRick Edgecombe unsigned long new_ssp;
1684804e382SThomas Gleixner int ret = 0;
1692fff071dSThomas Gleixner
1702fff071dSThomas Gleixner childregs = task_pt_regs(p);
1712fff071dSThomas Gleixner fork_frame = container_of(childregs, struct fork_frame, regs);
1722fff071dSThomas Gleixner frame = &fork_frame->frame;
1732fff071dSThomas Gleixner
1746f9885a3SJosh Poimboeuf frame->bp = encode_frame_pointer(childregs);
1753aec4ecbSBrian Gerst frame->ret_addr = (unsigned long) ret_from_fork_asm;
1762fff071dSThomas Gleixner p->thread.sp = (unsigned long) fork_frame;
177577d5cd7SThomas Gleixner p->thread.io_bitmap = NULL;
178b968e84bSPeter Zijlstra p->thread.iopl_warn = 0;
1792fff071dSThomas Gleixner memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
1802fff071dSThomas Gleixner
1812fff071dSThomas Gleixner #ifdef CONFIG_X86_64
182005f141eSChang S. Bae current_save_fsgs();
183005f141eSChang S. Bae p->thread.fsindex = current->thread.fsindex;
184005f141eSChang S. Bae p->thread.fsbase = current->thread.fsbase;
185005f141eSChang S. Bae p->thread.gsindex = current->thread.gsindex;
186005f141eSChang S. Bae p->thread.gsbase = current->thread.gsbase;
187005f141eSChang S. Bae
1882fff071dSThomas Gleixner savesegment(es, p->thread.es);
1892fff071dSThomas Gleixner savesegment(ds, p->thread.ds);
1902f8794bdSKirill A. Shutemov
1912f8794bdSKirill A. Shutemov if (p->mm && (clone_flags & (CLONE_VM | CLONE_VFORK)) == CLONE_VM)
1922f8794bdSKirill A. Shutemov set_bit(MM_CONTEXT_LOCK_LAM, &p->mm->context.flags);
1932fff071dSThomas Gleixner #else
1942fff071dSThomas Gleixner p->thread.sp0 = (unsigned long) (childregs + 1);
1953a24a608SBrian Gerst savesegment(gs, p->thread.gs);
1962fff071dSThomas Gleixner /*
1972fff071dSThomas Gleixner * Clear all status flags including IF and set fixed bit. 64bit
1982fff071dSThomas Gleixner * does not have this initialization as the frame does not contain
1992fff071dSThomas Gleixner * flags. The flags consistency (especially vs. AC) is there
2002fff071dSThomas Gleixner * ensured via objtool, which lacks 32bit support.
2012fff071dSThomas Gleixner */
2022fff071dSThomas Gleixner frame->flags = X86_EFLAGS_FIXED;
2032fff071dSThomas Gleixner #endif
2042fff071dSThomas Gleixner
205b2926a36SRick Edgecombe /*
206b2926a36SRick Edgecombe * Allocate a new shadow stack for thread if needed. If shadow stack,
207b2926a36SRick Edgecombe * is disabled, new_ssp will remain 0, and fpu_clone() will know not to
208b2926a36SRick Edgecombe * update it.
209b2926a36SRick Edgecombe */
210b2926a36SRick Edgecombe new_ssp = shstk_alloc_thread_stack(p, clone_flags, args->stack_size);
211b2926a36SRick Edgecombe if (IS_ERR_VALUE(new_ssp))
212b2926a36SRick Edgecombe return PTR_ERR((void *)new_ssp);
213b2926a36SRick Edgecombe
214b2926a36SRick Edgecombe fpu_clone(p, clone_flags, args->fn, new_ssp);
2152d16a187SThomas Gleixner
2162fff071dSThomas Gleixner /* Kernel thread ? */
21750b7b6f2SStefan Metzmacher if (unlikely(p->flags & PF_KTHREAD)) {
2189782a712SDave Hansen p->thread.pkru = pkru_get_init_value();
2192fff071dSThomas Gleixner memset(childregs, 0, sizeof(struct pt_regs));
2205bd2e97cSEric W. Biederman kthread_frame_init(frame, args->fn, args->fn_arg);
2212fff071dSThomas Gleixner return 0;
2222fff071dSThomas Gleixner }
2232fff071dSThomas Gleixner
2249782a712SDave Hansen /*
2259782a712SDave Hansen * Clone current's PKRU value from hardware. tsk->thread.pkru
2269782a712SDave Hansen * is only valid when scheduled out.
2279782a712SDave Hansen */
2289782a712SDave Hansen p->thread.pkru = read_pkru();
2299782a712SDave Hansen
2302fff071dSThomas Gleixner frame->bx = 0;
2312fff071dSThomas Gleixner *childregs = *current_pt_regs();
2322fff071dSThomas Gleixner childregs->ax = 0;
2332fff071dSThomas Gleixner if (sp)
2342fff071dSThomas Gleixner childregs->sp = sp;
2352fff071dSThomas Gleixner
2365bd2e97cSEric W. Biederman if (unlikely(args->fn)) {
23750b7b6f2SStefan Metzmacher /*
2385bd2e97cSEric W. Biederman * A user space thread, but it doesn't return to
2395bd2e97cSEric W. Biederman * ret_after_fork().
24050b7b6f2SStefan Metzmacher *
24150b7b6f2SStefan Metzmacher * In order to indicate that to tools like gdb,
24250b7b6f2SStefan Metzmacher * we reset the stack and instruction pointers.
24350b7b6f2SStefan Metzmacher *
24450b7b6f2SStefan Metzmacher * It does the same kernel frame setup to return to a kernel
24550b7b6f2SStefan Metzmacher * function that a kernel thread does.
24650b7b6f2SStefan Metzmacher */
24750b7b6f2SStefan Metzmacher childregs->sp = 0;
24850b7b6f2SStefan Metzmacher childregs->ip = 0;
2495bd2e97cSEric W. Biederman kthread_frame_init(frame, args->fn, args->fn_arg);
25050b7b6f2SStefan Metzmacher return 0;
25150b7b6f2SStefan Metzmacher }
25250b7b6f2SStefan Metzmacher
2532fff071dSThomas Gleixner /* Set a new TLS for the child thread? */
2544804e382SThomas Gleixner if (clone_flags & CLONE_SETTLS)
2552fff071dSThomas Gleixner ret = set_new_tls(p, tls);
2564804e382SThomas Gleixner
2574804e382SThomas Gleixner if (!ret && unlikely(test_tsk_thread_flag(current, TIF_IO_BITMAP)))
2584804e382SThomas Gleixner io_bitmap_share(p);
2594804e382SThomas Gleixner
2602fff071dSThomas Gleixner return ret;
2612fff071dSThomas Gleixner }
2622fff071dSThomas Gleixner
pkru_flush_thread(void)26333344368SAndy Lutomirski static void pkru_flush_thread(void)
26433344368SAndy Lutomirski {
26533344368SAndy Lutomirski /*
26633344368SAndy Lutomirski * If PKRU is enabled the default PKRU value has to be loaded into
26733344368SAndy Lutomirski * the hardware right here (similar to context switch).
26833344368SAndy Lutomirski */
26933344368SAndy Lutomirski pkru_write_default();
27033344368SAndy Lutomirski }
27133344368SAndy Lutomirski
flush_thread(void)272389d1fb1SJeremy Fitzhardinge void flush_thread(void)
273389d1fb1SJeremy Fitzhardinge {
274389d1fb1SJeremy Fitzhardinge struct task_struct *tsk = current;
275389d1fb1SJeremy Fitzhardinge
27624f1e32cSFrederic Weisbecker flush_ptrace_hw_breakpoint(tsk);
277389d1fb1SJeremy Fitzhardinge memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
278110d7f75SOleg Nesterov
279e7ecad17SThomas Gleixner fpu_flush_thread();
28033344368SAndy Lutomirski pkru_flush_thread();
281389d1fb1SJeremy Fitzhardinge }
282389d1fb1SJeremy Fitzhardinge
disable_TSC(void)283389d1fb1SJeremy Fitzhardinge void disable_TSC(void)
284389d1fb1SJeremy Fitzhardinge {
285389d1fb1SJeremy Fitzhardinge preempt_disable();
286389d1fb1SJeremy Fitzhardinge if (!test_and_set_thread_flag(TIF_NOTSC))
287389d1fb1SJeremy Fitzhardinge /*
288389d1fb1SJeremy Fitzhardinge * Must flip the CPU state synchronously with
289389d1fb1SJeremy Fitzhardinge * TIF_NOTSC in the current running context.
290389d1fb1SJeremy Fitzhardinge */
2915a920155SThomas Gleixner cr4_set_bits(X86_CR4_TSD);
292389d1fb1SJeremy Fitzhardinge preempt_enable();
293389d1fb1SJeremy Fitzhardinge }
294389d1fb1SJeremy Fitzhardinge
enable_TSC(void)295389d1fb1SJeremy Fitzhardinge static void enable_TSC(void)
296389d1fb1SJeremy Fitzhardinge {
297389d1fb1SJeremy Fitzhardinge preempt_disable();
298389d1fb1SJeremy Fitzhardinge if (test_and_clear_thread_flag(TIF_NOTSC))
299389d1fb1SJeremy Fitzhardinge /*
300389d1fb1SJeremy Fitzhardinge * Must flip the CPU state synchronously with
301389d1fb1SJeremy Fitzhardinge * TIF_NOTSC in the current running context.
302389d1fb1SJeremy Fitzhardinge */
3035a920155SThomas Gleixner cr4_clear_bits(X86_CR4_TSD);
304389d1fb1SJeremy Fitzhardinge preempt_enable();
305389d1fb1SJeremy Fitzhardinge }
306389d1fb1SJeremy Fitzhardinge
get_tsc_mode(unsigned long adr)307389d1fb1SJeremy Fitzhardinge int get_tsc_mode(unsigned long adr)
308389d1fb1SJeremy Fitzhardinge {
309389d1fb1SJeremy Fitzhardinge unsigned int val;
310389d1fb1SJeremy Fitzhardinge
311389d1fb1SJeremy Fitzhardinge if (test_thread_flag(TIF_NOTSC))
312389d1fb1SJeremy Fitzhardinge val = PR_TSC_SIGSEGV;
313389d1fb1SJeremy Fitzhardinge else
314389d1fb1SJeremy Fitzhardinge val = PR_TSC_ENABLE;
315389d1fb1SJeremy Fitzhardinge
316389d1fb1SJeremy Fitzhardinge return put_user(val, (unsigned int __user *)adr);
317389d1fb1SJeremy Fitzhardinge }
318389d1fb1SJeremy Fitzhardinge
set_tsc_mode(unsigned int val)319389d1fb1SJeremy Fitzhardinge int set_tsc_mode(unsigned int val)
320389d1fb1SJeremy Fitzhardinge {
321389d1fb1SJeremy Fitzhardinge if (val == PR_TSC_SIGSEGV)
322389d1fb1SJeremy Fitzhardinge disable_TSC();
323389d1fb1SJeremy Fitzhardinge else if (val == PR_TSC_ENABLE)
324389d1fb1SJeremy Fitzhardinge enable_TSC();
325389d1fb1SJeremy Fitzhardinge else
326389d1fb1SJeremy Fitzhardinge return -EINVAL;
327389d1fb1SJeremy Fitzhardinge
328389d1fb1SJeremy Fitzhardinge return 0;
329389d1fb1SJeremy Fitzhardinge }
330389d1fb1SJeremy Fitzhardinge
331e9ea1e7fSKyle Huey DEFINE_PER_CPU(u64, msr_misc_features_shadow);
332e9ea1e7fSKyle Huey
set_cpuid_faulting(bool on)333e9ea1e7fSKyle Huey static void set_cpuid_faulting(bool on)
334e9ea1e7fSKyle Huey {
335e9ea1e7fSKyle Huey u64 msrval;
336e9ea1e7fSKyle Huey
337e9ea1e7fSKyle Huey msrval = this_cpu_read(msr_misc_features_shadow);
338e9ea1e7fSKyle Huey msrval &= ~MSR_MISC_FEATURES_ENABLES_CPUID_FAULT;
339e9ea1e7fSKyle Huey msrval |= (on << MSR_MISC_FEATURES_ENABLES_CPUID_FAULT_BIT);
340e9ea1e7fSKyle Huey this_cpu_write(msr_misc_features_shadow, msrval);
341e9ea1e7fSKyle Huey wrmsrl(MSR_MISC_FEATURES_ENABLES, msrval);
342e9ea1e7fSKyle Huey }
343e9ea1e7fSKyle Huey
disable_cpuid(void)344e9ea1e7fSKyle Huey static void disable_cpuid(void)
345e9ea1e7fSKyle Huey {
346e9ea1e7fSKyle Huey preempt_disable();
347e9ea1e7fSKyle Huey if (!test_and_set_thread_flag(TIF_NOCPUID)) {
348e9ea1e7fSKyle Huey /*
349e9ea1e7fSKyle Huey * Must flip the CPU state synchronously with
350e9ea1e7fSKyle Huey * TIF_NOCPUID in the current running context.
351e9ea1e7fSKyle Huey */
352e9ea1e7fSKyle Huey set_cpuid_faulting(true);
353e9ea1e7fSKyle Huey }
354e9ea1e7fSKyle Huey preempt_enable();
355e9ea1e7fSKyle Huey }
356e9ea1e7fSKyle Huey
enable_cpuid(void)357e9ea1e7fSKyle Huey static void enable_cpuid(void)
358e9ea1e7fSKyle Huey {
359e9ea1e7fSKyle Huey preempt_disable();
360e9ea1e7fSKyle Huey if (test_and_clear_thread_flag(TIF_NOCPUID)) {
361e9ea1e7fSKyle Huey /*
362e9ea1e7fSKyle Huey * Must flip the CPU state synchronously with
363e9ea1e7fSKyle Huey * TIF_NOCPUID in the current running context.
364e9ea1e7fSKyle Huey */
365e9ea1e7fSKyle Huey set_cpuid_faulting(false);
366e9ea1e7fSKyle Huey }
367e9ea1e7fSKyle Huey preempt_enable();
368e9ea1e7fSKyle Huey }
369e9ea1e7fSKyle Huey
get_cpuid_mode(void)370e9ea1e7fSKyle Huey static int get_cpuid_mode(void)
371e9ea1e7fSKyle Huey {
372e9ea1e7fSKyle Huey return !test_thread_flag(TIF_NOCPUID);
373e9ea1e7fSKyle Huey }
374e9ea1e7fSKyle Huey
set_cpuid_mode(unsigned long cpuid_enabled)375f5c0b4f3SThomas Gleixner static int set_cpuid_mode(unsigned long cpuid_enabled)
376e9ea1e7fSKyle Huey {
37767e87d43SBorislav Petkov if (!boot_cpu_has(X86_FEATURE_CPUID_FAULT))
378e9ea1e7fSKyle Huey return -ENODEV;
379e9ea1e7fSKyle Huey
380e9ea1e7fSKyle Huey if (cpuid_enabled)
381e9ea1e7fSKyle Huey enable_cpuid();
382e9ea1e7fSKyle Huey else
383e9ea1e7fSKyle Huey disable_cpuid();
384e9ea1e7fSKyle Huey
385e9ea1e7fSKyle Huey return 0;
386e9ea1e7fSKyle Huey }
387e9ea1e7fSKyle Huey
388e9ea1e7fSKyle Huey /*
389e9ea1e7fSKyle Huey * Called immediately after a successful exec.
390e9ea1e7fSKyle Huey */
arch_setup_new_exec(void)391e9ea1e7fSKyle Huey void arch_setup_new_exec(void)
392e9ea1e7fSKyle Huey {
393e9ea1e7fSKyle Huey /* If cpuid was previously disabled for this task, re-enable it. */
394e9ea1e7fSKyle Huey if (test_thread_flag(TIF_NOCPUID))
395e9ea1e7fSKyle Huey enable_cpuid();
39671368af9SWaiman Long
39771368af9SWaiman Long /*
39871368af9SWaiman Long * Don't inherit TIF_SSBD across exec boundary when
39971368af9SWaiman Long * PR_SPEC_DISABLE_NOEXEC is used.
40071368af9SWaiman Long */
40171368af9SWaiman Long if (test_thread_flag(TIF_SSBD) &&
40271368af9SWaiman Long task_spec_ssb_noexec(current)) {
40371368af9SWaiman Long clear_thread_flag(TIF_SSBD);
40471368af9SWaiman Long task_clear_spec_ssb_disable(current);
40571368af9SWaiman Long task_clear_spec_ssb_noexec(current);
406dca99fb6SMark Rutland speculation_ctrl_update(read_thread_flags());
40771368af9SWaiman Long }
40874c228d2SKirill A. Shutemov
40974c228d2SKirill A. Shutemov mm_reset_untag_mask(current->mm);
410e9ea1e7fSKyle Huey }
411e9ea1e7fSKyle Huey
412111e7b15SThomas Gleixner #ifdef CONFIG_X86_IOPL_IOPERM
switch_to_bitmap(unsigned long tifp)41322fe5b04SThomas Gleixner static inline void switch_to_bitmap(unsigned long tifp)
41422fe5b04SThomas Gleixner {
41522fe5b04SThomas Gleixner /*
41622fe5b04SThomas Gleixner * Invalidate I/O bitmap if the previous task used it. This prevents
41722fe5b04SThomas Gleixner * any possible leakage of an active I/O bitmap.
41822fe5b04SThomas Gleixner *
41922fe5b04SThomas Gleixner * If the next task has an I/O bitmap it will handle it on exit to
42022fe5b04SThomas Gleixner * user mode.
42122fe5b04SThomas Gleixner */
42222fe5b04SThomas Gleixner if (tifp & _TIF_IO_BITMAP)
423cadfad87SAndy Lutomirski tss_invalidate_io_bitmap();
42422fe5b04SThomas Gleixner }
42522fe5b04SThomas Gleixner
tss_copy_io_bitmap(struct tss_struct * tss,struct io_bitmap * iobm)42622fe5b04SThomas Gleixner static void tss_copy_io_bitmap(struct tss_struct *tss, struct io_bitmap *iobm)
427060aa16fSThomas Gleixner {
428060aa16fSThomas Gleixner /*
429060aa16fSThomas Gleixner * Copy at least the byte range of the incoming tasks bitmap which
430060aa16fSThomas Gleixner * covers the permitted I/O ports.
431060aa16fSThomas Gleixner *
432060aa16fSThomas Gleixner * If the previous task which used an I/O bitmap had more bits
433060aa16fSThomas Gleixner * permitted, then the copy needs to cover those as well so they
434060aa16fSThomas Gleixner * get turned off.
435060aa16fSThomas Gleixner */
436060aa16fSThomas Gleixner memcpy(tss->io_bitmap.bitmap, iobm->bitmap,
437060aa16fSThomas Gleixner max(tss->io_bitmap.prev_max, iobm->max));
438060aa16fSThomas Gleixner
439060aa16fSThomas Gleixner /*
440060aa16fSThomas Gleixner * Store the new max and the sequence number of this bitmap
441060aa16fSThomas Gleixner * and a pointer to the bitmap itself.
442060aa16fSThomas Gleixner */
443060aa16fSThomas Gleixner tss->io_bitmap.prev_max = iobm->max;
444060aa16fSThomas Gleixner tss->io_bitmap.prev_sequence = iobm->sequence;
445060aa16fSThomas Gleixner }
446060aa16fSThomas Gleixner
44722fe5b04SThomas Gleixner /**
448dbb5ab6dSJiapeng Chong * native_tss_update_io_bitmap - Update I/O bitmap before exiting to user mode
44922fe5b04SThomas Gleixner */
native_tss_update_io_bitmap(void)45099bcd4a6SJuergen Gross void native_tss_update_io_bitmap(void)
451389d1fb1SJeremy Fitzhardinge {
452ff16701aSThomas Gleixner struct tss_struct *tss = this_cpu_ptr(&cpu_tss_rw);
4537b0b8cfdSBorislav Petkov struct thread_struct *t = ¤t->thread;
454c8137aceSThomas Gleixner u16 *base = &tss->x86_tss.io_bitmap_base;
455ff16701aSThomas Gleixner
4567b0b8cfdSBorislav Petkov if (!test_thread_flag(TIF_IO_BITMAP)) {
457cadfad87SAndy Lutomirski native_tss_invalidate_io_bitmap();
4587b0b8cfdSBorislav Petkov return;
4597b0b8cfdSBorislav Petkov }
460577d5cd7SThomas Gleixner
461e3cb0c71SAlexander Duyck if (IS_ENABLED(CONFIG_X86_IOPL_IOPERM) && t->iopl_emul == 3) {
462c8137aceSThomas Gleixner *base = IO_BITMAP_OFFSET_VALID_ALL;
463c8137aceSThomas Gleixner } else {
464c8137aceSThomas Gleixner struct io_bitmap *iobm = t->io_bitmap;
4657b0b8cfdSBorislav Petkov
466389d1fb1SJeremy Fitzhardinge /*
4677b0b8cfdSBorislav Petkov * Only copy bitmap data when the sequence number differs. The
4687b0b8cfdSBorislav Petkov * update time is accounted to the incoming task.
469389d1fb1SJeremy Fitzhardinge */
470060aa16fSThomas Gleixner if (tss->io_bitmap.prev_sequence != iobm->sequence)
47122fe5b04SThomas Gleixner tss_copy_io_bitmap(tss, iobm);
472ecc7e37dSThomas Gleixner
473060aa16fSThomas Gleixner /* Enable the bitmap */
474c8137aceSThomas Gleixner *base = IO_BITMAP_OFFSET_VALID_MAP;
475c8137aceSThomas Gleixner }
4767b0b8cfdSBorislav Petkov
477b7ffc44dSAndy Lutomirski /*
4787b0b8cfdSBorislav Petkov * Make sure that the TSS limit is covering the IO bitmap. It might have
4797b0b8cfdSBorislav Petkov * been cut down by a VMEXIT to 0x67 which would cause a subsequent I/O
4807b0b8cfdSBorislav Petkov * access from user space to trigger a #GP because tbe bitmap is outside
4817b0b8cfdSBorislav Petkov * the TSS limit.
482b7ffc44dSAndy Lutomirski */
483b7ceaec1SAndy Lutomirski refresh_tss_limit();
484af8b3cd3SKyle Huey }
485111e7b15SThomas Gleixner #else /* CONFIG_X86_IOPL_IOPERM */
switch_to_bitmap(unsigned long tifp)486111e7b15SThomas Gleixner static inline void switch_to_bitmap(unsigned long tifp) { }
487111e7b15SThomas Gleixner #endif
488af8b3cd3SKyle Huey
4891f50ddb4SThomas Gleixner #ifdef CONFIG_SMP
490885f82bfSThomas Gleixner
4911f50ddb4SThomas Gleixner struct ssb_state {
4921f50ddb4SThomas Gleixner struct ssb_state *shared_state;
4931f50ddb4SThomas Gleixner raw_spinlock_t lock;
4941f50ddb4SThomas Gleixner unsigned int disable_state;
4951f50ddb4SThomas Gleixner unsigned long local_state;
4961f50ddb4SThomas Gleixner };
4971f50ddb4SThomas Gleixner
4981f50ddb4SThomas Gleixner #define LSTATE_SSB 0
4991f50ddb4SThomas Gleixner
5001f50ddb4SThomas Gleixner static DEFINE_PER_CPU(struct ssb_state, ssb_state);
5011f50ddb4SThomas Gleixner
speculative_store_bypass_ht_init(void)5021f50ddb4SThomas Gleixner void speculative_store_bypass_ht_init(void)
5031f50ddb4SThomas Gleixner {
5041f50ddb4SThomas Gleixner struct ssb_state *st = this_cpu_ptr(&ssb_state);
5051f50ddb4SThomas Gleixner unsigned int this_cpu = smp_processor_id();
5061f50ddb4SThomas Gleixner unsigned int cpu;
5071f50ddb4SThomas Gleixner
5081f50ddb4SThomas Gleixner st->local_state = 0;
5091f50ddb4SThomas Gleixner
5101f50ddb4SThomas Gleixner /*
5111f50ddb4SThomas Gleixner * Shared state setup happens once on the first bringup
5121f50ddb4SThomas Gleixner * of the CPU. It's not destroyed on CPU hotunplug.
5131f50ddb4SThomas Gleixner */
5141f50ddb4SThomas Gleixner if (st->shared_state)
5151f50ddb4SThomas Gleixner return;
5161f50ddb4SThomas Gleixner
5171f50ddb4SThomas Gleixner raw_spin_lock_init(&st->lock);
5181f50ddb4SThomas Gleixner
5191f50ddb4SThomas Gleixner /*
5201f50ddb4SThomas Gleixner * Go over HT siblings and check whether one of them has set up the
5211f50ddb4SThomas Gleixner * shared state pointer already.
5221f50ddb4SThomas Gleixner */
5231f50ddb4SThomas Gleixner for_each_cpu(cpu, topology_sibling_cpumask(this_cpu)) {
5241f50ddb4SThomas Gleixner if (cpu == this_cpu)
5251f50ddb4SThomas Gleixner continue;
5261f50ddb4SThomas Gleixner
5271f50ddb4SThomas Gleixner if (!per_cpu(ssb_state, cpu).shared_state)
5281f50ddb4SThomas Gleixner continue;
5291f50ddb4SThomas Gleixner
5301f50ddb4SThomas Gleixner /* Link it to the state of the sibling: */
5311f50ddb4SThomas Gleixner st->shared_state = per_cpu(ssb_state, cpu).shared_state;
5321f50ddb4SThomas Gleixner return;
5331f50ddb4SThomas Gleixner }
5341f50ddb4SThomas Gleixner
5351f50ddb4SThomas Gleixner /*
5361f50ddb4SThomas Gleixner * First HT sibling to come up on the core. Link shared state of
5371f50ddb4SThomas Gleixner * the first HT sibling to itself. The siblings on the same core
5381f50ddb4SThomas Gleixner * which come up later will see the shared state pointer and link
539d9f6e12fSIngo Molnar * themselves to the state of this CPU.
5401f50ddb4SThomas Gleixner */
5411f50ddb4SThomas Gleixner st->shared_state = st;
5421f50ddb4SThomas Gleixner }
5431f50ddb4SThomas Gleixner
5441f50ddb4SThomas Gleixner /*
5451f50ddb4SThomas Gleixner * Logic is: First HT sibling enables SSBD for both siblings in the core
5461f50ddb4SThomas Gleixner * and last sibling to disable it, disables it for the whole core. This how
5471f50ddb4SThomas Gleixner * MSR_SPEC_CTRL works in "hardware":
5481f50ddb4SThomas Gleixner *
5491f50ddb4SThomas Gleixner * CORE_SPEC_CTRL = THREAD0_SPEC_CTRL | THREAD1_SPEC_CTRL
5501f50ddb4SThomas Gleixner */
amd_set_core_ssb_state(unsigned long tifn)5511f50ddb4SThomas Gleixner static __always_inline void amd_set_core_ssb_state(unsigned long tifn)
5521f50ddb4SThomas Gleixner {
5531f50ddb4SThomas Gleixner struct ssb_state *st = this_cpu_ptr(&ssb_state);
5541f50ddb4SThomas Gleixner u64 msr = x86_amd_ls_cfg_base;
5551f50ddb4SThomas Gleixner
5561f50ddb4SThomas Gleixner if (!static_cpu_has(X86_FEATURE_ZEN)) {
5571f50ddb4SThomas Gleixner msr |= ssbd_tif_to_amd_ls_cfg(tifn);
558885f82bfSThomas Gleixner wrmsrl(MSR_AMD64_LS_CFG, msr);
5591f50ddb4SThomas Gleixner return;
5601f50ddb4SThomas Gleixner }
5611f50ddb4SThomas Gleixner
5621f50ddb4SThomas Gleixner if (tifn & _TIF_SSBD) {
5631f50ddb4SThomas Gleixner /*
5641f50ddb4SThomas Gleixner * Since this can race with prctl(), block reentry on the
5651f50ddb4SThomas Gleixner * same CPU.
5661f50ddb4SThomas Gleixner */
5671f50ddb4SThomas Gleixner if (__test_and_set_bit(LSTATE_SSB, &st->local_state))
5681f50ddb4SThomas Gleixner return;
5691f50ddb4SThomas Gleixner
5701f50ddb4SThomas Gleixner msr |= x86_amd_ls_cfg_ssbd_mask;
5711f50ddb4SThomas Gleixner
5721f50ddb4SThomas Gleixner raw_spin_lock(&st->shared_state->lock);
5731f50ddb4SThomas Gleixner /* First sibling enables SSBD: */
5741f50ddb4SThomas Gleixner if (!st->shared_state->disable_state)
5751f50ddb4SThomas Gleixner wrmsrl(MSR_AMD64_LS_CFG, msr);
5761f50ddb4SThomas Gleixner st->shared_state->disable_state++;
5771f50ddb4SThomas Gleixner raw_spin_unlock(&st->shared_state->lock);
578885f82bfSThomas Gleixner } else {
5791f50ddb4SThomas Gleixner if (!__test_and_clear_bit(LSTATE_SSB, &st->local_state))
5801f50ddb4SThomas Gleixner return;
5811f50ddb4SThomas Gleixner
5821f50ddb4SThomas Gleixner raw_spin_lock(&st->shared_state->lock);
5831f50ddb4SThomas Gleixner st->shared_state->disable_state--;
5841f50ddb4SThomas Gleixner if (!st->shared_state->disable_state)
5851f50ddb4SThomas Gleixner wrmsrl(MSR_AMD64_LS_CFG, msr);
5861f50ddb4SThomas Gleixner raw_spin_unlock(&st->shared_state->lock);
5871f50ddb4SThomas Gleixner }
5881f50ddb4SThomas Gleixner }
5891f50ddb4SThomas Gleixner #else
amd_set_core_ssb_state(unsigned long tifn)5901f50ddb4SThomas Gleixner static __always_inline void amd_set_core_ssb_state(unsigned long tifn)
5911f50ddb4SThomas Gleixner {
5921f50ddb4SThomas Gleixner u64 msr = x86_amd_ls_cfg_base | ssbd_tif_to_amd_ls_cfg(tifn);
5931f50ddb4SThomas Gleixner
5941f50ddb4SThomas Gleixner wrmsrl(MSR_AMD64_LS_CFG, msr);
5951f50ddb4SThomas Gleixner }
5961f50ddb4SThomas Gleixner #endif
5971f50ddb4SThomas Gleixner
amd_set_ssb_virt_state(unsigned long tifn)59811fb0683STom Lendacky static __always_inline void amd_set_ssb_virt_state(unsigned long tifn)
59911fb0683STom Lendacky {
60011fb0683STom Lendacky /*
60111fb0683STom Lendacky * SSBD has the same definition in SPEC_CTRL and VIRT_SPEC_CTRL,
60211fb0683STom Lendacky * so ssbd_tif_to_spec_ctrl() just works.
60311fb0683STom Lendacky */
60411fb0683STom Lendacky wrmsrl(MSR_AMD64_VIRT_SPEC_CTRL, ssbd_tif_to_spec_ctrl(tifn));
60511fb0683STom Lendacky }
60611fb0683STom Lendacky
60701daf568STim Chen /*
60801daf568STim Chen * Update the MSRs managing speculation control, during context switch.
60901daf568STim Chen *
61001daf568STim Chen * tifp: Previous task's thread flags
61101daf568STim Chen * tifn: Next task's thread flags
61201daf568STim Chen */
__speculation_ctrl_update(unsigned long tifp,unsigned long tifn)61301daf568STim Chen static __always_inline void __speculation_ctrl_update(unsigned long tifp,
61401daf568STim Chen unsigned long tifn)
6151f50ddb4SThomas Gleixner {
6165bfbe3adSTim Chen unsigned long tif_diff = tifp ^ tifn;
61701daf568STim Chen u64 msr = x86_spec_ctrl_base;
61801daf568STim Chen bool updmsr = false;
6191f50ddb4SThomas Gleixner
6202f5fb193SThomas Gleixner lockdep_assert_irqs_disabled();
6212f5fb193SThomas Gleixner
622dbbe2ad0SAnthony Steinhauser /* Handle change of TIF_SSBD depending on the mitigation method. */
62301daf568STim Chen if (static_cpu_has(X86_FEATURE_VIRT_SSBD)) {
624dbbe2ad0SAnthony Steinhauser if (tif_diff & _TIF_SSBD)
62501daf568STim Chen amd_set_ssb_virt_state(tifn);
62601daf568STim Chen } else if (static_cpu_has(X86_FEATURE_LS_CFG_SSBD)) {
627dbbe2ad0SAnthony Steinhauser if (tif_diff & _TIF_SSBD)
62801daf568STim Chen amd_set_core_ssb_state(tifn);
62901daf568STim Chen } else if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) ||
63001daf568STim Chen static_cpu_has(X86_FEATURE_AMD_SSBD)) {
631dbbe2ad0SAnthony Steinhauser updmsr |= !!(tif_diff & _TIF_SSBD);
63201daf568STim Chen msr |= ssbd_tif_to_spec_ctrl(tifn);
633885f82bfSThomas Gleixner }
6341f50ddb4SThomas Gleixner
635dbbe2ad0SAnthony Steinhauser /* Only evaluate TIF_SPEC_IB if conditional STIBP is enabled. */
6365bfbe3adSTim Chen if (IS_ENABLED(CONFIG_SMP) &&
6375bfbe3adSTim Chen static_branch_unlikely(&switch_to_cond_stibp)) {
6385bfbe3adSTim Chen updmsr |= !!(tif_diff & _TIF_SPEC_IB);
6395bfbe3adSTim Chen msr |= stibp_tif_to_spec_ctrl(tifn);
6405bfbe3adSTim Chen }
6415bfbe3adSTim Chen
64201daf568STim Chen if (updmsr)
64366065157SPawan Gupta update_spec_ctrl_cond(msr);
644885f82bfSThomas Gleixner }
6451f50ddb4SThomas Gleixner
speculation_ctrl_update_tif(struct task_struct * tsk)6466d991ba5SThomas Gleixner static unsigned long speculation_ctrl_update_tif(struct task_struct *tsk)
6471f50ddb4SThomas Gleixner {
6486d991ba5SThomas Gleixner if (test_and_clear_tsk_thread_flag(tsk, TIF_SPEC_FORCE_UPDATE)) {
6496d991ba5SThomas Gleixner if (task_spec_ssb_disable(tsk))
6506d991ba5SThomas Gleixner set_tsk_thread_flag(tsk, TIF_SSBD);
6511f50ddb4SThomas Gleixner else
6526d991ba5SThomas Gleixner clear_tsk_thread_flag(tsk, TIF_SSBD);
6539137bb27SThomas Gleixner
6549137bb27SThomas Gleixner if (task_spec_ib_disable(tsk))
6559137bb27SThomas Gleixner set_tsk_thread_flag(tsk, TIF_SPEC_IB);
6569137bb27SThomas Gleixner else
6579137bb27SThomas Gleixner clear_tsk_thread_flag(tsk, TIF_SPEC_IB);
6586d991ba5SThomas Gleixner }
6596d991ba5SThomas Gleixner /* Return the updated threadinfo flags*/
660dca99fb6SMark Rutland return read_task_thread_flags(tsk);
661885f82bfSThomas Gleixner }
662885f82bfSThomas Gleixner
speculation_ctrl_update(unsigned long tif)66326c4d75bSThomas Gleixner void speculation_ctrl_update(unsigned long tif)
664885f82bfSThomas Gleixner {
6652f5fb193SThomas Gleixner unsigned long flags;
6662f5fb193SThomas Gleixner
66701daf568STim Chen /* Forced update. Make sure all relevant TIF flags are different */
6682f5fb193SThomas Gleixner local_irq_save(flags);
66901daf568STim Chen __speculation_ctrl_update(~tif, tif);
6702f5fb193SThomas Gleixner local_irq_restore(flags);
671885f82bfSThomas Gleixner }
672885f82bfSThomas Gleixner
6736d991ba5SThomas Gleixner /* Called from seccomp/prctl update */
speculation_ctrl_update_current(void)6746d991ba5SThomas Gleixner void speculation_ctrl_update_current(void)
6756d991ba5SThomas Gleixner {
6766d991ba5SThomas Gleixner preempt_disable();
6776d991ba5SThomas Gleixner speculation_ctrl_update(speculation_ctrl_update_tif(current));
6786d991ba5SThomas Gleixner preempt_enable();
6796d991ba5SThomas Gleixner }
6806d991ba5SThomas Gleixner
cr4_toggle_bits_irqsoff(unsigned long mask)681d8f0b353SThomas Gleixner static inline void cr4_toggle_bits_irqsoff(unsigned long mask)
682d8f0b353SThomas Gleixner {
683d8f0b353SThomas Gleixner unsigned long newval, cr4 = this_cpu_read(cpu_tlbstate.cr4);
684d8f0b353SThomas Gleixner
685d8f0b353SThomas Gleixner newval = cr4 ^ mask;
686d8f0b353SThomas Gleixner if (newval != cr4) {
687d8f0b353SThomas Gleixner this_cpu_write(cpu_tlbstate.cr4, newval);
688d8f0b353SThomas Gleixner __write_cr4(newval);
689d8f0b353SThomas Gleixner }
690d8f0b353SThomas Gleixner }
691d8f0b353SThomas Gleixner
__switch_to_xtra(struct task_struct * prev_p,struct task_struct * next_p)692ff16701aSThomas Gleixner void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p)
693af8b3cd3SKyle Huey {
694af8b3cd3SKyle Huey unsigned long tifp, tifn;
695af8b3cd3SKyle Huey
696dca99fb6SMark Rutland tifn = read_task_thread_flags(next_p);
697dca99fb6SMark Rutland tifp = read_task_thread_flags(prev_p);
69822fe5b04SThomas Gleixner
69922fe5b04SThomas Gleixner switch_to_bitmap(tifp);
700af8b3cd3SKyle Huey
7017c68af6eSAvi Kivity propagate_user_return_notify(prev_p, next_p);
702af8b3cd3SKyle Huey
703b9894a2fSKyle Huey if ((tifp & _TIF_BLOCKSTEP || tifn & _TIF_BLOCKSTEP) &&
704b9894a2fSKyle Huey arch_has_block_step()) {
705b9894a2fSKyle Huey unsigned long debugctl, msk;
706af8b3cd3SKyle Huey
707b9894a2fSKyle Huey rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
708af8b3cd3SKyle Huey debugctl &= ~DEBUGCTLMSR_BTF;
709b9894a2fSKyle Huey msk = tifn & _TIF_BLOCKSTEP;
710b9894a2fSKyle Huey debugctl |= (msk >> TIF_BLOCKSTEP) << DEBUGCTLMSR_BTF_SHIFT;
711b9894a2fSKyle Huey wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
712af8b3cd3SKyle Huey }
713af8b3cd3SKyle Huey
7145a920155SThomas Gleixner if ((tifp ^ tifn) & _TIF_NOTSC)
7159d0b6232SNadav Amit cr4_toggle_bits_irqsoff(X86_CR4_TSD);
716e9ea1e7fSKyle Huey
717e9ea1e7fSKyle Huey if ((tifp ^ tifn) & _TIF_NOCPUID)
718e9ea1e7fSKyle Huey set_cpuid_faulting(!!(tifn & _TIF_NOCPUID));
719885f82bfSThomas Gleixner
7206d991ba5SThomas Gleixner if (likely(!((tifp | tifn) & _TIF_SPEC_FORCE_UPDATE))) {
72101daf568STim Chen __speculation_ctrl_update(tifp, tifn);
7226d991ba5SThomas Gleixner } else {
7236d991ba5SThomas Gleixner speculation_ctrl_update_tif(prev_p);
7246d991ba5SThomas Gleixner tifn = speculation_ctrl_update_tif(next_p);
7256d991ba5SThomas Gleixner
7266d991ba5SThomas Gleixner /* Enforce MSR update to ensure consistent state */
7276d991ba5SThomas Gleixner __speculation_ctrl_update(~tifn, tifn);
7286d991ba5SThomas Gleixner }
729389d1fb1SJeremy Fitzhardinge }
730389d1fb1SJeremy Fitzhardinge
731df59e7bfSBrian Gerst /*
73200dba564SThomas Gleixner * Idle related variables and functions
73300dba564SThomas Gleixner */
734d1896049SThomas Renninger unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE;
73500dba564SThomas Gleixner EXPORT_SYMBOL(boot_option_idle_override);
73600dba564SThomas Gleixner
737aaa3896bSPeter Zijlstra /*
738aaa3896bSPeter Zijlstra * We use this if we don't have any better idle routine..
739aaa3896bSPeter Zijlstra */
default_idle(void)740aaa3896bSPeter Zijlstra void __cpuidle default_idle(void)
741aaa3896bSPeter Zijlstra {
742aaa3896bSPeter Zijlstra raw_safe_halt();
74389b30987SPeter Zijlstra raw_local_irq_disable();
744aaa3896bSPeter Zijlstra }
745aaa3896bSPeter Zijlstra #if defined(CONFIG_APM_MODULE) || defined(CONFIG_HALTPOLL_CPUIDLE_MODULE)
746aaa3896bSPeter Zijlstra EXPORT_SYMBOL(default_idle);
747aaa3896bSPeter Zijlstra #endif
748aaa3896bSPeter Zijlstra
749aaa3896bSPeter Zijlstra DEFINE_STATIC_CALL_NULL(x86_idle, default_idle);
750aaa3896bSPeter Zijlstra
x86_idle_set(void)751aaa3896bSPeter Zijlstra static bool x86_idle_set(void)
752aaa3896bSPeter Zijlstra {
753aaa3896bSPeter Zijlstra return !!static_call_query(x86_idle);
754aaa3896bSPeter Zijlstra }
75500dba564SThomas Gleixner
75690e24014SRichard Weinberger #ifndef CONFIG_SMP
play_dead(void)757eab89405SJosh Poimboeuf static inline void __noreturn play_dead(void)
75890e24014SRichard Weinberger {
75990e24014SRichard Weinberger BUG();
76090e24014SRichard Weinberger }
76190e24014SRichard Weinberger #endif
76290e24014SRichard Weinberger
arch_cpu_idle_enter(void)7637d1a9417SThomas Gleixner void arch_cpu_idle_enter(void)
7647d1a9417SThomas Gleixner {
7656a369583SThomas Gleixner tsc_verify_tsc_adjust(false);
76690e24014SRichard Weinberger local_touch_nmi();
76790e24014SRichard Weinberger }
76890e24014SRichard Weinberger
arch_cpu_idle_dead(void)769071c44e4SJosh Poimboeuf void __noreturn arch_cpu_idle_dead(void)
7707d1a9417SThomas Gleixner {
7717d1a9417SThomas Gleixner play_dead();
77290e24014SRichard Weinberger }
77390e24014SRichard Weinberger
77400dba564SThomas Gleixner /*
7757d1a9417SThomas Gleixner * Called from the generic idle code.
7767d1a9417SThomas Gleixner */
arch_cpu_idle(void)777aaa3896bSPeter Zijlstra void __cpuidle arch_cpu_idle(void)
7787d1a9417SThomas Gleixner {
779aaa3896bSPeter Zijlstra static_call(x86_idle)();
7807d1a9417SThomas Gleixner }
781716ff71aSLi RongQing EXPORT_SYMBOL_GPL(arch_cpu_idle);
7827d1a9417SThomas Gleixner
7836a377ddcSLen Brown #ifdef CONFIG_XEN
xen_set_default_idle(void)7846a377ddcSLen Brown bool xen_set_default_idle(void)
785e5fd47bfSKonrad Rzeszutek Wilk {
786aaa3896bSPeter Zijlstra bool ret = x86_idle_set();
787e5fd47bfSKonrad Rzeszutek Wilk
788aaa3896bSPeter Zijlstra static_call_update(x86_idle, default_idle);
789e5fd47bfSKonrad Rzeszutek Wilk
790e5fd47bfSKonrad Rzeszutek Wilk return ret;
791e5fd47bfSKonrad Rzeszutek Wilk }
7926a377ddcSLen Brown #endif
793bba4ed01STom Lendacky
7941f5e7eb7SThomas Gleixner struct cpumask cpus_stop_mask;
7951f5e7eb7SThomas Gleixner
stop_this_cpu(void * dummy)796f9cdf7caSPeter Zijlstra void __noreturn stop_this_cpu(void *dummy)
797d3ec5caeSIvan Vecera {
7989b040453STony Battersby struct cpuinfo_x86 *c = this_cpu_ptr(&cpu_info);
7991f5e7eb7SThomas Gleixner unsigned int cpu = smp_processor_id();
8001f5e7eb7SThomas Gleixner
801d3ec5caeSIvan Vecera local_irq_disable();
8021f5e7eb7SThomas Gleixner
803d3ec5caeSIvan Vecera /*
8041f5e7eb7SThomas Gleixner * Remove this CPU from the online mask and disable it
8051f5e7eb7SThomas Gleixner * unconditionally. This might be redundant in case that the reboot
8061f5e7eb7SThomas Gleixner * vector was handled late and stop_other_cpus() sent an NMI.
8071f5e7eb7SThomas Gleixner *
8081f5e7eb7SThomas Gleixner * According to SDM and APM NMIs can be accepted even after soft
8091f5e7eb7SThomas Gleixner * disabling the local APIC.
810d3ec5caeSIvan Vecera */
8111f5e7eb7SThomas Gleixner set_cpu_online(cpu, false);
812d3ec5caeSIvan Vecera disable_local_APIC();
8139b040453STony Battersby mcheck_cpu_clear(c);
814d3ec5caeSIvan Vecera
815f23d74f6STom Lendacky /*
816f23d74f6STom Lendacky * Use wbinvd on processors that support SME. This provides support
817f23d74f6STom Lendacky * for performing a successful kexec when going from SME inactive
818f23d74f6STom Lendacky * to SME active (or vice-versa). The cache must be cleared so that
819f23d74f6STom Lendacky * if there are entries with the same physical address, both with and
820f23d74f6STom Lendacky * without the encryption bit, they don't race each other when flushed
821f23d74f6STom Lendacky * and potentially end up with the wrong entry being committed to
822f23d74f6STom Lendacky * memory.
82308f253ecSMario Limonciello *
82408f253ecSMario Limonciello * Test the CPUID bit directly because the machine might've cleared
82508f253ecSMario Limonciello * X86_FEATURE_SME due to cmdline options.
826f23d74f6STom Lendacky */
8279b040453STony Battersby if (c->extended_cpuid_level >= 0x8000001f && (cpuid_eax(0x8000001f) & BIT(0)))
828f23d74f6STom Lendacky native_wbinvd();
8291f5e7eb7SThomas Gleixner
8301f5e7eb7SThomas Gleixner /*
8311f5e7eb7SThomas Gleixner * This brings a cache line back and dirties it, but
8321f5e7eb7SThomas Gleixner * native_stop_other_cpus() will overwrite cpus_stop_mask after it
8331f5e7eb7SThomas Gleixner * observed that all CPUs reported stop. This write will invalidate
8341f5e7eb7SThomas Gleixner * the related cache line on this CPU.
8351f5e7eb7SThomas Gleixner */
8361f5e7eb7SThomas Gleixner cpumask_clear_cpu(cpu, &cpus_stop_mask);
8371f5e7eb7SThomas Gleixner
838bba4ed01STom Lendacky for (;;) {
839bba4ed01STom Lendacky /*
840f23d74f6STom Lendacky * Use native_halt() so that memory contents don't change
841f23d74f6STom Lendacky * (stack usage and variables) after possibly issuing the
842f23d74f6STom Lendacky * native_wbinvd() above.
843bba4ed01STom Lendacky */
844f23d74f6STom Lendacky native_halt();
845bba4ed01STom Lendacky }
846d3ec5caeSIvan Vecera }
8477f424a8bSPeter Zijlstra
848aa276e1cSThomas Gleixner /*
84907c94a38SBorislav Petkov * AMD Erratum 400 aware idle routine. We handle it the same way as C3 power
85007c94a38SBorislav Petkov * states (local apic timer and TSC stop).
85158c644baSPeter Zijlstra *
85258c644baSPeter Zijlstra * XXX this function is completely buggered vs RCU and tracing.
853aa276e1cSThomas Gleixner */
amd_e400_idle(void)85402c68a02SLen Brown static void amd_e400_idle(void)
855aa276e1cSThomas Gleixner {
85607c94a38SBorislav Petkov /*
85707c94a38SBorislav Petkov * We cannot use static_cpu_has_bug() here because X86_BUG_AMD_APIC_C1E
85807c94a38SBorislav Petkov * gets set after static_cpu_has() places have been converted via
85907c94a38SBorislav Petkov * alternatives.
86007c94a38SBorislav Petkov */
86107c94a38SBorislav Petkov if (!boot_cpu_has_bug(X86_BUG_AMD_APIC_C1E)) {
86207c94a38SBorislav Petkov default_idle();
86307c94a38SBorislav Petkov return;
864aa276e1cSThomas Gleixner }
865aa276e1cSThomas Gleixner
866435c350eSThomas Gleixner tick_broadcast_enter();
8670beefa20SThomas Gleixner
868aa276e1cSThomas Gleixner default_idle();
8690beefa20SThomas Gleixner
870435c350eSThomas Gleixner tick_broadcast_exit();
871aa276e1cSThomas Gleixner }
872aa276e1cSThomas Gleixner
873b253149bSLen Brown /*
874aebef63cSWyes Karny * Prefer MWAIT over HALT if MWAIT is supported, MWAIT_CPUID leaf
875aebef63cSWyes Karny * exists and whenever MONITOR/MWAIT extensions are present there is at
876aebef63cSWyes Karny * least one C1 substate.
877b253149bSLen Brown *
878aebef63cSWyes Karny * Do not prefer MWAIT if MONITOR instruction has a bug or idle=nomwait
879aebef63cSWyes Karny * is passed to kernel commandline parameter.
880b253149bSLen Brown */
prefer_mwait_c1_over_halt(const struct cpuinfo_x86 * c)881b253149bSLen Brown static int prefer_mwait_c1_over_halt(const struct cpuinfo_x86 *c)
882b253149bSLen Brown {
883aebef63cSWyes Karny u32 eax, ebx, ecx, edx;
884aebef63cSWyes Karny
8858bcedb4cSWyes Karny /* User has disallowed the use of MWAIT. Fallback to HALT */
8868bcedb4cSWyes Karny if (boot_option_idle_override == IDLE_NOMWAIT)
887b253149bSLen Brown return 0;
888b253149bSLen Brown
889aebef63cSWyes Karny /* MWAIT is not supported on this platform. Fallback to HALT */
890aebef63cSWyes Karny if (!cpu_has(c, X86_FEATURE_MWAIT))
891b253149bSLen Brown return 0;
892b253149bSLen Brown
893aebef63cSWyes Karny /* Monitor has a bug. Fallback to HALT */
894aebef63cSWyes Karny if (boot_cpu_has_bug(X86_BUG_MONITOR))
895b253149bSLen Brown return 0;
896b253149bSLen Brown
897aebef63cSWyes Karny cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx);
898aebef63cSWyes Karny
899aebef63cSWyes Karny /*
900aebef63cSWyes Karny * If MWAIT extensions are not available, it is safe to use MWAIT
901aebef63cSWyes Karny * with EAX=0, ECX=0.
902aebef63cSWyes Karny */
903aebef63cSWyes Karny if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED))
904b253149bSLen Brown return 1;
905aebef63cSWyes Karny
906aebef63cSWyes Karny /*
907aebef63cSWyes Karny * If MWAIT extensions are available, there should be at least one
908aebef63cSWyes Karny * MWAIT C1 substate present.
909aebef63cSWyes Karny */
910aebef63cSWyes Karny return (edx & MWAIT_C1_SUBSTATE_MASK);
911b253149bSLen Brown }
912b253149bSLen Brown
913b253149bSLen Brown /*
9140fb0328dSHuang Rui * MONITOR/MWAIT with no hints, used for default C1 state. This invokes MWAIT
9150fb0328dSHuang Rui * with interrupts enabled and no flags, which is backwards compatible with the
9160fb0328dSHuang Rui * original MWAIT implementation.
917b253149bSLen Brown */
mwait_idle(void)9186727ad9eSChris Metcalf static __cpuidle void mwait_idle(void)
919b253149bSLen Brown {
920f8e617f4SMike Galbraith if (!current_set_polling_and_test()) {
921f8e617f4SMike Galbraith if (this_cpu_has(X86_BUG_CLFLUSH_MONITOR)) {
922ca59809fSMichael S. Tsirkin mb(); /* quirk */
923b253149bSLen Brown clflush((void *)¤t_thread_info()->flags);
924ca59809fSMichael S. Tsirkin mb(); /* quirk */
925f8e617f4SMike Galbraith }
926b253149bSLen Brown
927b253149bSLen Brown __monitor((void *)¤t_thread_info()->flags, 0, 0);
92889b30987SPeter Zijlstra if (!need_resched()) {
929b253149bSLen Brown __sti_mwait(0, 0);
93089b30987SPeter Zijlstra raw_local_irq_disable();
93189b30987SPeter Zijlstra }
932b253149bSLen Brown }
933f8e617f4SMike Galbraith __current_clr_polling();
934f8e617f4SMike Galbraith }
935b253149bSLen Brown
select_idle_routine(const struct cpuinfo_x86 * c)936148f9bb8SPaul Gortmaker void select_idle_routine(const struct cpuinfo_x86 *c)
9377f424a8bSPeter Zijlstra {
9383e5095d1SIngo Molnar #ifdef CONFIG_SMP
9397d1a9417SThomas Gleixner if (boot_option_idle_override == IDLE_POLL && smp_num_siblings > 1)
940c767a54bSJoe Perches pr_warn_once("WARNING: polling idle and HT enabled, performance may degrade\n");
9417f424a8bSPeter Zijlstra #endif
942aaa3896bSPeter Zijlstra if (x86_idle_set() || boot_option_idle_override == IDLE_POLL)
9436ddd2a27SThomas Gleixner return;
9446ddd2a27SThomas Gleixner
9453344ed30SThomas Gleixner if (boot_cpu_has_bug(X86_BUG_AMD_E400)) {
946c767a54bSJoe Perches pr_info("using AMD E400 aware idle routine\n");
947aaa3896bSPeter Zijlstra static_call_update(x86_idle, amd_e400_idle);
948b253149bSLen Brown } else if (prefer_mwait_c1_over_halt(c)) {
949b253149bSLen Brown pr_info("using mwait in idle threads\n");
950aaa3896bSPeter Zijlstra static_call_update(x86_idle, mwait_idle);
951bfe6ed0cSKirill A. Shutemov } else if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) {
952bfe6ed0cSKirill A. Shutemov pr_info("using TDX aware idle routine\n");
953aaa3896bSPeter Zijlstra static_call_update(x86_idle, tdx_safe_halt);
9546ddd2a27SThomas Gleixner } else
955aaa3896bSPeter Zijlstra static_call_update(x86_idle, default_idle);
9567f424a8bSPeter Zijlstra }
9577f424a8bSPeter Zijlstra
amd_e400_c1e_apic_setup(void)95807c94a38SBorislav Petkov void amd_e400_c1e_apic_setup(void)
95930e1e6d1SRusty Russell {
96007c94a38SBorislav Petkov if (boot_cpu_has_bug(X86_BUG_AMD_APIC_C1E)) {
96107c94a38SBorislav Petkov pr_info("Switch to broadcast mode on CPU%d\n", smp_processor_id());
96207c94a38SBorislav Petkov local_irq_disable();
96307c94a38SBorislav Petkov tick_broadcast_force();
96407c94a38SBorislav Petkov local_irq_enable();
96507c94a38SBorislav Petkov }
96630e1e6d1SRusty Russell }
96730e1e6d1SRusty Russell
arch_post_acpi_subsys_init(void)968e7ff3a47SThomas Gleixner void __init arch_post_acpi_subsys_init(void)
969e7ff3a47SThomas Gleixner {
970e7ff3a47SThomas Gleixner u32 lo, hi;
971e7ff3a47SThomas Gleixner
972e7ff3a47SThomas Gleixner if (!boot_cpu_has_bug(X86_BUG_AMD_E400))
973e7ff3a47SThomas Gleixner return;
974e7ff3a47SThomas Gleixner
975e7ff3a47SThomas Gleixner /*
976e7ff3a47SThomas Gleixner * AMD E400 detection needs to happen after ACPI has been enabled. If
977e7ff3a47SThomas Gleixner * the machine is affected K8_INTP_C1E_ACTIVE_MASK bits are set in
978e7ff3a47SThomas Gleixner * MSR_K8_INT_PENDING_MSG.
979e7ff3a47SThomas Gleixner */
980e7ff3a47SThomas Gleixner rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi);
981e7ff3a47SThomas Gleixner if (!(lo & K8_INTP_C1E_ACTIVE_MASK))
982e7ff3a47SThomas Gleixner return;
983e7ff3a47SThomas Gleixner
984e7ff3a47SThomas Gleixner boot_cpu_set_bug(X86_BUG_AMD_APIC_C1E);
985e7ff3a47SThomas Gleixner
986e7ff3a47SThomas Gleixner if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
987e7ff3a47SThomas Gleixner mark_tsc_unstable("TSC halt in AMD C1E");
988e7ff3a47SThomas Gleixner pr_info("System has AMD C1E enabled\n");
989e7ff3a47SThomas Gleixner }
990e7ff3a47SThomas Gleixner
idle_setup(char * str)9917f424a8bSPeter Zijlstra static int __init idle_setup(char *str)
9927f424a8bSPeter Zijlstra {
993ab6bc3e3SCyrill Gorcunov if (!str)
994ab6bc3e3SCyrill Gorcunov return -EINVAL;
995ab6bc3e3SCyrill Gorcunov
9967f424a8bSPeter Zijlstra if (!strcmp(str, "poll")) {
997c767a54bSJoe Perches pr_info("using polling idle threads\n");
998d1896049SThomas Renninger boot_option_idle_override = IDLE_POLL;
9997d1a9417SThomas Gleixner cpu_idle_poll_ctrl(true);
1000d1896049SThomas Renninger } else if (!strcmp(str, "halt")) {
1001c1e3b377SZhao Yakui /*
1002c1e3b377SZhao Yakui * When the boot option of idle=halt is added, halt is
1003c1e3b377SZhao Yakui * forced to be used for CPU idle. In such case CPU C2/C3
1004c1e3b377SZhao Yakui * won't be used again.
1005c1e3b377SZhao Yakui * To continue to load the CPU idle driver, don't touch
1006c1e3b377SZhao Yakui * the boot_option_idle_override.
1007c1e3b377SZhao Yakui */
1008aaa3896bSPeter Zijlstra static_call_update(x86_idle, default_idle);
1009d1896049SThomas Renninger boot_option_idle_override = IDLE_HALT;
1010da5e09a1SZhao Yakui } else if (!strcmp(str, "nomwait")) {
1011da5e09a1SZhao Yakui /*
1012da5e09a1SZhao Yakui * If the boot option of "idle=nomwait" is added,
10138bcedb4cSWyes Karny * it means that mwait will be disabled for CPU C1/C2/C3
10148bcedb4cSWyes Karny * states.
1015da5e09a1SZhao Yakui */
1016d1896049SThomas Renninger boot_option_idle_override = IDLE_NOMWAIT;
1017c1e3b377SZhao Yakui } else
10187f424a8bSPeter Zijlstra return -1;
10197f424a8bSPeter Zijlstra
10207f424a8bSPeter Zijlstra return 0;
10217f424a8bSPeter Zijlstra }
10227f424a8bSPeter Zijlstra early_param("idle", idle_setup);
10237f424a8bSPeter Zijlstra
arch_align_stack(unsigned long sp)10249d62dcdfSAmerigo Wang unsigned long arch_align_stack(unsigned long sp)
10259d62dcdfSAmerigo Wang {
10269d62dcdfSAmerigo Wang if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
10278032bf12SJason A. Donenfeld sp -= get_random_u32_below(8192);
10289d62dcdfSAmerigo Wang return sp & ~0xf;
10299d62dcdfSAmerigo Wang }
10309d62dcdfSAmerigo Wang
arch_randomize_brk(struct mm_struct * mm)10319d62dcdfSAmerigo Wang unsigned long arch_randomize_brk(struct mm_struct *mm)
10329d62dcdfSAmerigo Wang {
1033*1a45994fSKees Cook if (mmap_is_ia32())
1034*1a45994fSKees Cook return randomize_page(mm->brk, SZ_32M);
1035*1a45994fSKees Cook
1036*1a45994fSKees Cook return randomize_page(mm->brk, SZ_1G);
10379d62dcdfSAmerigo Wang }
10389d62dcdfSAmerigo Wang
10397ba78053SThomas Gleixner /*
10407ba78053SThomas Gleixner * Called from fs/proc with a reference on @p to find the function
10417ba78053SThomas Gleixner * which called into schedule(). This needs to be done carefully
10427ba78053SThomas Gleixner * because the task might wake up and we might look at a stack
10437ba78053SThomas Gleixner * changing under us.
10447ba78053SThomas Gleixner */
__get_wchan(struct task_struct * p)104542a20f86SKees Cook unsigned long __get_wchan(struct task_struct *p)
10467ba78053SThomas Gleixner {
10475d1ceb39SPeter Zijlstra struct unwind_state state;
10485d1ceb39SPeter Zijlstra unsigned long addr = 0;
10497ba78053SThomas Gleixner
10500dc636b3SPeter Zijlstra if (!try_get_task_stack(p))
10510dc636b3SPeter Zijlstra return 0;
10520dc636b3SPeter Zijlstra
10535d1ceb39SPeter Zijlstra for (unwind_start(&state, p, NULL, NULL); !unwind_done(&state);
10545d1ceb39SPeter Zijlstra unwind_next_frame(&state)) {
10555d1ceb39SPeter Zijlstra addr = unwind_get_return_address(&state);
10565d1ceb39SPeter Zijlstra if (!addr)
10575d1ceb39SPeter Zijlstra break;
10585d1ceb39SPeter Zijlstra if (in_sched_functions(addr))
10595d1ceb39SPeter Zijlstra continue;
10605d1ceb39SPeter Zijlstra break;
10615d1ceb39SPeter Zijlstra }
10625d1ceb39SPeter Zijlstra
10630dc636b3SPeter Zijlstra put_task_stack(p);
10640dc636b3SPeter Zijlstra
10655d1ceb39SPeter Zijlstra return addr;
10667ba78053SThomas Gleixner }
1067b0b9b014SKyle Huey
do_arch_prctl_common(int option,unsigned long arg2)1068f5c0b4f3SThomas Gleixner long do_arch_prctl_common(int option, unsigned long arg2)
1069b0b9b014SKyle Huey {
1070e9ea1e7fSKyle Huey switch (option) {
1071e9ea1e7fSKyle Huey case ARCH_GET_CPUID:
1072e9ea1e7fSKyle Huey return get_cpuid_mode();
1073e9ea1e7fSKyle Huey case ARCH_SET_CPUID:
1074f5c0b4f3SThomas Gleixner return set_cpuid_mode(arg2);
1075db8268dfSChang S. Bae case ARCH_GET_XCOMP_SUPP:
1076db8268dfSChang S. Bae case ARCH_GET_XCOMP_PERM:
1077db8268dfSChang S. Bae case ARCH_REQ_XCOMP_PERM:
1078980fe2fdSThomas Gleixner case ARCH_GET_XCOMP_GUEST_PERM:
1079980fe2fdSThomas Gleixner case ARCH_REQ_XCOMP_GUEST_PERM:
1080f5c0b4f3SThomas Gleixner return fpu_xstate_prctl(option, arg2);
1081e9ea1e7fSKyle Huey }
1082e9ea1e7fSKyle Huey
1083b0b9b014SKyle Huey return -EINVAL;
1084b0b9b014SKyle Huey }
1085