]> git.proxmox.com Git - pve-kernel.git/blob - patches/kernel/0026-x86-traps-Simplify-pagefault-tracing-logic.patch
KPTI: add follow-up fixes
[pve-kernel.git] / patches / kernel / 0026-x86-traps-Simplify-pagefault-tracing-logic.patch
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
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 CVE-2017-5754
10
11 Make use of the new irqvector tracing static key and remove the duplicated
12 trace_do_pagefault() implementation.
13
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
16 unholy macro mess.
17
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>
31 ---
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(-)
38
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);
45
46 #ifdef CONFIG_TRACING
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
56 #endif
57
58 dotraplinkage void do_divide_error(struct pt_regs *, long);
59 @@ -74,14 +74,6 @@ asmlinkage struct pt_regs *sync_regs(struct pt_regs *);
60 #endif
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);
65 -#else
66 -static inline void trace_do_page_fault(struct pt_regs *regs, unsigned long error)
67 -{
68 - do_page_fault(regs, error);
69 -}
70 -#endif
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)
79
80 switch (kvm_read_and_reset_pf_reason()) {
81 default:
82 - trace_do_page_fault(regs, error_code);
83 + do_page_fault(regs, error_code);
84 break;
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
94 * routines.
95 - *
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.
99 */
100 static noinline void
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,
103 }
104 NOKPROBE_SYMBOL(__do_page_fault);
105
106 -dotraplinkage void notrace
107 -do_page_fault(struct pt_regs *regs, unsigned long error_code)
108 -{
109 - unsigned long address = read_cr2(); /* Get the faulting address */
110 - enum ctx_state prev_state;
111 -
112 - /*
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.
116 - *
117 - * exception_{enter,exit}() contain all sorts of tracepoints.
118 - */
119 -
120 - prev_state = exception_enter();
121 - __do_page_fault(regs, error_code, address);
122 - exception_exit(prev_state);
123 -}
124 -NOKPROBE_SYMBOL(do_page_fault);
125 -
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);
132 }
133
134 +/*
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.
138 + *
139 + * exception_{enter,exit}() contains all sorts of tracepoints.
140 + */
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)
144 {
145 - /*
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.
150 - */
151 - unsigned long address = read_cr2();
152 + unsigned long address = read_cr2(); /* Get the faulting address */
153 enum ctx_state prev_state;
154
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);
159 +
160 __do_page_fault(regs, error_code, address);
161 exception_exit(prev_state);
162 }
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,
171
172 #endif /* CONFIG_HYPERV */
173
174 -#ifdef CONFIG_TRACING
175 -ENTRY(trace_page_fault)
176 - ASM_CLAC
177 - pushl $trace_do_page_fault
178 - jmp common_exception
179 -END(trace_page_fault)
180 -#endif
181 -
182 ENTRY(page_fault)
183 ASM_CLAC
184 pushl $do_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)
190 END(\sym)
191 .endm
192
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
197 -.endm
198 -#else
199 -.macro trace_idtentry sym do_sym has_error_code:req
200 -idtentry \sym \do_sym has_error_code=\has_error_code
201 -.endm
202 -#endif
203 -
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
208 #endif
209
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
213
214 #ifdef CONFIG_KVM_GUEST
215 idtentry async_page_fault do_async_page_fault has_error_code=1
216 --
217 2.14.2
218