Linux 64位上下文切换
发布时间:2020-12-13 22:57:09 所属栏目:Linux 来源:网络整理
导读:在32位模式的switch_to宏中,在调用__switch_to函数之前执行以下代码: asm volatile("pushflnt" /* save flags */ "pushl %%ebpnt" /* save EBP */ "movl %%esp,%[prev_sp]nt" /* save ESP */ "movl %[next_sp],%%espnt" /* restore ESP */
在32位模式的switch_to宏中,在调用__switch_to函数之前执行以下代码:
asm volatile("pushflnt" /* save flags */ "pushl %%ebpnt" /* save EBP */ "movl %%esp,%[prev_sp]nt" /* save ESP */ "movl %[next_sp],%%espnt" /* restore ESP */ "movl $1f,%[prev_ip]nt" /* save EIP */ "pushl %[next_ip]nt" /* restore EIP */ __switch_canary "jmp __switch_ton" /* regparm call */ EIP被压入堆栈(恢复EIP).当__switch_to完成时,会有一个返回到该位置的ret. asm volatile(SAVE_CONTEXT "movq %%rsp,%P[threadrsp](%[prev])nt" /* save RSP */ "movq %P[threadrsp](%[next]),%%rspnt" /* restore RSP */ "call __switch_tont" 在那里,只保存和恢复rsp.我认为RIP已经在 提前致谢! 解决方法
在32位内核中,thread.ip可能是以下之一:
> switch_to中的1个标签 通过使用push jmp对模拟呼叫来确保返回正确的位置. 在64位内核中,thread.ip不是这样使用的.在调用之后执行总是继续(以前是32位情况下的1标签).因此,不需要模拟呼叫,它可以正常完成.在__switch_to返回后使用条件跳转调度到ret_from_fork(您已省略此部分): #define switch_to(prev,next,last) asm volatile(SAVE_CONTEXT "movq %%rsp,%P[threadrsp](%[prev])nt" /* save RSP */ "movq %P[threadrsp](%[next]),%%rspnt" /* restore RSP */ "call __switch_tont" "movq "__percpu_arg([current_task])",%%rsint" __switch_canary "movq %P[thread_info](%%rsi),%%r8nt" "movq %%rax,%%rdint" "testl %[_tif_fork],%P[ti_flags](%%r8)nt" "jnz ret_from_forknt" RESTORE_CONTEXT ret_from_kernel_thread包含在ret_from_fork路径中,使用entry_64.S中的另一个条件跳转: ENTRY(ret_from_fork) DEFAULT_FRAME LOCK ; btr $TIF_FORK,TI_flags(%r8) pushq_cfi $0x0002 popfq_cfi # reset kernel eflags call schedule_tail # rdi: 'prev' task parameter GET_THREAD_INFO(%rcx) RESTORE_REST testl $3,CS-ARGOFFSET(%rsp) # from kernel_thread? jz 1f (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |