0026-x86-traps-Simplify-pagefault-tracing-logic.patch 7.8 KB

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