diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/process_64.c | 3 | ||||
-rw-r--r-- | arch/x86/lib/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/lib/thunk_32.S | 47 | ||||
-rw-r--r-- | arch/x86/lib/thunk_64.S | 19 |
4 files changed, 68 insertions, 2 deletions
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index e2319f39988b..dd349c92f051 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -165,7 +165,10 @@ void cpu_idle(void) | |||
165 | */ | 165 | */ |
166 | local_irq_disable(); | 166 | local_irq_disable(); |
167 | enter_idle(); | 167 | enter_idle(); |
168 | /* Don't trace irqs off for idle */ | ||
169 | stop_critical_timings(); | ||
168 | idle(); | 170 | idle(); |
171 | start_critical_timings(); | ||
169 | /* In many cases the interrupt that ended idle | 172 | /* In many cases the interrupt that ended idle |
170 | has already called exit_idle. But some idle | 173 | has already called exit_idle. But some idle |
171 | loops can be woken up without interrupt. */ | 174 | loops can be woken up without interrupt. */ |
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 76f60f52a885..84aa2883fe15 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile | |||
@@ -5,6 +5,7 @@ | |||
5 | obj-$(CONFIG_SMP) := msr-on-cpu.o | 5 | obj-$(CONFIG_SMP) := msr-on-cpu.o |
6 | 6 | ||
7 | lib-y := delay_$(BITS).o | 7 | lib-y := delay_$(BITS).o |
8 | lib-y += thunk_$(BITS).o | ||
8 | lib-y += usercopy_$(BITS).o getuser_$(BITS).o putuser_$(BITS).o | 9 | lib-y += usercopy_$(BITS).o getuser_$(BITS).o putuser_$(BITS).o |
9 | lib-y += memcpy_$(BITS).o | 10 | lib-y += memcpy_$(BITS).o |
10 | 11 | ||
diff --git a/arch/x86/lib/thunk_32.S b/arch/x86/lib/thunk_32.S new file mode 100644 index 000000000000..650b11e00ecc --- /dev/null +++ b/arch/x86/lib/thunk_32.S | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * Trampoline to trace irqs off. (otherwise CALLER_ADDR1 might crash) | ||
3 | * Copyright 2008 by Steven Rostedt, Red Hat, Inc | ||
4 | * (inspired by Andi Kleen's thunk_64.S) | ||
5 | * Subject to the GNU public license, v.2. No warranty of any kind. | ||
6 | */ | ||
7 | |||
8 | #include <linux/linkage.h> | ||
9 | |||
10 | #define ARCH_TRACE_IRQS_ON \ | ||
11 | pushl %eax; \ | ||
12 | pushl %ecx; \ | ||
13 | pushl %edx; \ | ||
14 | call trace_hardirqs_on; \ | ||
15 | popl %edx; \ | ||
16 | popl %ecx; \ | ||
17 | popl %eax; | ||
18 | |||
19 | #define ARCH_TRACE_IRQS_OFF \ | ||
20 | pushl %eax; \ | ||
21 | pushl %ecx; \ | ||
22 | pushl %edx; \ | ||
23 | call trace_hardirqs_off; \ | ||
24 | popl %edx; \ | ||
25 | popl %ecx; \ | ||
26 | popl %eax; | ||
27 | |||
28 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
29 | /* put return address in eax (arg1) */ | ||
30 | .macro thunk_ra name,func | ||
31 | .globl \name | ||
32 | \name: | ||
33 | pushl %eax | ||
34 | pushl %ecx | ||
35 | pushl %edx | ||
36 | /* Place EIP in the arg1 */ | ||
37 | movl 3*4(%esp), %eax | ||
38 | call \func | ||
39 | popl %edx | ||
40 | popl %ecx | ||
41 | popl %eax | ||
42 | ret | ||
43 | .endm | ||
44 | |||
45 | thunk_ra trace_hardirqs_on_thunk,trace_hardirqs_on_caller | ||
46 | thunk_ra trace_hardirqs_off_thunk,trace_hardirqs_off_caller | ||
47 | #endif | ||
diff --git a/arch/x86/lib/thunk_64.S b/arch/x86/lib/thunk_64.S index e009251d4e9f..bf9a7d5a5428 100644 --- a/arch/x86/lib/thunk_64.S +++ b/arch/x86/lib/thunk_64.S | |||
@@ -2,6 +2,7 @@ | |||
2 | * Save registers before calling assembly functions. This avoids | 2 | * Save registers before calling assembly functions. This avoids |
3 | * disturbance of register allocation in some inline assembly constructs. | 3 | * disturbance of register allocation in some inline assembly constructs. |
4 | * Copyright 2001,2002 by Andi Kleen, SuSE Labs. | 4 | * Copyright 2001,2002 by Andi Kleen, SuSE Labs. |
5 | * Added trace_hardirqs callers - Copyright 2007 Steven Rostedt, Red Hat, Inc. | ||
5 | * Subject to the GNU public license, v.2. No warranty of any kind. | 6 | * Subject to the GNU public license, v.2. No warranty of any kind. |
6 | */ | 7 | */ |
7 | 8 | ||
@@ -42,8 +43,22 @@ | |||
42 | #endif | 43 | #endif |
43 | 44 | ||
44 | #ifdef CONFIG_TRACE_IRQFLAGS | 45 | #ifdef CONFIG_TRACE_IRQFLAGS |
45 | thunk trace_hardirqs_on_thunk,trace_hardirqs_on | 46 | /* put return address in rdi (arg1) */ |
46 | thunk trace_hardirqs_off_thunk,trace_hardirqs_off | 47 | .macro thunk_ra name,func |
48 | .globl \name | ||
49 | \name: | ||
50 | CFI_STARTPROC | ||
51 | SAVE_ARGS | ||
52 | /* SAVE_ARGS pushs 9 elements */ | ||
53 | /* the next element would be the rip */ | ||
54 | movq 9*8(%rsp), %rdi | ||
55 | call \func | ||
56 | jmp restore | ||
57 | CFI_ENDPROC | ||
58 | .endm | ||
59 | |||
60 | thunk_ra trace_hardirqs_on_thunk,trace_hardirqs_on_caller | ||
61 | thunk_ra trace_hardirqs_off_thunk,trace_hardirqs_off_caller | ||
47 | #endif | 62 | #endif |
48 | 63 | ||
49 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 64 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |