23 #define pr_fmt(fmt) "mmiotrace: " fmt
27 #include <linux/module.h>
29 #include <linux/slab.h>
33 #include <asm/pgtable.h>
77 static unsigned long filter_offset;
78 static bool nommiotrace;
100 pr_err(
"Error in %s: no pte for page 0x%08lx\n",
106 pr_emerg(
"4MB pages are not currently supported: 0x%08lx\n",
110 pr_info(
"pte for 0x%lx: 0x%llx 0x%llx\n",
112 (
unsigned long long)
pte_val(*pte),
120 static void die_kmmio_nesting_error(
struct pt_regs *
regs,
unsigned long addr)
123 pr_emerg(
"unexpected fault for address: 0x%08lx, last fault for address: 0x%08lx\n",
124 addr, my_reason->
addr);
126 print_symbol(
KERN_EMERG "faulting IP is at %s\n", regs->ip);
127 print_symbol(
KERN_EMERG "last faulting IP was at %s\n", my_reason->
ip);
129 pr_emerg(
"eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
130 regs->ax, regs->bx, regs->cx, regs->dx);
131 pr_emerg(
"esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
132 regs->si, regs->di, regs->bp, regs->
sp);
134 pr_emerg(
"rax: %016lx rcx: %016lx rdx: %016lx\n",
135 regs->ax, regs->cx, regs->dx);
136 pr_emerg(
"rsi: %016lx rdi: %016lx rbp: %016lx rsp: %016lx\n",
137 regs->si, regs->di, regs->bp, regs->
sp);
154 die_kmmio_nesting_error(regs, addr);
160 my_reason->
ip = instptr;
170 my_trace->
pc = instptr;
197 unsigned char *
ip = (
unsigned char *)instptr;
200 my_trace->
value = (*ip) << 16 | *(ip + 1) << 8 |
217 pr_emerg(
"unexpected post handler");
221 switch (my_reason->
type) {
242 .virt = (
unsigned long)addr,
248 pr_err(
"kmalloc failed in ioremap\n");
254 .addr = (
unsigned long)addr,
257 .post_handler =
post,
265 spin_lock_irq(&trace_lock);
277 spin_unlock_irq(&trace_lock);
286 pr_debug(
"ioremap_*(0x%llx, 0x%lx) = %p\n",
287 (
unsigned long long)offset, size, addr);
288 if ((filter_offset) && (offset != filter_offset))
290 ioremap_trace_core(offset, size, addr);
293 static void iounmap_trace_core(
volatile void __iomem *addr)
297 .virt = (
unsigned long)addr,
307 spin_lock_irq(&trace_lock);
312 if ((
unsigned long)addr == trace->
probe.addr) {
320 map.
map_id = (found_trace) ? found_trace->
id : -1;
324 spin_unlock_irq(&trace_lock);
335 iounmap_trace_core(addr);
348 spin_unlock_irqrestore(&trace_lock, flags);
355 static void clear_trace_list(
void)
367 pr_notice(
"purging non-iounmapped trace @0x%08lx, size 0x%lx.\n",
380 #ifdef CONFIG_HOTPLUG_CPU
383 static void enter_uniprocessor(
void)
388 if (downed_cpus ==
NULL &&
389 !alloc_cpumask_var(&downed_cpus,
GFP_KERNEL)) {
395 cpumask_copy(downed_cpus, cpu_online_mask);
396 cpumask_clear_cpu(cpumask_first(cpu_online_mask), downed_cpus);
398 pr_notice(
"Disabling non-boot CPUs...\n");
404 pr_info(
"CPU%d is down.\n", cpu);
406 pr_err(
"Error taking CPU%d down: %d\n", cpu, err);
410 pr_warning(
"multiple CPUs still online, may miss events.\n");
415 static void __ref leave_uniprocessor(
void)
420 if (downed_cpus ==
NULL || cpumask_weight(downed_cpus) == 0)
426 pr_info(
"enabled CPU%d.\n", cpu);
428 pr_err(
"cannot re-enable CPU%d: %d\n", cpu, err);
433 static void enter_uniprocessor(
void)
436 pr_warning(
"multiple CPUs are online, may miss events. "
437 "Suggest booting with maxcpus=1 kernel argument.\n");
440 static void leave_uniprocessor(
void)
452 pr_info(
"MMIO tracing disabled.\n");
454 enter_uniprocessor();
455 spin_lock_irq(&trace_lock);
457 spin_unlock_irq(&trace_lock);
469 spin_lock_irq(&trace_lock);
472 spin_unlock_irq(&trace_lock);
475 leave_uniprocessor();