Error[8]: Undefined offset: 4, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

概述在32位模式的switch_to宏中,在调用__switch_to函数之前执行以下代码: asm volatile("pushfl\n\t" /* save flags */ \ "pushl %%ebp\n\t" /* save EBP */ \ "movl %%esp,%[prev_sp]\n\t" /* save 在32位模式的switch_to宏中,在调用__switch_to函数之前执行以下代码:

asm volatile("pushfl\n\t"       /* save    flags */ \         "pushl %%ebp\n\t"      /* save    EBP   */ \         "movl %%esp,%[prev_sp]\n\t"    /* save    ESP   */ \         "movl %[next_sp],%%esp\n\t"    /* restore ESP   */ \         "movl f,%[prev_ip]\n\t"  /* save    EIP   */ \         "pushl %[next_ip]\n\t" /* restore EIP   */ \         __switch_canary                    \         "jmp __switch_to\n"    /* regparm call  */

EIP被压入堆栈(恢复EIP).当__switch_to完成时,会有一个返回到该位置的ret.
这是相应的64位代码:

asm volatile(SAVE_CONTEXT                     \     "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */   \     "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */    \     "call __switch_to\n\t"

在那里,只保存和恢复rsp.我认为RIP已经在
堆栈的顶部.但是我无法找到指示的地方.
如何实际完成64位上下文切换,特别是对于RIP寄存器?

提前致谢!

解决方法 在32位内核中,thread.ip可能是以下之一:

> switch_to中的1个标签
> ret_from_fork
> ret_from_kernel_thread

通过使用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])\n\t" /* save RSP */       \             "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */    \             "call __switch_to\n\t"                                       \             "movq "__percpu_arg([current_task])",%%rsi\n\t"              \             __switch_canary                                              \             "movq %P[thread_info](%%rsi),%%r8\n\t"                       \             "movq %%rax,%%rdi\n\t"                                       \             "testl  %[_tif_fork],%P[ti_flags](%%r8)\n\t"                 \             "jnz   ret_from_fork\n\t"                                    \             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 [+++]x0002        popfq_cfi                               # reset kernel eflags        call schedule_tail                      # rdi: 'prev' task parameter        GET_THREAD_INFO(%rcx)        RESTORE_REST        testl ,CS-ARGOFFSET(%rsp)            # from kernel_thread?        jz   1f
总结

以上是内存溢出为你收集整理的Linux 64位上下文切换全部内容,希望文章能够帮你解决Linux 64位上下文切换所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Linux 64位上下文切换_系统运维_内存溢出

Linux 64位上下文切换

Linux 64位上下文切换,第1张

概述在32位模式的switch_to宏中,在调用__switch_to函数之前执行以下代码: asm volatile("pushfl\n\t" /* save flags */ \ "pushl %%ebp\n\t" /* save EBP */ \ "movl %%esp,%[prev_sp]\n\t" /* save 在32位模式的switch_to宏中,在调用__switch_to函数之前执行以下代码:

asm volatile("pushfl\n\t"       /* save    flags */ \         "pushl %%ebp\n\t"      /* save    EBP   */ \         "movl %%esp,%[prev_sp]\n\t"    /* save    ESP   */ \         "movl %[next_sp],%%esp\n\t"    /* restore ESP   */ \         "movl f,%[prev_ip]\n\t"  /* save    EIP   */ \         "pushl %[next_ip]\n\t" /* restore EIP   */ \         __switch_canary                    \         "jmp __switch_to\n"    /* regparm call  */

EIP被压入堆栈(恢复EIP).当__switch_to完成时,会有一个返回到该位置的ret.
这是相应的64位代码:

asm volatile(SAVE_CONTEXT                     \     "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */   \     "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */    \     "call __switch_to\n\t"

在那里,只保存和恢复rsp.我认为RIP已经在
堆栈的顶部.但是我无法找到指示的地方.
如何实际完成64位上下文切换,特别是对于RIP寄存器?

提前致谢!

解决方法 在32位内核中,thread.ip可能是以下之一:

> switch_to中的1个标签
> ret_from_fork
> ret_from_kernel_thread

通过使用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])\n\t" /* save RSP */       \             "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */    \             "call __switch_to\n\t"                                       \             "movq "__percpu_arg([current_task])",%%rsi\n\t"              \             __switch_canary                                              \             "movq %P[thread_info](%%rsi),%%r8\n\t"                       \             "movq %%rax,%%rdi\n\t"                                       \             "testl  %[_tif_fork],%P[ti_flags](%%r8)\n\t"                 \             "jnz   ret_from_fork\n\t"                                    \             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 x0002        popfq_cfi                               # reset kernel eflags        call schedule_tail                      # rdi: 'prev' task parameter        GET_THREAD_INFO(%rcx)        RESTORE_REST        testl ,CS-ARGOFFSET(%rsp)            # from kernel_thread?        jz   1f
总结

以上是内存溢出为你收集整理的Linux 64位上下文切换全部内容,希望文章能够帮你解决Linux 64位上下文切换所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/1018135.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存