diff options
Diffstat (limited to 'arch/x86/mm/mmio-mod.c')
-rw-r--r-- | arch/x86/mm/mmio-mod.c | 72 |
1 files changed, 36 insertions, 36 deletions
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index 132772a8ec57..3adff7dcc148 100644 --- a/arch/x86/mm/mmio-mod.c +++ b/arch/x86/mm/mmio-mod.c | |||
@@ -19,10 +19,14 @@ | |||
19 | * | 19 | * |
20 | * Derived from the read-mod example from relay-examples by Tom Zanussi. | 20 | * Derived from the read-mod example from relay-examples by Tom Zanussi. |
21 | */ | 21 | */ |
22 | |||
23 | #define pr_fmt(fmt) "mmiotrace: " fmt | ||
24 | |||
22 | #define DEBUG 1 | 25 | #define DEBUG 1 |
23 | 26 | ||
24 | #include <linux/module.h> | 27 | #include <linux/module.h> |
25 | #include <linux/debugfs.h> | 28 | #include <linux/debugfs.h> |
29 | #include <linux/slab.h> | ||
26 | #include <linux/uaccess.h> | 30 | #include <linux/uaccess.h> |
27 | #include <linux/io.h> | 31 | #include <linux/io.h> |
28 | #include <linux/version.h> | 32 | #include <linux/version.h> |
@@ -36,8 +40,6 @@ | |||
36 | 40 | ||
37 | #include "pf_in.h" | 41 | #include "pf_in.h" |
38 | 42 | ||
39 | #define NAME "mmiotrace: " | ||
40 | |||
41 | struct trap_reason { | 43 | struct trap_reason { |
42 | unsigned long addr; | 44 | unsigned long addr; |
43 | unsigned long ip; | 45 | unsigned long ip; |
@@ -96,17 +98,18 @@ static void print_pte(unsigned long address) | |||
96 | pte_t *pte = lookup_address(address, &level); | 98 | pte_t *pte = lookup_address(address, &level); |
97 | 99 | ||
98 | if (!pte) { | 100 | if (!pte) { |
99 | pr_err(NAME "Error in %s: no pte for page 0x%08lx\n", | 101 | pr_err("Error in %s: no pte for page 0x%08lx\n", |
100 | __func__, address); | 102 | __func__, address); |
101 | return; | 103 | return; |
102 | } | 104 | } |
103 | 105 | ||
104 | if (level == PG_LEVEL_2M) { | 106 | if (level == PG_LEVEL_2M) { |
105 | pr_emerg(NAME "4MB pages are not currently supported: " | 107 | pr_emerg("4MB pages are not currently supported: 0x%08lx\n", |
106 | "0x%08lx\n", address); | 108 | address); |
107 | BUG(); | 109 | BUG(); |
108 | } | 110 | } |
109 | pr_info(NAME "pte for 0x%lx: 0x%llx 0x%llx\n", address, | 111 | pr_info("pte for 0x%lx: 0x%llx 0x%llx\n", |
112 | address, | ||
110 | (unsigned long long)pte_val(*pte), | 113 | (unsigned long long)pte_val(*pte), |
111 | (unsigned long long)pte_val(*pte) & _PAGE_PRESENT); | 114 | (unsigned long long)pte_val(*pte) & _PAGE_PRESENT); |
112 | } | 115 | } |
@@ -118,22 +121,21 @@ static void print_pte(unsigned long address) | |||
118 | static void die_kmmio_nesting_error(struct pt_regs *regs, unsigned long addr) | 121 | static void die_kmmio_nesting_error(struct pt_regs *regs, unsigned long addr) |
119 | { | 122 | { |
120 | const struct trap_reason *my_reason = &get_cpu_var(pf_reason); | 123 | const struct trap_reason *my_reason = &get_cpu_var(pf_reason); |
121 | pr_emerg(NAME "unexpected fault for address: 0x%08lx, " | 124 | pr_emerg("unexpected fault for address: 0x%08lx, last fault for address: 0x%08lx\n", |
122 | "last fault for address: 0x%08lx\n", | 125 | addr, my_reason->addr); |
123 | addr, my_reason->addr); | ||
124 | print_pte(addr); | 126 | print_pte(addr); |
125 | print_symbol(KERN_EMERG "faulting IP is at %s\n", regs->ip); | 127 | print_symbol(KERN_EMERG "faulting IP is at %s\n", regs->ip); |
126 | print_symbol(KERN_EMERG "last faulting IP was at %s\n", my_reason->ip); | 128 | print_symbol(KERN_EMERG "last faulting IP was at %s\n", my_reason->ip); |
127 | #ifdef __i386__ | 129 | #ifdef __i386__ |
128 | pr_emerg("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", | 130 | pr_emerg("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", |
129 | regs->ax, regs->bx, regs->cx, regs->dx); | 131 | regs->ax, regs->bx, regs->cx, regs->dx); |
130 | pr_emerg("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", | 132 | pr_emerg("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", |
131 | regs->si, regs->di, regs->bp, regs->sp); | 133 | regs->si, regs->di, regs->bp, regs->sp); |
132 | #else | 134 | #else |
133 | pr_emerg("rax: %016lx rcx: %016lx rdx: %016lx\n", | 135 | pr_emerg("rax: %016lx rcx: %016lx rdx: %016lx\n", |
134 | regs->ax, regs->cx, regs->dx); | 136 | regs->ax, regs->cx, regs->dx); |
135 | pr_emerg("rsi: %016lx rdi: %016lx rbp: %016lx rsp: %016lx\n", | 137 | pr_emerg("rsi: %016lx rdi: %016lx rbp: %016lx rsp: %016lx\n", |
136 | regs->si, regs->di, regs->bp, regs->sp); | 138 | regs->si, regs->di, regs->bp, regs->sp); |
137 | #endif | 139 | #endif |
138 | put_cpu_var(pf_reason); | 140 | put_cpu_var(pf_reason); |
139 | BUG(); | 141 | BUG(); |
@@ -213,7 +215,7 @@ static void post(struct kmmio_probe *p, unsigned long condition, | |||
213 | /* this should always return the active_trace count to 0 */ | 215 | /* this should always return the active_trace count to 0 */ |
214 | my_reason->active_traces--; | 216 | my_reason->active_traces--; |
215 | if (my_reason->active_traces) { | 217 | if (my_reason->active_traces) { |
216 | pr_emerg(NAME "unexpected post handler"); | 218 | pr_emerg("unexpected post handler"); |
217 | BUG(); | 219 | BUG(); |
218 | } | 220 | } |
219 | 221 | ||
@@ -244,7 +246,7 @@ static void ioremap_trace_core(resource_size_t offset, unsigned long size, | |||
244 | }; | 246 | }; |
245 | 247 | ||
246 | if (!trace) { | 248 | if (!trace) { |
247 | pr_err(NAME "kmalloc failed in ioremap\n"); | 249 | pr_err("kmalloc failed in ioremap\n"); |
248 | return; | 250 | return; |
249 | } | 251 | } |
250 | 252 | ||
@@ -282,8 +284,8 @@ void mmiotrace_ioremap(resource_size_t offset, unsigned long size, | |||
282 | if (!is_enabled()) /* recheck and proper locking in *_core() */ | 284 | if (!is_enabled()) /* recheck and proper locking in *_core() */ |
283 | return; | 285 | return; |
284 | 286 | ||
285 | pr_debug(NAME "ioremap_*(0x%llx, 0x%lx) = %p\n", | 287 | pr_debug("ioremap_*(0x%llx, 0x%lx) = %p\n", |
286 | (unsigned long long)offset, size, addr); | 288 | (unsigned long long)offset, size, addr); |
287 | if ((filter_offset) && (offset != filter_offset)) | 289 | if ((filter_offset) && (offset != filter_offset)) |
288 | return; | 290 | return; |
289 | ioremap_trace_core(offset, size, addr); | 291 | ioremap_trace_core(offset, size, addr); |
@@ -301,7 +303,7 @@ static void iounmap_trace_core(volatile void __iomem *addr) | |||
301 | struct remap_trace *tmp; | 303 | struct remap_trace *tmp; |
302 | struct remap_trace *found_trace = NULL; | 304 | struct remap_trace *found_trace = NULL; |
303 | 305 | ||
304 | pr_debug(NAME "Unmapping %p.\n", addr); | 306 | pr_debug("Unmapping %p.\n", addr); |
305 | 307 | ||
306 | spin_lock_irq(&trace_lock); | 308 | spin_lock_irq(&trace_lock); |
307 | if (!is_enabled()) | 309 | if (!is_enabled()) |
@@ -363,9 +365,8 @@ static void clear_trace_list(void) | |||
363 | * Caller also ensures is_enabled() cannot change. | 365 | * Caller also ensures is_enabled() cannot change. |
364 | */ | 366 | */ |
365 | list_for_each_entry(trace, &trace_list, list) { | 367 | list_for_each_entry(trace, &trace_list, list) { |
366 | pr_notice(NAME "purging non-iounmapped " | 368 | pr_notice("purging non-iounmapped trace @0x%08lx, size 0x%lx.\n", |
367 | "trace @0x%08lx, size 0x%lx.\n", | 369 | trace->probe.addr, trace->probe.len); |
368 | trace->probe.addr, trace->probe.len); | ||
369 | if (!nommiotrace) | 370 | if (!nommiotrace) |
370 | unregister_kmmio_probe(&trace->probe); | 371 | unregister_kmmio_probe(&trace->probe); |
371 | } | 372 | } |
@@ -387,7 +388,7 @@ static void enter_uniprocessor(void) | |||
387 | 388 | ||
388 | if (downed_cpus == NULL && | 389 | if (downed_cpus == NULL && |
389 | !alloc_cpumask_var(&downed_cpus, GFP_KERNEL)) { | 390 | !alloc_cpumask_var(&downed_cpus, GFP_KERNEL)) { |
390 | pr_notice(NAME "Failed to allocate mask\n"); | 391 | pr_notice("Failed to allocate mask\n"); |
391 | goto out; | 392 | goto out; |
392 | } | 393 | } |
393 | 394 | ||
@@ -395,20 +396,19 @@ static void enter_uniprocessor(void) | |||
395 | cpumask_copy(downed_cpus, cpu_online_mask); | 396 | cpumask_copy(downed_cpus, cpu_online_mask); |
396 | cpumask_clear_cpu(cpumask_first(cpu_online_mask), downed_cpus); | 397 | cpumask_clear_cpu(cpumask_first(cpu_online_mask), downed_cpus); |
397 | if (num_online_cpus() > 1) | 398 | if (num_online_cpus() > 1) |
398 | pr_notice(NAME "Disabling non-boot CPUs...\n"); | 399 | pr_notice("Disabling non-boot CPUs...\n"); |
399 | put_online_cpus(); | 400 | put_online_cpus(); |
400 | 401 | ||
401 | for_each_cpu(cpu, downed_cpus) { | 402 | for_each_cpu(cpu, downed_cpus) { |
402 | err = cpu_down(cpu); | 403 | err = cpu_down(cpu); |
403 | if (!err) | 404 | if (!err) |
404 | pr_info(NAME "CPU%d is down.\n", cpu); | 405 | pr_info("CPU%d is down.\n", cpu); |
405 | else | 406 | else |
406 | pr_err(NAME "Error taking CPU%d down: %d\n", cpu, err); | 407 | pr_err("Error taking CPU%d down: %d\n", cpu, err); |
407 | } | 408 | } |
408 | out: | 409 | out: |
409 | if (num_online_cpus() > 1) | 410 | if (num_online_cpus() > 1) |
410 | pr_warning(NAME "multiple CPUs still online, " | 411 | pr_warning("multiple CPUs still online, may miss events.\n"); |
411 | "may miss events.\n"); | ||
412 | } | 412 | } |
413 | 413 | ||
414 | /* __ref because leave_uniprocessor calls cpu_up which is __cpuinit, | 414 | /* __ref because leave_uniprocessor calls cpu_up which is __cpuinit, |
@@ -420,13 +420,13 @@ static void __ref leave_uniprocessor(void) | |||
420 | 420 | ||
421 | if (downed_cpus == NULL || cpumask_weight(downed_cpus) == 0) | 421 | if (downed_cpus == NULL || cpumask_weight(downed_cpus) == 0) |
422 | return; | 422 | return; |
423 | pr_notice(NAME "Re-enabling CPUs...\n"); | 423 | pr_notice("Re-enabling CPUs...\n"); |
424 | for_each_cpu(cpu, downed_cpus) { | 424 | for_each_cpu(cpu, downed_cpus) { |
425 | err = cpu_up(cpu); | 425 | err = cpu_up(cpu); |
426 | if (!err) | 426 | if (!err) |
427 | pr_info(NAME "enabled CPU%d.\n", cpu); | 427 | pr_info("enabled CPU%d.\n", cpu); |
428 | else | 428 | else |
429 | pr_err(NAME "cannot re-enable CPU%d: %d\n", cpu, err); | 429 | pr_err("cannot re-enable CPU%d: %d\n", cpu, err); |
430 | } | 430 | } |
431 | } | 431 | } |
432 | 432 | ||
@@ -434,8 +434,8 @@ static void __ref leave_uniprocessor(void) | |||
434 | static void enter_uniprocessor(void) | 434 | static void enter_uniprocessor(void) |
435 | { | 435 | { |
436 | if (num_online_cpus() > 1) | 436 | if (num_online_cpus() > 1) |
437 | pr_warning(NAME "multiple CPUs are online, may miss events. " | 437 | pr_warning("multiple CPUs are online, may miss events. " |
438 | "Suggest booting with maxcpus=1 kernel argument.\n"); | 438 | "Suggest booting with maxcpus=1 kernel argument.\n"); |
439 | } | 439 | } |
440 | 440 | ||
441 | static void leave_uniprocessor(void) | 441 | static void leave_uniprocessor(void) |
@@ -450,13 +450,13 @@ void enable_mmiotrace(void) | |||
450 | goto out; | 450 | goto out; |
451 | 451 | ||
452 | if (nommiotrace) | 452 | if (nommiotrace) |
453 | pr_info(NAME "MMIO tracing disabled.\n"); | 453 | pr_info("MMIO tracing disabled.\n"); |
454 | kmmio_init(); | 454 | kmmio_init(); |
455 | enter_uniprocessor(); | 455 | enter_uniprocessor(); |
456 | spin_lock_irq(&trace_lock); | 456 | spin_lock_irq(&trace_lock); |
457 | atomic_inc(&mmiotrace_enabled); | 457 | atomic_inc(&mmiotrace_enabled); |
458 | spin_unlock_irq(&trace_lock); | 458 | spin_unlock_irq(&trace_lock); |
459 | pr_info(NAME "enabled.\n"); | 459 | pr_info("enabled.\n"); |
460 | out: | 460 | out: |
461 | mutex_unlock(&mmiotrace_mutex); | 461 | mutex_unlock(&mmiotrace_mutex); |
462 | } | 462 | } |
@@ -475,7 +475,7 @@ void disable_mmiotrace(void) | |||
475 | clear_trace_list(); /* guarantees: no more kmmio callbacks */ | 475 | clear_trace_list(); /* guarantees: no more kmmio callbacks */ |
476 | leave_uniprocessor(); | 476 | leave_uniprocessor(); |
477 | kmmio_cleanup(); | 477 | kmmio_cleanup(); |
478 | pr_info(NAME "disabled.\n"); | 478 | pr_info("disabled.\n"); |
479 | out: | 479 | out: |
480 | mutex_unlock(&mmiotrace_mutex); | 480 | mutex_unlock(&mmiotrace_mutex); |
481 | } | 481 | } |