提交 b339a18b 编写于 作者: L Linus Torvalds

Fix up incorrect "unlikely()" on %gs reload in x86 __switch_to

These days %gs is normally the TLS segment, so it's no longer zero.  As
a result, we shouldn't just assume that %fs/%gs tend to be zero
together, but test them independently instead.

Also, fix setting of debug registers to use the "next" pointer instead
of "current".  It so happens that the scheduler will have set the new
current pointer before calling __switch_to(), but that's just an
implementation detail.
上级 f60f7008
......@@ -700,23 +700,27 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
/*
* Restore %fs and %gs if needed.
*
* Glibc normally makes %fs be zero, and %gs is one of
* the TLS segments.
*/
if (unlikely(prev->fs | prev->gs | next->fs | next->gs)) {
if (unlikely(prev->fs | next->fs))
loadsegment(fs, next->fs);
if (prev->gs | next->gs)
loadsegment(gs, next->gs);
}
/*
* Now maybe reload the debug registers
*/
if (unlikely(next->debugreg[7])) {
set_debugreg(current->thread.debugreg[0], 0);
set_debugreg(current->thread.debugreg[1], 1);
set_debugreg(current->thread.debugreg[2], 2);
set_debugreg(current->thread.debugreg[3], 3);
set_debugreg(next->debugreg[0], 0);
set_debugreg(next->debugreg[1], 1);
set_debugreg(next->debugreg[2], 2);
set_debugreg(next->debugreg[3], 3);
/* no 4 and 5 */
set_debugreg(current->thread.debugreg[6], 6);
set_debugreg(current->thread.debugreg[7], 7);
set_debugreg(next->debugreg[6], 6);
set_debugreg(next->debugreg[7], 7);
}
if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册