Detailed analysis of contrex-A9 assembly code _ switch_to (process switching)

Source: Internet
Author: User

// Function prototype: Version linux-3.0.8

Struct task_struct * _ switch_to (structtask_struct *, struct thread_info *, struct thread_info *);

 

# Define switch_to (prev, next, last )\

Do {\

Last =__ switch_to (prev, task_thread_info (prev), task_thread_info (next ));\

} While (0)

// First, let's take a look at the macro below:

# Define offsetof (type, member) (size_t) & (type *) 0)-> Member)

// The following actually points to the corresponding struct Member

/*

The cc_stackprotect patch is a patch that tejun Heo submitted to the main kernel in years to prevent Kernel stack overflow.

The default config option is disabled. You can change the. config file to config_cc_stackprotector = y when compiling the kernel.

. In the future, the Apsara kernel can enable this option to prevent the day attack caused by Kernel stack overflow. Defense against this patch

Overflow principle: when the process starts, place a pre-configured stack canary behind each buffer. You

It can be understood as a sentinel. When buffer overflow occurs, the value of the stack canary will be damaged.

When the value of the stack canary is damaged, the kernel will directly act as the machine. So how can we determine that the stack canary is overwritten?

In fact, this is done by GCC. The kernel adds the-fstack-Protector parameter to GCC during compilation.

*/

Define (tsk_stack_canary, offsetof (struct task_struct, stack_canary ));

// Task_struct

Define (ti_task, offsetof (struct thread_info, task ));

//

/*

* Domain types

*/

/*

# Define domain_noaccess 0

# Define domain_client 1 // is the user's domain (Execution program, access data), and is protected by the access described above

// Permissions for grouping individual chapters and pages into domains.

# Ifdef config_cpu_use_domains

# Define domain_manager 3 // control domain behavior (the current domain's sections, page, and domain access ).

# Else

# Define domain_manager 1

# Endif

*/

// Corresponding graph

// This domain uses the coprocessor to set the register domainaccess Control

Define (ti_cpu_domain, offsetof (struct thread_info, cpu_domain ));

/*

Struct cpu_context_save {

_ U32 R4;

_ U32 R5;

_ U32 R6;

_ U32 R7;

_ U32 R8;

_ U32 R9;

_ U32 SL;

_ U32 FP;

_ U32 sp;

_ U32 PC;

_ U32 extra [2];/* XScale 'Acc 'register, etc */

};

*/

Define (ti_cpu_save, offsetof (struct thread_info, cpu_context ));

 

/*

There is a set_tls below, corresponding to my platform set_tls_v6k

. Macroset_tls_v6k, TP, tmp1, tmp2

MCR P15, 0, \ TP, C13, C0, 3 @ set TLs register

. Endm

 

Tp_value is used to set the value of TLS register.

In multi-threaded applications, one process shares all threads in the same address space, and the data to be maintained is often unique.

. TLS or Thread Local Storage, because you may be able to figure it out from its name now, it is a concept used for thread abstraction. It is

A fast and effective way to store the local data of each thread. The offset of the local data of the thread is obtained through the TLS register (H/W or S

/W blocks), which points to the respective thread to control block access.

Previously, some of the ARM kernel and arm11 core did not have such TLS registration physically available. Operating System (Linux starts from here)

Software to be imitated. Next-generation ARM kernel. Starting from cortex-ax, the TLS register is indeed available (CP15 ).

 

What the kernel needs to do for TLS is to enable user-state programs (usually nptl-A pthread implementation) to set at a certain time point.

The unique base address value of a thread is in the thread information structure of the kernel.

*/

Define (ti_tp_value, offsetof (struct thread_info, tp_value ));

 

/*

* These are the reasoncodes for the thread notifier.

*/

# Define thread_policy_flush 0

# Define thread_policy_exit 1

# Define thread_policy_switch 2

# Define thread_policy_copy 3

/** Register switch for armv3 and armv4 processors * R0 = previous task_struct, R1 = previous thread_info, R2 = next thread_info * Previous and next are guaranteed not to be the same. */entry (_ switch_to) unwind (. fnstart) unwind (. cantunwind) // the IP address is the cpu_context address in thread_info of the previous thread. Add IP, R1, # ti_cpu_save/R3 contains the next thread TP value LDR R3, [R2, # ti_tp_value] // store R4-SL, FP, SP, LR to thread_info-> cpu_contex T. Use arm and thumb respectively to implement // This is to save the scene. Arm (stmia IP !, {R4-SL, FP, SP, LR}) @ store most regs on Stack thumb (stmia IP !, {R4-SL, FP}) @ store most regs on Stack thumb (STR sp, [IP], #4) thumb (str lr, [IP], #4) # ifdef config_cpu_use_domains // R6 stores the domain attribute LDR R6, [R2, # ti_cpu_domain] # The set_tls R3, R4, r5 # If defined (config_cc_stackprotector )&&! Defined (config_smp) LDR R7, [R2, # ti_task] // The task_struct LDR R8, =__ stack_chk_guard of the next thread // R8 contains _ stack_chk_guard address LDR R7, [R7, # ti_task, # tsk_stack_canary] // here, R7 contains the stack_canary value # endif # ifdef config_cpu_use_domains // set the domain register. MCR P15, 0, R6, C3, C0, 0 @ set domain register # endif // R5 contains the task_struct mov R5 of the previous thread, r0 // R4 is the cpu_context address in thread_info of the next thread. Add R4, R2, # ti_cpu_save // R4 R5 only temporarily stores the thread_policy_head notification chain below, the following example shows LDR r0, = thread_policy_head mov R1, # thread_policy_switch BL atomic_notifier_call_chain # If defined (config_cc_stackprotector )&&! Defined (config_smp) STR R7, [R8] // _ stack_chk_guard = (next) threadinfo-> task-> stack_canary # endif thumb (mov IP, R4) // The IP points to the cpu_context address mov R0 in thread_info of the thread, and R5 // R0 points to task_struct of the previous thread, which corresponds to the storage site above, here is the recovery site. The PC corresponds to the cpu_context-> PC of the next process // from the above, we can see that the cpu_context-> PC is the LR stored in the previous scene, that is, the place where the next thread is to be executed. Arm (ldmia R4, {R4-SL, FP, SP, PC}) @ load all regs saved previusly thumb (ldmia IP !, {R4-SL, FP}) @ load all regs saved previusly thumb (LDR sp, [IP], #4) thumb (ldr pc, [IP]) unwind (. fnend) endproc (_ switch_to)

Lab code:

#include <linux/kernel.h>#include <linux/notifier.h>#include <linux/module.h>#include <asm/thread_notify.h>MODULE_LICENSE("GPL");static int test_event(struct notifier_block *this, unsigned long event, void *ptr){    printk(KERN_INFO "In Event: Event Number is %ld\n",event);    return NOTIFY_DONE;}static struct notifier_block test_notifier ={    .notifier_call = test_event,};static int __init reg_notifier(void){    int err = 0;    printk(KERN_INFO "Begin to register:\n");    err = thread_register_notifier(&test_notifier);    if (err)    {        printk(KERN_ERR "register test_notifier error\n");        goto fail1;    }    printk(KERN_INFO "register reboot_notifier completed\n");    return 0;fail1:    return err;}static void __exit unreg_notifier(void){    thread_unregister_notifier(&test_notifier);    printk(KERN_INFO "Unregister finished\n");}module_init(reg_notifier);module_exit(unreg_notifier);

Print:

Both are thread_policy_switch. Of course, they will continue to switch!


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.