Linux kernel thread context

I wrote a simple kernel module that processes all processes and retrieves their registers stored when they were scheduled (especially EIP).

If I am not mistaken, what I need is saved on the kernel stack indicated by sp0 in the thread_struct of each process. This is what I do:

#include <linux/kernel.h> #include <linux/module.h> #include <linux/sched.h> int init_module(void){ struct task_struct *t; struct pt_regs regs; for_each_process(t){ memcpy(&regs, (unsigned long*)(t->thread.sp0-sizeof(struct pt_regs)), sizeof(struct pt_regs)); printk(KERN_INFO "%s eip: %lx\n", t->comm, regs.ip); } return 0; } void cleanup_module(void){ } MODULE_LICENSE("GPL"); 

Now, the conclusion about user-level processes seems legitimate:

 [ 3558.322088] bash eip: b770b430 

BUT everything that I get from kernel threads is always 0.

 [ 3558.322095] kworker/0:0 eip: 0 

I do not understand. Does the kernel save registers somewhere else when it comes to kernel threads?
Is this accidentally related to the kernel advantage?

I'm on the core 3.14-1-486.

Thanks in advance.

+5
source share
1 answer

thread.sp0 is userland SP. The SP core is thread.sp (and the ip core is just thread.ip ; it seems to exist on x86-32, but not x86-64).

The context switch always occurs in the kernel in the macro switch_to (one of the definitions) called from context_switch is called from schedule . Thus, IP and SP used there indicate kernel space.

When returning to userland, other SPs and IPs are required. This is what you are reading.

kworker is a thread created inside the kernel to schedule events that should not be executed by interrupts and do not have any specific process in the context of which they will work. Thus, it does not have any user code, and therefore its user SP and IP are zero. You can look at the kernel SP and IP, they must be non-zero (the IP address must always be the same, pointing to the same place in context_switch )

+2
source

Source: https://habr.com/ru/post/1200063/


All Articles