Loading arch/microblaze/kernel/entry.S +60 −12 Original line number Original line Diff line number Diff line Loading @@ -308,38 +308,69 @@ C_ENTRY(_user_exception): swi r12, r1, PTO+PT_R0; swi r12, r1, PTO+PT_R0; tovirt(r1,r1) tovirt(r1,r1) la r15, r0, ret_from_trap-8 /* where the trap should return need -8 to adjust for rtsd r15, 8*/ /* where the trap should return need -8 to adjust for rtsd r15, 8*/ /* Jump to the appropriate function for the system call number in r12 /* Jump to the appropriate function for the system call number in r12 * (r12 is not preserved), or return an error if r12 is not valid. The LP * (r12 is not preserved), or return an error if r12 is not valid. The LP * register should point to the location where * register should point to the location where * the called function should return. [note that MAKE_SYS_CALL uses label 1] */ * the called function should return. [note that MAKE_SYS_CALL uses label 1] */ /* See if the system call number is valid. */ # Step into virtual mode. set_vms; addik r11, r0, 3f rtid r11, 0 nop 3: add r11, r0, CURRENT_TASK /* Get current task ptr into r11 */ lwi r11, r11, TS_THREAD_INFO /* get thread info */ lwi r11, r11, TI_FLAGS /* get flags in thread info */ andi r11, r11, _TIF_WORK_SYSCALL_MASK beqi r11, 4f addik r3, r0, -ENOSYS swi r3, r1, PTO + PT_R3 brlid r15, do_syscall_trace_enter addik r5, r1, PTO + PT_R0 # do_syscall_trace_enter returns the new syscall nr. addk r12, r0, r3 lwi r5, r1, PTO+PT_R5; lwi r6, r1, PTO+PT_R6; lwi r7, r1, PTO+PT_R7; lwi r8, r1, PTO+PT_R8; lwi r9, r1, PTO+PT_R9; lwi r10, r1, PTO+PT_R10; 4: /* Jump to the appropriate function for the system call number in r12 * (r12 is not preserved), or return an error if r12 is not valid. * The LP register should point to the location where the called function * should return. [note that MAKE_SYS_CALL uses label 1] */ /* See if the system call number is valid */ addi r11, r12, -__NR_syscalls; addi r11, r12, -__NR_syscalls; bgei r11,1f; bgei r11,5f; /* Figure out which function to use for this system call. */ /* Figure out which function to use for this system call. */ /* Note Microblaze barrel shift is optional, so don't rely on it */ /* Note Microblaze barrel shift is optional, so don't rely on it */ add r12, r12, r12; /* convert num -> ptr */ add r12, r12, r12; /* convert num -> ptr */ add r12, r12, r12; add r12, r12, r12; /* Trac syscalls and stored them to r0_ram */ /* Trac syscalls and stored them to r0_ram */ lwi r3, r12, 0x400 + TOPHYS(r0_ram) lwi r3, r12, 0x400 + r0_ram addi r3, r3, 1 addi r3, r3, 1 swi r3, r12, 0x400 + TOPHYS(r0_ram) swi r3, r12, 0x400 + r0_ram # Find and jump into the syscall handler. lwi r12, r12, sys_call_table /* where the trap should return need -8 to adjust for rtsd r15, 8 */ la r15, r0, ret_from_trap-8 bra r12 lwi r12, r12, TOPHYS(sys_call_table); /* Function ptr */ /* Make the system call. to r12*/ set_vms; rtid r12, 0; nop; /* The syscall number is invalid, return an error. */ /* The syscall number is invalid, return an error. */ 1: VM_ON; /* RETURN() expects virtual mode*/ 5: addi r3, r0, -ENOSYS; addi r3, r0, -ENOSYS; rtsd r15,8; /* looks like a normal subroutine return */ rtsd r15,8; /* looks like a normal subroutine return */ or r0, r0, r0 or r0, r0, r0 /* Entry point used to return from a syscall/trap. */ /* Entry point used to return from a syscall/trap */ /* We re-enable BIP bit before state restore */ /* We re-enable BIP bit before state restore */ C_ENTRY(ret_from_trap): C_ENTRY(ret_from_trap): set_bip; /* Ints masked for state restore*/ set_bip; /* Ints masked for state restore*/ Loading @@ -347,6 +378,23 @@ C_ENTRY(ret_from_trap): /* See if returning to kernel mode, if so, skip resched &c. */ /* See if returning to kernel mode, if so, skip resched &c. */ bnei r11, 2f; bnei r11, 2f; /* We're returning to user mode, so check for various conditions that * trigger rescheduling. */ # FIXME: Restructure all these flag checks. add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */ lwi r11, r11, TS_THREAD_INFO; /* get thread info */ lwi r11, r11, TI_FLAGS; /* get flags in thread info */ andi r11, r11, _TIF_WORK_SYSCALL_MASK beqi r11, 1f swi r3, r1, PTO + PT_R3 swi r4, r1, PTO + PT_R4 brlid r15, do_syscall_trace_leave addik r5, r1, PTO + PT_R0 lwi r3, r1, PTO + PT_R3 lwi r4, r1, PTO + PT_R4 1: /* We're returning to user mode, so check for various conditions that /* We're returning to user mode, so check for various conditions that * trigger rescheduling. */ * trigger rescheduling. */ /* Get current task ptr into r11 */ /* Get current task ptr into r11 */ Loading arch/microblaze/kernel/ptrace.c +62 −0 Original line number Original line Diff line number Diff line Loading @@ -29,6 +29,10 @@ #include <linux/sched.h> #include <linux/sched.h> #include <linux/ptrace.h> #include <linux/ptrace.h> #include <linux/signal.h> #include <linux/signal.h> #include <linux/elf.h> #include <linux/audit.h> #include <linux/seccomp.h> #include <linux/tracehook.h> #include <linux/errno.h> #include <linux/errno.h> #include <asm/processor.h> #include <asm/processor.h> Loading Loading @@ -174,6 +178,64 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) return rval; return rval; } } asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) { long ret = 0; secure_computing(regs->r12); if (test_thread_flag(TIF_SYSCALL_TRACE) && tracehook_report_syscall_entry(regs)) /* * Tracing decided this syscall should not happen. * We'll return a bogus call number to get an ENOSYS * error, but leave the original number in regs->regs[0]. */ ret = -1L; if (unlikely(current->audit_context)) audit_syscall_entry(EM_XILINX_MICROBLAZE, regs->r12, regs->r5, regs->r6, regs->r7, regs->r8); return ret ?: regs->r12; } asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) { int step; if (unlikely(current->audit_context)) audit_syscall_exit(AUDITSC_RESULT(regs->r3), regs->r3); step = test_thread_flag(TIF_SINGLESTEP); if (step || test_thread_flag(TIF_SYSCALL_TRACE)) tracehook_report_syscall_exit(regs, step); } #if 0 static asmlinkage void syscall_trace(void) { if (!test_thread_flag(TIF_SYSCALL_TRACE)) return; if (!(current->ptrace & PT_PTRACED)) return; /* The 0x80 provides a way for the tracing parent to distinguish between a syscall stop and SIGTRAP delivery */ ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); /* * this isn't the same as continuing with a signal, but it will do * for normal use. strace only continues with a signal if the * stopping signal is not SIGTRAP. -brl */ if (current->exit_code) { send_sig(current->exit_code, current, 1); current->exit_code = 0; } } #endif void ptrace_disable(struct task_struct *child) void ptrace_disable(struct task_struct *child) { { /* nothing to do */ /* nothing to do */ Loading Loading
arch/microblaze/kernel/entry.S +60 −12 Original line number Original line Diff line number Diff line Loading @@ -308,38 +308,69 @@ C_ENTRY(_user_exception): swi r12, r1, PTO+PT_R0; swi r12, r1, PTO+PT_R0; tovirt(r1,r1) tovirt(r1,r1) la r15, r0, ret_from_trap-8 /* where the trap should return need -8 to adjust for rtsd r15, 8*/ /* where the trap should return need -8 to adjust for rtsd r15, 8*/ /* Jump to the appropriate function for the system call number in r12 /* Jump to the appropriate function for the system call number in r12 * (r12 is not preserved), or return an error if r12 is not valid. The LP * (r12 is not preserved), or return an error if r12 is not valid. The LP * register should point to the location where * register should point to the location where * the called function should return. [note that MAKE_SYS_CALL uses label 1] */ * the called function should return. [note that MAKE_SYS_CALL uses label 1] */ /* See if the system call number is valid. */ # Step into virtual mode. set_vms; addik r11, r0, 3f rtid r11, 0 nop 3: add r11, r0, CURRENT_TASK /* Get current task ptr into r11 */ lwi r11, r11, TS_THREAD_INFO /* get thread info */ lwi r11, r11, TI_FLAGS /* get flags in thread info */ andi r11, r11, _TIF_WORK_SYSCALL_MASK beqi r11, 4f addik r3, r0, -ENOSYS swi r3, r1, PTO + PT_R3 brlid r15, do_syscall_trace_enter addik r5, r1, PTO + PT_R0 # do_syscall_trace_enter returns the new syscall nr. addk r12, r0, r3 lwi r5, r1, PTO+PT_R5; lwi r6, r1, PTO+PT_R6; lwi r7, r1, PTO+PT_R7; lwi r8, r1, PTO+PT_R8; lwi r9, r1, PTO+PT_R9; lwi r10, r1, PTO+PT_R10; 4: /* Jump to the appropriate function for the system call number in r12 * (r12 is not preserved), or return an error if r12 is not valid. * The LP register should point to the location where the called function * should return. [note that MAKE_SYS_CALL uses label 1] */ /* See if the system call number is valid */ addi r11, r12, -__NR_syscalls; addi r11, r12, -__NR_syscalls; bgei r11,1f; bgei r11,5f; /* Figure out which function to use for this system call. */ /* Figure out which function to use for this system call. */ /* Note Microblaze barrel shift is optional, so don't rely on it */ /* Note Microblaze barrel shift is optional, so don't rely on it */ add r12, r12, r12; /* convert num -> ptr */ add r12, r12, r12; /* convert num -> ptr */ add r12, r12, r12; add r12, r12, r12; /* Trac syscalls and stored them to r0_ram */ /* Trac syscalls and stored them to r0_ram */ lwi r3, r12, 0x400 + TOPHYS(r0_ram) lwi r3, r12, 0x400 + r0_ram addi r3, r3, 1 addi r3, r3, 1 swi r3, r12, 0x400 + TOPHYS(r0_ram) swi r3, r12, 0x400 + r0_ram # Find and jump into the syscall handler. lwi r12, r12, sys_call_table /* where the trap should return need -8 to adjust for rtsd r15, 8 */ la r15, r0, ret_from_trap-8 bra r12 lwi r12, r12, TOPHYS(sys_call_table); /* Function ptr */ /* Make the system call. to r12*/ set_vms; rtid r12, 0; nop; /* The syscall number is invalid, return an error. */ /* The syscall number is invalid, return an error. */ 1: VM_ON; /* RETURN() expects virtual mode*/ 5: addi r3, r0, -ENOSYS; addi r3, r0, -ENOSYS; rtsd r15,8; /* looks like a normal subroutine return */ rtsd r15,8; /* looks like a normal subroutine return */ or r0, r0, r0 or r0, r0, r0 /* Entry point used to return from a syscall/trap. */ /* Entry point used to return from a syscall/trap */ /* We re-enable BIP bit before state restore */ /* We re-enable BIP bit before state restore */ C_ENTRY(ret_from_trap): C_ENTRY(ret_from_trap): set_bip; /* Ints masked for state restore*/ set_bip; /* Ints masked for state restore*/ Loading @@ -347,6 +378,23 @@ C_ENTRY(ret_from_trap): /* See if returning to kernel mode, if so, skip resched &c. */ /* See if returning to kernel mode, if so, skip resched &c. */ bnei r11, 2f; bnei r11, 2f; /* We're returning to user mode, so check for various conditions that * trigger rescheduling. */ # FIXME: Restructure all these flag checks. add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */ lwi r11, r11, TS_THREAD_INFO; /* get thread info */ lwi r11, r11, TI_FLAGS; /* get flags in thread info */ andi r11, r11, _TIF_WORK_SYSCALL_MASK beqi r11, 1f swi r3, r1, PTO + PT_R3 swi r4, r1, PTO + PT_R4 brlid r15, do_syscall_trace_leave addik r5, r1, PTO + PT_R0 lwi r3, r1, PTO + PT_R3 lwi r4, r1, PTO + PT_R4 1: /* We're returning to user mode, so check for various conditions that /* We're returning to user mode, so check for various conditions that * trigger rescheduling. */ * trigger rescheduling. */ /* Get current task ptr into r11 */ /* Get current task ptr into r11 */ Loading
arch/microblaze/kernel/ptrace.c +62 −0 Original line number Original line Diff line number Diff line Loading @@ -29,6 +29,10 @@ #include <linux/sched.h> #include <linux/sched.h> #include <linux/ptrace.h> #include <linux/ptrace.h> #include <linux/signal.h> #include <linux/signal.h> #include <linux/elf.h> #include <linux/audit.h> #include <linux/seccomp.h> #include <linux/tracehook.h> #include <linux/errno.h> #include <linux/errno.h> #include <asm/processor.h> #include <asm/processor.h> Loading Loading @@ -174,6 +178,64 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) return rval; return rval; } } asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) { long ret = 0; secure_computing(regs->r12); if (test_thread_flag(TIF_SYSCALL_TRACE) && tracehook_report_syscall_entry(regs)) /* * Tracing decided this syscall should not happen. * We'll return a bogus call number to get an ENOSYS * error, but leave the original number in regs->regs[0]. */ ret = -1L; if (unlikely(current->audit_context)) audit_syscall_entry(EM_XILINX_MICROBLAZE, regs->r12, regs->r5, regs->r6, regs->r7, regs->r8); return ret ?: regs->r12; } asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) { int step; if (unlikely(current->audit_context)) audit_syscall_exit(AUDITSC_RESULT(regs->r3), regs->r3); step = test_thread_flag(TIF_SINGLESTEP); if (step || test_thread_flag(TIF_SYSCALL_TRACE)) tracehook_report_syscall_exit(regs, step); } #if 0 static asmlinkage void syscall_trace(void) { if (!test_thread_flag(TIF_SYSCALL_TRACE)) return; if (!(current->ptrace & PT_PTRACED)) return; /* The 0x80 provides a way for the tracing parent to distinguish between a syscall stop and SIGTRAP delivery */ ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); /* * this isn't the same as continuing with a signal, but it will do * for normal use. strace only continues with a signal if the * stopping signal is not SIGTRAP. -brl */ if (current->exit_code) { send_sig(current->exit_code, current, 1); current->exit_code = 0; } } #endif void ptrace_disable(struct task_struct *child) void ptrace_disable(struct task_struct *child) { { /* nothing to do */ /* nothing to do */ Loading