aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/ptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/ptrace.c')
-rw-r--r--arch/x86/kernel/ptrace.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index d862e396b099..d5904eef1d31 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -323,6 +323,16 @@ static int putreg(struct task_struct *child,
323 return set_flags(child, value); 323 return set_flags(child, value);
324 324
325#ifdef CONFIG_X86_64 325#ifdef CONFIG_X86_64
326 /*
327 * Orig_ax is really just a flag with small positive and
328 * negative values, so make sure to always sign-extend it
329 * from 32 bits so that it works correctly regardless of
330 * whether we come from a 32-bit environment or not.
331 */
332 case offsetof(struct user_regs_struct, orig_ax):
333 value = (long) (s32) value;
334 break;
335
326 case offsetof(struct user_regs_struct,fs_base): 336 case offsetof(struct user_regs_struct,fs_base):
327 if (value >= TASK_SIZE_OF(child)) 337 if (value >= TASK_SIZE_OF(child))
328 return -EIO; 338 return -EIO;
@@ -544,6 +554,8 @@ static int ptrace_set_debugreg(struct task_struct *child,
544 return 0; 554 return 0;
545} 555}
546 556
557#ifdef X86_BTS
558
547static int ptrace_bts_get_size(struct task_struct *child) 559static int ptrace_bts_get_size(struct task_struct *child)
548{ 560{
549 if (!child->thread.ds_area_msr) 561 if (!child->thread.ds_area_msr)
@@ -826,6 +838,7 @@ void ptrace_bts_take_timestamp(struct task_struct *tsk,
826 838
827 ptrace_bts_write_record(tsk, &rec); 839 ptrace_bts_write_record(tsk, &rec);
828} 840}
841#endif /* X86_BTS */
829 842
830/* 843/*
831 * Called by kernel/ptrace.c when detaching.. 844 * Called by kernel/ptrace.c when detaching..
@@ -839,7 +852,9 @@ void ptrace_disable(struct task_struct *child)
839 clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); 852 clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
840#endif 853#endif
841 if (child->thread.ds_area_msr) { 854 if (child->thread.ds_area_msr) {
855#ifdef X86_BTS
842 ptrace_bts_realloc(child, 0, 0); 856 ptrace_bts_realloc(child, 0, 0);
857#endif
843 child->thread.debugctlmsr &= ~ds_debugctl_mask(); 858 child->thread.debugctlmsr &= ~ds_debugctl_mask();
844 if (!child->thread.debugctlmsr) 859 if (!child->thread.debugctlmsr)
845 clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR); 860 clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
@@ -961,6 +976,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
961 break; 976 break;
962#endif 977#endif
963 978
979 /*
980 * These bits need more cooking - not enabled yet:
981 */
982#ifdef X86_BTS
964 case PTRACE_BTS_CONFIG: 983 case PTRACE_BTS_CONFIG:
965 ret = ptrace_bts_config 984 ret = ptrace_bts_config
966 (child, data, (struct ptrace_bts_config __user *)addr); 985 (child, data, (struct ptrace_bts_config __user *)addr);
@@ -988,6 +1007,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
988 ret = ptrace_bts_drain 1007 ret = ptrace_bts_drain
989 (child, data, (struct bts_struct __user *) addr); 1008 (child, data, (struct bts_struct __user *) addr);
990 break; 1009 break;
1010#endif
991 1011
992 default: 1012 default:
993 ret = ptrace_request(child, request, addr, data); 1013 ret = ptrace_request(child, request, addr, data);
@@ -1035,10 +1055,17 @@ static int putreg32(struct task_struct *child, unsigned regno, u32 value)
1035 R32(esi, si); 1055 R32(esi, si);
1036 R32(ebp, bp); 1056 R32(ebp, bp);
1037 R32(eax, ax); 1057 R32(eax, ax);
1038 R32(orig_eax, orig_ax);
1039 R32(eip, ip); 1058 R32(eip, ip);
1040 R32(esp, sp); 1059 R32(esp, sp);
1041 1060
1061 case offsetof(struct user32, regs.orig_eax):
1062 /*
1063 * Sign-extend the value so that orig_eax = -1
1064 * causes (long)orig_ax < 0 tests to fire correctly.
1065 */
1066 regs->orig_ax = (long) (s32) value;
1067 break;
1068
1042 case offsetof(struct user32, regs.eflags): 1069 case offsetof(struct user32, regs.eflags):
1043 return set_flags(child, value); 1070 return set_flags(child, value);
1044 1071
@@ -1226,12 +1253,14 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
1226 case PTRACE_SETOPTIONS: 1253 case PTRACE_SETOPTIONS:
1227 case PTRACE_SET_THREAD_AREA: 1254 case PTRACE_SET_THREAD_AREA:
1228 case PTRACE_GET_THREAD_AREA: 1255 case PTRACE_GET_THREAD_AREA:
1256#ifdef X86_BTS
1229 case PTRACE_BTS_CONFIG: 1257 case PTRACE_BTS_CONFIG:
1230 case PTRACE_BTS_STATUS: 1258 case PTRACE_BTS_STATUS:
1231 case PTRACE_BTS_SIZE: 1259 case PTRACE_BTS_SIZE:
1232 case PTRACE_BTS_GET: 1260 case PTRACE_BTS_GET:
1233 case PTRACE_BTS_CLEAR: 1261 case PTRACE_BTS_CLEAR:
1234 case PTRACE_BTS_DRAIN: 1262 case PTRACE_BTS_DRAIN:
1263#endif
1235 return sys_ptrace(request, pid, addr, data); 1264 return sys_ptrace(request, pid, addr, data);
1236 1265
1237 default: 1266 default: