1 From e61177a6feca143d431be190d4758bda23f6174d Mon Sep 17 00:00:00 2001
2 From: Thomas Gleixner <tglx@linutronix.de>
3 Date: Mon, 28 Aug 2017 08:47:22 +0200
4 Subject: [PATCH 026/241] x86/traps: Simplify pagefault tracing logic
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
11 Make use of the new irqvector tracing static key and remove the duplicated
12 trace_do_pagefault() implementation.
14 If irq vector tracing is disabled, then the overhead of this is a single
15 NOP5, which is a reasonable tradeoff to avoid duplicated code and the
18 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
19 Cc: Andy Lutomirski <luto@kernel.org>
20 Cc: Borislav Petkov <bp@alien8.de>
21 Cc: Linus Torvalds <torvalds@linux-foundation.org>
22 Cc: Peter Zijlstra <peterz@infradead.org>
23 Cc: Steven Rostedt <rostedt@goodmis.org>
24 Link: http://lkml.kernel.org/r/20170828064956.672965407@linutronix.de
25 Signed-off-by: Ingo Molnar <mingo@kernel.org>
26 (cherry picked from commit 11a7ffb01703c3bbb1e9b968893f4487a1b0b5a8)
27 Signed-off-by: Andy Whitcroft <apw@canonical.com>
28 Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
29 (cherry picked from commit 8478bb5608747fd64c9fd4a2f5422fb4af756a50)
30 Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
32 arch/x86/include/asm/traps.h | 10 +--------
33 arch/x86/kernel/kvm.c | 2 +-
34 arch/x86/mm/fault.c | 49 ++++++++++++--------------------------------
35 arch/x86/entry/entry_32.S | 8 --------
36 arch/x86/entry/entry_64.S | 13 +-----------
37 5 files changed, 16 insertions(+), 66 deletions(-)
39 diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
40 index 01fd0a7f48cd..b4f322d6c95f 100644
41 --- a/arch/x86/include/asm/traps.h
42 +++ b/arch/x86/include/asm/traps.h
43 @@ -39,7 +39,6 @@ asmlinkage void machine_check(void);
44 asmlinkage void simd_coprocessor_error(void);
47 -asmlinkage void trace_page_fault(void);
48 #define trace_stack_segment stack_segment
49 #define trace_divide_error divide_error
50 #define trace_bounds bounds
51 @@ -54,6 +53,7 @@ asmlinkage void trace_page_fault(void);
52 #define trace_alignment_check alignment_check
53 #define trace_simd_coprocessor_error simd_coprocessor_error
54 #define trace_async_page_fault async_page_fault
55 +#define trace_page_fault page_fault
58 dotraplinkage void do_divide_error(struct pt_regs *, long);
59 @@ -74,14 +74,6 @@ asmlinkage struct pt_regs *sync_regs(struct pt_regs *);
61 dotraplinkage void do_general_protection(struct pt_regs *, long);
62 dotraplinkage void do_page_fault(struct pt_regs *, unsigned long);
63 -#ifdef CONFIG_TRACING
64 -dotraplinkage void trace_do_page_fault(struct pt_regs *, unsigned long);
66 -static inline void trace_do_page_fault(struct pt_regs *regs, unsigned long error)
68 - do_page_fault(regs, error);
71 dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *, long);
72 dotraplinkage void do_coprocessor_error(struct pt_regs *, long);
73 dotraplinkage void do_alignment_check(struct pt_regs *, long);
74 diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
75 index e5e4306e4546..9e3798b00e40 100644
76 --- a/arch/x86/kernel/kvm.c
77 +++ b/arch/x86/kernel/kvm.c
78 @@ -270,7 +270,7 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code)
80 switch (kvm_read_and_reset_pf_reason()) {
82 - trace_do_page_fault(regs, error_code);
83 + do_page_fault(regs, error_code);
85 case KVM_PV_REASON_PAGE_NOT_PRESENT:
86 /* page is swapped out by the host. */
87 diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
88 index 955be01dd9cc..4ee9eb916826 100644
89 --- a/arch/x86/mm/fault.c
90 +++ b/arch/x86/mm/fault.c
91 @@ -1253,10 +1253,6 @@ static inline bool smap_violation(int error_code, struct pt_regs *regs)
92 * This routine handles page faults. It determines the address,
93 * and the problem, and then passes it off to one of the appropriate
96 - * This function must have noinline because both callers
97 - * {,trace_}do_page_fault() have notrace on. Having this an actual function
98 - * guarantees there's a function trace entry.
101 __do_page_fault(struct pt_regs *regs, unsigned long error_code,
102 @@ -1491,27 +1487,6 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code,
104 NOKPROBE_SYMBOL(__do_page_fault);
106 -dotraplinkage void notrace
107 -do_page_fault(struct pt_regs *regs, unsigned long error_code)
109 - unsigned long address = read_cr2(); /* Get the faulting address */
110 - enum ctx_state prev_state;
113 - * We must have this function tagged with __kprobes, notrace and call
114 - * read_cr2() before calling anything else. To avoid calling any kind
115 - * of tracing machinery before we've observed the CR2 value.
117 - * exception_{enter,exit}() contain all sorts of tracepoints.
120 - prev_state = exception_enter();
121 - __do_page_fault(regs, error_code, address);
122 - exception_exit(prev_state);
124 -NOKPROBE_SYMBOL(do_page_fault);
126 -#ifdef CONFIG_TRACING
127 static nokprobe_inline void
128 trace_page_fault_entries(unsigned long address, struct pt_regs *regs,
129 unsigned long error_code)
130 @@ -1522,22 +1497,24 @@ trace_page_fault_entries(unsigned long address, struct pt_regs *regs,
131 trace_page_fault_kernel(address, regs, error_code);
135 + * We must have this function blacklisted from kprobes, tagged with notrace
136 + * and call read_cr2() before calling anything else. To avoid calling any
137 + * kind of tracing machinery before we've observed the CR2 value.
139 + * exception_{enter,exit}() contains all sorts of tracepoints.
141 dotraplinkage void notrace
142 -trace_do_page_fault(struct pt_regs *regs, unsigned long error_code)
143 +do_page_fault(struct pt_regs *regs, unsigned long error_code)
146 - * The exception_enter and tracepoint processing could
147 - * trigger another page faults (user space callchain
148 - * reading) and destroy the original cr2 value, so read
149 - * the faulting address now.
151 - unsigned long address = read_cr2();
152 + unsigned long address = read_cr2(); /* Get the faulting address */
153 enum ctx_state prev_state;
155 prev_state = exception_enter();
156 - trace_page_fault_entries(address, regs, error_code);
157 + if (trace_irqvectors_enabled())
158 + trace_page_fault_entries(address, regs, error_code);
160 __do_page_fault(regs, error_code, address);
161 exception_exit(prev_state);
163 -NOKPROBE_SYMBOL(trace_do_page_fault);
164 -#endif /* CONFIG_TRACING */
165 +NOKPROBE_SYMBOL(do_page_fault);
166 diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
167 index 48ef7bb32c42..0092da1c056f 100644
168 --- a/arch/x86/entry/entry_32.S
169 +++ b/arch/x86/entry/entry_32.S
170 @@ -891,14 +891,6 @@ BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR,
172 #endif /* CONFIG_HYPERV */
174 -#ifdef CONFIG_TRACING
175 -ENTRY(trace_page_fault)
177 - pushl $trace_do_page_fault
178 - jmp common_exception
179 -END(trace_page_fault)
185 diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
186 index ca0b250eefc4..dfabcbf8e813 100644
187 --- a/arch/x86/entry/entry_64.S
188 +++ b/arch/x86/entry/entry_64.S
189 @@ -913,17 +913,6 @@ ENTRY(\sym)
193 -#ifdef CONFIG_TRACING
194 -.macro trace_idtentry sym do_sym has_error_code:req
195 -idtentry trace(\sym) trace(\do_sym) has_error_code=\has_error_code
196 -idtentry \sym \do_sym has_error_code=\has_error_code
199 -.macro trace_idtentry sym do_sym has_error_code:req
200 -idtentry \sym \do_sym has_error_code=\has_error_code
204 idtentry divide_error do_divide_error has_error_code=0
205 idtentry overflow do_overflow has_error_code=0
206 idtentry bounds do_bounds has_error_code=0
207 @@ -1091,7 +1080,7 @@ idtentry xen_stack_segment do_stack_segment has_error_code=1
210 idtentry general_protection do_general_protection has_error_code=1
211 -trace_idtentry page_fault do_page_fault has_error_code=1
212 +idtentry page_fault do_page_fault has_error_code=1
214 #ifdef CONFIG_KVM_GUEST
215 idtentry async_page_fault do_async_page_fault has_error_code=1