Loading arch/ia64/hp/sim/simserial.c +2 −8 Original line number Original line Diff line number Diff line Loading @@ -167,15 +167,9 @@ static void receive_chars(struct tty_struct *tty, struct pt_regs *regs) } } } } seen_esc = 0; seen_esc = 0; if (tty->flip.count >= TTY_FLIPBUF_SIZE) break; *tty->flip.char_buf_ptr = ch; if (tty_insert_flip_char(tty, ch, TTY_NORMAL) == 0) break; *tty->flip.flag_buf_ptr = 0; tty->flip.flag_buf_ptr++; tty->flip.char_buf_ptr++; tty->flip.count++; } } tty_flip_buffer_push(tty); tty_flip_buffer_push(tty); } } Loading arch/ia64/kernel/fsys.S +1 −0 Original line number Original line Diff line number Diff line Loading @@ -903,5 +903,6 @@ fsyscall_table: data8 0 data8 0 data8 0 data8 0 data8 0 data8 0 data8 0 // 1280 .org fsyscall_table + 8*NR_syscalls // guard against failures to increase NR_syscalls .org fsyscall_table + 8*NR_syscalls // guard against failures to increase NR_syscalls arch/ia64/kernel/jprobes.S +27 −0 Original line number Original line Diff line number Diff line Loading @@ -60,3 +60,30 @@ END(jprobe_break) GLOBAL_ENTRY(jprobe_inst_return) GLOBAL_ENTRY(jprobe_inst_return) br.call.sptk.many b0=jprobe_break br.call.sptk.many b0=jprobe_break END(jprobe_inst_return) END(jprobe_inst_return) GLOBAL_ENTRY(invalidate_stacked_regs) movl r16=invalidate_restore_cfm ;; mov b6=r16 ;; br.ret.sptk.many b6 ;; invalidate_restore_cfm: mov r16=ar.rsc ;; mov ar.rsc=r0 ;; loadrs ;; mov ar.rsc=r16 ;; br.cond.sptk.many rp END(invalidate_stacked_regs) GLOBAL_ENTRY(flush_register_stack) // flush dirty regs to backing store (must be first in insn group) flushrs ;; br.ret.sptk.many rp END(flush_register_stack) arch/ia64/kernel/kprobes.c +57 −0 Original line number Original line Diff line number Diff line Loading @@ -766,11 +766,56 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, return ret; return ret; } } struct param_bsp_cfm { unsigned long ip; unsigned long *bsp; unsigned long cfm; }; static void ia64_get_bsp_cfm(struct unw_frame_info *info, void *arg) { unsigned long ip; struct param_bsp_cfm *lp = arg; do { unw_get_ip(info, &ip); if (ip == 0) break; if (ip == lp->ip) { unw_get_bsp(info, (unsigned long*)&lp->bsp); unw_get_cfm(info, (unsigned long*)&lp->cfm); return; } } while (unw_unwind(info) >= 0); lp->bsp = 0; lp->cfm = 0; return; } int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) { { struct jprobe *jp = container_of(p, struct jprobe, kp); struct jprobe *jp = container_of(p, struct jprobe, kp); unsigned long addr = ((struct fnptr *)(jp->entry))->ip; unsigned long addr = ((struct fnptr *)(jp->entry))->ip; struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); struct param_bsp_cfm pa; int bytes; /* * Callee owns the argument space and could overwrite it, eg * tail call optimization. So to be absolutely safe * we save the argument space before transfering the control * to instrumented jprobe function which runs in * the process context */ pa.ip = regs->cr_iip; unw_init_running(ia64_get_bsp_cfm, &pa); bytes = (char *)ia64_rse_skip_regs(pa.bsp, pa.cfm & 0x3f) - (char *)pa.bsp; memcpy( kcb->jprobes_saved_stacked_regs, pa.bsp, bytes ); kcb->bsp = pa.bsp; kcb->cfm = pa.cfm; /* save architectural state */ /* save architectural state */ kcb->jprobe_saved_regs = *regs; kcb->jprobe_saved_regs = *regs; Loading @@ -792,8 +837,20 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) { { struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); int bytes; /* restoring architectural state */ *regs = kcb->jprobe_saved_regs; *regs = kcb->jprobe_saved_regs; /* restoring the original argument space */ flush_register_stack(); bytes = (char *)ia64_rse_skip_regs(kcb->bsp, kcb->cfm & 0x3f) - (char *)kcb->bsp; memcpy( kcb->bsp, kcb->jprobes_saved_stacked_regs, bytes ); invalidate_stacked_regs(); preempt_enable_no_resched(); preempt_enable_no_resched(); return 1; return 1; } } Loading arch/ia64/kernel/mca_asm.S +1 −1 Original line number Original line Diff line number Diff line Loading @@ -847,7 +847,7 @@ ia64_state_restore: ;; ;; mov cr.iim=temp3 mov cr.iim=temp3 mov cr.iha=temp4 mov cr.iha=temp4 dep r22=0,r22,62,2 // pal_min_state, physical, uncached dep r22=0,r22,62,1 // pal_min_state, physical, uncached mov IA64_KR(CURRENT)=r21 mov IA64_KR(CURRENT)=r21 ld8 r8=[temp1] // os_status ld8 r8=[temp1] // os_status ld8 r10=[temp2] // context ld8 r10=[temp2] // context Loading Loading
arch/ia64/hp/sim/simserial.c +2 −8 Original line number Original line Diff line number Diff line Loading @@ -167,15 +167,9 @@ static void receive_chars(struct tty_struct *tty, struct pt_regs *regs) } } } } seen_esc = 0; seen_esc = 0; if (tty->flip.count >= TTY_FLIPBUF_SIZE) break; *tty->flip.char_buf_ptr = ch; if (tty_insert_flip_char(tty, ch, TTY_NORMAL) == 0) break; *tty->flip.flag_buf_ptr = 0; tty->flip.flag_buf_ptr++; tty->flip.char_buf_ptr++; tty->flip.count++; } } tty_flip_buffer_push(tty); tty_flip_buffer_push(tty); } } Loading
arch/ia64/kernel/fsys.S +1 −0 Original line number Original line Diff line number Diff line Loading @@ -903,5 +903,6 @@ fsyscall_table: data8 0 data8 0 data8 0 data8 0 data8 0 data8 0 data8 0 // 1280 .org fsyscall_table + 8*NR_syscalls // guard against failures to increase NR_syscalls .org fsyscall_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
arch/ia64/kernel/jprobes.S +27 −0 Original line number Original line Diff line number Diff line Loading @@ -60,3 +60,30 @@ END(jprobe_break) GLOBAL_ENTRY(jprobe_inst_return) GLOBAL_ENTRY(jprobe_inst_return) br.call.sptk.many b0=jprobe_break br.call.sptk.many b0=jprobe_break END(jprobe_inst_return) END(jprobe_inst_return) GLOBAL_ENTRY(invalidate_stacked_regs) movl r16=invalidate_restore_cfm ;; mov b6=r16 ;; br.ret.sptk.many b6 ;; invalidate_restore_cfm: mov r16=ar.rsc ;; mov ar.rsc=r0 ;; loadrs ;; mov ar.rsc=r16 ;; br.cond.sptk.many rp END(invalidate_stacked_regs) GLOBAL_ENTRY(flush_register_stack) // flush dirty regs to backing store (must be first in insn group) flushrs ;; br.ret.sptk.many rp END(flush_register_stack)
arch/ia64/kernel/kprobes.c +57 −0 Original line number Original line Diff line number Diff line Loading @@ -766,11 +766,56 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, return ret; return ret; } } struct param_bsp_cfm { unsigned long ip; unsigned long *bsp; unsigned long cfm; }; static void ia64_get_bsp_cfm(struct unw_frame_info *info, void *arg) { unsigned long ip; struct param_bsp_cfm *lp = arg; do { unw_get_ip(info, &ip); if (ip == 0) break; if (ip == lp->ip) { unw_get_bsp(info, (unsigned long*)&lp->bsp); unw_get_cfm(info, (unsigned long*)&lp->cfm); return; } } while (unw_unwind(info) >= 0); lp->bsp = 0; lp->cfm = 0; return; } int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) { { struct jprobe *jp = container_of(p, struct jprobe, kp); struct jprobe *jp = container_of(p, struct jprobe, kp); unsigned long addr = ((struct fnptr *)(jp->entry))->ip; unsigned long addr = ((struct fnptr *)(jp->entry))->ip; struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); struct param_bsp_cfm pa; int bytes; /* * Callee owns the argument space and could overwrite it, eg * tail call optimization. So to be absolutely safe * we save the argument space before transfering the control * to instrumented jprobe function which runs in * the process context */ pa.ip = regs->cr_iip; unw_init_running(ia64_get_bsp_cfm, &pa); bytes = (char *)ia64_rse_skip_regs(pa.bsp, pa.cfm & 0x3f) - (char *)pa.bsp; memcpy( kcb->jprobes_saved_stacked_regs, pa.bsp, bytes ); kcb->bsp = pa.bsp; kcb->cfm = pa.cfm; /* save architectural state */ /* save architectural state */ kcb->jprobe_saved_regs = *regs; kcb->jprobe_saved_regs = *regs; Loading @@ -792,8 +837,20 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) { { struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); int bytes; /* restoring architectural state */ *regs = kcb->jprobe_saved_regs; *regs = kcb->jprobe_saved_regs; /* restoring the original argument space */ flush_register_stack(); bytes = (char *)ia64_rse_skip_regs(kcb->bsp, kcb->cfm & 0x3f) - (char *)kcb->bsp; memcpy( kcb->bsp, kcb->jprobes_saved_stacked_regs, bytes ); invalidate_stacked_regs(); preempt_enable_no_resched(); preempt_enable_no_resched(); return 1; return 1; } } Loading
arch/ia64/kernel/mca_asm.S +1 −1 Original line number Original line Diff line number Diff line Loading @@ -847,7 +847,7 @@ ia64_state_restore: ;; ;; mov cr.iim=temp3 mov cr.iim=temp3 mov cr.iha=temp4 mov cr.iha=temp4 dep r22=0,r22,62,2 // pal_min_state, physical, uncached dep r22=0,r22,62,1 // pal_min_state, physical, uncached mov IA64_KR(CURRENT)=r21 mov IA64_KR(CURRENT)=r21 ld8 r8=[temp1] // os_status ld8 r8=[temp1] // os_status ld8 r10=[temp2] // context ld8 r10=[temp2] // context Loading