[PATCH] i386: Fix places where using %gs changes the usermode ABI
authorJeremy Fitzhardinge <jeremy@goop.org>
Thu, 7 Dec 2006 01:14:02 +0000 (02:14 +0100)
committerAndi Kleen <andi@basil.nowhere.org>
Thu, 7 Dec 2006 01:14:02 +0000 (02:14 +0100)
There are a few places where the change in struct pt_regs and the use of %gs
affect the userspace ABI.  These are primarily debugging interfaces where
thread state can be inspected or extracted.

Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Cc: Chuck Ebbert <76306.1226@compuserve.com>
Cc: Zachary Amsden <zach@vmware.com>
Cc: Jan Beulich <jbeulich@novell.com>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
arch/i386/kernel/process.c
arch/i386/kernel/ptrace.c
include/asm-i386/elf.h
include/asm-i386/unwind.h

index 905364d42847cea5f164462305073b6845af1ad5..dc427254517981e98e91929956db3685e4e37f54 100644 (file)
@@ -315,8 +315,8 @@ void show_regs(struct pt_regs * regs)
                regs->eax,regs->ebx,regs->ecx,regs->edx);
        printk("ESI: %08lx EDI: %08lx EBP: %08lx",
                regs->esi, regs->edi, regs->ebp);
-       printk(" DS: %04x ES: %04x\n",
-               0xffff & regs->xds,0xffff & regs->xes);
+       printk(" DS: %04x ES: %04x GS: %04x\n",
+              0xffff & regs->xds,0xffff & regs->xes, 0xffff & regs->xgs);
 
        cr0 = read_cr0();
        cr2 = read_cr2();
@@ -509,7 +509,7 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
        dump->regs.ds = regs->xds;
        dump->regs.es = regs->xes;
        savesegment(fs,dump->regs.fs);
-       savesegment(gs,dump->regs.gs);
+       dump->regs.gs = regs->xgs;
        dump->regs.orig_eax = regs->orig_eax;
        dump->regs.eip = regs->eip;
        dump->regs.cs = regs->xcs;
index 775f50e9395bb048a2e193ef60483af172c7c045..f3f94ac5736a254c4a97eb58aa7335a70328df18 100644 (file)
@@ -94,13 +94,9 @@ static int putreg(struct task_struct *child,
                                return -EIO;
                        child->thread.fs = value;
                        return 0;
-               case GS:
-                       if (value && (value & 3) != 3)
-                               return -EIO;
-                       child->thread.gs = value;
-                       return 0;
                case DS:
                case ES:
+               case GS:
                        if (value && (value & 3) != 3)
                                return -EIO;
                        value &= 0xffff;
@@ -116,8 +112,8 @@ static int putreg(struct task_struct *child,
                        value |= get_stack_long(child, EFL_OFFSET) & ~FLAG_MASK;
                        break;
        }
-       if (regno > GS*4)
-               regno -= 2*4;
+       if (regno > ES*4)
+               regno -= 1*4;
        put_stack_long(child, regno - sizeof(struct pt_regs), value);
        return 0;
 }
@@ -131,18 +127,16 @@ static unsigned long getreg(struct task_struct *child,
                case FS:
                        retval = child->thread.fs;
                        break;
-               case GS:
-                       retval = child->thread.gs;
-                       break;
                case DS:
                case ES:
+               case GS:
                case SS:
                case CS:
                        retval = 0xffff;
                        /* fall through */
                default:
-                       if (regno > GS*4)
-                               regno -= 2*4;
+                       if (regno > ES*4)
+                               regno -= 1*4;
                        regno = regno - sizeof(struct pt_regs);
                        retval &= get_stack_long(child, regno);
        }
index 3a05436f31c0e8252e01389f251d7d5225711583..45d21a0c95bf8127368f7fe273facaabf2f6a9ee 100644 (file)
@@ -91,7 +91,7 @@ typedef struct user_fxsr_struct elf_fpxregset_t;
        pr_reg[7] = regs->xds;                          \
        pr_reg[8] = regs->xes;                          \
        savesegment(fs,pr_reg[9]);                      \
-       savesegment(gs,pr_reg[10]);                     \
+       pr_reg[10] = regs->xgs;                         \
        pr_reg[11] = regs->orig_eax;                    \
        pr_reg[12] = regs->eip;                         \
        pr_reg[13] = regs->xcs;                         \
index 5031d693b89d35fb3f7cfce8db78a79bb1db5503..601fc67bd775ca8fbdb954f7053cf9c730a772c1 100644 (file)
@@ -71,6 +71,7 @@ static inline void arch_unw_init_blocked(struct unwind_frame_info *info)
        info->regs.xss = __KERNEL_DS;
        info->regs.xds = __USER_DS;
        info->regs.xes = __USER_DS;
+       info->regs.xgs = __KERNEL_PDA;
 }
 
 extern asmlinkage int arch_unwind_init_running(struct unwind_frame_info *,