···2121 select HAVE_KRETPROBES2222 select HAVE_DMA_ATTRS2323 select HAVE_KVM2424+ select HAVE_ARCH_TRACEHOOK2425 default y2526 help2627 The Itanium Processor Family is Intel's 64-bit successor to
+6-1
arch/ia64/ia32/ia32_entry.S
···108108 ;;109109 st8 [r2]=r3 // initialize return code to -ENOSYS110110 br.call.sptk.few rp=syscall_trace_enter // give parent a chance to catch syscall args111111+ cmp.lt p6,p0=r8,r0 // check tracehook112112+ adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8113113+ ;;114114+(p6) st8.spill [r2]=r8 // store return value in slot for r8115115+(p6) br.spnt.few .ret4111116.ret2: // Need to reload arguments (they may be changed by the tracing process)112117 adds r2=IA64_PT_REGS_R1_OFFSET+16,sp // r2 = &pt_regs.r1113118 adds r3=IA64_PT_REGS_R13_OFFSET+16,sp // r3 = &pt_regs.r13···204199 data8 sys_setuid /* 16-bit version */205200 data8 sys_getuid /* 16-bit version */206201 data8 compat_sys_stime /* 25 */207207- data8 sys32_ptrace202202+ data8 compat_sys_ptrace208203 data8 sys32_alarm209204 data8 sys_ni_syscall210205 data8 sys_pause
+6-77
arch/ia64/ia32/sys_ia32.c
···11941194 return compat_sys_wait4(pid, stat_addr, options, NULL);11951195}1196119611971197-static unsigned int11981198-ia32_peek (struct task_struct *child, unsigned long addr, unsigned int *val)11991199-{12001200- size_t copied;12011201- unsigned int ret;12021202-12031203- copied = access_process_vm(child, addr, val, sizeof(*val), 0);12041204- return (copied != sizeof(ret)) ? -EIO : 0;12051205-}12061206-12071207-static unsigned int12081208-ia32_poke (struct task_struct *child, unsigned long addr, unsigned int val)12091209-{12101210-12111211- if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val))12121212- return -EIO;12131213- return 0;12141214-}12151215-12161197/*12171198 * The order in which registers are stored in the ptrace regs structure12181199 */···14911510 return 0;14921511}1493151214941494-asmlinkage long14951495-sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data)15131513+long compat_arch_ptrace(struct task_struct *child, compat_long_t request,15141514+ compat_ulong_t caddr, compat_ulong_t cdata)14961515{14971497- struct task_struct *child;14981498- unsigned int value, tmp;15161516+ unsigned long addr = caddr;15171517+ unsigned long data = cdata;15181518+ unsigned int tmp;14991519 long i, ret;1500152015011501- lock_kernel();15021502- if (request == PTRACE_TRACEME) {15031503- ret = ptrace_traceme();15041504- goto out;15051505- }15061506-15071507- child = ptrace_get_task_struct(pid);15081508- if (IS_ERR(child)) {15091509- ret = PTR_ERR(child);15101510- goto out;15111511- }15121512-15131513- if (request == PTRACE_ATTACH) {15141514- ret = sys_ptrace(request, pid, addr, data);15151515- goto out_tsk;15161516- }15171517-15181518- ret = ptrace_check_attach(child, request == PTRACE_KILL);15191519- if (ret < 0)15201520- goto out_tsk;15211521-15221521 switch (request) {15231523- case PTRACE_PEEKTEXT:15241524- case PTRACE_PEEKDATA: /* read word at location addr */15251525- ret = ia32_peek(child, addr, &value);15261526- if (ret == 0)15271527- ret = put_user(value, (unsigned int __user *) compat_ptr(data));15281528- else15291529- ret = -EIO;15301530- goto out_tsk;15311531-15321532- case PTRACE_POKETEXT:15331533- case PTRACE_POKEDATA: /* write the word at location addr */15341534- ret = ia32_poke(child, addr, data);15351535- goto out_tsk;15361536-15371522 case PTRACE_PEEKUSR: /* read word at addr in USER area */15381523 ret = -EIO;15391524 if ((addr & 3) || addr > 17*sizeof(int))···15641617 compat_ptr(data));15651618 break;1566161915671567- case PTRACE_GETEVENTMSG: 15681568- ret = put_user(child->ptrace_message, (unsigned int __user *) compat_ptr(data));15691569- break;15701570-15711571- case PTRACE_SYSCALL: /* continue, stop after next syscall */15721572- case PTRACE_CONT: /* restart after signal. */15731573- case PTRACE_KILL:15741574- case PTRACE_SINGLESTEP: /* execute chile for one instruction */15751575- case PTRACE_DETACH: /* detach a process */15761576- ret = sys_ptrace(request, pid, addr, data);15771577- break;15781578-15791620 default:15801580- ret = ptrace_request(child, request, addr, data);15811581- break;15821582-16211621+ return compat_ptrace_request(child, request, caddr, cdata);15831622 }15841584- out_tsk:15851585- put_task_struct(child);15861586- out:15871587- unlock_kernel();15881623 return ret;15891624}15901625
+8
arch/ia64/include/asm/ptrace.h
···240240 */241241# define instruction_pointer(regs) ((regs)->cr_iip + ia64_psr(regs)->ri)242242243243+static inline unsigned long user_stack_pointer(struct pt_regs *regs)244244+{245245+ /* FIXME: should this be bspstore + nr_dirty regs? */246246+ return regs->ar_bspstore;247247+}248248+243249#define regs_return_value(regs) ((regs)->r8)244250245251/* Conserve space in histogram by encoding slot bits in address···324318325319 #define arch_has_block_step() (1)326320 extern void user_enable_block_step(struct task_struct *);321321+322322+#define __ARCH_WANT_COMPAT_SYS_PTRACE327323328324#endif /* !__KERNEL__ */329325
+163
arch/ia64/include/asm/syscall.h
···11+/*22+ * Access to user system call parameters and results33+ *44+ * Copyright (C) 2008 Intel Corp. Shaohua Li <shaohua.li@intel.com>55+ *66+ * This copyrighted material is made available to anyone wishing to use,77+ * modify, copy, or redistribute it subject to the terms and conditions88+ * of the GNU General Public License v.2.99+ *1010+ * See asm-generic/syscall.h for descriptions of what we must do here.1111+ */1212+1313+#ifndef _ASM_SYSCALL_H1414+#define _ASM_SYSCALL_H 11515+1616+#include <linux/sched.h>1717+#include <linux/err.h>1818+1919+static inline long syscall_get_nr(struct task_struct *task,2020+ struct pt_regs *regs)2121+{2222+ if ((long)regs->cr_ifs < 0) /* Not a syscall */2323+ return -1;2424+2525+#ifdef CONFIG_IA32_SUPPORT2626+ if (IS_IA32_PROCESS(regs))2727+ return regs->r1;2828+#endif2929+3030+ return regs->r15;3131+}3232+3333+static inline void syscall_rollback(struct task_struct *task,3434+ struct pt_regs *regs)3535+{3636+#ifdef CONFIG_IA32_SUPPORT3737+ if (IS_IA32_PROCESS(regs))3838+ regs->r8 = regs->r1;3939+#endif4040+4141+ /* do nothing */4242+}4343+4444+static inline long syscall_get_error(struct task_struct *task,4545+ struct pt_regs *regs)4646+{4747+#ifdef CONFIG_IA32_SUPPORT4848+ if (IS_IA32_PROCESS(regs))4949+ return regs->r8;5050+#endif5151+5252+ return regs->r10 == -1 ? regs->r8:0;5353+}5454+5555+static inline long syscall_get_return_value(struct task_struct *task,5656+ struct pt_regs *regs)5757+{5858+ return regs->r8;5959+}6060+6161+static inline void syscall_set_return_value(struct task_struct *task,6262+ struct pt_regs *regs,6363+ int error, long val)6464+{6565+#ifdef CONFIG_IA32_SUPPORT6666+ if (IS_IA32_PROCESS(regs)) {6767+ regs->r8 = (long) error ? error : val;6868+ return;6969+ }7070+#endif7171+7272+ if (error) {7373+ /* error < 0, but ia64 uses > 0 return value */7474+ regs->r8 = -error;7575+ regs->r10 = -1;7676+ } else {7777+ regs->r8 = val;7878+ regs->r10 = 0;7979+ }8080+}8181+8282+extern void ia64_syscall_get_set_arguments(struct task_struct *task,8383+ struct pt_regs *regs, unsigned int i, unsigned int n,8484+ unsigned long *args, int rw);8585+static inline void syscall_get_arguments(struct task_struct *task,8686+ struct pt_regs *regs,8787+ unsigned int i, unsigned int n,8888+ unsigned long *args)8989+{9090+ BUG_ON(i + n > 6);9191+9292+#ifdef CONFIG_IA32_SUPPORT9393+ if (IS_IA32_PROCESS(regs)) {9494+ switch (i + n) {9595+ case 6:9696+ if (!n--) break;9797+ *args++ = regs->r13;9898+ case 5:9999+ if (!n--) break;100100+ *args++ = regs->r15;101101+ case 4:102102+ if (!n--) break;103103+ *args++ = regs->r14;104104+ case 3:105105+ if (!n--) break;106106+ *args++ = regs->r10;107107+ case 2:108108+ if (!n--) break;109109+ *args++ = regs->r9;110110+ case 1:111111+ if (!n--) break;112112+ *args++ = regs->r11;113113+ case 0:114114+ if (!n--) break;115115+ default:116116+ BUG();117117+ break;118118+ }119119+120120+ return;121121+ }122122+#endif123123+ ia64_syscall_get_set_arguments(task, regs, i, n, args, 0);124124+}125125+126126+static inline void syscall_set_arguments(struct task_struct *task,127127+ struct pt_regs *regs,128128+ unsigned int i, unsigned int n,129129+ unsigned long *args)130130+{131131+ BUG_ON(i + n > 6);132132+133133+#ifdef CONFIG_IA32_SUPPORT134134+ if (IS_IA32_PROCESS(regs)) {135135+ switch (i + n) {136136+ case 6:137137+ if (!n--) break;138138+ regs->r13 = *args++;139139+ case 5:140140+ if (!n--) break;141141+ regs->r15 = *args++;142142+ case 4:143143+ if (!n--) break;144144+ regs->r14 = *args++;145145+ case 3:146146+ if (!n--) break;147147+ regs->r10 = *args++;148148+ case 2:149149+ if (!n--) break;150150+ regs->r9 = *args++;151151+ case 1:152152+ if (!n--) break;153153+ regs->r11 = *args++;154154+ case 0:155155+ if (!n--) break;156156+ }157157+158158+ return;159159+ }160160+#endif161161+ ia64_syscall_get_set_arguments(task, regs, i, n, args, 1);162162+}163163+#endif /* _ASM_SYSCALL_H */
···4040#include <linux/capability.h>4141#include <linux/rcupdate.h>4242#include <linux/completion.h>4343+#include <linux/tracehook.h>43444445#include <asm/errno.h>4546#include <asm/intrinsics.h>···3685368436863685 PFM_SET_WORK_PENDING(task, 1);3687368636883688- tsk_set_notify_resume(task);36873687+ set_notify_resume(task);3689368836903689 /*36913690 * XXX: send reschedule if task runs on another CPU···5045504450465045 PFM_SET_WORK_PENDING(current, 0);5047504650485048- tsk_clear_notify_resume(current);50495049-50505047 regs = task_pt_regs(current);5051504850525049 /*···54135414 * when coming from ctxsw, current still points to the54145415 * previous task, therefore we must work with task and not current.54155416 */54165416- tsk_set_notify_resume(task);54175417+ set_notify_resume(task);54175418 }54185419 /*54195420 * defer until state is changed (shorten spin window). the context is locked
+6-15
arch/ia64/kernel/process.c
···2828#include <linux/delay.h>2929#include <linux/kdebug.h>3030#include <linux/utsname.h>3131+#include <linux/tracehook.h>31323233#include <asm/cpu.h>3334#include <asm/delay.h>···161160 show_stack(NULL, NULL);162161}163162164164-void tsk_clear_notify_resume(struct task_struct *tsk)165165-{166166-#ifdef CONFIG_PERFMON167167- if (tsk->thread.pfm_needs_checking)168168- return;169169-#endif170170- if (test_ti_thread_flag(task_thread_info(tsk), TIF_RESTORE_RSE))171171- return;172172- clear_ti_thread_flag(task_thread_info(tsk), TIF_NOTIFY_RESUME);173173-}174174-175175-/*176176- * do_notify_resume_user():177177- * Called from notify_resume_user at entry.S, with interrupts disabled.178178- */179163void180164do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)181165{···187201 if (test_thread_flag(TIF_SIGPENDING)) {188202 local_irq_enable(); /* force interrupt enable */189203 ia64_do_signal(scr, in_syscall);204204+ }205205+206206+ if (test_thread_flag(TIF_NOTIFY_RESUME)) {207207+ clear_thread_flag(TIF_NOTIFY_RESUME);208208+ tracehook_notify_resume(&scr->pt);190209 }191210192211 /* copy user rbs to kernel rbs */
+79-33
arch/ia64/kernel/ptrace.c
···2222#include <linux/signal.h>2323#include <linux/regset.h>2424#include <linux/elf.h>2525+#include <linux/tracehook.h>25262627#include <asm/pgtable.h>2728#include <asm/processor.h>···604603{605604 if (test_and_set_tsk_thread_flag(current, TIF_RESTORE_RSE))606605 return;607607- tsk_set_notify_resume(current);606606+ set_notify_resume(current);608607 unw_init_running(do_sync_rbs, ia64_sync_user_rbs);609608}610609···614613void ia64_sync_krbs(void)615614{616615 clear_tsk_thread_flag(current, TIF_RESTORE_RSE);617617- tsk_clear_notify_resume(current);618616619617 unw_init_running(do_sync_rbs, ia64_sync_kernel_rbs);620618}···644644 spin_lock_irq(&child->sighand->siglock);645645 if (child->state == TASK_STOPPED &&646646 !test_and_set_tsk_thread_flag(child, TIF_RESTORE_RSE)) {647647- tsk_set_notify_resume(child);647647+ set_notify_resume(child);648648649649 child->state = TASK_TRACED;650650 stopped = 1;···12321232}123312331234123412351235-static void12361236-syscall_trace (void)12371237-{12381238- /*12391239- * The 0x80 provides a way for the tracing parent to12401240- * distinguish between a syscall stop and SIGTRAP delivery.12411241- */12421242- ptrace_notify(SIGTRAP12431243- | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));12441244-12451245- /*12461246- * This isn't the same as continuing with a signal, but it12471247- * will do for normal use. strace only continues with a12481248- * signal if the stopping signal is not SIGTRAP. -brl12491249- */12501250- if (current->exit_code) {12511251- send_sig(current->exit_code, current, 1);12521252- current->exit_code = 0;12531253- }12541254-}12551255-12561235/* "asmlinkage" so the input arguments are preserved... */1257123612581258-asmlinkage void12371237+asmlinkage long12591238syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,12601239 long arg4, long arg5, long arg6, long arg7,12611240 struct pt_regs regs)12621241{12631263- if (test_thread_flag(TIF_SYSCALL_TRACE) 12641264- && (current->ptrace & PT_PTRACED))12651265- syscall_trace();12421242+ if (test_thread_flag(TIF_SYSCALL_TRACE))12431243+ if (tracehook_report_syscall_entry(®s))12441244+ return -ENOSYS;1266124512671246 /* copy user rbs to kernel rbs */12681247 if (test_thread_flag(TIF_RESTORE_RSE))···12621283 audit_syscall_entry(arch, syscall, arg0, arg1, arg2, arg3);12631284 }1264128512861286+ return 0;12651287}1266128812671289/* "asmlinkage" so the input arguments are preserved... */···12721292 long arg4, long arg5, long arg6, long arg7,12731293 struct pt_regs regs)12741294{12951295+ int step;12961296+12751297 if (unlikely(current->audit_context)) {12761298 int success = AUDITSC_RESULT(regs.r10);12771299 long result = regs.r8;···12831301 audit_syscall_exit(success, result);12841302 }1285130312861286- if ((test_thread_flag(TIF_SYSCALL_TRACE)12871287- || test_thread_flag(TIF_SINGLESTEP))12881288- && (current->ptrace & PT_PTRACED))12891289- syscall_trace();13041304+ step = test_thread_flag(TIF_SINGLESTEP);13051305+ if (step || test_thread_flag(TIF_SYSCALL_TRACE))13061306+ tracehook_report_syscall_exit(®s, step);1290130712911308 /* copy user rbs to kernel rbs */12921309 if (test_thread_flag(TIF_RESTORE_RSE))···19211940{19221941 if (test_and_set_tsk_thread_flag(target, TIF_RESTORE_RSE))19231942 return 0;19241924- tsk_set_notify_resume(target);19431943+ set_notify_resume(target);19251944 return do_regset_call(do_gpregs_writeback, target, regset, 0, 0,19261945 NULL, NULL);19271946}···21792198 return &user_ia32_view;21802199#endif21812200 return &user_ia64_view;22012201+}22022202+22032203+struct syscall_get_set_args {22042204+ unsigned int i;22052205+ unsigned int n;22062206+ unsigned long *args;22072207+ struct pt_regs *regs;22082208+ int rw;22092209+};22102210+22112211+static void syscall_get_set_args_cb(struct unw_frame_info *info, void *data)22122212+{22132213+ struct syscall_get_set_args *args = data;22142214+ struct pt_regs *pt = args->regs;22152215+ unsigned long *krbs, cfm, ndirty;22162216+ int i, count;22172217+22182218+ if (unw_unwind_to_user(info) < 0)22192219+ return;22202220+22212221+ cfm = pt->cr_ifs;22222222+ krbs = (unsigned long *)info->task + IA64_RBS_OFFSET/8;22232223+ ndirty = ia64_rse_num_regs(krbs, krbs + (pt->loadrs >> 19));22242224+22252225+ count = 0;22262226+ if (in_syscall(pt))22272227+ count = min_t(int, args->n, cfm & 0x7f);22282228+22292229+ for (i = 0; i < count; i++) {22302230+ if (args->rw)22312231+ *ia64_rse_skip_regs(krbs, ndirty + i + args->i) =22322232+ args->args[i];22332233+ else22342234+ args->args[i] = *ia64_rse_skip_regs(krbs,22352235+ ndirty + i + args->i);22362236+ }22372237+22382238+ if (!args->rw) {22392239+ while (i < args->n) {22402240+ args->args[i] = 0;22412241+ i++;22422242+ }22432243+ }22442244+}22452245+22462246+void ia64_syscall_get_set_arguments(struct task_struct *task,22472247+ struct pt_regs *regs, unsigned int i, unsigned int n,22482248+ unsigned long *args, int rw)22492249+{22502250+ struct syscall_get_set_args data = {22512251+ .i = i,22522252+ .n = n,22532253+ .args = args,22542254+ .regs = regs,22552255+ .rw = rw,22562256+ };22572257+22582258+ if (task == current)22592259+ unw_init_running(syscall_get_set_args_cb, &data);22602260+ else {22612261+ struct unw_frame_info ufi;22622262+ memset(&ufi, 0, sizeof(ufi));22632263+ unw_init_from_blocked_task(&ufi, task);22642264+ syscall_get_set_args_cb(&ufi, &data);22652265+ }21822266}
+8
arch/ia64/kernel/signal.c
···1111#include <linux/kernel.h>1212#include <linux/mm.h>1313#include <linux/ptrace.h>1414+#include <linux/tracehook.h>1415#include <linux/sched.h>1516#include <linux/signal.h>1617#include <linux/smp.h>···440439 sigaddset(¤t->blocked, sig);441440 recalc_sigpending();442441 spin_unlock_irq(¤t->sighand->siglock);442442+443443+ /*444444+ * Let tracing know that we've done the handler setup.445445+ */446446+ tracehook_signal_handler(sig, info, ka, &scr->pt,447447+ test_thread_flag(TIF_SINGLESTEP));448448+443449 return 1;444450}445451