···1414#include <linux/linkage.h>1515#include <linux/types.h>1616#include <asm/isadep.h>1717+#include <asm/page.h>1818+#include <asm/thread_info.h>1719#include <uapi/asm/ptrace.h>18201921/*2022 * This struct defines the way the registers are stored on the stack during a2123 * system call/exception. As usual the registers k0/k1 aren't being saved.2424+ *2525+ * If you add a register here, also add it to regoffset_table[] in2626+ * arch/mips/kernel/ptrace.c.2227 */2328struct pt_regs {2429#ifdef CONFIG_32BIT···4843 unsigned long long mpl[6]; /* MTM{0-5} */4944 unsigned long long mtp[6]; /* MTP{0-5} */5045#endif4646+ unsigned long __last[0];5147} __aligned(8);4848+4949+static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)5050+{5151+ return regs->regs[31];5252+}5353+5454+/*5555+ * Don't use asm-generic/ptrace.h it defines FP accessors that don't make5656+ * sense on MIPS. We rather want an error if they get invoked.5757+ */5858+5959+static inline void instruction_pointer_set(struct pt_regs *regs,6060+ unsigned long val)6161+{6262+ regs->cp0_epc = val;6363+}6464+6565+/* Query offset/name of register from its name/offset */6666+extern int regs_query_register_offset(const char *name);6767+#define MAX_REG_OFFSET (offsetof(struct pt_regs, __last))6868+6969+/**7070+ * regs_get_register() - get register value from its offset7171+ * @regs: pt_regs from which register value is gotten.7272+ * @offset: offset number of the register.7373+ *7474+ * regs_get_register returns the value of a register. The @offset is the7575+ * offset of the register in struct pt_regs address which specified by @regs.7676+ * If @offset is bigger than MAX_REG_OFFSET, this returns 0.7777+ */7878+static inline unsigned long regs_get_register(struct pt_regs *regs,7979+ unsigned int offset)8080+{8181+ if (unlikely(offset > MAX_REG_OFFSET))8282+ return 0;8383+8484+ return *(unsigned long *)((unsigned long)regs + offset);8585+}8686+8787+/**8888+ * regs_within_kernel_stack() - check the address in the stack8989+ * @regs: pt_regs which contains kernel stack pointer.9090+ * @addr: address which is checked.9191+ *9292+ * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).9393+ * If @addr is within the kernel stack, it returns true. If not, returns false.9494+ */9595+static inline int regs_within_kernel_stack(struct pt_regs *regs,9696+ unsigned long addr)9797+{9898+ return ((addr & ~(THREAD_SIZE - 1)) ==9999+ (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));100100+}101101+102102+/**103103+ * regs_get_kernel_stack_nth() - get Nth entry of the stack104104+ * @regs: pt_regs which contains kernel stack pointer.105105+ * @n: stack entry number.106106+ *107107+ * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which108108+ * is specified by @regs. If the @n th entry is NOT in the kernel stack,109109+ * this returns 0.110110+ */111111+static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,112112+ unsigned int n)113113+{114114+ unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);115115+116116+ addr += n;117117+ if (regs_within_kernel_stack(regs, (unsigned long)addr))118118+ return *addr;119119+ else120120+ return 0;121121+}5212253123struct task_struct;54124
+4-1
arch/mips/include/asm/thread_info.h
···9999#define TIF_SYSCALL_AUDIT 3 /* syscall auditing active */100100#define TIF_SECCOMP 4 /* secure computing */101101#define TIF_NOTIFY_RESUME 5 /* callback before returning to user */102102+#define TIF_UPROBE 6 /* breakpointed or singlestepping */102103#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */103104#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */104105#define TIF_MEMDIE 18 /* is terminating due to OOM killer */···123122#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)124123#define _TIF_SECCOMP (1<<TIF_SECCOMP)125124#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)125125+#define _TIF_UPROBE (1<<TIF_UPROBE)126126#define _TIF_USEDFPU (1<<TIF_USEDFPU)127127#define _TIF_NOHZ (1<<TIF_NOHZ)128128#define _TIF_FIXADE (1<<TIF_FIXADE)···148146149147/* work to do on interrupt/exception return */150148#define _TIF_WORK_MASK \151151- (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME)149149+ (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME | \150150+ _TIF_UPROBE)152151/* work to do on any return to u-space */153152#define _TIF_ALLWORK_MASK (_TIF_NOHZ | _TIF_WORK_MASK | \154153 _TIF_WORK_SYSCALL_EXIT | \
+58
arch/mips/include/asm/uprobes.h
···11+/*22+ * This file is subject to the terms and conditions of the GNU General Public33+ * License. See the file "COPYING" in the main directory of this archive44+ * for more details.55+ */66+#ifndef __ASM_UPROBES_H77+#define __ASM_UPROBES_H88+99+#include <linux/notifier.h>1010+#include <linux/types.h>1111+1212+#include <asm/break.h>1313+#include <asm/inst.h>1414+1515+/*1616+ * We want this to be defined as union mips_instruction but that makes the1717+ * generic code blow up.1818+ */1919+typedef u32 uprobe_opcode_t;2020+2121+/*2222+ * Classic MIPS (note this implementation doesn't consider microMIPS yet)2323+ * instructions are always 4 bytes but in order to deal with branches and2424+ * their delay slots, we treat instructions as having 8 bytes maximum.2525+ */2626+#define MAX_UINSN_BYTES 82727+#define UPROBE_XOL_SLOT_BYTES 128 /* Max. cache line size */2828+2929+#define UPROBE_BRK_UPROBE 0x000d000d /* break 13 */3030+#define UPROBE_BRK_UPROBE_XOL 0x000e000d /* break 14 */3131+3232+#define UPROBE_SWBP_INSN UPROBE_BRK_UPROBE3333+#define UPROBE_SWBP_INSN_SIZE 43434+3535+struct arch_uprobe {3636+ unsigned long resume_epc;3737+ u32 insn[2];3838+ u32 ixol[2];3939+ union mips_instruction orig_inst[MAX_UINSN_BYTES / 4];4040+};4141+4242+struct arch_uprobe_task {4343+ unsigned long saved_trap_nr;4444+};4545+4646+extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup,4747+ struct mm_struct *mm, unsigned long addr);4848+extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs);4949+extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs);5050+extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk);5151+extern int arch_uprobe_exception_notify(struct notifier_block *self,5252+ unsigned long val, void *data);5353+extern void arch_uprobe_abort_xol(struct arch_uprobe *aup,5454+ struct pt_regs *regs);5555+extern unsigned long arch_uretprobe_hijack_return_addr(5656+ unsigned long trampoline_vaddr, struct pt_regs *regs);5757+5858+#endif /* __ASM_UPROBES_H */
+2
arch/mips/include/uapi/asm/break.h
···2121#define BRK_DIVZERO 7 /* Divide by zero check */2222#define BRK_RANGE 8 /* Range error check */2323#define BRK_BUG 12 /* Used by BUG() */2424+#define BRK_UPROBE 13 /* See <asm/uprobes.h> */2525+#define BRK_UPROBE_XOL 14 /* See <asm/uprobes.h> */2426#define BRK_MEMU 514 /* Used by FPU emulator */2527#define BRK_KPROBE_BP 515 /* Kprobe break */2628#define BRK_KPROBE_SSTEPBP 516 /* Kprobe single step software implementation */
···2121#include <linux/wait.h>2222#include <linux/ptrace.h>2323#include <linux/unistd.h>2424+#include <linux/uprobes.h>2425#include <linux/compiler.h>2526#include <linux/syscalls.h>2627#include <linux/uaccess.h>···856855 local_irq_enable();857856858857 user_exit();858858+859859+ if (thread_info_flags & _TIF_UPROBE)860860+ uprobe_notify_resume(regs);859861860862 /* deal with pending signal delivery */861863 if (thread_info_flags & _TIF_SIGPENDING)
+12
arch/mips/kernel/traps.c
···984984 * pertain to them.985985 */986986 switch (bcode) {987987+ case BRK_UPROBE:988988+ if (notify_die(DIE_UPROBE, "uprobe", regs, bcode,989989+ current->thread.trap_nr, SIGTRAP) == NOTIFY_STOP)990990+ goto out;991991+ else992992+ break;993993+ case BRK_UPROBE_XOL:994994+ if (notify_die(DIE_UPROBE_XOL, "uprobe_xol", regs, bcode,995995+ current->thread.trap_nr, SIGTRAP) == NOTIFY_STOP)996996+ goto out;997997+ else998998+ break;987999 case BRK_KPROBE_BP:9881000 if (notify_die(DIE_BREAK, "debug", regs, bcode,9891001 current->thread.trap_nr, SIGTRAP) == NOTIFY_STOP)
+341
arch/mips/kernel/uprobes.c
···11+#include <linux/highmem.h>22+#include <linux/kdebug.h>33+#include <linux/types.h>44+#include <linux/notifier.h>55+#include <linux/sched.h>66+#include <linux/uprobes.h>77+88+#include <asm/branch.h>99+#include <asm/cpu-features.h>1010+#include <asm/ptrace.h>1111+#include <asm/inst.h>1212+1313+static inline int insn_has_delay_slot(const union mips_instruction insn)1414+{1515+ switch (insn.i_format.opcode) {1616+ /*1717+ * jr and jalr are in r_format format.1818+ */1919+ case spec_op:2020+ switch (insn.r_format.func) {2121+ case jalr_op:2222+ case jr_op:2323+ return 1;2424+ }2525+ break;2626+2727+ /*2828+ * This group contains:2929+ * bltz_op, bgez_op, bltzl_op, bgezl_op,3030+ * bltzal_op, bgezal_op, bltzall_op, bgezall_op.3131+ */3232+ case bcond_op:3333+ switch (insn.i_format.rt) {3434+ case bltz_op:3535+ case bltzl_op:3636+ case bgez_op:3737+ case bgezl_op:3838+ case bltzal_op:3939+ case bltzall_op:4040+ case bgezal_op:4141+ case bgezall_op:4242+ case bposge32_op:4343+ return 1;4444+ }4545+ break;4646+4747+ /*4848+ * These are unconditional and in j_format.4949+ */5050+ case jal_op:5151+ case j_op:5252+ case beq_op:5353+ case beql_op:5454+ case bne_op:5555+ case bnel_op:5656+ case blez_op: /* not really i_format */5757+ case blezl_op:5858+ case bgtz_op:5959+ case bgtzl_op:6060+ return 1;6161+6262+ /*6363+ * And now the FPA/cp1 branch instructions.6464+ */6565+ case cop1_op:6666+#ifdef CONFIG_CPU_CAVIUM_OCTEON6767+ case lwc2_op: /* This is bbit0 on Octeon */6868+ case ldc2_op: /* This is bbit032 on Octeon */6969+ case swc2_op: /* This is bbit1 on Octeon */7070+ case sdc2_op: /* This is bbit132 on Octeon */7171+#endif7272+ return 1;7373+ }7474+7575+ return 0;7676+}7777+7878+/**7979+ * arch_uprobe_analyze_insn - instruction analysis including validity and fixups.8080+ * @mm: the probed address space.8181+ * @arch_uprobe: the probepoint information.8282+ * @addr: virtual address at which to install the probepoint8383+ * Return 0 on success or a -ve number on error.8484+ */8585+int arch_uprobe_analyze_insn(struct arch_uprobe *aup,8686+ struct mm_struct *mm, unsigned long addr)8787+{8888+ union mips_instruction inst;8989+9090+ /*9191+ * For the time being this also blocks attempts to use uprobes with9292+ * MIPS16 and microMIPS.9393+ */9494+ if (addr & 0x03)9595+ return -EINVAL;9696+9797+ inst.word = aup->insn[0];9898+ aup->ixol[0] = aup->insn[insn_has_delay_slot(inst)];9999+ aup->ixol[1] = UPROBE_BRK_UPROBE_XOL; /* NOP */100100+101101+ return 0;102102+}103103+104104+/**105105+ * is_trap_insn - check if the instruction is a trap variant106106+ * @insn: instruction to be checked.107107+ * Returns true if @insn is a trap variant.108108+ *109109+ * This definition overrides the weak definition in kernel/events/uprobes.c.110110+ * and is needed for the case where an architecture has multiple trap111111+ * instructions (like PowerPC or MIPS). We treat BREAK just like the more112112+ * modern conditional trap instructions.113113+ */114114+bool is_trap_insn(uprobe_opcode_t *insn)115115+{116116+ union mips_instruction inst;117117+118118+ inst.word = *insn;119119+120120+ switch (inst.i_format.opcode) {121121+ case spec_op:122122+ switch (inst.r_format.func) {123123+ case break_op:124124+ case teq_op:125125+ case tge_op:126126+ case tgeu_op:127127+ case tlt_op:128128+ case tltu_op:129129+ case tne_op:130130+ return 1;131131+ }132132+ break;133133+134134+ case bcond_op: /* Yes, really ... */135135+ switch (inst.u_format.rt) {136136+ case teqi_op:137137+ case tgei_op:138138+ case tgeiu_op:139139+ case tlti_op:140140+ case tltiu_op:141141+ case tnei_op:142142+ return 1;143143+ }144144+ break;145145+ }146146+147147+ return 0;148148+}149149+150150+#define UPROBE_TRAP_NR ULONG_MAX151151+152152+/*153153+ * arch_uprobe_pre_xol - prepare to execute out of line.154154+ * @auprobe: the probepoint information.155155+ * @regs: reflects the saved user state of current task.156156+ */157157+int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs)158158+{159159+ struct uprobe_task *utask = current->utask;160160+ union mips_instruction insn;161161+162162+ /*163163+ * Now find the EPC where to resume after the breakpoint has been164164+ * dealt with. This may require emulation of a branch.165165+ */166166+ aup->resume_epc = regs->cp0_epc + 4;167167+ if (insn_has_delay_slot((union mips_instruction) aup->insn[0])) {168168+ unsigned long epc;169169+170170+ epc = regs->cp0_epc;171171+ __compute_return_epc_for_insn(regs, insn);172172+ aup->resume_epc = regs->cp0_epc;173173+ }174174+175175+ utask->autask.saved_trap_nr = current->thread.trap_nr;176176+ current->thread.trap_nr = UPROBE_TRAP_NR;177177+ regs->cp0_epc = current->utask->xol_vaddr;178178+179179+ return 0;180180+}181181+182182+int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs)183183+{184184+ struct uprobe_task *utask = current->utask;185185+186186+ current->thread.trap_nr = utask->autask.saved_trap_nr;187187+ regs->cp0_epc = aup->resume_epc;188188+189189+ return 0;190190+}191191+192192+/*193193+ * If xol insn itself traps and generates a signal(Say,194194+ * SIGILL/SIGSEGV/etc), then detect the case where a singlestepped195195+ * instruction jumps back to its own address. It is assumed that anything196196+ * like do_page_fault/do_trap/etc sets thread.trap_nr != -1.197197+ *198198+ * arch_uprobe_pre_xol/arch_uprobe_post_xol save/restore thread.trap_nr,199199+ * arch_uprobe_xol_was_trapped() simply checks that ->trap_nr is not equal to200200+ * UPROBE_TRAP_NR == -1 set by arch_uprobe_pre_xol().201201+ */202202+bool arch_uprobe_xol_was_trapped(struct task_struct *tsk)203203+{204204+ if (tsk->thread.trap_nr != UPROBE_TRAP_NR)205205+ return true;206206+207207+ return false;208208+}209209+210210+int arch_uprobe_exception_notify(struct notifier_block *self,211211+ unsigned long val, void *data)212212+{213213+ struct die_args *args = data;214214+ struct pt_regs *regs = args->regs;215215+216216+ /* regs == NULL is a kernel bug */217217+ if (WARN_ON(!regs))218218+ return NOTIFY_DONE;219219+220220+ /* We are only interested in userspace traps */221221+ if (!user_mode(regs))222222+ return NOTIFY_DONE;223223+224224+ switch (val) {225225+ case DIE_BREAK:226226+ if (uprobe_pre_sstep_notifier(regs))227227+ return NOTIFY_STOP;228228+ break;229229+ case DIE_UPROBE_XOL:230230+ if (uprobe_post_sstep_notifier(regs))231231+ return NOTIFY_STOP;232232+ default:233233+ break;234234+ }235235+236236+ return 0;237237+}238238+239239+/*240240+ * This function gets called when XOL instruction either gets trapped or241241+ * the thread has a fatal signal. Reset the instruction pointer to its242242+ * probed address for the potential restart or for post mortem analysis.243243+ */244244+void arch_uprobe_abort_xol(struct arch_uprobe *aup,245245+ struct pt_regs *regs)246246+{247247+ struct uprobe_task *utask = current->utask;248248+249249+ instruction_pointer_set(regs, utask->vaddr);250250+}251251+252252+unsigned long arch_uretprobe_hijack_return_addr(253253+ unsigned long trampoline_vaddr, struct pt_regs *regs)254254+{255255+ unsigned long ra;256256+257257+ ra = regs->regs[31];258258+259259+ /* Replace the return address with the trampoline address */260260+ regs->regs[31] = ra;261261+262262+ return ra;263263+}264264+265265+/**266266+ * set_swbp - store breakpoint at a given address.267267+ * @auprobe: arch specific probepoint information.268268+ * @mm: the probed process address space.269269+ * @vaddr: the virtual address to insert the opcode.270270+ *271271+ * For mm @mm, store the breakpoint instruction at @vaddr.272272+ * Return 0 (success) or a negative errno.273273+ *274274+ * This version overrides the weak version in kernel/events/uprobes.c.275275+ * It is required to handle MIPS16 and microMIPS.276276+ */277277+int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm,278278+ unsigned long vaddr)279279+{280280+ return uprobe_write_opcode(mm, vaddr, UPROBE_SWBP_INSN);281281+}282282+283283+/**284284+ * set_orig_insn - Restore the original instruction.285285+ * @mm: the probed process address space.286286+ * @auprobe: arch specific probepoint information.287287+ * @vaddr: the virtual address to insert the opcode.288288+ *289289+ * For mm @mm, restore the original opcode (opcode) at @vaddr.290290+ * Return 0 (success) or a negative errno.291291+ *292292+ * This overrides the weak version in kernel/events/uprobes.c.293293+ */294294+int set_orig_insn(struct arch_uprobe *auprobe, struct mm_struct *mm,295295+ unsigned long vaddr)296296+{297297+ return uprobe_write_opcode(mm, vaddr,298298+ *(uprobe_opcode_t *)&auprobe->orig_inst[0].word);299299+}300300+301301+void __weak arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,302302+ void *src, unsigned long len)303303+{304304+ void *kaddr;305305+306306+ /* Initialize the slot */307307+ kaddr = kmap_atomic(page);308308+ memcpy(kaddr + (vaddr & ~PAGE_MASK), src, len);309309+ kunmap_atomic(kaddr);310310+311311+ /*312312+ * The MIPS version of flush_icache_range will operate safely on313313+ * user space addresses and more importantly, it doesn't require a314314+ * VMA argument.315315+ */316316+ flush_icache_range(vaddr, vaddr + len);317317+}318318+319319+/**320320+ * uprobe_get_swbp_addr - compute address of swbp given post-swbp regs321321+ * @regs: Reflects the saved state of the task after it has hit a breakpoint322322+ * instruction.323323+ * Return the address of the breakpoint instruction.324324+ *325325+ * This overrides the weak version in kernel/events/uprobes.c.326326+ */327327+unsigned long uprobe_get_swbp_addr(struct pt_regs *regs)328328+{329329+ return instruction_pointer(regs);330330+}331331+332332+/*333333+ * See if the instruction can be emulated.334334+ * Returns true if instruction was emulated, false otherwise.335335+ *336336+ * For now we always emulate so this function just returns 0.337337+ */338338+bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)339339+{340340+ return 0;341341+}