The kernel stack contains a special structure at the top - thread_info :
26 struct thread_info { 27 struct task_struct *task; 28 struct exec_domain *exec_domain; 29 __u32 flags; 30 __u32 status; 31 __u32 cpu; 32 int preempt_count; 34 mm_segment_t addr_limit; 35 struct restart_block restart_block; 36 void __user *sysenter_return; 37 #ifdef CONFIG_X86_32 38 unsigned long previous_esp; 41 __u8 supervisor_stack[0]; 42 #endif 43 unsigned int sig_on_uaccess_error:1; 44 unsigned int uaccess_err:1; 45 };
So, to get task_struct , you need to get the thread_info pointer with GET_THREAD_INFO from the ASM code:
183 184 #define GET_THREAD_INFO(reg) \ 185 movl $-THREAD_SIZE, reg; \ 186 andl %esp, reg
... or current_thread_info from C code:
174 175 static inline struct thread_info *current_thread_info(void) 176 { 177 return (struct thread_info *) 178 (current_stack_pointer & ~(THREAD_SIZE - 1)); 179 }
Note that THREAD_SIZE , defined as (PAGE_SIZE << THREAD_SIZE_ORDER) and THREAD_SIZE_ORDER , is 1 for x86_32 and x86_64, so THREAD_SIZE results in 8192 (2 ^ 13 or 1 <13).
Ilya Matveychikov Aug 16 '12 at 23:00 2012-08-16 23:00
source share