11ccea77eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 2e8f4aa60SAllen Pais /* 3e8f4aa60SAllen Pais * User-space Probes (UProbes) for sparc 4e8f4aa60SAllen Pais * 5e8f4aa60SAllen Pais * Copyright (C) 2013 Oracle Inc. 6e8f4aa60SAllen Pais * 7e8f4aa60SAllen Pais * Authors: 8e8f4aa60SAllen Pais * Jose E. Marchesi <jose.marchesi@oracle.com> 9e8f4aa60SAllen Pais * Eric Saint Etienne <eric.saint.etienne@oracle.com> 10e8f4aa60SAllen Pais */ 11e8f4aa60SAllen Pais 12e8f4aa60SAllen Pais #include <linux/kernel.h> 13e8f4aa60SAllen Pais #include <linux/highmem.h> 14e8f4aa60SAllen Pais #include <linux/uprobes.h> 15e8f4aa60SAllen Pais #include <linux/uaccess.h> 16e8f4aa60SAllen Pais #include <linux/sched.h> /* For struct task_struct */ 17e8f4aa60SAllen Pais #include <linux/kdebug.h> 18e8f4aa60SAllen Pais 19e8f4aa60SAllen Pais #include <asm/cacheflush.h> 20e8f4aa60SAllen Pais 21*a51b8c83SSam Ravnborg #include "kernel.h" 22*a51b8c83SSam Ravnborg 23e8f4aa60SAllen Pais /* Compute the address of the breakpoint instruction and return it. 24e8f4aa60SAllen Pais * 25e8f4aa60SAllen Pais * Note that uprobe_get_swbp_addr is defined as a weak symbol in 26e8f4aa60SAllen Pais * kernel/events/uprobe.c. 27e8f4aa60SAllen Pais */ 28e8f4aa60SAllen Pais unsigned long uprobe_get_swbp_addr(struct pt_regs *regs) 29e8f4aa60SAllen Pais { 30e8f4aa60SAllen Pais return instruction_pointer(regs); 31e8f4aa60SAllen Pais } 32e8f4aa60SAllen Pais 33e8f4aa60SAllen Pais static void copy_to_page(struct page *page, unsigned long vaddr, 34e8f4aa60SAllen Pais const void *src, int len) 35e8f4aa60SAllen Pais { 36e8f4aa60SAllen Pais void *kaddr = kmap_atomic(page); 37e8f4aa60SAllen Pais 38e8f4aa60SAllen Pais memcpy(kaddr + (vaddr & ~PAGE_MASK), src, len); 39e8f4aa60SAllen Pais kunmap_atomic(kaddr); 40e8f4aa60SAllen Pais } 41e8f4aa60SAllen Pais 42e8f4aa60SAllen Pais /* Fill in the xol area with the probed instruction followed by the 43e8f4aa60SAllen Pais * single-step trap. Some fixups in the copied instruction are 44e8f4aa60SAllen Pais * performed at this point. 45e8f4aa60SAllen Pais * 46e8f4aa60SAllen Pais * Note that uprobe_xol_copy is defined as a weak symbol in 47e8f4aa60SAllen Pais * kernel/events/uprobe.c. 48e8f4aa60SAllen Pais */ 49e8f4aa60SAllen Pais void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, 50e8f4aa60SAllen Pais void *src, unsigned long len) 51e8f4aa60SAllen Pais { 52e8f4aa60SAllen Pais const u32 stp_insn = UPROBE_STP_INSN; 53e8f4aa60SAllen Pais u32 insn = *(u32 *) src; 54e8f4aa60SAllen Pais 55e8f4aa60SAllen Pais /* Branches annulling their delay slot must be fixed to not do 56e8f4aa60SAllen Pais * so. Clearing the annul bit on these instructions we can be 57e8f4aa60SAllen Pais * sure the single-step breakpoint in the XOL slot will be 58e8f4aa60SAllen Pais * executed. 59e8f4aa60SAllen Pais */ 60e8f4aa60SAllen Pais 61e8f4aa60SAllen Pais u32 op = (insn >> 30) & 0x3; 62e8f4aa60SAllen Pais u32 op2 = (insn >> 22) & 0x7; 63e8f4aa60SAllen Pais 64e8f4aa60SAllen Pais if (op == 0 && 65e8f4aa60SAllen Pais (op2 == 1 || op2 == 2 || op2 == 3 || op2 == 5 || op2 == 6) && 66e8f4aa60SAllen Pais (insn & ANNUL_BIT) == ANNUL_BIT) 67e8f4aa60SAllen Pais insn &= ~ANNUL_BIT; 68e8f4aa60SAllen Pais 69e8f4aa60SAllen Pais copy_to_page(page, vaddr, &insn, len); 70e8f4aa60SAllen Pais copy_to_page(page, vaddr+len, &stp_insn, 4); 71e8f4aa60SAllen Pais } 72e8f4aa60SAllen Pais 73e8f4aa60SAllen Pais 74e8f4aa60SAllen Pais /* Instruction analysis/validity. 75e8f4aa60SAllen Pais * 76e8f4aa60SAllen Pais * This function returns 0 on success or a -ve number on error. 77e8f4aa60SAllen Pais */ 78e8f4aa60SAllen Pais int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, 79e8f4aa60SAllen Pais struct mm_struct *mm, unsigned long addr) 80e8f4aa60SAllen Pais { 81e8f4aa60SAllen Pais /* Any unsupported instruction? Then return -EINVAL */ 82e8f4aa60SAllen Pais return 0; 83e8f4aa60SAllen Pais } 84e8f4aa60SAllen Pais 85e8f4aa60SAllen Pais /* If INSN is a relative control transfer instruction, return the 86e8f4aa60SAllen Pais * corrected branch destination value. 87e8f4aa60SAllen Pais * 88e8f4aa60SAllen Pais * Note that regs->tpc and regs->tnpc still hold the values of the 89e8f4aa60SAllen Pais * program counters at the time of the single-step trap due to the 90e8f4aa60SAllen Pais * execution of the UPROBE_STP_INSN at utask->xol_vaddr + 4. 91e8f4aa60SAllen Pais * 92e8f4aa60SAllen Pais */ 93e8f4aa60SAllen Pais static unsigned long relbranch_fixup(u32 insn, struct uprobe_task *utask, 94e8f4aa60SAllen Pais struct pt_regs *regs) 95e8f4aa60SAllen Pais { 96e8f4aa60SAllen Pais /* Branch not taken, no mods necessary. */ 97e8f4aa60SAllen Pais if (regs->tnpc == regs->tpc + 0x4UL) 98e8f4aa60SAllen Pais return utask->autask.saved_tnpc + 0x4UL; 99e8f4aa60SAllen Pais 100e8f4aa60SAllen Pais /* The three cases are call, branch w/prediction, 101e8f4aa60SAllen Pais * and traditional branch. 102e8f4aa60SAllen Pais */ 103e8f4aa60SAllen Pais if ((insn & 0xc0000000) == 0x40000000 || 104e8f4aa60SAllen Pais (insn & 0xc1c00000) == 0x00400000 || 105e8f4aa60SAllen Pais (insn & 0xc1c00000) == 0x00800000) { 106e8f4aa60SAllen Pais unsigned long real_pc = (unsigned long) utask->vaddr; 107e8f4aa60SAllen Pais unsigned long ixol_addr = utask->xol_vaddr; 108e8f4aa60SAllen Pais 109e8f4aa60SAllen Pais /* The instruction did all the work for us 110e8f4aa60SAllen Pais * already, just apply the offset to the correct 111e8f4aa60SAllen Pais * instruction location. 112e8f4aa60SAllen Pais */ 113e8f4aa60SAllen Pais return (real_pc + (regs->tnpc - ixol_addr)); 114e8f4aa60SAllen Pais } 115e8f4aa60SAllen Pais 116e8f4aa60SAllen Pais /* It is jmpl or some other absolute PC modification instruction, 117e8f4aa60SAllen Pais * leave NPC as-is. 118e8f4aa60SAllen Pais */ 119e8f4aa60SAllen Pais return regs->tnpc; 120e8f4aa60SAllen Pais } 121e8f4aa60SAllen Pais 122e8f4aa60SAllen Pais /* If INSN is an instruction which writes its PC location 123e8f4aa60SAllen Pais * into a destination register, fix that up. 124e8f4aa60SAllen Pais */ 125e8f4aa60SAllen Pais static int retpc_fixup(struct pt_regs *regs, u32 insn, 126e8f4aa60SAllen Pais unsigned long real_pc) 127e8f4aa60SAllen Pais { 128e8f4aa60SAllen Pais unsigned long *slot = NULL; 129e8f4aa60SAllen Pais int rc = 0; 130e8f4aa60SAllen Pais 131e8f4aa60SAllen Pais /* Simplest case is 'call', which always uses %o7 */ 132e8f4aa60SAllen Pais if ((insn & 0xc0000000) == 0x40000000) 133e8f4aa60SAllen Pais slot = ®s->u_regs[UREG_I7]; 134e8f4aa60SAllen Pais 135e8f4aa60SAllen Pais /* 'jmpl' encodes the register inside of the opcode */ 136e8f4aa60SAllen Pais if ((insn & 0xc1f80000) == 0x81c00000) { 137e8f4aa60SAllen Pais unsigned long rd = ((insn >> 25) & 0x1f); 138e8f4aa60SAllen Pais 139e8f4aa60SAllen Pais if (rd <= 15) { 140e8f4aa60SAllen Pais slot = ®s->u_regs[rd]; 141e8f4aa60SAllen Pais } else { 142e8f4aa60SAllen Pais unsigned long fp = regs->u_regs[UREG_FP]; 143e8f4aa60SAllen Pais /* Hard case, it goes onto the stack. */ 144e8f4aa60SAllen Pais flushw_all(); 145e8f4aa60SAllen Pais 146e8f4aa60SAllen Pais rd -= 16; 147e8f4aa60SAllen Pais if (test_thread_64bit_stack(fp)) { 148e8f4aa60SAllen Pais unsigned long __user *uslot = 149e8f4aa60SAllen Pais (unsigned long __user *) (fp + STACK_BIAS) + rd; 150e8f4aa60SAllen Pais rc = __put_user(real_pc, uslot); 151e8f4aa60SAllen Pais } else { 152e8f4aa60SAllen Pais unsigned int __user *uslot = (unsigned int 153e8f4aa60SAllen Pais __user *) fp + rd; 154e8f4aa60SAllen Pais rc = __put_user((u32) real_pc, uslot); 155e8f4aa60SAllen Pais } 156e8f4aa60SAllen Pais } 157e8f4aa60SAllen Pais } 158e8f4aa60SAllen Pais if (slot != NULL) 159e8f4aa60SAllen Pais *slot = real_pc; 160e8f4aa60SAllen Pais return rc; 161e8f4aa60SAllen Pais } 162e8f4aa60SAllen Pais 163e8f4aa60SAllen Pais /* Single-stepping can be avoided for certain instructions: NOPs and 164e8f4aa60SAllen Pais * instructions that can be emulated. This function determines 165e8f4aa60SAllen Pais * whether the instruction where the uprobe is installed falls in one 166e8f4aa60SAllen Pais * of these cases and emulates it. 167e8f4aa60SAllen Pais * 168e8f4aa60SAllen Pais * This function returns true if the single-stepping can be skipped, 169e8f4aa60SAllen Pais * false otherwise. 170e8f4aa60SAllen Pais */ 171e8f4aa60SAllen Pais bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) 172e8f4aa60SAllen Pais { 173e8f4aa60SAllen Pais /* We currently only emulate NOP instructions. 174e8f4aa60SAllen Pais */ 175e8f4aa60SAllen Pais 176e8f4aa60SAllen Pais if (auprobe->ixol == (1 << 24)) { 177e8f4aa60SAllen Pais regs->tnpc += 4; 178e8f4aa60SAllen Pais regs->tpc += 4; 179e8f4aa60SAllen Pais return true; 180e8f4aa60SAllen Pais } 181e8f4aa60SAllen Pais 182e8f4aa60SAllen Pais return false; 183e8f4aa60SAllen Pais } 184e8f4aa60SAllen Pais 185e8f4aa60SAllen Pais /* Prepare to execute out of line. At this point 186e8f4aa60SAllen Pais * current->utask->xol_vaddr points to an allocated XOL slot properly 187e8f4aa60SAllen Pais * initialized with the original instruction and the single-stepping 188e8f4aa60SAllen Pais * trap instruction. 189e8f4aa60SAllen Pais * 190e8f4aa60SAllen Pais * This function returns 0 on success, any other number on error. 191e8f4aa60SAllen Pais */ 192e8f4aa60SAllen Pais int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) 193e8f4aa60SAllen Pais { 194e8f4aa60SAllen Pais struct uprobe_task *utask = current->utask; 195e8f4aa60SAllen Pais struct arch_uprobe_task *autask = ¤t->utask->autask; 196e8f4aa60SAllen Pais 197e8f4aa60SAllen Pais /* Save the current program counters so they can be restored 198e8f4aa60SAllen Pais * later. 199e8f4aa60SAllen Pais */ 200e8f4aa60SAllen Pais autask->saved_tpc = regs->tpc; 201e8f4aa60SAllen Pais autask->saved_tnpc = regs->tnpc; 202e8f4aa60SAllen Pais 203e8f4aa60SAllen Pais /* Adjust PC and NPC so the first instruction in the XOL slot 204e8f4aa60SAllen Pais * will be executed by the user task. 205e8f4aa60SAllen Pais */ 206e8f4aa60SAllen Pais instruction_pointer_set(regs, utask->xol_vaddr); 207e8f4aa60SAllen Pais 208e8f4aa60SAllen Pais return 0; 209e8f4aa60SAllen Pais } 210e8f4aa60SAllen Pais 211e8f4aa60SAllen Pais /* Prepare to resume execution after the single-step. Called after 212e8f4aa60SAllen Pais * single-stepping. To avoid the SMP problems that can occur when we 213e8f4aa60SAllen Pais * temporarily put back the original opcode to single-step, we 214e8f4aa60SAllen Pais * single-stepped a copy of the instruction. 215e8f4aa60SAllen Pais * 216e8f4aa60SAllen Pais * This function returns 0 on success, any other number on error. 217e8f4aa60SAllen Pais */ 218e8f4aa60SAllen Pais int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) 219e8f4aa60SAllen Pais { 220e8f4aa60SAllen Pais struct uprobe_task *utask = current->utask; 221e8f4aa60SAllen Pais struct arch_uprobe_task *autask = &utask->autask; 222e8f4aa60SAllen Pais u32 insn = auprobe->ixol; 223e8f4aa60SAllen Pais int rc = 0; 224e8f4aa60SAllen Pais 225e8f4aa60SAllen Pais if (utask->state == UTASK_SSTEP_ACK) { 226e8f4aa60SAllen Pais regs->tnpc = relbranch_fixup(insn, utask, regs); 227e8f4aa60SAllen Pais regs->tpc = autask->saved_tnpc; 228e8f4aa60SAllen Pais rc = retpc_fixup(regs, insn, (unsigned long) utask->vaddr); 229e8f4aa60SAllen Pais } else { 230e8f4aa60SAllen Pais regs->tnpc = utask->vaddr+4; 231e8f4aa60SAllen Pais regs->tpc = autask->saved_tnpc+4; 232e8f4aa60SAllen Pais } 233e8f4aa60SAllen Pais return rc; 234e8f4aa60SAllen Pais } 235e8f4aa60SAllen Pais 236e8f4aa60SAllen Pais /* Handler for uprobe traps. This is called from the traps table and 237e8f4aa60SAllen Pais * triggers the proper die notification. 238e8f4aa60SAllen Pais */ 239e8f4aa60SAllen Pais asmlinkage void uprobe_trap(struct pt_regs *regs, 240e8f4aa60SAllen Pais unsigned long trap_level) 241e8f4aa60SAllen Pais { 242e8f4aa60SAllen Pais BUG_ON(trap_level != 0x173 && trap_level != 0x174); 243e8f4aa60SAllen Pais 244e8f4aa60SAllen Pais /* We are only interested in user-mode code. Uprobe traps 245e8f4aa60SAllen Pais * shall not be present in kernel code. 246e8f4aa60SAllen Pais */ 247e8f4aa60SAllen Pais if (!user_mode(regs)) { 248e8f4aa60SAllen Pais local_irq_enable(); 249e8f4aa60SAllen Pais bad_trap(regs, trap_level); 250e8f4aa60SAllen Pais return; 251e8f4aa60SAllen Pais } 252e8f4aa60SAllen Pais 253e8f4aa60SAllen Pais /* trap_level == 0x173 --> ta 0x73 254e8f4aa60SAllen Pais * trap_level == 0x174 --> ta 0x74 255e8f4aa60SAllen Pais */ 256e8f4aa60SAllen Pais if (notify_die((trap_level == 0x173) ? DIE_BPT : DIE_SSTEP, 257e8f4aa60SAllen Pais (trap_level == 0x173) ? "bpt" : "sstep", 258e8f4aa60SAllen Pais regs, 0, trap_level, SIGTRAP) != NOTIFY_STOP) 259e8f4aa60SAllen Pais bad_trap(regs, trap_level); 260e8f4aa60SAllen Pais } 261e8f4aa60SAllen Pais 262e8f4aa60SAllen Pais /* Callback routine for handling die notifications. 263e8f4aa60SAllen Pais */ 264e8f4aa60SAllen Pais int arch_uprobe_exception_notify(struct notifier_block *self, 265e8f4aa60SAllen Pais unsigned long val, void *data) 266e8f4aa60SAllen Pais { 267e8f4aa60SAllen Pais int ret = NOTIFY_DONE; 268e8f4aa60SAllen Pais struct die_args *args = (struct die_args *)data; 269e8f4aa60SAllen Pais 270e8f4aa60SAllen Pais /* We are only interested in userspace traps */ 271e8f4aa60SAllen Pais if (args->regs && !user_mode(args->regs)) 272e8f4aa60SAllen Pais return NOTIFY_DONE; 273e8f4aa60SAllen Pais 274e8f4aa60SAllen Pais switch (val) { 275e8f4aa60SAllen Pais case DIE_BPT: 276e8f4aa60SAllen Pais if (uprobe_pre_sstep_notifier(args->regs)) 277e8f4aa60SAllen Pais ret = NOTIFY_STOP; 278e8f4aa60SAllen Pais break; 279e8f4aa60SAllen Pais 280e8f4aa60SAllen Pais case DIE_SSTEP: 281e8f4aa60SAllen Pais if (uprobe_post_sstep_notifier(args->regs)) 282e8f4aa60SAllen Pais ret = NOTIFY_STOP; 283e8f4aa60SAllen Pais 284e8f4aa60SAllen Pais default: 285e8f4aa60SAllen Pais break; 286e8f4aa60SAllen Pais } 287e8f4aa60SAllen Pais 288e8f4aa60SAllen Pais return ret; 289e8f4aa60SAllen Pais } 290e8f4aa60SAllen Pais 291e8f4aa60SAllen Pais /* This function gets called when a XOL instruction either gets 292e8f4aa60SAllen Pais * trapped or the thread has a fatal signal, so reset the instruction 293e8f4aa60SAllen Pais * pointer to its probed address. 294e8f4aa60SAllen Pais */ 295e8f4aa60SAllen Pais void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) 296e8f4aa60SAllen Pais { 297e8f4aa60SAllen Pais struct uprobe_task *utask = current->utask; 298e8f4aa60SAllen Pais 299e8f4aa60SAllen Pais instruction_pointer_set(regs, utask->vaddr); 300e8f4aa60SAllen Pais } 301e8f4aa60SAllen Pais 302e8f4aa60SAllen Pais /* If xol insn itself traps and generates a signal(Say, 303e8f4aa60SAllen Pais * SIGILL/SIGSEGV/etc), then detect the case where a singlestepped 304e8f4aa60SAllen Pais * instruction jumps back to its own address. 305e8f4aa60SAllen Pais */ 306e8f4aa60SAllen Pais bool arch_uprobe_xol_was_trapped(struct task_struct *t) 307e8f4aa60SAllen Pais { 308e8f4aa60SAllen Pais return false; 309e8f4aa60SAllen Pais } 310e8f4aa60SAllen Pais 311e8f4aa60SAllen Pais unsigned long 312e8f4aa60SAllen Pais arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, 313e8f4aa60SAllen Pais struct pt_regs *regs) 314e8f4aa60SAllen Pais { 315e8f4aa60SAllen Pais unsigned long orig_ret_vaddr = regs->u_regs[UREG_I7]; 316e8f4aa60SAllen Pais 317e8f4aa60SAllen Pais regs->u_regs[UREG_I7] = trampoline_vaddr-8; 318e8f4aa60SAllen Pais 319e8f4aa60SAllen Pais return orig_ret_vaddr + 8; 320e8f4aa60SAllen Pais } 321