]>
Commit | Line | Data |
---|---|---|
af53c2aa GKH |
1 | From 42f3bdc5dd962a5958bc024c1e1444248a6b8b4a Mon Sep 17 00:00:00 2001 |
2 | From: Peter Zijlstra <peterz@infradead.org> | |
3 | Date: Thu, 4 Jan 2018 18:07:12 +0100 | |
4 | Subject: x86/events/intel/ds: Use the proper cache flush method for mapping ds buffers | |
5 | ||
6 | From: Peter Zijlstra <peterz@infradead.org> | |
7 | ||
8 | commit 42f3bdc5dd962a5958bc024c1e1444248a6b8b4a upstream. | |
9 | ||
10 | Thomas reported the following warning: | |
11 | ||
12 | BUG: using smp_processor_id() in preemptible [00000000] code: ovsdb-server/4498 | |
13 | caller is native_flush_tlb_single+0x57/0xc0 | |
14 | native_flush_tlb_single+0x57/0xc0 | |
15 | __set_pte_vaddr+0x2d/0x40 | |
16 | set_pte_vaddr+0x2f/0x40 | |
17 | cea_set_pte+0x30/0x40 | |
18 | ds_update_cea.constprop.4+0x4d/0x70 | |
19 | reserve_ds_buffers+0x159/0x410 | |
20 | x86_reserve_hardware+0x150/0x160 | |
21 | x86_pmu_event_init+0x3e/0x1f0 | |
22 | perf_try_init_event+0x69/0x80 | |
23 | perf_event_alloc+0x652/0x740 | |
24 | SyS_perf_event_open+0x3f6/0xd60 | |
25 | do_syscall_64+0x5c/0x190 | |
26 | ||
27 | set_pte_vaddr is used to map the ds buffers into the cpu entry area, but | |
28 | there are two problems with that: | |
29 | ||
30 | 1) The resulting flush is not supposed to be called in preemptible context | |
31 | ||
32 | 2) The cpu entry area is supposed to be per CPU, but the debug store | |
33 | buffers are mapped for all CPUs so these mappings need to be flushed | |
34 | globally. | |
35 | ||
36 | Add the necessary preemption protection across the mapping code and flush | |
37 | TLBs globally. | |
38 | ||
39 | Fixes: c1961a4631da ("x86/events/intel/ds: Map debug buffers in cpu_entry_area") | |
40 | Reported-by: Thomas Zeitlhofer <thomas.zeitlhofer+lkml@ze-it.at> | |
41 | Signed-off-by: Peter Zijlstra <peterz@infradead.org> | |
42 | Signed-off-by: Thomas Gleixner <tglx@linutronix.de> | |
43 | Tested-by: Thomas Zeitlhofer <thomas.zeitlhofer+lkml@ze-it.at> | |
44 | Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
45 | Cc: Hugh Dickins <hughd@google.com> | |
46 | Link: https://lkml.kernel.org/r/20180104170712.GB3040@hirez.programming.kicks-ass.net | |
47 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
48 | ||
49 | --- | |
50 | arch/x86/events/intel/ds.c | 16 ++++++++++++++++ | |
51 | 1 file changed, 16 insertions(+) | |
52 | ||
53 | --- a/arch/x86/events/intel/ds.c | |
54 | +++ b/arch/x86/events/intel/ds.c | |
55 | @@ -5,6 +5,7 @@ | |
56 | ||
57 | #include <asm/cpu_entry_area.h> | |
58 | #include <asm/perf_event.h> | |
59 | +#include <asm/tlbflush.h> | |
60 | #include <asm/insn.h> | |
61 | ||
62 | #include "../perf_event.h" | |
63 | @@ -283,20 +284,35 @@ static DEFINE_PER_CPU(void *, insn_buffe | |
64 | ||
65 | static void ds_update_cea(void *cea, void *addr, size_t size, pgprot_t prot) | |
66 | { | |
67 | + unsigned long start = (unsigned long)cea; | |
68 | phys_addr_t pa; | |
69 | size_t msz = 0; | |
70 | ||
71 | pa = virt_to_phys(addr); | |
72 | + | |
73 | + preempt_disable(); | |
74 | for (; msz < size; msz += PAGE_SIZE, pa += PAGE_SIZE, cea += PAGE_SIZE) | |
75 | cea_set_pte(cea, pa, prot); | |
76 | + | |
77 | + /* | |
78 | + * This is a cross-CPU update of the cpu_entry_area, we must shoot down | |
79 | + * all TLB entries for it. | |
80 | + */ | |
81 | + flush_tlb_kernel_range(start, start + size); | |
82 | + preempt_enable(); | |
83 | } | |
84 | ||
85 | static void ds_clear_cea(void *cea, size_t size) | |
86 | { | |
87 | + unsigned long start = (unsigned long)cea; | |
88 | size_t msz = 0; | |
89 | ||
90 | + preempt_disable(); | |
91 | for (; msz < size; msz += PAGE_SIZE, cea += PAGE_SIZE) | |
92 | cea_set_pte(cea, 0, PAGE_NONE); | |
93 | + | |
94 | + flush_tlb_kernel_range(start, start + size); | |
95 | + preempt_enable(); | |
96 | } | |
97 | ||
98 | static void *dsalloc_pages(size_t size, gfp_t flags, int cpu) |