decode-insn.c (7ae9fb1b7ecbb5d85d07857943f677fd1a559b18) decode-insn.c (acc450aa07099d071b18174c22a1119c57da8227)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * arch/arm64/kernel/probes/decode-insn.c
4 *
5 * Copyright (C) 2013 Linaro Limited.
6 */
7
8#include <linux/kernel.h>

--- 85 unchanged lines hidden (view full) ---

94 api->handler = simulate_adr_adrp;
95 } else if (aarch64_insn_is_b(insn) ||
96 aarch64_insn_is_bl(insn)) {
97 api->handler = simulate_b_bl;
98 } else if (aarch64_insn_is_br(insn) ||
99 aarch64_insn_is_blr(insn) ||
100 aarch64_insn_is_ret(insn)) {
101 api->handler = simulate_br_blr_ret;
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * arch/arm64/kernel/probes/decode-insn.c
4 *
5 * Copyright (C) 2013 Linaro Limited.
6 */
7
8#include <linux/kernel.h>

--- 85 unchanged lines hidden (view full) ---

94 api->handler = simulate_adr_adrp;
95 } else if (aarch64_insn_is_b(insn) ||
96 aarch64_insn_is_bl(insn)) {
97 api->handler = simulate_b_bl;
98 } else if (aarch64_insn_is_br(insn) ||
99 aarch64_insn_is_blr(insn) ||
100 aarch64_insn_is_ret(insn)) {
101 api->handler = simulate_br_blr_ret;
102 } else if (aarch64_insn_is_ldr_lit(insn)) {
103 api->handler = simulate_ldr_literal;
104 } else if (aarch64_insn_is_ldrsw_lit(insn)) {
105 api->handler = simulate_ldrsw_literal;
106 } else {
107 /*
108 * Instruction cannot be stepped out-of-line and we don't
109 * (yet) simulate it.
110 */
111 return INSN_REJECTED;
112 }
113

--- 21 unchanged lines hidden (view full) ---

135
136enum probe_insn __kprobes
137arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct arch_specific_insn *asi)
138{
139 enum probe_insn decoded;
140 probe_opcode_t insn = le32_to_cpu(*addr);
141 probe_opcode_t *scan_end = NULL;
142 unsigned long size = 0, offset = 0;
102 } else {
103 /*
104 * Instruction cannot be stepped out-of-line and we don't
105 * (yet) simulate it.
106 */
107 return INSN_REJECTED;
108 }
109

--- 21 unchanged lines hidden (view full) ---

131
132enum probe_insn __kprobes
133arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct arch_specific_insn *asi)
134{
135 enum probe_insn decoded;
136 probe_opcode_t insn = le32_to_cpu(*addr);
137 probe_opcode_t *scan_end = NULL;
138 unsigned long size = 0, offset = 0;
139 struct arch_probe_insn *api = &asi->api;
143
140
141 if (aarch64_insn_is_ldr_lit(insn)) {
142 api->handler = simulate_ldr_literal;
143 decoded = INSN_GOOD_NO_SLOT;
144 } else if (aarch64_insn_is_ldrsw_lit(insn)) {
145 api->handler = simulate_ldrsw_literal;
146 decoded = INSN_GOOD_NO_SLOT;
147 } else {
148 decoded = arm_probe_decode_insn(insn, &asi->api);
149 }
150
144 /*
145 * If there's a symbol defined in front of and near enough to
146 * the probe address assume it is the entry point to this
147 * code and use it to further limit how far back we search
148 * when determining if we're in an atomic sequence. If we could
149 * not find any symbol skip the atomic test altogether as we
150 * could otherwise end up searching irrelevant text/literals.
151 * KPROBES depends on KALLSYMS so this last case should never
152 * happen.
153 */
154 if (kallsyms_lookup_size_offset((unsigned long) addr, &size, &offset)) {
155 if (offset < (MAX_ATOMIC_CONTEXT_SIZE*sizeof(kprobe_opcode_t)))
156 scan_end = addr - (offset / sizeof(kprobe_opcode_t));
157 else
158 scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
159 }
151 /*
152 * If there's a symbol defined in front of and near enough to
153 * the probe address assume it is the entry point to this
154 * code and use it to further limit how far back we search
155 * when determining if we're in an atomic sequence. If we could
156 * not find any symbol skip the atomic test altogether as we
157 * could otherwise end up searching irrelevant text/literals.
158 * KPROBES depends on KALLSYMS so this last case should never
159 * happen.
160 */
161 if (kallsyms_lookup_size_offset((unsigned long) addr, &size, &offset)) {
162 if (offset < (MAX_ATOMIC_CONTEXT_SIZE*sizeof(kprobe_opcode_t)))
163 scan_end = addr - (offset / sizeof(kprobe_opcode_t));
164 else
165 scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
166 }
160 decoded = arm_probe_decode_insn(insn, &asi->api);
161
162 if (decoded != INSN_REJECTED && scan_end)
163 if (is_probed_address_atomic(addr - 1, scan_end))
164 return INSN_REJECTED;
165
166 return decoded;
167}
168#endif
167
168 if (decoded != INSN_REJECTED && scan_end)
169 if (is_probed_address_atomic(addr - 1, scan_end))
170 return INSN_REJECTED;
171
172 return decoded;
173}
174#endif