diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2006-12-06 20:14:02 -0500 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-12-06 20:14:02 -0500 |
commit | 66e10a44d724f1464b5e8b5a3eae1e2cbbc2cca6 (patch) | |
tree | 0d2a1a1d5edaf98506ef7cb271cad62f5644268e /arch/i386/kernel/ptrace.c | |
parent | f95d47caae5302a63d92be9a0292abc90e2a14e1 (diff) |
[PATCH] i386: Fix places where using %gs changes the usermode ABI
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>
Diffstat (limited to 'arch/i386/kernel/ptrace.c')
-rw-r--r-- | arch/i386/kernel/ptrace.c | 18 |
1 files changed, 6 insertions, 12 deletions
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index 775f50e9395b..f3f94ac5736a 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c | |||
@@ -94,13 +94,9 @@ static int putreg(struct task_struct *child, | |||
94 | return -EIO; | 94 | return -EIO; |
95 | child->thread.fs = value; | 95 | child->thread.fs = value; |
96 | return 0; | 96 | return 0; |
97 | case GS: | ||
98 | if (value && (value & 3) != 3) | ||
99 | return -EIO; | ||
100 | child->thread.gs = value; | ||
101 | return 0; | ||
102 | case DS: | 97 | case DS: |
103 | case ES: | 98 | case ES: |
99 | case GS: | ||
104 | if (value && (value & 3) != 3) | 100 | if (value && (value & 3) != 3) |
105 | return -EIO; | 101 | return -EIO; |
106 | value &= 0xffff; | 102 | value &= 0xffff; |
@@ -116,8 +112,8 @@ static int putreg(struct task_struct *child, | |||
116 | value |= get_stack_long(child, EFL_OFFSET) & ~FLAG_MASK; | 112 | value |= get_stack_long(child, EFL_OFFSET) & ~FLAG_MASK; |
117 | break; | 113 | break; |
118 | } | 114 | } |
119 | if (regno > GS*4) | 115 | if (regno > ES*4) |
120 | regno -= 2*4; | 116 | regno -= 1*4; |
121 | put_stack_long(child, regno - sizeof(struct pt_regs), value); | 117 | put_stack_long(child, regno - sizeof(struct pt_regs), value); |
122 | return 0; | 118 | return 0; |
123 | } | 119 | } |
@@ -131,18 +127,16 @@ static unsigned long getreg(struct task_struct *child, | |||
131 | case FS: | 127 | case FS: |
132 | retval = child->thread.fs; | 128 | retval = child->thread.fs; |
133 | break; | 129 | break; |
134 | case GS: | ||
135 | retval = child->thread.gs; | ||
136 | break; | ||
137 | case DS: | 130 | case DS: |
138 | case ES: | 131 | case ES: |
132 | case GS: | ||
139 | case SS: | 133 | case SS: |
140 | case CS: | 134 | case CS: |
141 | retval = 0xffff; | 135 | retval = 0xffff; |
142 | /* fall through */ | 136 | /* fall through */ |
143 | default: | 137 | default: |
144 | if (regno > GS*4) | 138 | if (regno > ES*4) |
145 | regno -= 2*4; | 139 | regno -= 1*4; |
146 | regno = regno - sizeof(struct pt_regs); | 140 | regno = regno - sizeof(struct pt_regs); |
147 | retval &= get_stack_long(child, regno); | 141 | retval &= get_stack_long(child, regno); |
148 | } | 142 | } |