diff options
Diffstat (limited to 'arch/x86')
| -rw-r--r-- | arch/x86/kernel/entry_32.S | 7 | ||||
| -rw-r--r-- | arch/x86/kernel/entry_64.S | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/ftrace.c | 84 | ||||
| -rw-r--r-- | arch/x86/mm/testmmiotrace.c | 29 |
4 files changed, 26 insertions, 100 deletions
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index c097e7d607c6..7d52e9da5e0c 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
| @@ -1185,17 +1185,14 @@ END(ftrace_graph_caller) | |||
| 1185 | 1185 | ||
| 1186 | .globl return_to_handler | 1186 | .globl return_to_handler |
| 1187 | return_to_handler: | 1187 | return_to_handler: |
| 1188 | pushl $0 | ||
| 1189 | pushl %eax | 1188 | pushl %eax |
| 1190 | pushl %ecx | ||
| 1191 | pushl %edx | 1189 | pushl %edx |
| 1192 | movl %ebp, %eax | 1190 | movl %ebp, %eax |
| 1193 | call ftrace_return_to_handler | 1191 | call ftrace_return_to_handler |
| 1194 | movl %eax, 0xc(%esp) | 1192 | movl %eax, %ecx |
| 1195 | popl %edx | 1193 | popl %edx |
| 1196 | popl %ecx | ||
| 1197 | popl %eax | 1194 | popl %eax |
| 1198 | ret | 1195 | jmp *%ecx |
| 1199 | #endif | 1196 | #endif |
| 1200 | 1197 | ||
| 1201 | .section .rodata,"a" | 1198 | .section .rodata,"a" |
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index b5c061f8f358..bd5bbddddf91 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
| @@ -155,11 +155,11 @@ GLOBAL(return_to_handler) | |||
| 155 | 155 | ||
| 156 | call ftrace_return_to_handler | 156 | call ftrace_return_to_handler |
| 157 | 157 | ||
| 158 | movq %rax, 16(%rsp) | 158 | movq %rax, %rdi |
| 159 | movq 8(%rsp), %rdx | 159 | movq 8(%rsp), %rdx |
| 160 | movq (%rsp), %rax | 160 | movq (%rsp), %rax |
| 161 | addq $16, %rsp | 161 | addq $24, %rsp |
| 162 | retq | 162 | jmp *%rdi |
| 163 | #endif | 163 | #endif |
| 164 | 164 | ||
| 165 | 165 | ||
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 9dbb527e1652..5a1b9758fd62 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c | |||
| @@ -9,6 +9,8 @@ | |||
| 9 | * the dangers of modifying code on the run. | 9 | * the dangers of modifying code on the run. |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 13 | |||
| 12 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
| 13 | #include <linux/hardirq.h> | 15 | #include <linux/hardirq.h> |
| 14 | #include <linux/uaccess.h> | 16 | #include <linux/uaccess.h> |
| @@ -336,15 +338,15 @@ int __init ftrace_dyn_arch_init(void *data) | |||
| 336 | 338 | ||
| 337 | switch (faulted) { | 339 | switch (faulted) { |
| 338 | case 0: | 340 | case 0: |
| 339 | pr_info("ftrace: converting mcount calls to 0f 1f 44 00 00\n"); | 341 | pr_info("converting mcount calls to 0f 1f 44 00 00\n"); |
| 340 | memcpy(ftrace_nop, ftrace_test_p6nop, MCOUNT_INSN_SIZE); | 342 | memcpy(ftrace_nop, ftrace_test_p6nop, MCOUNT_INSN_SIZE); |
| 341 | break; | 343 | break; |
| 342 | case 1: | 344 | case 1: |
| 343 | pr_info("ftrace: converting mcount calls to 66 66 66 66 90\n"); | 345 | pr_info("converting mcount calls to 66 66 66 66 90\n"); |
| 344 | memcpy(ftrace_nop, ftrace_test_nop5, MCOUNT_INSN_SIZE); | 346 | memcpy(ftrace_nop, ftrace_test_nop5, MCOUNT_INSN_SIZE); |
| 345 | break; | 347 | break; |
| 346 | case 2: | 348 | case 2: |
| 347 | pr_info("ftrace: converting mcount calls to jmp . + 5\n"); | 349 | pr_info("converting mcount calls to jmp . + 5\n"); |
| 348 | memcpy(ftrace_nop, ftrace_test_jmp, MCOUNT_INSN_SIZE); | 350 | memcpy(ftrace_nop, ftrace_test_jmp, MCOUNT_INSN_SIZE); |
| 349 | break; | 351 | break; |
| 350 | } | 352 | } |
| @@ -468,82 +470,10 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, | |||
| 468 | 470 | ||
| 469 | #ifdef CONFIG_FTRACE_SYSCALLS | 471 | #ifdef CONFIG_FTRACE_SYSCALLS |
| 470 | 472 | ||
| 471 | extern unsigned long __start_syscalls_metadata[]; | ||
| 472 | extern unsigned long __stop_syscalls_metadata[]; | ||
| 473 | extern unsigned long *sys_call_table; | 473 | extern unsigned long *sys_call_table; |
| 474 | 474 | ||
| 475 | static struct syscall_metadata **syscalls_metadata; | 475 | unsigned long __init arch_syscall_addr(int nr) |
| 476 | |||
| 477 | static struct syscall_metadata *find_syscall_meta(unsigned long *syscall) | ||
| 478 | { | ||
| 479 | struct syscall_metadata *start; | ||
| 480 | struct syscall_metadata *stop; | ||
| 481 | char str[KSYM_SYMBOL_LEN]; | ||
| 482 | |||
| 483 | |||
| 484 | start = (struct syscall_metadata *)__start_syscalls_metadata; | ||
| 485 | stop = (struct syscall_metadata *)__stop_syscalls_metadata; | ||
| 486 | kallsyms_lookup((unsigned long) syscall, NULL, NULL, NULL, str); | ||
| 487 | |||
| 488 | for ( ; start < stop; start++) { | ||
| 489 | if (start->name && !strcmp(start->name, str)) | ||
| 490 | return start; | ||
| 491 | } | ||
| 492 | return NULL; | ||
| 493 | } | ||
| 494 | |||
| 495 | struct syscall_metadata *syscall_nr_to_meta(int nr) | ||
| 496 | { | ||
| 497 | if (!syscalls_metadata || nr >= NR_syscalls || nr < 0) | ||
| 498 | return NULL; | ||
| 499 | |||
| 500 | return syscalls_metadata[nr]; | ||
| 501 | } | ||
| 502 | |||
| 503 | int syscall_name_to_nr(char *name) | ||
| 504 | { | 476 | { |
| 505 | int i; | 477 | return (unsigned long)(&sys_call_table)[nr]; |
| 506 | |||
| 507 | if (!syscalls_metadata) | ||
| 508 | return -1; | ||
| 509 | |||
| 510 | for (i = 0; i < NR_syscalls; i++) { | ||
| 511 | if (syscalls_metadata[i]) { | ||
| 512 | if (!strcmp(syscalls_metadata[i]->name, name)) | ||
| 513 | return i; | ||
| 514 | } | ||
| 515 | } | ||
| 516 | return -1; | ||
| 517 | } | ||
| 518 | |||
| 519 | void set_syscall_enter_id(int num, int id) | ||
| 520 | { | ||
| 521 | syscalls_metadata[num]->enter_id = id; | ||
| 522 | } | ||
| 523 | |||
| 524 | void set_syscall_exit_id(int num, int id) | ||
| 525 | { | ||
| 526 | syscalls_metadata[num]->exit_id = id; | ||
| 527 | } | ||
| 528 | |||
| 529 | static int __init arch_init_ftrace_syscalls(void) | ||
| 530 | { | ||
| 531 | int i; | ||
| 532 | struct syscall_metadata *meta; | ||
| 533 | unsigned long **psys_syscall_table = &sys_call_table; | ||
| 534 | |||
| 535 | syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * | ||
| 536 | NR_syscalls, GFP_KERNEL); | ||
| 537 | if (!syscalls_metadata) { | ||
| 538 | WARN_ON(1); | ||
| 539 | return -ENOMEM; | ||
| 540 | } | ||
| 541 | |||
| 542 | for (i = 0; i < NR_syscalls; i++) { | ||
| 543 | meta = find_syscall_meta(psys_syscall_table[i]); | ||
| 544 | syscalls_metadata[i] = meta; | ||
| 545 | } | ||
| 546 | return 0; | ||
| 547 | } | 478 | } |
| 548 | arch_initcall(arch_init_ftrace_syscalls); | ||
| 549 | #endif | 479 | #endif |
diff --git a/arch/x86/mm/testmmiotrace.c b/arch/x86/mm/testmmiotrace.c index 427fd1b56df5..8565d944f7cf 100644 --- a/arch/x86/mm/testmmiotrace.c +++ b/arch/x86/mm/testmmiotrace.c | |||
| @@ -1,12 +1,13 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Written by Pekka Paalanen, 2008-2009 <pq@iki.fi> | 2 | * Written by Pekka Paalanen, 2008-2009 <pq@iki.fi> |
| 3 | */ | 3 | */ |
| 4 | |||
| 5 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 6 | |||
| 4 | #include <linux/module.h> | 7 | #include <linux/module.h> |
| 5 | #include <linux/io.h> | 8 | #include <linux/io.h> |
| 6 | #include <linux/mmiotrace.h> | 9 | #include <linux/mmiotrace.h> |
| 7 | 10 | ||
| 8 | #define MODULE_NAME "testmmiotrace" | ||
| 9 | |||
| 10 | static unsigned long mmio_address; | 11 | static unsigned long mmio_address; |
| 11 | module_param(mmio_address, ulong, 0); | 12 | module_param(mmio_address, ulong, 0); |
| 12 | MODULE_PARM_DESC(mmio_address, " Start address of the mapping of 16 kB " | 13 | MODULE_PARM_DESC(mmio_address, " Start address of the mapping of 16 kB " |
| @@ -30,7 +31,7 @@ static unsigned v32(unsigned i) | |||
| 30 | static void do_write_test(void __iomem *p) | 31 | static void do_write_test(void __iomem *p) |
| 31 | { | 32 | { |
| 32 | unsigned int i; | 33 | unsigned int i; |
| 33 | pr_info(MODULE_NAME ": write test.\n"); | 34 | pr_info("write test.\n"); |
| 34 | mmiotrace_printk("Write test.\n"); | 35 | mmiotrace_printk("Write test.\n"); |
| 35 | 36 | ||
| 36 | for (i = 0; i < 256; i++) | 37 | for (i = 0; i < 256; i++) |
| @@ -47,7 +48,7 @@ static void do_read_test(void __iomem *p) | |||
| 47 | { | 48 | { |
| 48 | unsigned int i; | 49 | unsigned int i; |
| 49 | unsigned errs[3] = { 0 }; | 50 | unsigned errs[3] = { 0 }; |
| 50 | pr_info(MODULE_NAME ": read test.\n"); | 51 | pr_info("read test.\n"); |
| 51 | mmiotrace_printk("Read test.\n"); | 52 | mmiotrace_printk("Read test.\n"); |
| 52 | 53 | ||
| 53 | for (i = 0; i < 256; i++) | 54 | for (i = 0; i < 256; i++) |
| @@ -68,7 +69,7 @@ static void do_read_test(void __iomem *p) | |||
| 68 | 69 | ||
| 69 | static void do_read_far_test(void __iomem *p) | 70 | static void do_read_far_test(void __iomem *p) |
| 70 | { | 71 | { |
| 71 | pr_info(MODULE_NAME ": read far test.\n"); | 72 | pr_info("read far test.\n"); |
| 72 | mmiotrace_printk("Read far test.\n"); | 73 | mmiotrace_printk("Read far test.\n"); |
| 73 | 74 | ||
| 74 | ioread32(p + read_far); | 75 | ioread32(p + read_far); |
| @@ -78,7 +79,7 @@ static void do_test(unsigned long size) | |||
| 78 | { | 79 | { |
| 79 | void __iomem *p = ioremap_nocache(mmio_address, size); | 80 | void __iomem *p = ioremap_nocache(mmio_address, size); |
| 80 | if (!p) { | 81 | if (!p) { |
| 81 | pr_err(MODULE_NAME ": could not ioremap, aborting.\n"); | 82 | pr_err("could not ioremap, aborting.\n"); |
| 82 | return; | 83 | return; |
| 83 | } | 84 | } |
| 84 | mmiotrace_printk("ioremap returned %p.\n", p); | 85 | mmiotrace_printk("ioremap returned %p.\n", p); |
| @@ -94,24 +95,22 @@ static int __init init(void) | |||
| 94 | unsigned long size = (read_far) ? (8 << 20) : (16 << 10); | 95 | unsigned long size = (read_far) ? (8 << 20) : (16 << 10); |
| 95 | 96 | ||
| 96 | if (mmio_address == 0) { | 97 | if (mmio_address == 0) { |
| 97 | pr_err(MODULE_NAME ": you have to use the module argument " | 98 | pr_err("you have to use the module argument mmio_address.\n"); |
| 98 | "mmio_address.\n"); | 99 | pr_err("DO NOT LOAD THIS MODULE UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!\n"); |
| 99 | pr_err(MODULE_NAME ": DO NOT LOAD THIS MODULE UNLESS" | ||
| 100 | " YOU REALLY KNOW WHAT YOU ARE DOING!\n"); | ||
| 101 | return -ENXIO; | 100 | return -ENXIO; |
| 102 | } | 101 | } |
| 103 | 102 | ||
| 104 | pr_warning(MODULE_NAME ": WARNING: mapping %lu kB @ 0x%08lx in PCI " | 103 | pr_warning("WARNING: mapping %lu kB @ 0x%08lx in PCI address space, " |
| 105 | "address space, and writing 16 kB of rubbish in there.\n", | 104 | "and writing 16 kB of rubbish in there.\n", |
| 106 | size >> 10, mmio_address); | 105 | size >> 10, mmio_address); |
| 107 | do_test(size); | 106 | do_test(size); |
| 108 | pr_info(MODULE_NAME ": All done.\n"); | 107 | pr_info("All done.\n"); |
| 109 | return 0; | 108 | return 0; |
| 110 | } | 109 | } |
| 111 | 110 | ||
| 112 | static void __exit cleanup(void) | 111 | static void __exit cleanup(void) |
| 113 | { | 112 | { |
| 114 | pr_debug(MODULE_NAME ": unloaded.\n"); | 113 | pr_debug("unloaded.\n"); |
| 115 | } | 114 | } |
| 116 | 115 | ||
| 117 | module_init(init); | 116 | module_init(init); |
