aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c35
-rw-r--r--arch/arm64/include/asm/cputype.h2
-rw-r--r--arch/arm64/include/asm/stacktrace.h2
-rw-r--r--arch/arm64/include/asm/uaccess.h12
-rw-r--r--arch/arm64/kernel/armv8_deprecated.c4
-rw-r--r--arch/arm64/kernel/cpufeature.c6
-rw-r--r--arch/arm64/kernel/perf_event.c4
-rw-r--r--arch/arm64/kernel/process.c11
-rw-r--r--arch/arm64/kernel/stacktrace.c5
-rw-r--r--arch/arm64/kernel/sys_compat.c2
-rw-r--r--arch/arm64/kernel/time.c2
-rw-r--r--arch/arm64/kernel/traps.c10
-rw-r--r--arch/arm64/mm/mmu.c10
-rw-r--r--drivers/perf/arm_pmu.c138
-rw-r--r--drivers/perf/arm_pmu_acpi.c61
-rw-r--r--drivers/perf/arm_pmu_platform.c37
-rw-r--r--include/linux/perf/arm_pmu.h26
17 files changed, 183 insertions, 184 deletions
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index 57058ac46f49..7e5d7a083707 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -23,7 +23,6 @@
23#include <linux/of.h> 23#include <linux/of.h>
24#include <linux/of_address.h> 24#include <linux/of_address.h>
25#include <linux/of_platform.h> 25#include <linux/of_platform.h>
26#include <linux/perf/arm_pmu.h>
27#include <linux/regulator/machine.h> 26#include <linux/regulator/machine.h>
28 27
29#include <asm/outercache.h> 28#include <asm/outercache.h>
@@ -112,37 +111,6 @@ static void ux500_restart(enum reboot_mode mode, const char *cmd)
112 prcmu_system_reset(0); 111 prcmu_system_reset(0);
113} 112}
114 113
115/*
116 * The PMU IRQ lines of two cores are wired together into a single interrupt.
117 * Bounce the interrupt to the other core if it's not ours.
118 */
119static irqreturn_t db8500_pmu_handler(int irq, void *dev, irq_handler_t handler)
120{
121 irqreturn_t ret = handler(irq, dev);
122 int other = !smp_processor_id();
123
124 if (ret == IRQ_NONE && cpu_online(other))
125 irq_set_affinity(irq, cpumask_of(other));
126
127 /*
128 * We should be able to get away with the amount of IRQ_NONEs we give,
129 * while still having the spurious IRQ detection code kick in if the
130 * interrupt really starts hitting spuriously.
131 */
132 return ret;
133}
134
135static struct arm_pmu_platdata db8500_pmu_platdata = {
136 .handle_irq = db8500_pmu_handler,
137 .irq_flags = IRQF_NOBALANCING | IRQF_NO_THREAD,
138};
139
140static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
141 /* Requires call-back bindings. */
142 OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata),
143 {},
144};
145
146static struct of_dev_auxdata u8540_auxdata_lookup[] __initdata = { 114static struct of_dev_auxdata u8540_auxdata_lookup[] __initdata = {
147 OF_DEV_AUXDATA("stericsson,db8500-prcmu", 0x80157000, "db8500-prcmu", NULL), 115 OF_DEV_AUXDATA("stericsson,db8500-prcmu", 0x80157000, "db8500-prcmu", NULL),
148 {}, 116 {},
@@ -165,9 +133,6 @@ static void __init u8500_init_machine(void)
165 if (of_machine_is_compatible("st-ericsson,u8540")) 133 if (of_machine_is_compatible("st-ericsson,u8540"))
166 of_platform_populate(NULL, u8500_local_bus_nodes, 134 of_platform_populate(NULL, u8500_local_bus_nodes,
167 u8540_auxdata_lookup, NULL); 135 u8540_auxdata_lookup, NULL);
168 else
169 of_platform_populate(NULL, u8500_local_bus_nodes,
170 u8500_auxdata_lookup, NULL);
171} 136}
172 137
173static const char * stericsson_dt_platform_compat[] = { 138static const char * stericsson_dt_platform_compat[] = {
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index eda8c5f629fc..350c76a1d15b 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -20,7 +20,7 @@
20 20
21#define MPIDR_UP_BITMASK (0x1 << 30) 21#define MPIDR_UP_BITMASK (0x1 << 30)
22#define MPIDR_MT_BITMASK (0x1 << 24) 22#define MPIDR_MT_BITMASK (0x1 << 24)
23#define MPIDR_HWID_BITMASK 0xff00ffffffUL 23#define MPIDR_HWID_BITMASK UL(0xff00ffffff)
24 24
25#define MPIDR_LEVEL_BITS_SHIFT 3 25#define MPIDR_LEVEL_BITS_SHIFT 3
26#define MPIDR_LEVEL_BITS (1 << MPIDR_LEVEL_BITS_SHIFT) 26#define MPIDR_LEVEL_BITS (1 << MPIDR_LEVEL_BITS_SHIFT)
diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index 472ef944e932..902f9edacbea 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -28,7 +28,7 @@ struct stackframe {
28 unsigned long fp; 28 unsigned long fp;
29 unsigned long pc; 29 unsigned long pc;
30#ifdef CONFIG_FUNCTION_GRAPH_TRACER 30#ifdef CONFIG_FUNCTION_GRAPH_TRACER
31 unsigned int graph; 31 int graph;
32#endif 32#endif
33}; 33};
34 34
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index 543e11f0f657..e66b0fca99c2 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -72,15 +72,15 @@ static inline void set_fs(mm_segment_t fs)
72 * This is equivalent to the following test: 72 * This is equivalent to the following test:
73 * (u65)addr + (u65)size <= (u65)current->addr_limit + 1 73 * (u65)addr + (u65)size <= (u65)current->addr_limit + 1
74 */ 74 */
75static inline unsigned long __range_ok(unsigned long addr, unsigned long size) 75static inline unsigned long __range_ok(const void __user *addr, unsigned long size)
76{ 76{
77 unsigned long limit = current_thread_info()->addr_limit; 77 unsigned long ret, limit = current_thread_info()->addr_limit;
78 78
79 __chk_user_ptr(addr); 79 __chk_user_ptr(addr);
80 asm volatile( 80 asm volatile(
81 // A + B <= C + 1 for all A,B,C, in four easy steps: 81 // A + B <= C + 1 for all A,B,C, in four easy steps:
82 // 1: X = A + B; X' = X % 2^64 82 // 1: X = A + B; X' = X % 2^64
83 " adds %0, %0, %2\n" 83 " adds %0, %3, %2\n"
84 // 2: Set C = 0 if X > 2^64, to guarantee X' > C in step 4 84 // 2: Set C = 0 if X > 2^64, to guarantee X' > C in step 4
85 " csel %1, xzr, %1, hi\n" 85 " csel %1, xzr, %1, hi\n"
86 // 3: Set X' = ~0 if X >= 2^64. For X == 2^64, this decrements X' 86 // 3: Set X' = ~0 if X >= 2^64. For X == 2^64, this decrements X'
@@ -92,9 +92,9 @@ static inline unsigned long __range_ok(unsigned long addr, unsigned long size)
92 // testing X' - C == 0, subject to the previous adjustments. 92 // testing X' - C == 0, subject to the previous adjustments.
93 " sbcs xzr, %0, %1\n" 93 " sbcs xzr, %0, %1\n"
94 " cset %0, ls\n" 94 " cset %0, ls\n"
95 : "+r" (addr), "+r" (limit) : "Ir" (size) : "cc"); 95 : "=&r" (ret), "+r" (limit) : "Ir" (size), "0" (addr) : "cc");
96 96
97 return addr; 97 return ret;
98} 98}
99 99
100/* 100/*
@@ -104,7 +104,7 @@ static inline unsigned long __range_ok(unsigned long addr, unsigned long size)
104 */ 104 */
105#define untagged_addr(addr) sign_extend64(addr, 55) 105#define untagged_addr(addr) sign_extend64(addr, 55)
106 106
107#define access_ok(type, addr, size) __range_ok((unsigned long)(addr), size) 107#define access_ok(type, addr, size) __range_ok(addr, size)
108#define user_addr_max get_fs 108#define user_addr_max get_fs
109 109
110#define _ASM_EXTABLE(from, to) \ 110#define _ASM_EXTABLE(from, to) \
diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c
index c33b5e4010ab..68450e954d47 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -370,6 +370,7 @@ static unsigned int __kprobes aarch32_check_condition(u32 opcode, u32 psr)
370static int swp_handler(struct pt_regs *regs, u32 instr) 370static int swp_handler(struct pt_regs *regs, u32 instr)
371{ 371{
372 u32 destreg, data, type, address = 0; 372 u32 destreg, data, type, address = 0;
373 const void __user *user_ptr;
373 int rn, rt2, res = 0; 374 int rn, rt2, res = 0;
374 375
375 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs->pc); 376 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs->pc);
@@ -401,7 +402,8 @@ static int swp_handler(struct pt_regs *regs, u32 instr)
401 aarch32_insn_extract_reg_num(instr, A32_RT2_OFFSET), data); 402 aarch32_insn_extract_reg_num(instr, A32_RT2_OFFSET), data);
402 403
403 /* Check access in reasonable access range for both SWP and SWPB */ 404 /* Check access in reasonable access range for both SWP and SWPB */
404 if (!access_ok(VERIFY_WRITE, (address & ~3), 4)) { 405 user_ptr = (const void __user *)(unsigned long)(address & ~3);
406 if (!access_ok(VERIFY_WRITE, user_ptr, 4)) {
405 pr_debug("SWP{B} emulation: access to 0x%08x not allowed!\n", 407 pr_debug("SWP{B} emulation: access to 0x%08x not allowed!\n",
406 address); 408 address);
407 goto fault; 409 goto fault;
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 29b1f873e337..2985a067fc13 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -199,9 +199,11 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr2[] = {
199}; 199};
200 200
201static const struct arm64_ftr_bits ftr_ctr[] = { 201static const struct arm64_ftr_bits ftr_ctr[] = {
202 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, 31, 1, 1), /* RAO */ 202 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, 31, 1, 1), /* RES1 */
203 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, 29, 1, 1), /* DIC */
204 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, 28, 1, 1), /* IDC */
203 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_HIGHER_SAFE, 24, 4, 0), /* CWG */ 205 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_HIGHER_SAFE, 24, 4, 0), /* CWG */
204 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, 20, 4, 0), /* ERG */ 206 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_HIGHER_SAFE, 20, 4, 0), /* ERG */
205 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 1), /* DminLine */ 207 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 1), /* DminLine */
206 /* 208 /*
207 * Linux can handle differing I-cache policies. Userspace JITs will 209 * Linux can handle differing I-cache policies. Userspace JITs will
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index 75b220ba73a3..85a251b6dfa8 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -908,9 +908,9 @@ static void __armv8pmu_probe_pmu(void *info)
908 int pmuver; 908 int pmuver;
909 909
910 dfr0 = read_sysreg(id_aa64dfr0_el1); 910 dfr0 = read_sysreg(id_aa64dfr0_el1);
911 pmuver = cpuid_feature_extract_signed_field(dfr0, 911 pmuver = cpuid_feature_extract_unsigned_field(dfr0,
912 ID_AA64DFR0_PMUVER_SHIFT); 912 ID_AA64DFR0_PMUVER_SHIFT);
913 if (pmuver < 1) 913 if (pmuver == 0xf || pmuver == 0)
914 return; 914 return;
915 915
916 probe->present = true; 916 probe->present = true;
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index ad8aeb098b31..c0da6efe5465 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -220,8 +220,15 @@ void __show_regs(struct pt_regs *regs)
220 220
221 show_regs_print_info(KERN_DEFAULT); 221 show_regs_print_info(KERN_DEFAULT);
222 print_pstate(regs); 222 print_pstate(regs);
223 printk("pc : %pS\n", (void *)regs->pc); 223
224 printk("lr : %pS\n", (void *)lr); 224 if (!user_mode(regs)) {
225 printk("pc : %pS\n", (void *)regs->pc);
226 printk("lr : %pS\n", (void *)lr);
227 } else {
228 printk("pc : %016llx\n", regs->pc);
229 printk("lr : %016llx\n", lr);
230 }
231
225 printk("sp : %016llx\n", sp); 232 printk("sp : %016llx\n", sp);
226 233
227 i = top_reg; 234 i = top_reg;
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 76809ccd309c..d5718a060672 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -59,6 +59,11 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
59#ifdef CONFIG_FUNCTION_GRAPH_TRACER 59#ifdef CONFIG_FUNCTION_GRAPH_TRACER
60 if (tsk->ret_stack && 60 if (tsk->ret_stack &&
61 (frame->pc == (unsigned long)return_to_handler)) { 61 (frame->pc == (unsigned long)return_to_handler)) {
62 if (WARN_ON_ONCE(frame->graph == -1))
63 return -EINVAL;
64 if (frame->graph < -1)
65 frame->graph += FTRACE_NOTRACE_DEPTH;
66
62 /* 67 /*
63 * This is a case where function graph tracer has 68 * This is a case where function graph tracer has
64 * modified a return address (LR) in a stack frame 69 * modified a return address (LR) in a stack frame
diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c
index 8b8bbd3eaa52..a382b2a1b84e 100644
--- a/arch/arm64/kernel/sys_compat.c
+++ b/arch/arm64/kernel/sys_compat.c
@@ -57,7 +57,7 @@ do_compat_cache_op(unsigned long start, unsigned long end, int flags)
57 if (end < start || flags) 57 if (end < start || flags)
58 return -EINVAL; 58 return -EINVAL;
59 59
60 if (!access_ok(VERIFY_READ, start, end - start)) 60 if (!access_ok(VERIFY_READ, (const void __user *)start, end - start))
61 return -EFAULT; 61 return -EFAULT;
62 62
63 return __do_compat_cache_op(start, end); 63 return __do_compat_cache_op(start, end);
diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
index a4391280fba9..f258636273c9 100644
--- a/arch/arm64/kernel/time.c
+++ b/arch/arm64/kernel/time.c
@@ -52,7 +52,7 @@ unsigned long profile_pc(struct pt_regs *regs)
52 frame.fp = regs->regs[29]; 52 frame.fp = regs->regs[29];
53 frame.pc = regs->pc; 53 frame.pc = regs->pc;
54#ifdef CONFIG_FUNCTION_GRAPH_TRACER 54#ifdef CONFIG_FUNCTION_GRAPH_TRACER
55 frame.graph = -1; /* no task info */ 55 frame.graph = current->curr_ret_stack;
56#endif 56#endif
57 do { 57 do {
58 int ret = unwind_frame(NULL, &frame); 58 int ret = unwind_frame(NULL, &frame);
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index bbb0fde2780e..eb2d15147e8d 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -57,7 +57,7 @@ static const char *handler[]= {
57 "Error" 57 "Error"
58}; 58};
59 59
60int show_unhandled_signals = 1; 60int show_unhandled_signals = 0;
61 61
62static void dump_backtrace_entry(unsigned long where) 62static void dump_backtrace_entry(unsigned long where)
63{ 63{
@@ -526,14 +526,6 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs)
526 } 526 }
527#endif 527#endif
528 528
529 if (show_unhandled_signals_ratelimited()) {
530 pr_info("%s[%d]: syscall %d\n", current->comm,
531 task_pid_nr(current), regs->syscallno);
532 dump_instr("", regs);
533 if (user_mode(regs))
534 __show_regs(regs);
535 }
536
537 return sys_ni_syscall(); 529 return sys_ni_syscall();
538} 530}
539 531
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 3161b853f29e..84a019f55022 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -933,6 +933,11 @@ int pud_set_huge(pud_t *pudp, phys_addr_t phys, pgprot_t prot)
933{ 933{
934 pgprot_t sect_prot = __pgprot(PUD_TYPE_SECT | 934 pgprot_t sect_prot = __pgprot(PUD_TYPE_SECT |
935 pgprot_val(mk_sect_prot(prot))); 935 pgprot_val(mk_sect_prot(prot)));
936
937 /* ioremap_page_range doesn't honour BBM */
938 if (pud_present(READ_ONCE(*pudp)))
939 return 0;
940
936 BUG_ON(phys & ~PUD_MASK); 941 BUG_ON(phys & ~PUD_MASK);
937 set_pud(pudp, pfn_pud(__phys_to_pfn(phys), sect_prot)); 942 set_pud(pudp, pfn_pud(__phys_to_pfn(phys), sect_prot));
938 return 1; 943 return 1;
@@ -942,6 +947,11 @@ int pmd_set_huge(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot)
942{ 947{
943 pgprot_t sect_prot = __pgprot(PMD_TYPE_SECT | 948 pgprot_t sect_prot = __pgprot(PMD_TYPE_SECT |
944 pgprot_val(mk_sect_prot(prot))); 949 pgprot_val(mk_sect_prot(prot)));
950
951 /* ioremap_page_range doesn't honour BBM */
952 if (pmd_present(READ_ONCE(*pmdp)))
953 return 0;
954
945 BUG_ON(phys & ~PMD_MASK); 955 BUG_ON(phys & ~PMD_MASK);
946 set_pmd(pmdp, pfn_pmd(__phys_to_pfn(phys), sect_prot)); 956 set_pmd(pmdp, pfn_pmd(__phys_to_pfn(phys), sect_prot));
947 return 1; 957 return 1;
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
index 7bc5eee96b31..0c2ed11c0603 100644
--- a/drivers/perf/arm_pmu.c
+++ b/drivers/perf/arm_pmu.c
@@ -17,7 +17,6 @@
17#include <linux/export.h> 17#include <linux/export.h>
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/perf/arm_pmu.h> 19#include <linux/perf/arm_pmu.h>
20#include <linux/platform_device.h>
21#include <linux/slab.h> 20#include <linux/slab.h>
22#include <linux/sched/clock.h> 21#include <linux/sched/clock.h>
23#include <linux/spinlock.h> 22#include <linux/spinlock.h>
@@ -26,6 +25,9 @@
26 25
27#include <asm/irq_regs.h> 26#include <asm/irq_regs.h>
28 27
28static DEFINE_PER_CPU(struct arm_pmu *, cpu_armpmu);
29static DEFINE_PER_CPU(int, cpu_irq);
30
29static int 31static int
30armpmu_map_cache_event(const unsigned (*cache_map) 32armpmu_map_cache_event(const unsigned (*cache_map)
31 [PERF_COUNT_HW_CACHE_MAX] 33 [PERF_COUNT_HW_CACHE_MAX]
@@ -320,17 +322,9 @@ validate_group(struct perf_event *event)
320 return 0; 322 return 0;
321} 323}
322 324
323static struct arm_pmu_platdata *armpmu_get_platdata(struct arm_pmu *armpmu)
324{
325 struct platform_device *pdev = armpmu->plat_device;
326
327 return pdev ? dev_get_platdata(&pdev->dev) : NULL;
328}
329
330static irqreturn_t armpmu_dispatch_irq(int irq, void *dev) 325static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)
331{ 326{
332 struct arm_pmu *armpmu; 327 struct arm_pmu *armpmu;
333 struct arm_pmu_platdata *plat;
334 int ret; 328 int ret;
335 u64 start_clock, finish_clock; 329 u64 start_clock, finish_clock;
336 330
@@ -341,14 +335,11 @@ static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)
341 * dereference. 335 * dereference.
342 */ 336 */
343 armpmu = *(void **)dev; 337 armpmu = *(void **)dev;
344 338 if (WARN_ON_ONCE(!armpmu))
345 plat = armpmu_get_platdata(armpmu); 339 return IRQ_NONE;
346 340
347 start_clock = sched_clock(); 341 start_clock = sched_clock();
348 if (plat && plat->handle_irq) 342 ret = armpmu->handle_irq(irq, armpmu);
349 ret = plat->handle_irq(irq, armpmu, armpmu->handle_irq);
350 else
351 ret = armpmu->handle_irq(irq, armpmu);
352 finish_clock = sched_clock(); 343 finish_clock = sched_clock();
353 344
354 perf_sample_event_took(finish_clock - start_clock); 345 perf_sample_event_took(finish_clock - start_clock);
@@ -531,54 +522,41 @@ int perf_num_counters(void)
531} 522}
532EXPORT_SYMBOL_GPL(perf_num_counters); 523EXPORT_SYMBOL_GPL(perf_num_counters);
533 524
534void armpmu_free_irq(struct arm_pmu *armpmu, int cpu) 525static int armpmu_count_irq_users(const int irq)
535{ 526{
536 struct pmu_hw_events __percpu *hw_events = armpmu->hw_events; 527 int cpu, count = 0;
537 int irq = per_cpu(hw_events->irq, cpu);
538 528
539 if (!cpumask_test_and_clear_cpu(cpu, &armpmu->active_irqs)) 529 for_each_possible_cpu(cpu) {
540 return; 530 if (per_cpu(cpu_irq, cpu) == irq)
541 531 count++;
542 if (irq_is_percpu_devid(irq)) {
543 free_percpu_irq(irq, &hw_events->percpu_pmu);
544 cpumask_clear(&armpmu->active_irqs);
545 return;
546 } 532 }
547 533
548 free_irq(irq, per_cpu_ptr(&hw_events->percpu_pmu, cpu)); 534 return count;
549} 535}
550 536
551void armpmu_free_irqs(struct arm_pmu *armpmu) 537void armpmu_free_irq(int irq, int cpu)
552{ 538{
553 int cpu; 539 if (per_cpu(cpu_irq, cpu) == 0)
540 return;
541 if (WARN_ON(irq != per_cpu(cpu_irq, cpu)))
542 return;
543
544 if (!irq_is_percpu_devid(irq))
545 free_irq(irq, per_cpu_ptr(&cpu_armpmu, cpu));
546 else if (armpmu_count_irq_users(irq) == 1)
547 free_percpu_irq(irq, &cpu_armpmu);
554 548
555 for_each_cpu(cpu, &armpmu->supported_cpus) 549 per_cpu(cpu_irq, cpu) = 0;
556 armpmu_free_irq(armpmu, cpu);
557} 550}
558 551
559int armpmu_request_irq(struct arm_pmu *armpmu, int cpu) 552int armpmu_request_irq(int irq, int cpu)
560{ 553{
561 int err = 0; 554 int err = 0;
562 struct pmu_hw_events __percpu *hw_events = armpmu->hw_events;
563 const irq_handler_t handler = armpmu_dispatch_irq; 555 const irq_handler_t handler = armpmu_dispatch_irq;
564 int irq = per_cpu(hw_events->irq, cpu);
565 if (!irq) 556 if (!irq)
566 return 0; 557 return 0;
567 558
568 if (irq_is_percpu_devid(irq) && cpumask_empty(&armpmu->active_irqs)) { 559 if (!irq_is_percpu_devid(irq)) {
569 err = request_percpu_irq(irq, handler, "arm-pmu",
570 &hw_events->percpu_pmu);
571 } else if (irq_is_percpu_devid(irq)) {
572 int other_cpu = cpumask_first(&armpmu->active_irqs);
573 int other_irq = per_cpu(hw_events->irq, other_cpu);
574
575 if (irq != other_irq) {
576 pr_warn("mismatched PPIs detected.\n");
577 err = -EINVAL;
578 goto err_out;
579 }
580 } else {
581 struct arm_pmu_platdata *platdata = armpmu_get_platdata(armpmu);
582 unsigned long irq_flags; 560 unsigned long irq_flags;
583 561
584 err = irq_force_affinity(irq, cpumask_of(cpu)); 562 err = irq_force_affinity(irq, cpumask_of(cpu));
@@ -589,22 +567,22 @@ int armpmu_request_irq(struct arm_pmu *armpmu, int cpu)
589 goto err_out; 567 goto err_out;
590 } 568 }
591 569
592 if (platdata && platdata->irq_flags) { 570 irq_flags = IRQF_PERCPU |
593 irq_flags = platdata->irq_flags; 571 IRQF_NOBALANCING |
594 } else { 572 IRQF_NO_THREAD;
595 irq_flags = IRQF_PERCPU |
596 IRQF_NOBALANCING |
597 IRQF_NO_THREAD;
598 }
599 573
574 irq_set_status_flags(irq, IRQ_NOAUTOEN);
600 err = request_irq(irq, handler, irq_flags, "arm-pmu", 575 err = request_irq(irq, handler, irq_flags, "arm-pmu",
601 per_cpu_ptr(&hw_events->percpu_pmu, cpu)); 576 per_cpu_ptr(&cpu_armpmu, cpu));
577 } else if (armpmu_count_irq_users(irq) == 0) {
578 err = request_percpu_irq(irq, handler, "arm-pmu",
579 &cpu_armpmu);
602 } 580 }
603 581
604 if (err) 582 if (err)
605 goto err_out; 583 goto err_out;
606 584
607 cpumask_set_cpu(cpu, &armpmu->active_irqs); 585 per_cpu(cpu_irq, cpu) = irq;
608 return 0; 586 return 0;
609 587
610err_out: 588err_out:
@@ -612,19 +590,6 @@ err_out:
612 return err; 590 return err;
613} 591}
614 592
615int armpmu_request_irqs(struct arm_pmu *armpmu)
616{
617 int cpu, err;
618
619 for_each_cpu(cpu, &armpmu->supported_cpus) {
620 err = armpmu_request_irq(armpmu, cpu);
621 if (err)
622 break;
623 }
624
625 return err;
626}
627
628static int armpmu_get_cpu_irq(struct arm_pmu *pmu, int cpu) 593static int armpmu_get_cpu_irq(struct arm_pmu *pmu, int cpu)
629{ 594{
630 struct pmu_hw_events __percpu *hw_events = pmu->hw_events; 595 struct pmu_hw_events __percpu *hw_events = pmu->hw_events;
@@ -647,12 +612,14 @@ static int arm_perf_starting_cpu(unsigned int cpu, struct hlist_node *node)
647 if (pmu->reset) 612 if (pmu->reset)
648 pmu->reset(pmu); 613 pmu->reset(pmu);
649 614
615 per_cpu(cpu_armpmu, cpu) = pmu;
616
650 irq = armpmu_get_cpu_irq(pmu, cpu); 617 irq = armpmu_get_cpu_irq(pmu, cpu);
651 if (irq) { 618 if (irq) {
652 if (irq_is_percpu_devid(irq)) { 619 if (irq_is_percpu_devid(irq))
653 enable_percpu_irq(irq, IRQ_TYPE_NONE); 620 enable_percpu_irq(irq, IRQ_TYPE_NONE);
654 return 0; 621 else
655 } 622 enable_irq(irq);
656 } 623 }
657 624
658 return 0; 625 return 0;
@@ -667,8 +634,14 @@ static int arm_perf_teardown_cpu(unsigned int cpu, struct hlist_node *node)
667 return 0; 634 return 0;
668 635
669 irq = armpmu_get_cpu_irq(pmu, cpu); 636 irq = armpmu_get_cpu_irq(pmu, cpu);
670 if (irq && irq_is_percpu_devid(irq)) 637 if (irq) {
671 disable_percpu_irq(irq); 638 if (irq_is_percpu_devid(irq))
639 disable_percpu_irq(irq);
640 else
641 disable_irq(irq);
642 }
643
644 per_cpu(cpu_armpmu, cpu) = NULL;
672 645
673 return 0; 646 return 0;
674} 647}
@@ -800,18 +773,18 @@ static void cpu_pmu_destroy(struct arm_pmu *cpu_pmu)
800 &cpu_pmu->node); 773 &cpu_pmu->node);
801} 774}
802 775
803struct arm_pmu *armpmu_alloc(void) 776static struct arm_pmu *__armpmu_alloc(gfp_t flags)
804{ 777{
805 struct arm_pmu *pmu; 778 struct arm_pmu *pmu;
806 int cpu; 779 int cpu;
807 780
808 pmu = kzalloc(sizeof(*pmu), GFP_KERNEL); 781 pmu = kzalloc(sizeof(*pmu), flags);
809 if (!pmu) { 782 if (!pmu) {
810 pr_info("failed to allocate PMU device!\n"); 783 pr_info("failed to allocate PMU device!\n");
811 goto out; 784 goto out;
812 } 785 }
813 786
814 pmu->hw_events = alloc_percpu(struct pmu_hw_events); 787 pmu->hw_events = alloc_percpu_gfp(struct pmu_hw_events, flags);
815 if (!pmu->hw_events) { 788 if (!pmu->hw_events) {
816 pr_info("failed to allocate per-cpu PMU data.\n"); 789 pr_info("failed to allocate per-cpu PMU data.\n");
817 goto out_free_pmu; 790 goto out_free_pmu;
@@ -857,6 +830,17 @@ out:
857 return NULL; 830 return NULL;
858} 831}
859 832
833struct arm_pmu *armpmu_alloc(void)
834{
835 return __armpmu_alloc(GFP_KERNEL);
836}
837
838struct arm_pmu *armpmu_alloc_atomic(void)
839{
840 return __armpmu_alloc(GFP_ATOMIC);
841}
842
843
860void armpmu_free(struct arm_pmu *pmu) 844void armpmu_free(struct arm_pmu *pmu)
861{ 845{
862 free_percpu(pmu->hw_events); 846 free_percpu(pmu->hw_events);
diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c
index 705f1a390e31..0f197516d708 100644
--- a/drivers/perf/arm_pmu_acpi.c
+++ b/drivers/perf/arm_pmu_acpi.c
@@ -11,6 +11,8 @@
11#include <linux/acpi.h> 11#include <linux/acpi.h>
12#include <linux/cpumask.h> 12#include <linux/cpumask.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/irq.h>
15#include <linux/irqdesc.h>
14#include <linux/percpu.h> 16#include <linux/percpu.h>
15#include <linux/perf/arm_pmu.h> 17#include <linux/perf/arm_pmu.h>
16 18
@@ -87,7 +89,13 @@ static int arm_pmu_acpi_parse_irqs(void)
87 pr_warn("No ACPI PMU IRQ for CPU%d\n", cpu); 89 pr_warn("No ACPI PMU IRQ for CPU%d\n", cpu);
88 } 90 }
89 91
92 /*
93 * Log and request the IRQ so the core arm_pmu code can manage
94 * it. We'll have to sanity-check IRQs later when we associate
95 * them with their PMUs.
96 */
90 per_cpu(pmu_irqs, cpu) = irq; 97 per_cpu(pmu_irqs, cpu) = irq;
98 armpmu_request_irq(irq, cpu);
91 } 99 }
92 100
93 return 0; 101 return 0;
@@ -127,7 +135,7 @@ static struct arm_pmu *arm_pmu_acpi_find_alloc_pmu(void)
127 return pmu; 135 return pmu;
128 } 136 }
129 137
130 pmu = armpmu_alloc(); 138 pmu = armpmu_alloc_atomic();
131 if (!pmu) { 139 if (!pmu) {
132 pr_warn("Unable to allocate PMU for CPU%d\n", 140 pr_warn("Unable to allocate PMU for CPU%d\n",
133 smp_processor_id()); 141 smp_processor_id());
@@ -140,6 +148,35 @@ static struct arm_pmu *arm_pmu_acpi_find_alloc_pmu(void)
140} 148}
141 149
142/* 150/*
151 * Check whether the new IRQ is compatible with those already associated with
152 * the PMU (e.g. we don't have mismatched PPIs).
153 */
154static bool pmu_irq_matches(struct arm_pmu *pmu, int irq)
155{
156 struct pmu_hw_events __percpu *hw_events = pmu->hw_events;
157 int cpu;
158
159 if (!irq)
160 return true;
161
162 for_each_cpu(cpu, &pmu->supported_cpus) {
163 int other_irq = per_cpu(hw_events->irq, cpu);
164 if (!other_irq)
165 continue;
166
167 if (irq == other_irq)
168 continue;
169 if (!irq_is_percpu_devid(irq) && !irq_is_percpu_devid(other_irq))
170 continue;
171
172 pr_warn("mismatched PPIs detected\n");
173 return false;
174 }
175
176 return true;
177}
178
179/*
143 * This must run before the common arm_pmu hotplug logic, so that we can 180 * This must run before the common arm_pmu hotplug logic, so that we can
144 * associate a CPU and its interrupt before the common code tries to manage the 181 * associate a CPU and its interrupt before the common code tries to manage the
145 * affinity and so on. 182 * affinity and so on.
@@ -164,19 +201,14 @@ static int arm_pmu_acpi_cpu_starting(unsigned int cpu)
164 if (!pmu) 201 if (!pmu)
165 return -ENOMEM; 202 return -ENOMEM;
166 203
167 cpumask_set_cpu(cpu, &pmu->supported_cpus);
168
169 per_cpu(probed_pmus, cpu) = pmu; 204 per_cpu(probed_pmus, cpu) = pmu;
170 205
171 /* 206 if (pmu_irq_matches(pmu, irq)) {
172 * Log and request the IRQ so the core arm_pmu code can manage it. In 207 hw_events = pmu->hw_events;
173 * some situations (e.g. mismatched PPIs), we may fail to request the 208 per_cpu(hw_events->irq, cpu) = irq;
174 * IRQ. However, it may be too late for us to do anything about it. 209 }
175 * The common ARM PMU code will log a warning in this case. 210
176 */ 211 cpumask_set_cpu(cpu, &pmu->supported_cpus);
177 hw_events = pmu->hw_events;
178 per_cpu(hw_events->irq, cpu) = irq;
179 armpmu_request_irq(pmu, cpu);
180 212
181 /* 213 /*
182 * Ideally, we'd probe the PMU here when we find the first matching 214 * Ideally, we'd probe the PMU here when we find the first matching
@@ -247,11 +279,6 @@ static int arm_pmu_acpi_init(void)
247 if (acpi_disabled) 279 if (acpi_disabled)
248 return 0; 280 return 0;
249 281
250 /*
251 * We can't request IRQs yet, since we don't know the cookie value
252 * until we know which CPUs share the same logical PMU. We'll handle
253 * that in arm_pmu_acpi_cpu_starting().
254 */
255 ret = arm_pmu_acpi_parse_irqs(); 282 ret = arm_pmu_acpi_parse_irqs();
256 if (ret) 283 if (ret)
257 return ret; 284 return ret;
diff --git a/drivers/perf/arm_pmu_platform.c b/drivers/perf/arm_pmu_platform.c
index 46501cc79fd7..7729eda5909d 100644
--- a/drivers/perf/arm_pmu_platform.c
+++ b/drivers/perf/arm_pmu_platform.c
@@ -127,13 +127,6 @@ static int pmu_parse_irqs(struct arm_pmu *pmu)
127 pdev->dev.of_node); 127 pdev->dev.of_node);
128 } 128 }
129 129
130 /*
131 * Some platforms have all PMU IRQs OR'd into a single IRQ, with a
132 * special platdata function that attempts to demux them.
133 */
134 if (dev_get_platdata(&pdev->dev))
135 cpumask_setall(&pmu->supported_cpus);
136
137 for (i = 0; i < num_irqs; i++) { 130 for (i = 0; i < num_irqs; i++) {
138 int cpu, irq; 131 int cpu, irq;
139 132
@@ -164,6 +157,36 @@ static int pmu_parse_irqs(struct arm_pmu *pmu)
164 return 0; 157 return 0;
165} 158}
166 159
160static int armpmu_request_irqs(struct arm_pmu *armpmu)
161{
162 struct pmu_hw_events __percpu *hw_events = armpmu->hw_events;
163 int cpu, err;
164
165 for_each_cpu(cpu, &armpmu->supported_cpus) {
166 int irq = per_cpu(hw_events->irq, cpu);
167 if (!irq)
168 continue;
169
170 err = armpmu_request_irq(irq, cpu);
171 if (err)
172 break;
173 }
174
175 return err;
176}
177
178static void armpmu_free_irqs(struct arm_pmu *armpmu)
179{
180 int cpu;
181 struct pmu_hw_events __percpu *hw_events = armpmu->hw_events;
182
183 for_each_cpu(cpu, &armpmu->supported_cpus) {
184 int irq = per_cpu(hw_events->irq, cpu);
185
186 armpmu_free_irq(irq, cpu);
187 }
188}
189
167int arm_pmu_device_probe(struct platform_device *pdev, 190int arm_pmu_device_probe(struct platform_device *pdev,
168 const struct of_device_id *of_table, 191 const struct of_device_id *of_table,
169 const struct pmu_probe_info *probe_table) 192 const struct pmu_probe_info *probe_table)
diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
index af0f44effd44..40036a57d072 100644
--- a/include/linux/perf/arm_pmu.h
+++ b/include/linux/perf/arm_pmu.h
@@ -14,26 +14,10 @@
14 14
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/perf_event.h> 16#include <linux/perf_event.h>
17#include <linux/platform_device.h>
17#include <linux/sysfs.h> 18#include <linux/sysfs.h>
18#include <asm/cputype.h> 19#include <asm/cputype.h>
19 20
20/*
21 * struct arm_pmu_platdata - ARM PMU platform data
22 *
23 * @handle_irq: an optional handler which will be called from the
24 * interrupt and passed the address of the low level handler,
25 * and can be used to implement any platform specific handling
26 * before or after calling it.
27 *
28 * @irq_flags: if non-zero, these flags will be passed to request_irq
29 * when requesting interrupts for this PMU device.
30 */
31struct arm_pmu_platdata {
32 irqreturn_t (*handle_irq)(int irq, void *dev,
33 irq_handler_t pmu_handler);
34 unsigned long irq_flags;
35};
36
37#ifdef CONFIG_ARM_PMU 21#ifdef CONFIG_ARM_PMU
38 22
39/* 23/*
@@ -92,7 +76,6 @@ enum armpmu_attr_groups {
92 76
93struct arm_pmu { 77struct arm_pmu {
94 struct pmu pmu; 78 struct pmu pmu;
95 cpumask_t active_irqs;
96 cpumask_t supported_cpus; 79 cpumask_t supported_cpus;
97 char *name; 80 char *name;
98 irqreturn_t (*handle_irq)(int irq_num, void *dev); 81 irqreturn_t (*handle_irq)(int irq_num, void *dev);
@@ -174,12 +157,11 @@ static inline int arm_pmu_acpi_probe(armpmu_init_fn init_fn) { return 0; }
174 157
175/* Internal functions only for core arm_pmu code */ 158/* Internal functions only for core arm_pmu code */
176struct arm_pmu *armpmu_alloc(void); 159struct arm_pmu *armpmu_alloc(void);
160struct arm_pmu *armpmu_alloc_atomic(void);
177void armpmu_free(struct arm_pmu *pmu); 161void armpmu_free(struct arm_pmu *pmu);
178int armpmu_register(struct arm_pmu *pmu); 162int armpmu_register(struct arm_pmu *pmu);
179int armpmu_request_irqs(struct arm_pmu *armpmu); 163int armpmu_request_irq(int irq, int cpu);
180void armpmu_free_irqs(struct arm_pmu *armpmu); 164void armpmu_free_irq(int irq, int cpu);
181int armpmu_request_irq(struct arm_pmu *armpmu, int cpu);
182void armpmu_free_irq(struct arm_pmu *armpmu, int cpu);
183 165
184#define ARMV8_PMU_PDEV_NAME "armv8-pmu" 166#define ARMV8_PMU_PDEV_NAME "armv8-pmu"
185 167