Lines Matching +full:static +full:- +full:trace +full:- +full:id

1 // SPDX-License-Identifier: GPL-2.0-or-later
8 * Derived from the read-mod example from relay-examples by Tom Zanussi.
38 unsigned long id; member
41 /* Accessed per-cpu. */
42 static DEFINE_PER_CPU(struct trap_reason, pf_reason);
43 static DEFINE_PER_CPU(struct mmiotrace_rw, cpu_trace);
45 static DEFINE_MUTEX(mmiotrace_mutex);
46 static DEFINE_SPINLOCK(trace_lock);
47 static atomic_t mmiotrace_enabled;
48 static LIST_HEAD(trace_list); /* struct remap_trace */
52 * - mmiotrace_mutex enforces enable/disable_mmiotrace() critical sections.
53 * - mmiotrace_enabled may be modified only when holding mmiotrace_mutex
55 * - Routines depending on is_enabled() must take trace_lock.
56 * - trace_list users must hold trace_lock.
57 * - is_enabled() guarantees that mmio_trace_{rw,mapping} are allowed.
58 * - pre/post callbacks assume the effect of is_enabled() being true.
62 static unsigned long filter_offset;
63 static bool nommiotrace;
64 static bool trace_pc;
74 static bool is_enabled(void) in is_enabled()
79 static void print_pte(unsigned long address) in print_pte()
105 static void die_kmmio_nesting_error(struct pt_regs *regs, unsigned long addr) in die_kmmio_nesting_error()
109 addr, my_reason->addr); in die_kmmio_nesting_error()
111 pr_emerg("faulting IP is at %pS\n", (void *)regs->ip); in die_kmmio_nesting_error()
112 pr_emerg("last faulting IP was at %pS\n", (void *)my_reason->ip); in die_kmmio_nesting_error()
115 regs->ax, regs->bx, regs->cx, regs->dx); in die_kmmio_nesting_error()
117 regs->si, regs->di, regs->bp, regs->sp); in die_kmmio_nesting_error()
120 regs->ax, regs->cx, regs->dx); in die_kmmio_nesting_error()
122 regs->si, regs->di, regs->bp, regs->sp); in die_kmmio_nesting_error()
128 static void pre(struct kmmio_probe *p, struct pt_regs *regs, in pre()
135 struct remap_trace *trace = p->private; in pre() local
137 /* it doesn't make sense to have more than one active trace per cpu */ in pre()
138 if (my_reason->active_traces) in pre()
141 my_reason->active_traces++; in pre()
143 my_reason->type = type; in pre()
144 my_reason->addr = addr; in pre()
145 my_reason->ip = instptr; in pre()
147 my_trace->phys = addr - trace->probe.addr + trace->phys; in pre()
148 my_trace->map_id = trace->id; in pre()
152 * It may taint clean-room reverse engineering. in pre()
155 my_trace->pc = instptr; in pre()
157 my_trace->pc = 0; in pre()
167 my_trace->opcode = MMIO_READ; in pre()
168 my_trace->width = get_ins_mem_width(instptr); in pre()
171 my_trace->opcode = MMIO_WRITE; in pre()
172 my_trace->width = get_ins_mem_width(instptr); in pre()
173 my_trace->value = get_ins_reg_val(instptr, regs); in pre()
176 my_trace->opcode = MMIO_WRITE; in pre()
177 my_trace->width = get_ins_mem_width(instptr); in pre()
178 my_trace->value = get_ins_imm_val(instptr); in pre()
183 my_trace->opcode = MMIO_UNKNOWN_OP; in pre()
184 my_trace->width = 0; in pre()
185 my_trace->value = (*ip) << 16 | *(ip + 1) << 8 | in pre()
193 static void post(struct kmmio_probe *p, unsigned long condition, in post()
200 my_reason->active_traces--; in post()
201 if (my_reason->active_traces) { in post()
206 switch (my_reason->type) { in post()
208 my_trace->value = get_ins_reg_val(my_reason->ip, regs); in post()
219 static void ioremap_trace_core(resource_size_t offset, unsigned long size, in ioremap_trace_core()
222 static atomic_t next_id; in ioremap_trace_core()
223 struct remap_trace *trace = kmalloc(sizeof(*trace), GFP_KERNEL); in ioremap_trace_core() local
224 /* These are page-unaligned. */ in ioremap_trace_core()
232 if (!trace) { in ioremap_trace_core()
237 *trace = (struct remap_trace) { in ioremap_trace_core()
243 .private = trace in ioremap_trace_core()
246 .id = atomic_inc_return(&next_id) in ioremap_trace_core()
248 map.map_id = trace->id; in ioremap_trace_core()
252 kfree(trace); in ioremap_trace_core()
257 list_add_tail(&trace->list, &trace_list); in ioremap_trace_core()
259 register_kmmio_probe(&trace->probe); in ioremap_trace_core()
278 static void iounmap_trace_core(volatile void __iomem *addr) in iounmap_trace_core()
286 struct remap_trace *trace; in iounmap_trace_core() local
296 list_for_each_entry_safe(trace, tmp, &trace_list, list) { in iounmap_trace_core()
297 if ((unsigned long)addr == trace->probe.addr) { in iounmap_trace_core()
299 unregister_kmmio_probe(&trace->probe); in iounmap_trace_core()
300 list_del(&trace->list); in iounmap_trace_core()
301 found_trace = trace; in iounmap_trace_core()
305 map.map_id = (found_trace) ? found_trace->id : -1; in iounmap_trace_core()
340 static void clear_trace_list(void) in clear_trace_list()
342 struct remap_trace *trace; in clear_trace_list() local
351 list_for_each_entry(trace, &trace_list, list) { in clear_trace_list()
352 pr_notice("purging non-iounmapped trace @0x%08lx, size 0x%lx.\n", in clear_trace_list()
353 trace->probe.addr, trace->probe.len); in clear_trace_list()
355 unregister_kmmio_probe(&trace->probe); in clear_trace_list()
359 list_for_each_entry_safe(trace, tmp, &trace_list, list) { in clear_trace_list()
360 list_del(&trace->list); in clear_trace_list()
361 kfree(trace); in clear_trace_list()
366 static cpumask_var_t downed_cpus;
368 static void enter_uniprocessor(void) in enter_uniprocessor()
383 pr_notice("Disabling non-boot CPUs...\n"); in enter_uniprocessor()
398 static void leave_uniprocessor(void) in leave_uniprocessor()
405 pr_notice("Re-enabling CPUs...\n"); in leave_uniprocessor()
411 pr_err("cannot re-enable CPU%d: %d\n", cpu, err); in leave_uniprocessor()
416 static void enter_uniprocessor(void) in enter_uniprocessor()
423 static void leave_uniprocessor(void) in leave_uniprocessor()