diff options
author | H. J. Lu <hjl@lucon.org> | 2005-05-01 11:58:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-05-01 11:58:48 -0400 |
commit | fd51f666fa591294bd7462447512666e61c56ea0 (patch) | |
tree | 0addf0006900152975c38bd75fdfd238c9179013 /arch/x86_64/kernel/process.c | |
parent | d5b63d78f1e75f6c6f04862dfb2f2a4aeffafd4c (diff) |
[PATCH] i386/x86_64 segment register access update
The new i386/x86_64 assemblers no longer accept instructions for moving
between a segment register and a 32bit memory location, i.e.,
movl (%eax),%ds
movl %ds,(%eax)
To generate instructions for moving between a segment register and a
16bit memory location without the 16bit operand size prefix, 0x66,
mov (%eax),%ds
mov %ds,(%eax)
should be used. It will work with both new and old assemblers. The
assembler starting from 2.16.90.0.1 will also support
movw (%eax),%ds
movw %ds,(%eax)
without the 0x66 prefix. I am enclosing patches for 2.4 and 2.6 kernels
here. The resulting kernel binaries should be unchanged as before, with
old and new assemblers, if gcc never generates memory access for
unsigned gsindex;
asm volatile("movl %%gs,%0" : "=g" (gsindex));
If gcc does generate memory access for the code above, the upper bits
in gsindex are undefined and the new assembler doesn't allow it.
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64/kernel/process.c')
-rw-r--r-- | arch/x86_64/kernel/process.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 9922d2ba24a3..761b6d35e338 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c | |||
@@ -402,10 +402,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp, | |||
402 | p->thread.fs = me->thread.fs; | 402 | p->thread.fs = me->thread.fs; |
403 | p->thread.gs = me->thread.gs; | 403 | p->thread.gs = me->thread.gs; |
404 | 404 | ||
405 | asm("movl %%gs,%0" : "=m" (p->thread.gsindex)); | 405 | asm("mov %%gs,%0" : "=m" (p->thread.gsindex)); |
406 | asm("movl %%fs,%0" : "=m" (p->thread.fsindex)); | 406 | asm("mov %%fs,%0" : "=m" (p->thread.fsindex)); |
407 | asm("movl %%es,%0" : "=m" (p->thread.es)); | 407 | asm("mov %%es,%0" : "=m" (p->thread.es)); |
408 | asm("movl %%ds,%0" : "=m" (p->thread.ds)); | 408 | asm("mov %%ds,%0" : "=m" (p->thread.ds)); |
409 | 409 | ||
410 | if (unlikely(me->thread.io_bitmap_ptr != NULL)) { | 410 | if (unlikely(me->thread.io_bitmap_ptr != NULL)) { |
411 | p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); | 411 | p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); |
@@ -468,11 +468,11 @@ struct task_struct *__switch_to(struct task_struct *prev_p, struct task_struct * | |||
468 | * Switch DS and ES. | 468 | * Switch DS and ES. |
469 | * This won't pick up thread selector changes, but I guess that is ok. | 469 | * This won't pick up thread selector changes, but I guess that is ok. |
470 | */ | 470 | */ |
471 | asm volatile("movl %%es,%0" : "=m" (prev->es)); | 471 | asm volatile("mov %%es,%0" : "=m" (prev->es)); |
472 | if (unlikely(next->es | prev->es)) | 472 | if (unlikely(next->es | prev->es)) |
473 | loadsegment(es, next->es); | 473 | loadsegment(es, next->es); |
474 | 474 | ||
475 | asm volatile ("movl %%ds,%0" : "=m" (prev->ds)); | 475 | asm volatile ("mov %%ds,%0" : "=m" (prev->ds)); |
476 | if (unlikely(next->ds | prev->ds)) | 476 | if (unlikely(next->ds | prev->ds)) |
477 | loadsegment(ds, next->ds); | 477 | loadsegment(ds, next->ds); |
478 | 478 | ||