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/decode.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Some contents moved here from arch/arm/include/asm/kprobes-arm.c which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Copyright (C) 2006, 2007 Motorola Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <asm/system_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "decode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #ifndef find_str_pc_offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * For STR and STM instructions, an ARM core may choose to use either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * a +8 or a +12 displacement from the current instruction's address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * Whichever value is chosen for a given core, it must be the same for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * both instructions and may not change.  This function measures it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) int str_pc_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) void __init find_str_pc_offset(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	int addr, scratch, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	__asm__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 		"sub	%[ret], pc, #4		\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		"str	pc, %[addr]		\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		"ldr	%[scr], %[addr]		\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 		"sub	%[ret], %[scr], %[ret]	\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		: [ret] "=r" (ret), [scr] "=r" (scratch), [addr] "+m" (addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	str_pc_offset = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #endif /* !find_str_pc_offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #ifndef test_load_write_pc_interworking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) bool load_write_pc_interworks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) void __init test_load_write_pc_interworking(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	int arch = cpu_architecture();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	BUG_ON(arch == CPU_ARCH_UNKNOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	load_write_pc_interworks = arch >= CPU_ARCH_ARMv5T;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #endif /* !test_load_write_pc_interworking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #ifndef test_alu_write_pc_interworking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) bool alu_write_pc_interworks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) void __init test_alu_write_pc_interworking(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	int arch = cpu_architecture();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	BUG_ON(arch == CPU_ARCH_UNKNOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	alu_write_pc_interworks = arch >= CPU_ARCH_ARMv7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #endif /* !test_alu_write_pc_interworking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) void __init arm_probes_decode_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	find_str_pc_offset();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	test_load_write_pc_interworking();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	test_alu_write_pc_interworking();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) static unsigned long __kprobes __check_eq(unsigned long cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	return cpsr & PSR_Z_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) static unsigned long __kprobes __check_ne(unsigned long cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	return (~cpsr) & PSR_Z_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) static unsigned long __kprobes __check_cs(unsigned long cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	return cpsr & PSR_C_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) static unsigned long __kprobes __check_cc(unsigned long cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	return (~cpsr) & PSR_C_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static unsigned long __kprobes __check_mi(unsigned long cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	return cpsr & PSR_N_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static unsigned long __kprobes __check_pl(unsigned long cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	return (~cpsr) & PSR_N_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static unsigned long __kprobes __check_vs(unsigned long cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	return cpsr & PSR_V_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static unsigned long __kprobes __check_vc(unsigned long cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	return (~cpsr) & PSR_V_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static unsigned long __kprobes __check_hi(unsigned long cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	return cpsr & PSR_C_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static unsigned long __kprobes __check_ls(unsigned long cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	return (~cpsr) & PSR_C_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static unsigned long __kprobes __check_ge(unsigned long cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	return (~cpsr) & PSR_N_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static unsigned long __kprobes __check_lt(unsigned long cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	return cpsr & PSR_N_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static unsigned long __kprobes __check_gt(unsigned long cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	temp |= (cpsr << 1);			 /* PSR_N_BIT |= PSR_Z_BIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	return (~temp) & PSR_N_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static unsigned long __kprobes __check_le(unsigned long cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	temp |= (cpsr << 1);			 /* PSR_N_BIT |= PSR_Z_BIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	return temp & PSR_N_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static unsigned long __kprobes __check_al(unsigned long cpsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) probes_check_cc * const probes_condition_checks[16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	&__check_eq, &__check_ne, &__check_cs, &__check_cc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	&__check_mi, &__check_pl, &__check_vs, &__check_vc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	&__check_hi, &__check_ls, &__check_ge, &__check_lt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	&__check_gt, &__check_le, &__check_al, &__check_al
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) void __kprobes probes_simulate_nop(probes_opcode_t opcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	struct arch_probes_insn *asi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) void __kprobes probes_emulate_none(probes_opcode_t opcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	struct arch_probes_insn *asi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	asi->insn_fn();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^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)  * Prepare an instruction slot to receive an instruction for emulating.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  * This is done by placing a subroutine return after the location where the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  * instruction will be placed. We also modify ARM instructions to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)  * unconditional as the condition code will already be checked before any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  * emulation handler is called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static probes_opcode_t __kprobes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) prepare_emulated_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		      bool thumb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #ifdef CONFIG_THUMB2_KERNEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	if (thumb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		u16 *thumb_insn = (u16 *)asi->insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		/* Thumb bx lr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		thumb_insn[1] = __opcode_to_mem_thumb16(0x4770);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		thumb_insn[2] = __opcode_to_mem_thumb16(0x4770);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		return insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	asi->insn[1] = __opcode_to_mem_arm(0xe12fff1e); /* ARM bx lr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	asi->insn[1] = __opcode_to_mem_arm(0xe1a0f00e); /* mov pc, lr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	/* Make an ARM instruction unconditional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	if (insn < 0xe0000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		insn = (insn | 0xe0000000) & ~0x10000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	return insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)  * Write a (probably modified) instruction into the slot previously prepared by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)  * prepare_emulated_insn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static void  __kprobes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) set_emulated_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		  bool thumb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #ifdef CONFIG_THUMB2_KERNEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	if (thumb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		u16 *ip = (u16 *)asi->insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		if (is_wide_instruction(insn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 			*ip++ = __opcode_to_mem_thumb16(insn >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		*ip++ = __opcode_to_mem_thumb16(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	asi->insn[0] = __opcode_to_mem_arm(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)  * When we modify the register numbers encoded in an instruction to be emulated,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)  * the new values come from this define. For ARM and 32-bit Thumb instructions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)  * this gives...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)  *	bit position	  16  12   8   4   0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)  *	---------------+---+---+---+---+---+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)  *	register	 r2  r0  r1  --  r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) #define INSN_NEW_BITS		0x00020103
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* Each nibble has same value as that at INSN_NEW_BITS bit 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #define INSN_SAMEAS16_BITS	0x22222222
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)  * Validate and modify each of the registers encoded in an instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)  * Each nibble in regs contains a value from enum decode_reg_type. For each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)  * non-zero value, the corresponding nibble in pinsn is validated and modified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)  * according to the type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static bool __kprobes decode_regs(probes_opcode_t *pinsn, u32 regs, bool modify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	probes_opcode_t insn = *pinsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	probes_opcode_t mask = 0xf; /* Start at least significant nibble */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	for (; regs != 0; regs >>= 4, mask <<= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		probes_opcode_t new_bits = INSN_NEW_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		switch (regs & 0xf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		case REG_TYPE_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 			/* Nibble not a register, skip to next */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		case REG_TYPE_ANY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 			/* Any register is allowed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		case REG_TYPE_SAMEAS16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 			/* Replace register with same as at bit position 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 			new_bits = INSN_SAMEAS16_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		case REG_TYPE_SP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 			/* Only allow SP (R13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			if ((insn ^ 0xdddddddd) & mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 				goto reject;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		case REG_TYPE_PC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 			/* Only allow PC (R15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 			if ((insn ^ 0xffffffff) & mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 				goto reject;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		case REG_TYPE_NOSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 			/* Reject SP (R13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 			if (((insn ^ 0xdddddddd) & mask) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 				goto reject;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		case REG_TYPE_NOSPPC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		case REG_TYPE_NOSPPCX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 			/* Reject SP and PC (R13 and R15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 			if (((insn ^ 0xdddddddd) & 0xdddddddd & mask) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 				goto reject;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		case REG_TYPE_NOPCWB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 			if (!is_writeback(insn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 				break; /* No writeback, so any register is OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		case REG_TYPE_NOPC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		case REG_TYPE_NOPCX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 			/* Reject PC (R15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 			if (((insn ^ 0xffffffff) & mask) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 				goto reject;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		/* Replace value of nibble with new register number... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		insn &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		insn |= new_bits & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	if (modify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		*pinsn = insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) reject:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static const int decode_struct_sizes[NUM_DECODE_TYPES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	[DECODE_TYPE_TABLE]	= sizeof(struct decode_table),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	[DECODE_TYPE_CUSTOM]	= sizeof(struct decode_custom),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	[DECODE_TYPE_SIMULATE]	= sizeof(struct decode_simulate),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	[DECODE_TYPE_EMULATE]	= sizeof(struct decode_emulate),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	[DECODE_TYPE_OR]	= sizeof(struct decode_or),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	[DECODE_TYPE_REJECT]	= sizeof(struct decode_reject)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static int run_checkers(const struct decode_checker *checkers[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		int action, probes_opcode_t insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		struct arch_probes_insn *asi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		const struct decode_header *h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	const struct decode_checker **p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	if (!checkers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		return INSN_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	p = checkers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	while (*p != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		probes_check_t *checker_func = (*p)[action].checker;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		retval = INSN_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		if (checker_func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 			retval = checker_func(insn, asi, h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		if (retval == INSN_REJECTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 			return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	return INSN_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)  * probes_decode_insn operates on data tables in order to decode an ARM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)  * architecture instruction onto which a kprobe has been placed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)  * These instruction decoding tables are a concatenation of entries each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)  * of which consist of one of the following structs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)  *	decode_table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)  *	decode_custom
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)  *	decode_simulate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)  *	decode_emulate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)  *	decode_or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)  *	decode_reject
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)  * Each of these starts with a struct decode_header which has the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)  * fields:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)  *	type_regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)  *	mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)  *	value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)  * The least significant DECODE_TYPE_BITS of type_regs contains a value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)  * from enum decode_type, this indicates which of the decode_* structs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)  * the entry contains. The value DECODE_TYPE_END indicates the end of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)  * table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)  * When the table is parsed, each entry is checked in turn to see if it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)  * matches the instruction to be decoded using the test:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)  *	(insn & mask) == value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)  * If no match is found before the end of the table is reached then decoding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)  * fails with INSN_REJECTED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)  * When a match is found, decode_regs() is called to validate and modify each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)  * of the registers encoded in the instruction; the data it uses to do this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)  * is (type_regs >> DECODE_TYPE_BITS). A validation failure will cause decoding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)  * to fail with INSN_REJECTED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)  * Once the instruction has passed the above tests, further processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)  * depends on the type of the table entry's decode struct.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) int __kprobes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		   const union decode_item *table, bool thumb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		   bool emulate, const union decode_action *actions,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		   const struct decode_checker *checkers[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	const struct decode_header *h = (struct decode_header *)table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	const struct decode_header *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	bool matched = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	 * @insn can be modified by decode_regs. Save its original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	 * value for checkers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	probes_opcode_t origin_insn = insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	 * stack_space is initialized to 0 here. Checker functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	 * should update is value if they find this is a stack store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	 * instruction: positive value means bytes of stack usage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	 * negitive value means unable to determine stack usage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	 * statically. For instruction doesn't store to stack, checker
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	 * do nothing with it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	asi->stack_space = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	 * Similarly to stack_space, register_usage_flags is filled by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	 * checkers. Its default value is set to ~0, which is 'all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	 * registers are used', to prevent any potential optimization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	asi->register_usage_flags = ~0UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	if (emulate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		insn = prepare_emulated_insn(insn, asi, thumb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	for (;; h = next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		u32 regs = h->type_regs.bits >> DECODE_TYPE_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		if (type == DECODE_TYPE_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 			return INSN_REJECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		next = (struct decode_header *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 				((uintptr_t)h + decode_struct_sizes[type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		if (!matched && (insn & h->mask.bits) != h->value.bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		if (!decode_regs(&insn, regs, emulate))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 			return INSN_REJECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		case DECODE_TYPE_TABLE: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 			struct decode_table *d = (struct decode_table *)h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 			next = (struct decode_header *)d->table.table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		case DECODE_TYPE_CUSTOM: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 			int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 			struct decode_custom *d = (struct decode_custom *)h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 			int action = d->decoder.action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 			err = run_checkers(checkers, action, origin_insn, asi, h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 			if (err == INSN_REJECTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 				return INSN_REJECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 			return actions[action].decoder(insn, asi, h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		case DECODE_TYPE_SIMULATE: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 			int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 			struct decode_simulate *d = (struct decode_simulate *)h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 			int action = d->handler.action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 			err = run_checkers(checkers, action, origin_insn, asi, h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 			if (err == INSN_REJECTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 				return INSN_REJECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 			asi->insn_handler = actions[action].handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 			return INSN_GOOD_NO_SLOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 		case DECODE_TYPE_EMULATE: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 			int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 			struct decode_emulate *d = (struct decode_emulate *)h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 			int action = d->handler.action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 			err = run_checkers(checkers, action, origin_insn, asi, h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 			if (err == INSN_REJECTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 				return INSN_REJECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 			if (!emulate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 				return actions[action].decoder(insn, asi, h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 			asi->insn_handler = actions[action].handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 			set_emulated_insn(insn, asi, thumb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 			return INSN_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		case DECODE_TYPE_OR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 			matched = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		case DECODE_TYPE_REJECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 			return INSN_REJECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }