2005-04-17 02:20:36 +04:00
/*
* Copyright ( C ) 1995 Linus Torvalds
*
* Pentium III FXSR , SSE support
* Gareth Hughes < gareth @ valinux . com > , May 2000
*/
/*
* This file handles the architecture - dependent parts of process handling . .
*/
2005-06-26 01:54:50 +04:00
# include <linux/cpu.h>
2005-04-17 02:20:36 +04:00
# include <linux/errno.h>
# include <linux/sched.h>
2017-02-08 20:51:36 +03:00
# include <linux/sched/task.h>
2017-02-08 20:51:37 +03:00
# include <linux/sched/task_stack.h>
2005-04-17 02:20:36 +04:00
# include <linux/fs.h>
# include <linux/kernel.h>
# include <linux/mm.h>
# include <linux/elfcore.h>
# include <linux/smp.h>
# include <linux/stddef.h>
# include <linux/slab.h>
# include <linux/vmalloc.h>
# include <linux/user.h>
# include <linux/interrupt.h>
# include <linux/delay.h>
# include <linux/reboot.h>
# include <linux/mc146818rtc.h>
2016-07-14 03:18:56 +03:00
# include <linux/export.h>
2005-04-17 02:20:36 +04:00
# include <linux/kallsyms.h>
# include <linux/ptrace.h>
2006-09-26 12:52:28 +04:00
# include <linux/personality.h>
2007-05-02 21:27:16 +04:00
# include <linux/percpu.h>
2008-04-14 02:24:18 +04:00
# include <linux/prctl.h>
2008-12-06 05:40:00 +03:00
# include <linux/ftrace.h>
2009-01-04 13:48:56 +03:00
# include <linux/uaccess.h>
# include <linux/io.h>
# include <linux/kdebug.h>
2017-03-20 11:16:24 +03:00
# include <linux/syscalls.h>
2005-04-17 02:20:36 +04:00
# include <asm/ldt.h>
# include <asm/processor.h>
2021-10-15 04:16:20 +03:00
# include <asm/fpu/sched.h>
2005-04-17 02:20:36 +04:00
# include <asm/desc.h>
# include <linux/err.h>
2005-06-26 01:54:50 +04:00
# include <asm/tlbflush.h>
# include <asm/cpu.h>
2009-06-01 22:14:55 +04:00
# include <asm/debugreg.h>
2012-03-28 21:11:12 +04:00
# include <asm/switch_to.h>
2015-07-29 08:41:21 +03:00
# include <asm/vm86.h>
2020-05-06 01:36:12 +03:00
# include <asm/resctrl.h>
2017-03-20 11:16:24 +03:00
# include <asm/proto.h>
2005-06-26 01:54:50 +04:00
2018-11-25 21:33:47 +03:00
# include "process.h"
2020-06-29 17:48:46 +03:00
void __show_regs ( struct pt_regs * regs , enum show_regs_mode mode ,
const char * log_lvl )
2005-04-17 02:20:36 +04:00
{
unsigned long cr0 = 0L , cr2 = 0L , cr3 = 0L , cr4 = 0L ;
2007-07-21 19:10:42 +04:00
unsigned long d0 , d1 , d2 , d3 , d6 , d7 ;
2019-05-08 00:25:54 +03:00
unsigned short gs ;
2007-10-19 22:35:03 +04:00
2022-03-25 18:39:52 +03:00
savesegment ( gs , gs ) ;
2005-04-17 02:20:36 +04:00
2020-06-29 17:48:46 +03:00
show_ip ( regs , log_lvl ) ;
2005-04-17 02:20:36 +04:00
2020-06-29 17:48:46 +03:00
printk ( " %sEAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx \n " ,
log_lvl , regs - > ax , regs - > bx , regs - > cx , regs - > dx ) ;
printk ( " %sESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx \n " ,
log_lvl , regs - > si , regs - > di , regs - > bp , regs - > sp ) ;
printk ( " %sDS: %04x ES: %04x FS: %04x GS: %04x SS: %04x EFLAGS: %08lx \n " ,
log_lvl , ( u16 ) regs - > ds , ( u16 ) regs - > es , ( u16 ) regs - > fs , gs , regs - > ss , regs - > flags ) ;
2007-10-19 22:35:03 +04:00
2018-08-31 22:41:51 +03:00
if ( mode ! = SHOW_REGS_ALL )
2007-10-19 22:35:03 +04:00
return ;
2005-04-17 02:20:36 +04:00
2005-09-04 02:56:36 +04:00
cr0 = read_cr0 ( ) ;
cr2 = read_cr2 ( ) ;
2017-06-12 20:26:14 +03:00
cr3 = __read_cr3 ( ) ;
2016-09-29 22:48:12 +03:00
cr4 = __read_cr4 ( ) ;
2020-06-29 17:48:46 +03:00
printk ( " %sCR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx \n " ,
log_lvl , cr0 , cr2 , cr3 , cr4 ) ;
2007-07-21 19:10:42 +04:00
get_debugreg ( d0 , 0 ) ;
get_debugreg ( d1 , 1 ) ;
get_debugreg ( d2 , 2 ) ;
get_debugreg ( d3 , 3 ) ;
get_debugreg ( d6 , 6 ) ;
get_debugreg ( d7 , 7 ) ;
2013-06-18 20:09:11 +04:00
/* Only print out debug registers if they are in their non-default state. */
if ( ( d0 = = 0 ) & & ( d1 = = 0 ) & & ( d2 = = 0 ) & & ( d3 = = 0 ) & &
( d6 = = DR6_RESERVED ) & & ( d7 = = 0x400 ) )
return ;
2020-06-29 17:48:46 +03:00
printk ( " %sDR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx \n " ,
log_lvl , d0 , d1 , d2 , d3 ) ;
printk ( " %sDR6: %08lx DR7: %08lx \n " ,
log_lvl , d6 , d7 ) ;
2007-10-19 22:35:03 +04:00
}
2007-07-21 19:10:42 +04:00
2005-04-17 02:20:36 +04:00
void release_thread ( struct task_struct * dead_task )
{
2006-01-06 11:11:59 +03:00
BUG_ON ( dead_task - > mm ) ;
2005-04-17 02:20:36 +04:00
release_vm86_irqs ( dead_task ) ;
}
2008-02-21 07:18:40 +03:00
void
start_thread ( struct pt_regs * regs , unsigned long new_ip , unsigned long new_sp )
{
2022-03-25 18:39:52 +03:00
loadsegment ( gs , 0 ) ;
2008-02-21 07:18:40 +03:00
regs - > fs = 0 ;
regs - > ds = __USER_DS ;
regs - > es = __USER_DS ;
regs - > ss = __USER_DS ;
regs - > cs = __USER_CS ;
regs - > ip = new_ip ;
regs - > sp = new_sp ;
2012-08-02 23:05:11 +04:00
regs - > flags = X86_EFLAGS_IF ;
2008-02-21 07:18:40 +03:00
}
EXPORT_SYMBOL_GPL ( start_thread ) ;
2005-04-17 02:20:36 +04:00
/*
2011-04-28 13:02:08 +04:00
* switch_to ( x , y ) should switch tasks from x to y .
2005-04-17 02:20:36 +04:00
*
* We fsave / fwait so that an exception goes off at the right time
* ( as a call from the fsave or fwait in effect ) rather than to
* the wrong process . Lazy FP saving no longer makes any sense
* with modern CPU ' s , and this simplifies a lot of things ( SMP
* and UP become the same ) .
*
* NOTE ! We used to use the x86 hardware context switching . The
* reason for not using it any more becomes apparent when you
* try to recover gracefully from saved state that is no longer
* valid ( stale segment register values in particular ) . With the
* hardware task - switch , there is no way to fix up bad state in
* a reasonable manner .
*
* The fact that Intel documents the hardware task - switching to
* be slow is a fairly red herring - this code is not noticeably
* faster . However , there _is_ some room for improvement here ,
* so the performance issues may eventually be a valid point .
* More important , however , is the fact that this allows us much
* more flexibility .
*
2008-01-30 15:30:56 +03:00
* The return value ( in % ax ) will be the " prev " task after
2005-04-17 02:20:36 +04:00
* the task - switch , and shows up in ret_from_fork in entry . S ,
* for example .
*/
2013-08-06 02:02:39 +04:00
__visible __notrace_funcgraph struct task_struct *
2008-12-06 05:40:00 +03:00
__switch_to ( struct task_struct * prev_p , struct task_struct * next_p )
2005-04-17 02:20:36 +04:00
{
struct thread_struct * prev = & prev_p - > thread ,
2015-04-23 18:43:27 +03:00
* next = & next_p - > thread ;
struct fpu * prev_fpu = & prev - > fpu ;
2005-04-17 02:20:36 +04:00
int cpu = smp_processor_id ( ) ;
/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
2019-04-03 19:41:52 +03:00
if ( ! test_thread_flag ( TIF_NEED_FPU_LOAD ) )
switch_fpu_prepare ( prev_fpu , cpu ) ;
2006-12-07 04:14:01 +03:00
2005-04-17 02:20:36 +04:00
/*
2007-02-13 15:26:20 +03:00
* Save away % gs . No need to save % fs , as it was saved on the
[PATCH] i386: Use %gs as the PDA base-segment in the kernel
This patch is the meat of the PDA change. This patch makes several related
changes:
1: Most significantly, %gs is now used in the kernel. This means that on
entry, the old value of %gs is saved away, and it is reloaded with
__KERNEL_PDA.
2: entry.S constructs the stack in the shape of struct pt_regs, and this
is passed around the kernel so that the process's saved register
state can be accessed.
Unfortunately struct pt_regs doesn't currently have space for %gs
(or %fs). This patch extends pt_regs to add space for gs (no space
is allocated for %fs, since it won't be used, and it would just
complicate the code in entry.S to work around the space).
3: Because %gs is now saved on the stack like %ds, %es and the integer
registers, there are a number of places where it no longer needs to
be handled specially; namely context switch, and saving/restoring the
register state in a signal context.
4: And since kernel threads run in kernel space and call normal kernel
code, they need to be created with their %gs == __KERNEL_PDA.
Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Cc: Chuck Ebbert <76306.1226@compuserve.com>
Cc: Zachary Amsden <zach@vmware.com>
Cc: Jan Beulich <jbeulich@novell.com>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
2006-12-07 04:14:02 +03:00
* stack on entry . No need to save % es and % ds , as those are
* always kernel segments while inside the kernel . Doing this
* before setting the new TLS descriptors avoids the situation
* where we temporarily have non - reloadable segments in % fs
* and % gs . This could be an issue if the NMI handler ever
* used % fs or % gs ( it does not today ) , or if the kernel is
* running inside of a hypervisor layer .
2005-04-17 02:20:36 +04:00
*/
2022-03-25 18:39:52 +03:00
savesegment ( gs , prev - > gs ) ;
2005-04-17 02:20:36 +04:00
/*
2005-09-04 02:56:39 +04:00
* Load the per - thread Thread - Local Storage descriptor .
2005-04-17 02:20:36 +04:00
*/
2005-09-04 02:56:39 +04:00
load_TLS ( next , cpu ) ;
2005-04-17 02:20:36 +04:00
2018-11-25 21:33:47 +03:00
switch_to_extra ( prev_p , next_p ) ;
2005-06-28 01:36:36 +04:00
2007-02-13 15:26:21 +03:00
/*
* Leave lazy mode , flushing any hypercalls made here .
* This must be done before restoring TLS segments so
2019-04-03 19:41:31 +03:00
* the GDT and LDT are properly updated .
2007-02-13 15:26:21 +03:00
*/
2009-02-18 22:18:57 +03:00
arch_end_context_switch ( next_p ) ;
2007-02-13 15:26:21 +03:00
2015-03-07 04:50:18 +03:00
/*
2022-09-15 14:11:04 +03:00
* Reload esp0 and pcpu_hot . top_of_stack . This changes
2017-11-02 10:59:09 +03:00
* current_thread_info ( ) . Refresh the SYSENTER configuration in
* case prev or next is vm86 .
2015-03-07 04:50:18 +03:00
*/
2018-07-18 12:40:51 +03:00
update_task_stack ( next_p ) ;
2017-11-02 10:59:09 +03:00
refresh_sysenter_cs ( next ) ;
2022-09-15 14:11:04 +03:00
this_cpu_write ( pcpu_hot . top_of_stack ,
2015-03-07 04:50:19 +03:00
( unsigned long ) task_stack_page ( next_p ) +
THREAD_SIZE ) ;
2014-02-06 18:41:31 +04:00
2007-02-13 15:26:21 +03:00
/*
* Restore % gs if needed ( which is common )
*/
if ( prev - > gs | next - > gs )
2022-03-25 18:39:52 +03:00
loadsegment ( gs , next - > gs ) ;
2007-02-13 15:26:21 +03:00
2022-09-15 14:11:01 +03:00
raw_cpu_write ( pcpu_hot . current_task , next_p ) ;
2007-02-13 15:26:21 +03:00
2021-10-15 04:15:54 +03:00
switch_fpu_finish ( ) ;
2019-04-03 19:41:36 +03:00
2016-10-29 01:04:48 +03:00
/* Load the Intel cache allocation PQR MSR. */
2018-11-21 23:28:27 +03:00
resctrl_sched_in ( ) ;
2016-10-29 01:04:48 +03:00
2005-04-17 02:20:36 +04:00
return prev_p ;
}
2017-03-20 11:16:24 +03:00
SYSCALL_DEFINE2 ( arch_prctl , int , option , unsigned long , arg2 )
{
2022-05-12 15:04:08 +03:00
return do_arch_prctl_common ( option , arg2 ) ;
2017-03-20 11:16:24 +03:00
}