Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * arch/arm/probes/kprobes/actions-arm.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2006, 2007 Motorola Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * We do not have hardware single-stepping on ARM, This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * effort is further complicated by the ARM not having a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * "next PC" register.  Instructions that change the PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * can't be safely single-stepped in a MP environment, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * we have a lot of work to do:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * In the prepare phase:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *   *) If it is an instruction that does anything
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  *      with the CPU mode, we reject it for a kprobe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *      (This is out of laziness rather than need.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *      instructions could be simulated.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  *   *) Otherwise, decode the instruction rewriting its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *      registers to take fixed, ordered registers and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  *      setting a handler for it to run the instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * In the execution phase by an instruction's handler:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  *   *) If the PC is written to by the instruction, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  *      instruction must be fully simulated in software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *   *) Otherwise, a modified form of the instruction is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  *      directly executed.  Its handler calls the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  *      instruction in insn[0].  In insn[1] is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  *      "mov pc, lr" to return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  *      Before calling, load up the reordered registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  *      from the original instruction's registers.  If one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  *      of the original input registers is the PC, compute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  *      and adjust the appropriate input register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  *	After call completes, copy the output registers to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *      the original instruction's original registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * We don't use a real breakpoint instruction since that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * would have us in the kernel go from SVC mode to SVC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  * mode losing the link register.  Instead we use an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * undefined instruction.  To simplify processing, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * undefined instruction used for kprobes must be reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  * exclusively for kprobes use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  * TODO: ifdef out some instruction decoding based on architecture.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #include <linux/kprobes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #include "../decode-arm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #include "core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #include "checkers.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #if  __LINUX_ARM_ARCH__ >= 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define BLX(reg)	"blx	"reg"		\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define BLX(reg)	"mov	lr, pc		\n\t"	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 			"mov	pc, "reg"	\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) static void __kprobes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) emulate_ldrdstrd(probes_opcode_t insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	struct arch_probes_insn *asi, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	unsigned long pc = regs->ARM_pc + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	int rt = (insn >> 12) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	int rn = (insn >> 16) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	int rm = insn & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	register unsigned long rtv asm("r0") = regs->uregs[rt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	register unsigned long rt2v asm("r1") = regs->uregs[rt+1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	register unsigned long rnv asm("r2") = (rn == 15) ? pc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 							  : regs->uregs[rn];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	register unsigned long rmv asm("r3") = regs->uregs[rm];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	__asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		BLX("%[fn]")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		: "=r" (rtv), "=r" (rt2v), "=r" (rnv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		: "0" (rtv), "1" (rt2v), "2" (rnv), "r" (rmv),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		  [fn] "r" (asi->insn_fn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		: "lr", "memory", "cc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	regs->uregs[rt] = rtv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	regs->uregs[rt+1] = rt2v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	if (is_writeback(insn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		regs->uregs[rn] = rnv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) static void __kprobes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) emulate_ldr(probes_opcode_t insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	struct arch_probes_insn *asi, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	unsigned long pc = regs->ARM_pc + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	int rt = (insn >> 12) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	int rn = (insn >> 16) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	int rm = insn & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	register unsigned long rtv asm("r0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	register unsigned long rnv asm("r2") = (rn == 15) ? pc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 							  : regs->uregs[rn];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	register unsigned long rmv asm("r3") = regs->uregs[rm];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	__asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		BLX("%[fn]")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		: "=r" (rtv), "=r" (rnv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		: "1" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		: "lr", "memory", "cc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	if (rt == 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		load_write_pc(rtv, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		regs->uregs[rt] = rtv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	if (is_writeback(insn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		regs->uregs[rn] = rnv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static void __kprobes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) emulate_str(probes_opcode_t insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	struct arch_probes_insn *asi, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	unsigned long rtpc = regs->ARM_pc - 4 + str_pc_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	unsigned long rnpc = regs->ARM_pc + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	int rt = (insn >> 12) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	int rn = (insn >> 16) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	int rm = insn & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	register unsigned long rtv asm("r0") = (rt == 15) ? rtpc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 							  : regs->uregs[rt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	register unsigned long rnv asm("r2") = (rn == 15) ? rnpc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 							  : regs->uregs[rn];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	register unsigned long rmv asm("r3") = regs->uregs[rm];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	__asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		BLX("%[fn]")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		: "=r" (rnv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		: "r" (rtv), "0" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		: "lr", "memory", "cc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	if (is_writeback(insn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		regs->uregs[rn] = rnv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static void __kprobes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) emulate_rd12rn16rm0rs8_rwflags(probes_opcode_t insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	struct arch_probes_insn *asi, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	unsigned long pc = regs->ARM_pc + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	int rd = (insn >> 12) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	int rn = (insn >> 16) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	int rm = insn & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	int rs = (insn >> 8) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	register unsigned long rdv asm("r0") = regs->uregs[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	register unsigned long rnv asm("r2") = (rn == 15) ? pc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 							  : regs->uregs[rn];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	register unsigned long rmv asm("r3") = (rm == 15) ? pc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 							  : regs->uregs[rm];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	register unsigned long rsv asm("r1") = regs->uregs[rs];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	unsigned long cpsr = regs->ARM_cpsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	__asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		"msr	cpsr_fs, %[cpsr]	\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		BLX("%[fn]")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		"mrs	%[cpsr], cpsr		\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		: "=r" (rdv), [cpsr] "=r" (cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		: "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		  "1" (cpsr), [fn] "r" (asi->insn_fn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		: "lr", "memory", "cc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	if (rd == 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		alu_write_pc(rdv, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		regs->uregs[rd] = rdv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static void __kprobes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) emulate_rd12rn16rm0_rwflags_nopc(probes_opcode_t insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	struct arch_probes_insn *asi, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	int rd = (insn >> 12) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	int rn = (insn >> 16) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	int rm = insn & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	register unsigned long rdv asm("r0") = regs->uregs[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	register unsigned long rnv asm("r2") = regs->uregs[rn];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	register unsigned long rmv asm("r3") = regs->uregs[rm];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	unsigned long cpsr = regs->ARM_cpsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	__asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		"msr	cpsr_fs, %[cpsr]	\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		BLX("%[fn]")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		"mrs	%[cpsr], cpsr		\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		: "=r" (rdv), [cpsr] "=r" (cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		: "0" (rdv), "r" (rnv), "r" (rmv),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		  "1" (cpsr), [fn] "r" (asi->insn_fn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		: "lr", "memory", "cc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	regs->uregs[rd] = rdv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static void __kprobes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) emulate_rd16rn12rm0rs8_rwflags_nopc(probes_opcode_t insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	struct arch_probes_insn *asi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	int rd = (insn >> 16) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	int rn = (insn >> 12) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	int rm = insn & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	int rs = (insn >> 8) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	register unsigned long rdv asm("r2") = regs->uregs[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	register unsigned long rnv asm("r0") = regs->uregs[rn];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	register unsigned long rmv asm("r3") = regs->uregs[rm];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	register unsigned long rsv asm("r1") = regs->uregs[rs];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	unsigned long cpsr = regs->ARM_cpsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	__asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		"msr	cpsr_fs, %[cpsr]	\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		BLX("%[fn]")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		"mrs	%[cpsr], cpsr		\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		: "=r" (rdv), [cpsr] "=r" (cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		: "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		  "1" (cpsr), [fn] "r" (asi->insn_fn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		: "lr", "memory", "cc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	regs->uregs[rd] = rdv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static void __kprobes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) emulate_rd12rm0_noflags_nopc(probes_opcode_t insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	struct arch_probes_insn *asi, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	int rd = (insn >> 12) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	int rm = insn & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	register unsigned long rdv asm("r0") = regs->uregs[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	register unsigned long rmv asm("r3") = regs->uregs[rm];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	__asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		BLX("%[fn]")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		: "=r" (rdv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		: "0" (rdv), "r" (rmv), [fn] "r" (asi->insn_fn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		: "lr", "memory", "cc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	regs->uregs[rd] = rdv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static void __kprobes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(probes_opcode_t insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	struct arch_probes_insn *asi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	int rdlo = (insn >> 12) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	int rdhi = (insn >> 16) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	int rn = insn & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	int rm = (insn >> 8) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	register unsigned long rdlov asm("r0") = regs->uregs[rdlo];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	register unsigned long rdhiv asm("r2") = regs->uregs[rdhi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	register unsigned long rnv asm("r3") = regs->uregs[rn];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	register unsigned long rmv asm("r1") = regs->uregs[rm];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	unsigned long cpsr = regs->ARM_cpsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	__asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		"msr	cpsr_fs, %[cpsr]	\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		BLX("%[fn]")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		"mrs	%[cpsr], cpsr		\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		: "=r" (rdlov), "=r" (rdhiv), [cpsr] "=r" (cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		: "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		  "2" (cpsr), [fn] "r" (asi->insn_fn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		: "lr", "memory", "cc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	regs->uregs[rdlo] = rdlov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	regs->uregs[rdhi] = rdhiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	[PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	[PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	[PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	[PROBES_MRS] = {.handler = simulate_mrs},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	[PROBES_BRANCH_REG] = {.handler = simulate_blx2bx},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	[PROBES_CLZ] = {.handler = emulate_rd12rm0_noflags_nopc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	[PROBES_SATURATING_ARITHMETIC] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		.handler = emulate_rd12rn16rm0_rwflags_nopc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	[PROBES_MUL1] = {.handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	[PROBES_MUL2] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	[PROBES_SWP] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	[PROBES_LDRSTRD] = {.handler = emulate_ldrdstrd},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	[PROBES_LOAD_EXTRA] = {.handler = emulate_ldr},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	[PROBES_LOAD] = {.handler = emulate_ldr},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	[PROBES_STORE_EXTRA] = {.handler = emulate_str},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	[PROBES_STORE] = {.handler = emulate_str},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	[PROBES_MOV_IP_SP] = {.handler = simulate_mov_ipsp},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	[PROBES_DATA_PROCESSING_REG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		.handler = emulate_rd12rn16rm0rs8_rwflags},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	[PROBES_DATA_PROCESSING_IMM] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		.handler = emulate_rd12rn16rm0rs8_rwflags},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	[PROBES_MOV_HALFWORD] = {.handler = emulate_rd12rm0_noflags_nopc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	[PROBES_SEV] = {.handler = probes_emulate_none},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	[PROBES_WFE] = {.handler = probes_simulate_nop},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	[PROBES_SATURATE] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	[PROBES_REV] = {.handler = emulate_rd12rm0_noflags_nopc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	[PROBES_MMI] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	[PROBES_PACK] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	[PROBES_EXTEND] = {.handler = emulate_rd12rm0_noflags_nopc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	[PROBES_EXTEND_ADD] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	[PROBES_MUL_ADD_LONG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		.handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	[PROBES_MUL_ADD] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	[PROBES_BITFIELD] = {.handler = emulate_rd12rm0_noflags_nopc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	[PROBES_BRANCH] = {.handler = simulate_bbl},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	[PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) const struct decode_checker *kprobes_arm_checkers[] = {arm_stack_checker, arm_regs_checker, NULL};