Commit 07b047fc2466249aff7cdb23fa0b0955a7a00d48

Authored by akpm@osdl.org
Committed by Linus Torvalds
1 parent 06b425d80f

[PATCH] i386: fix task_pt_regs()

)

From: Al Viro <viro@ftp.linux.org.uk>

task_pt_regs() needs the same offset-by-8 to match copy_thread()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 3 changed files with 14 additions and 21 deletions Side-by-side Diff

arch/i386/kernel/process.c
... ... @@ -424,18 +424,7 @@
424 424 struct task_struct *tsk;
425 425 int err;
426 426  
427   - childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
428   - /*
429   - * The below -8 is to reserve 8 bytes on top of the ring0 stack.
430   - * This is necessary to guarantee that the entire "struct pt_regs"
431   - * is accessable even if the CPU haven't stored the SS/ESP registers
432   - * on the stack (interrupt gate does not save these registers
433   - * when switching to the same priv ring).
434   - * Therefore beware: accessing the xss/esp fields of the
435   - * "struct pt_regs" is possible, but they may contain the
436   - * completely wrong values.
437   - */
438   - childregs = (struct pt_regs *) ((unsigned long) childregs - 8);
  427 + childregs = task_pt_regs(p);
439 428 *childregs = *regs;
440 429 childregs->eax = 0;
441 430 childregs->esp = esp;
... ... @@ -540,12 +529,7 @@
540 529 */
541 530 int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
542 531 {
543   - struct pt_regs ptregs;
544   -
545   - ptregs = *(struct pt_regs *)
546   - ((unsigned long)tsk->thread_info +
547   - /* see comments in copy_thread() about -8 */
548   - THREAD_SIZE - sizeof(ptregs) - 8);
  532 + struct pt_regs ptregs = *task_pt_regs(tsk);
549 533 ptregs.xcs &= 0xffff;
550 534 ptregs.xds &= 0xffff;
551 535 ptregs.xes &= 0xffff;
arch/i386/kernel/smpboot.c
... ... @@ -875,8 +875,7 @@
875 875 /* initialize thread_struct. we really want to avoid destroy
876 876 * idle tread
877 877 */
878   - idle->thread.esp = (unsigned long)(((struct pt_regs *)
879   - (THREAD_SIZE + (unsigned long) idle->thread_info)) - 1);
  878 + idle->thread.esp = (unsigned long)task_pt_regs(idle);
880 879 init_idle(idle, cpu);
881 880 return idle;
882 881 }
include/asm-i386/processor.h
... ... @@ -561,10 +561,20 @@
561 561 (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
562 562 })
563 563  
  564 +/*
  565 + * The below -8 is to reserve 8 bytes on top of the ring0 stack.
  566 + * This is necessary to guarantee that the entire "struct pt_regs"
  567 + * is accessable even if the CPU haven't stored the SS/ESP registers
  568 + * on the stack (interrupt gate does not save these registers
  569 + * when switching to the same priv ring).
  570 + * Therefore beware: accessing the xss/esp fields of the
  571 + * "struct pt_regs" is possible, but they may contain the
  572 + * completely wrong values.
  573 + */
564 574 #define task_pt_regs(task) \
565 575 ({ \
566 576 struct pt_regs *__regs__; \
567   - __regs__ = (struct pt_regs *)KSTK_TOP((task)->thread_info); \
  577 + __regs__ = (struct pt_regs *)(KSTK_TOP((task)->thread_info)-8); \
568 578 __regs__ - 1; \
569 579 })
570 580