aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/entry_32.S4
-rw-r--r--arch/x86/kernel/entry_64.S4
-rw-r--r--arch/x86/kernel/ftrace.c26
-rw-r--r--arch/x86/kernel/i386_ksyms_32.c2
-rw-r--r--arch/x86/kernel/x8664_ksyms_64.c2
5 files changed, 19 insertions, 19 deletions
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 04ea83ccb979..95e6bbe3665e 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -51,6 +51,7 @@
51#include <asm/percpu.h> 51#include <asm/percpu.h>
52#include <asm/dwarf2.h> 52#include <asm/dwarf2.h>
53#include <asm/processor-flags.h> 53#include <asm/processor-flags.h>
54#include <asm/ftrace.h>
54#include "irq_vectors.h" 55#include "irq_vectors.h"
55 56
56/* 57/*
@@ -1118,6 +1119,7 @@ ENTRY(mcount)
1118 pushl %ecx 1119 pushl %ecx
1119 pushl %edx 1120 pushl %edx
1120 movl 0xc(%esp), %eax 1121 movl 0xc(%esp), %eax
1122 subl $MCOUNT_INSN_SIZE, %eax
1121 1123
1122.globl mcount_call 1124.globl mcount_call
1123mcount_call: 1125mcount_call:
@@ -1136,6 +1138,7 @@ ENTRY(ftrace_caller)
1136 pushl %edx 1138 pushl %edx
1137 movl 0xc(%esp), %eax 1139 movl 0xc(%esp), %eax
1138 movl 0x4(%ebp), %edx 1140 movl 0x4(%ebp), %edx
1141 subl $MCOUNT_INSN_SIZE, %eax
1139 1142
1140.globl ftrace_call 1143.globl ftrace_call
1141ftrace_call: 1144ftrace_call:
@@ -1166,6 +1169,7 @@ trace:
1166 pushl %edx 1169 pushl %edx
1167 movl 0xc(%esp), %eax 1170 movl 0xc(%esp), %eax
1168 movl 0x4(%ebp), %edx 1171 movl 0x4(%ebp), %edx
1172 subl $MCOUNT_INSN_SIZE, %eax
1169 1173
1170 call *ftrace_trace_function 1174 call *ftrace_trace_function
1171 1175
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index fe25e5febca3..b0f7308f78a6 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -51,6 +51,7 @@
51#include <asm/page.h> 51#include <asm/page.h>
52#include <asm/irqflags.h> 52#include <asm/irqflags.h>
53#include <asm/paravirt.h> 53#include <asm/paravirt.h>
54#include <asm/ftrace.h>
54 55
55 .code64 56 .code64
56 57
@@ -68,6 +69,7 @@ ENTRY(mcount)
68 movq %r9, 48(%rsp) 69 movq %r9, 48(%rsp)
69 70
70 movq 0x38(%rsp), %rdi 71 movq 0x38(%rsp), %rdi
72 subq $MCOUNT_INSN_SIZE, %rdi
71 73
72.globl mcount_call 74.globl mcount_call
73mcount_call: 75mcount_call:
@@ -99,6 +101,7 @@ ENTRY(ftrace_caller)
99 101
100 movq 0x38(%rsp), %rdi 102 movq 0x38(%rsp), %rdi
101 movq 8(%rbp), %rsi 103 movq 8(%rbp), %rsi
104 subq $MCOUNT_INSN_SIZE, %rdi
102 105
103.globl ftrace_call 106.globl ftrace_call
104ftrace_call: 107ftrace_call:
@@ -139,6 +142,7 @@ trace:
139 142
140 movq 0x38(%rsp), %rdi 143 movq 0x38(%rsp), %rdi
141 movq 8(%rbp), %rsi 144 movq 8(%rbp), %rsi
145 subq $MCOUNT_INSN_SIZE, %rdi
142 146
143 call *ftrace_trace_function 147 call *ftrace_trace_function
144 148
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 55828149e01e..ab115cd15fdf 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -17,20 +17,21 @@
17#include <linux/list.h> 17#include <linux/list.h>
18 18
19#include <asm/alternative.h> 19#include <asm/alternative.h>
20#include <asm/ftrace.h>
20 21
21#define CALL_BACK 5
22 22
23/* Long is fine, even if it is only 4 bytes ;-) */ 23/* Long is fine, even if it is only 4 bytes ;-) */
24static long *ftrace_nop; 24static long *ftrace_nop;
25 25
26union ftrace_code_union { 26union ftrace_code_union {
27 char code[5]; 27 char code[MCOUNT_INSN_SIZE];
28 struct { 28 struct {
29 char e8; 29 char e8;
30 int offset; 30 int offset;
31 } __attribute__((packed)); 31 } __attribute__((packed));
32}; 32};
33 33
34
34static int notrace ftrace_calc_offset(long ip, long addr) 35static int notrace ftrace_calc_offset(long ip, long addr)
35{ 36{
36 return (int)(addr - ip); 37 return (int)(addr - ip);
@@ -46,7 +47,7 @@ notrace unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
46 static union ftrace_code_union calc; 47 static union ftrace_code_union calc;
47 48
48 calc.e8 = 0xe8; 49 calc.e8 = 0xe8;
49 calc.offset = ftrace_calc_offset(ip, addr); 50 calc.offset = ftrace_calc_offset(ip + MCOUNT_INSN_SIZE, addr);
50 51
51 /* 52 /*
52 * No locking needed, this must be called via kstop_machine 53 * No locking needed, this must be called via kstop_machine
@@ -65,9 +66,6 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code,
65 unsigned char newch = new_code[4]; 66 unsigned char newch = new_code[4];
66 int faulted = 0; 67 int faulted = 0;
67 68
68 /* move the IP back to the start of the call */
69 ip -= CALL_BACK;
70
71 /* 69 /*
72 * Note: Due to modules and __init, code can 70 * Note: Due to modules and __init, code can
73 * disappear and change, we need to protect against faulting 71 * disappear and change, we need to protect against faulting
@@ -102,12 +100,10 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code,
102notrace int ftrace_update_ftrace_func(ftrace_func_t func) 100notrace int ftrace_update_ftrace_func(ftrace_func_t func)
103{ 101{
104 unsigned long ip = (unsigned long)(&ftrace_call); 102 unsigned long ip = (unsigned long)(&ftrace_call);
105 unsigned char old[5], *new; 103 unsigned char old[MCOUNT_INSN_SIZE], *new;
106 int ret; 104 int ret;
107 105
108 ip += CALL_BACK; 106 memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
109
110 memcpy(old, &ftrace_call, 5);
111 new = ftrace_call_replace(ip, (unsigned long)func); 107 new = ftrace_call_replace(ip, (unsigned long)func);
112 ret = ftrace_modify_code(ip, old, new); 108 ret = ftrace_modify_code(ip, old, new);
113 109
@@ -118,16 +114,13 @@ notrace int ftrace_mcount_set(unsigned long *data)
118{ 114{
119 unsigned long ip = (long)(&mcount_call); 115 unsigned long ip = (long)(&mcount_call);
120 unsigned long *addr = data; 116 unsigned long *addr = data;
121 unsigned char old[5], *new; 117 unsigned char old[MCOUNT_INSN_SIZE], *new;
122
123 /* ip is at the location, but modify code will subtact this */
124 ip += CALL_BACK;
125 118
126 /* 119 /*
127 * Replace the mcount stub with a pointer to the 120 * Replace the mcount stub with a pointer to the
128 * ip recorder function. 121 * ip recorder function.
129 */ 122 */
130 memcpy(old, &mcount_call, 5); 123 memcpy(old, &mcount_call, MCOUNT_INSN_SIZE);
131 new = ftrace_call_replace(ip, *addr); 124 new = ftrace_call_replace(ip, *addr);
132 *addr = ftrace_modify_code(ip, old, new); 125 *addr = ftrace_modify_code(ip, old, new);
133 126
@@ -142,8 +135,7 @@ int __init ftrace_dyn_arch_init(void *data)
142 135
143 ftrace_mcount_set(data); 136 ftrace_mcount_set(data);
144 137
145 ftrace_nop = (unsigned long *)noptable[CALL_BACK]; 138 ftrace_nop = (unsigned long *)noptable[MCOUNT_INSN_SIZE];
146 139
147 return 0; 140 return 0;
148} 141}
149
diff --git a/arch/x86/kernel/i386_ksyms_32.c b/arch/x86/kernel/i386_ksyms_32.c
index 29999dbb754c..dd7ebee446af 100644
--- a/arch/x86/kernel/i386_ksyms_32.c
+++ b/arch/x86/kernel/i386_ksyms_32.c
@@ -1,9 +1,9 @@
1#include <linux/ftrace.h>
2#include <linux/module.h> 1#include <linux/module.h>
3 2
4#include <asm/checksum.h> 3#include <asm/checksum.h>
5#include <asm/pgtable.h> 4#include <asm/pgtable.h>
6#include <asm/desc.h> 5#include <asm/desc.h>
6#include <asm/ftrace.h>
7 7
8#ifdef CONFIG_FTRACE 8#ifdef CONFIG_FTRACE
9/* mcount is defined in assembly */ 9/* mcount is defined in assembly */
diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c
index 122885bc5f3b..16ff4bf418d9 100644
--- a/arch/x86/kernel/x8664_ksyms_64.c
+++ b/arch/x86/kernel/x8664_ksyms_64.c
@@ -1,7 +1,6 @@
1/* Exports for assembly files. 1/* Exports for assembly files.
2 All C exports should go in the respective C files. */ 2 All C exports should go in the respective C files. */
3 3
4#include <linux/ftrace.h>
5#include <linux/module.h> 4#include <linux/module.h>
6#include <linux/smp.h> 5#include <linux/smp.h>
7 6
@@ -11,6 +10,7 @@
11#include <asm/pgtable.h> 10#include <asm/pgtable.h>
12#include <asm/uaccess.h> 11#include <asm/uaccess.h>
13#include <asm/desc.h> 12#include <asm/desc.h>
13#include <asm/ftrace.h>
14 14
15#ifdef CONFIG_FTRACE 15#ifdef CONFIG_FTRACE
16/* mcount is defined in assembly */ 16/* mcount is defined in assembly */