| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- From e61177a6feca143d431be190d4758bda23f6174d Mon Sep 17 00:00:00 2001
- From: Thomas Gleixner <[email protected]>
- Date: Mon, 28 Aug 2017 08:47:22 +0200
- Subject: [PATCH 026/242] x86/traps: Simplify pagefault tracing logic
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- CVE-2017-5754
- Make use of the new irqvector tracing static key and remove the duplicated
- trace_do_pagefault() implementation.
- If irq vector tracing is disabled, then the overhead of this is a single
- NOP5, which is a reasonable tradeoff to avoid duplicated code and the
- unholy macro mess.
- Signed-off-by: Thomas Gleixner <[email protected]>
- Cc: Andy Lutomirski <[email protected]>
- Cc: Borislav Petkov <[email protected]>
- Cc: Linus Torvalds <[email protected]>
- Cc: Peter Zijlstra <[email protected]>
- Cc: Steven Rostedt <[email protected]>
- Link: http://lkml.kernel.org/r/[email protected]
- Signed-off-by: Ingo Molnar <[email protected]>
- (cherry picked from commit 11a7ffb01703c3bbb1e9b968893f4487a1b0b5a8)
- Signed-off-by: Andy Whitcroft <[email protected]>
- Signed-off-by: Kleber Sacilotto de Souza <[email protected]>
- (cherry picked from commit 8478bb5608747fd64c9fd4a2f5422fb4af756a50)
- Signed-off-by: Fabian Grünbichler <[email protected]>
- ---
- arch/x86/include/asm/traps.h | 10 +--------
- arch/x86/kernel/kvm.c | 2 +-
- arch/x86/mm/fault.c | 49 ++++++++++++--------------------------------
- arch/x86/entry/entry_32.S | 8 --------
- arch/x86/entry/entry_64.S | 13 +-----------
- 5 files changed, 16 insertions(+), 66 deletions(-)
- diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
- index 01fd0a7f48cd..b4f322d6c95f 100644
- --- a/arch/x86/include/asm/traps.h
- +++ b/arch/x86/include/asm/traps.h
- @@ -39,7 +39,6 @@ asmlinkage void machine_check(void);
- asmlinkage void simd_coprocessor_error(void);
-
- #ifdef CONFIG_TRACING
- -asmlinkage void trace_page_fault(void);
- #define trace_stack_segment stack_segment
- #define trace_divide_error divide_error
- #define trace_bounds bounds
- @@ -54,6 +53,7 @@ asmlinkage void trace_page_fault(void);
- #define trace_alignment_check alignment_check
- #define trace_simd_coprocessor_error simd_coprocessor_error
- #define trace_async_page_fault async_page_fault
- +#define trace_page_fault page_fault
- #endif
-
- dotraplinkage void do_divide_error(struct pt_regs *, long);
- @@ -74,14 +74,6 @@ asmlinkage struct pt_regs *sync_regs(struct pt_regs *);
- #endif
- dotraplinkage void do_general_protection(struct pt_regs *, long);
- dotraplinkage void do_page_fault(struct pt_regs *, unsigned long);
- -#ifdef CONFIG_TRACING
- -dotraplinkage void trace_do_page_fault(struct pt_regs *, unsigned long);
- -#else
- -static inline void trace_do_page_fault(struct pt_regs *regs, unsigned long error)
- -{
- - do_page_fault(regs, error);
- -}
- -#endif
- dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *, long);
- dotraplinkage void do_coprocessor_error(struct pt_regs *, long);
- dotraplinkage void do_alignment_check(struct pt_regs *, long);
- diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
- index e5e4306e4546..9e3798b00e40 100644
- --- a/arch/x86/kernel/kvm.c
- +++ b/arch/x86/kernel/kvm.c
- @@ -270,7 +270,7 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code)
-
- switch (kvm_read_and_reset_pf_reason()) {
- default:
- - trace_do_page_fault(regs, error_code);
- + do_page_fault(regs, error_code);
- break;
- case KVM_PV_REASON_PAGE_NOT_PRESENT:
- /* page is swapped out by the host. */
- diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
- index 955be01dd9cc..4ee9eb916826 100644
- --- a/arch/x86/mm/fault.c
- +++ b/arch/x86/mm/fault.c
- @@ -1253,10 +1253,6 @@ static inline bool smap_violation(int error_code, struct pt_regs *regs)
- * This routine handles page faults. It determines the address,
- * and the problem, and then passes it off to one of the appropriate
- * routines.
- - *
- - * This function must have noinline because both callers
- - * {,trace_}do_page_fault() have notrace on. Having this an actual function
- - * guarantees there's a function trace entry.
- */
- static noinline void
- __do_page_fault(struct pt_regs *regs, unsigned long error_code,
- @@ -1491,27 +1487,6 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code,
- }
- NOKPROBE_SYMBOL(__do_page_fault);
-
- -dotraplinkage void notrace
- -do_page_fault(struct pt_regs *regs, unsigned long error_code)
- -{
- - unsigned long address = read_cr2(); /* Get the faulting address */
- - enum ctx_state prev_state;
- -
- - /*
- - * We must have this function tagged with __kprobes, notrace and call
- - * read_cr2() before calling anything else. To avoid calling any kind
- - * of tracing machinery before we've observed the CR2 value.
- - *
- - * exception_{enter,exit}() contain all sorts of tracepoints.
- - */
- -
- - prev_state = exception_enter();
- - __do_page_fault(regs, error_code, address);
- - exception_exit(prev_state);
- -}
- -NOKPROBE_SYMBOL(do_page_fault);
- -
- -#ifdef CONFIG_TRACING
- static nokprobe_inline void
- trace_page_fault_entries(unsigned long address, struct pt_regs *regs,
- unsigned long error_code)
- @@ -1522,22 +1497,24 @@ trace_page_fault_entries(unsigned long address, struct pt_regs *regs,
- trace_page_fault_kernel(address, regs, error_code);
- }
-
- +/*
- + * We must have this function blacklisted from kprobes, tagged with notrace
- + * and call read_cr2() before calling anything else. To avoid calling any
- + * kind of tracing machinery before we've observed the CR2 value.
- + *
- + * exception_{enter,exit}() contains all sorts of tracepoints.
- + */
- dotraplinkage void notrace
- -trace_do_page_fault(struct pt_regs *regs, unsigned long error_code)
- +do_page_fault(struct pt_regs *regs, unsigned long error_code)
- {
- - /*
- - * The exception_enter and tracepoint processing could
- - * trigger another page faults (user space callchain
- - * reading) and destroy the original cr2 value, so read
- - * the faulting address now.
- - */
- - unsigned long address = read_cr2();
- + unsigned long address = read_cr2(); /* Get the faulting address */
- enum ctx_state prev_state;
-
- prev_state = exception_enter();
- - trace_page_fault_entries(address, regs, error_code);
- + if (trace_irqvectors_enabled())
- + trace_page_fault_entries(address, regs, error_code);
- +
- __do_page_fault(regs, error_code, address);
- exception_exit(prev_state);
- }
- -NOKPROBE_SYMBOL(trace_do_page_fault);
- -#endif /* CONFIG_TRACING */
- +NOKPROBE_SYMBOL(do_page_fault);
- diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
- index 48ef7bb32c42..0092da1c056f 100644
- --- a/arch/x86/entry/entry_32.S
- +++ b/arch/x86/entry/entry_32.S
- @@ -891,14 +891,6 @@ BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR,
-
- #endif /* CONFIG_HYPERV */
-
- -#ifdef CONFIG_TRACING
- -ENTRY(trace_page_fault)
- - ASM_CLAC
- - pushl $trace_do_page_fault
- - jmp common_exception
- -END(trace_page_fault)
- -#endif
- -
- ENTRY(page_fault)
- ASM_CLAC
- pushl $do_page_fault
- diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
- index ca0b250eefc4..dfabcbf8e813 100644
- --- a/arch/x86/entry/entry_64.S
- +++ b/arch/x86/entry/entry_64.S
- @@ -913,17 +913,6 @@ ENTRY(\sym)
- END(\sym)
- .endm
-
- -#ifdef CONFIG_TRACING
- -.macro trace_idtentry sym do_sym has_error_code:req
- -idtentry trace(\sym) trace(\do_sym) has_error_code=\has_error_code
- -idtentry \sym \do_sym has_error_code=\has_error_code
- -.endm
- -#else
- -.macro trace_idtentry sym do_sym has_error_code:req
- -idtentry \sym \do_sym has_error_code=\has_error_code
- -.endm
- -#endif
- -
- idtentry divide_error do_divide_error has_error_code=0
- idtentry overflow do_overflow has_error_code=0
- idtentry bounds do_bounds has_error_code=0
- @@ -1091,7 +1080,7 @@ idtentry xen_stack_segment do_stack_segment has_error_code=1
- #endif
-
- idtentry general_protection do_general_protection has_error_code=1
- -trace_idtentry page_fault do_page_fault has_error_code=1
- +idtentry page_fault do_page_fault has_error_code=1
-
- #ifdef CONFIG_KVM_GUEST
- idtentry async_page_fault do_async_page_fault has_error_code=1
- --
- 2.14.2
|