diff options
Diffstat (limited to 'arch/x86/kernel/ptrace.c')
| -rw-r--r-- | arch/x86/kernel/ptrace.c | 21 |
1 files changed, 8 insertions, 13 deletions
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 06ca07f6ad86..3d9672e59c16 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
| @@ -75,10 +75,7 @@ static inline bool invalid_selector(u16 value) | |||
| 75 | static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno) | 75 | static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno) |
| 76 | { | 76 | { |
| 77 | BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0); | 77 | BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0); |
| 78 | regno >>= 2; | 78 | return ®s->bx + (regno >> 2); |
| 79 | if (regno > FS) | ||
| 80 | --regno; | ||
| 81 | return ®s->bx + regno; | ||
| 82 | } | 79 | } |
| 83 | 80 | ||
| 84 | static u16 get_segment_reg(struct task_struct *task, unsigned long offset) | 81 | static u16 get_segment_reg(struct task_struct *task, unsigned long offset) |
| @@ -90,9 +87,10 @@ static u16 get_segment_reg(struct task_struct *task, unsigned long offset) | |||
| 90 | if (offset != offsetof(struct user_regs_struct, gs)) | 87 | if (offset != offsetof(struct user_regs_struct, gs)) |
| 91 | retval = *pt_regs_access(task_pt_regs(task), offset); | 88 | retval = *pt_regs_access(task_pt_regs(task), offset); |
| 92 | else { | 89 | else { |
| 93 | retval = task->thread.gs; | ||
| 94 | if (task == current) | 90 | if (task == current) |
| 95 | savesegment(gs, retval); | 91 | retval = get_user_gs(task_pt_regs(task)); |
| 92 | else | ||
| 93 | retval = task_user_gs(task); | ||
| 96 | } | 94 | } |
| 97 | return retval; | 95 | return retval; |
| 98 | } | 96 | } |
| @@ -126,13 +124,10 @@ static int set_segment_reg(struct task_struct *task, | |||
| 126 | break; | 124 | break; |
| 127 | 125 | ||
| 128 | case offsetof(struct user_regs_struct, gs): | 126 | case offsetof(struct user_regs_struct, gs): |
| 129 | task->thread.gs = value; | ||
| 130 | if (task == current) | 127 | if (task == current) |
| 131 | /* | 128 | set_user_gs(task_pt_regs(task), value); |
| 132 | * The user-mode %gs is not affected by | 129 | else |
| 133 | * kernel entry, so we must update the CPU. | 130 | task_user_gs(task) = value; |
| 134 | */ | ||
| 135 | loadsegment(gs, value); | ||
| 136 | } | 131 | } |
| 137 | 132 | ||
| 138 | return 0; | 133 | return 0; |
| @@ -273,7 +268,7 @@ static unsigned long debugreg_addr_limit(struct task_struct *task) | |||
| 273 | if (test_tsk_thread_flag(task, TIF_IA32)) | 268 | if (test_tsk_thread_flag(task, TIF_IA32)) |
| 274 | return IA32_PAGE_OFFSET - 3; | 269 | return IA32_PAGE_OFFSET - 3; |
| 275 | #endif | 270 | #endif |
| 276 | return TASK_SIZE64 - 7; | 271 | return TASK_SIZE_MAX - 7; |
| 277 | } | 272 | } |
| 278 | 273 | ||
| 279 | #endif /* CONFIG_X86_32 */ | 274 | #endif /* CONFIG_X86_32 */ |
