Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 fixes from Catalin Marinas:
"arm64 and perf fixes:

- build error when accessing MPIDR_HWID_BITMASK from .S

- fix CTR_EL0 field definitions

- remove/disable some kernel messages on user faults (unhandled
signals, unimplemented syscalls)

- fix kernel page fault in unwind_frame() with function graph tracing

- fix perf sleeping while atomic errors when booting with ACPI"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
arm64: fix unwind_frame() for filtered out fn for function graph tracing
arm64: Enforce BBM for huge IO/VMAP mappings
arm64: perf: correct PMUVer probing
arm_pmu: acpi: request IRQs up-front
arm_pmu: note IRQs and PMUs per-cpu
arm_pmu: explicitly enable/disable SPIs at hotplug
arm_pmu: acpi: check for mismatched PPIs
arm_pmu: add armpmu_alloc_atomic()
arm_pmu: fold platform helpers into platform code
arm_pmu: kill arm_pmu_platdata
ARM: ux500: remove PMU IRQ bouncer
arm64: __show_regs: Only resolve kernel symbols when running at EL1
arm64: Remove unimplemented syscall log message
arm64: Disable unhandled signal log messages by default
arm64: cpufeature: Fix CTR_EL0 field definitions
arm64: uaccess: Formalise types for access_ok()
arm64: Fix compilation error while accessing MPIDR_HWID_BITMASK from .S files

+183 -184
-35
arch/arm/mach-ux500/cpu-db8500.c
··· 23 23 #include <linux/of.h> 24 24 #include <linux/of_address.h> 25 25 #include <linux/of_platform.h> 26 - #include <linux/perf/arm_pmu.h> 27 26 #include <linux/regulator/machine.h> 28 27 29 28 #include <asm/outercache.h> ··· 111 112 prcmu_system_reset(0); 112 113 } 113 114 114 - /* 115 - * The PMU IRQ lines of two cores are wired together into a single interrupt. 116 - * Bounce the interrupt to the other core if it's not ours. 117 - */ 118 - static irqreturn_t db8500_pmu_handler(int irq, void *dev, irq_handler_t handler) 119 - { 120 - irqreturn_t ret = handler(irq, dev); 121 - int other = !smp_processor_id(); 122 - 123 - if (ret == IRQ_NONE && cpu_online(other)) 124 - irq_set_affinity(irq, cpumask_of(other)); 125 - 126 - /* 127 - * We should be able to get away with the amount of IRQ_NONEs we give, 128 - * while still having the spurious IRQ detection code kick in if the 129 - * interrupt really starts hitting spuriously. 130 - */ 131 - return ret; 132 - } 133 - 134 - static struct arm_pmu_platdata db8500_pmu_platdata = { 135 - .handle_irq = db8500_pmu_handler, 136 - .irq_flags = IRQF_NOBALANCING | IRQF_NO_THREAD, 137 - }; 138 - 139 - static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { 140 - /* Requires call-back bindings. */ 141 - OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata), 142 - {}, 143 - }; 144 - 145 115 static struct of_dev_auxdata u8540_auxdata_lookup[] __initdata = { 146 116 OF_DEV_AUXDATA("stericsson,db8500-prcmu", 0x80157000, "db8500-prcmu", NULL), 147 117 {}, ··· 133 165 if (of_machine_is_compatible("st-ericsson,u8540")) 134 166 of_platform_populate(NULL, u8500_local_bus_nodes, 135 167 u8540_auxdata_lookup, NULL); 136 - else 137 - of_platform_populate(NULL, u8500_local_bus_nodes, 138 - u8500_auxdata_lookup, NULL); 139 168 } 140 169 141 170 static const char * stericsson_dt_platform_compat[] = {
+1 -1
arch/arm64/include/asm/cputype.h
··· 20 20 21 21 #define MPIDR_UP_BITMASK (0x1 << 30) 22 22 #define MPIDR_MT_BITMASK (0x1 << 24) 23 - #define MPIDR_HWID_BITMASK 0xff00ffffffUL 23 + #define MPIDR_HWID_BITMASK UL(0xff00ffffff) 24 24 25 25 #define MPIDR_LEVEL_BITS_SHIFT 3 26 26 #define MPIDR_LEVEL_BITS (1 << MPIDR_LEVEL_BITS_SHIFT)
+1 -1
arch/arm64/include/asm/stacktrace.h
··· 28 28 unsigned long fp; 29 29 unsigned long pc; 30 30 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 31 - unsigned int graph; 31 + int graph; 32 32 #endif 33 33 }; 34 34
+6 -6
arch/arm64/include/asm/uaccess.h
··· 72 72 * This is equivalent to the following test: 73 73 * (u65)addr + (u65)size <= (u65)current->addr_limit + 1 74 74 */ 75 - static inline unsigned long __range_ok(unsigned long addr, unsigned long size) 75 + static 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 79 __chk_user_ptr(addr); 80 80 asm volatile( 81 81 // A + B <= C + 1 for all A,B,C, in four easy steps: 82 82 // 1: X = A + B; X' = X % 2^64 83 - " adds %0, %0, %2\n" 83 + " adds %0, %3, %2\n" 84 84 // 2: Set C = 0 if X > 2^64, to guarantee X' > C in step 4 85 85 " csel %1, xzr, %1, hi\n" 86 86 // 3: Set X' = ~0 if X >= 2^64. For X == 2^64, this decrements X' ··· 92 92 // testing X' - C == 0, subject to the previous adjustments. 93 93 " sbcs xzr, %0, %1\n" 94 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 104 */ 105 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 108 #define user_addr_max get_fs 109 109 110 110 #define _ASM_EXTABLE(from, to) \
+3 -1
arch/arm64/kernel/armv8_deprecated.c
··· 370 370 static int swp_handler(struct pt_regs *regs, u32 instr) 371 371 { 372 372 u32 destreg, data, type, address = 0; 373 + const void __user *user_ptr; 373 374 int rn, rt2, res = 0; 374 375 375 376 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs->pc); ··· 402 401 aarch32_insn_extract_reg_num(instr, A32_RT2_OFFSET), data); 403 402 404 403 /* Check access in reasonable access range for both SWP and SWPB */ 405 - if (!access_ok(VERIFY_WRITE, (address & ~3), 4)) { 404 + user_ptr = (const void __user *)(unsigned long)(address & ~3); 405 + if (!access_ok(VERIFY_WRITE, user_ptr, 4)) { 406 406 pr_debug("SWP{B} emulation: access to 0x%08x not allowed!\n", 407 407 address); 408 408 goto fault;
+4 -2
arch/arm64/kernel/cpufeature.c
··· 199 199 }; 200 200 201 201 static 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 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 207 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 1), /* DminLine */ 206 208 /* 207 209 * Linux can handle differing I-cache policies. Userspace JITs will
+2 -2
arch/arm64/kernel/perf_event.c
··· 908 908 int pmuver; 909 909 910 910 dfr0 = read_sysreg(id_aa64dfr0_el1); 911 - pmuver = cpuid_feature_extract_signed_field(dfr0, 911 + pmuver = cpuid_feature_extract_unsigned_field(dfr0, 912 912 ID_AA64DFR0_PMUVER_SHIFT); 913 - if (pmuver < 1) 913 + if (pmuver == 0xf || pmuver == 0) 914 914 return; 915 915 916 916 probe->present = true;
+9 -2
arch/arm64/kernel/process.c
··· 220 220 221 221 show_regs_print_info(KERN_DEFAULT); 222 222 print_pstate(regs); 223 - printk("pc : %pS\n", (void *)regs->pc); 224 - printk("lr : %pS\n", (void *)lr); 223 + 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 232 printk("sp : %016llx\n", sp); 226 233 227 234 i = top_reg;
+5
arch/arm64/kernel/stacktrace.c
··· 59 59 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 60 60 if (tsk->ret_stack && 61 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 68 * This is a case where function graph tracer has 64 69 * modified a return address (LR) in a stack frame
+1 -1
arch/arm64/kernel/sys_compat.c
··· 57 57 if (end < start || flags) 58 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 61 return -EFAULT; 62 62 63 63 return __do_compat_cache_op(start, end);
+1 -1
arch/arm64/kernel/time.c
··· 52 52 frame.fp = regs->regs[29]; 53 53 frame.pc = regs->pc; 54 54 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 55 - frame.graph = -1; /* no task info */ 55 + frame.graph = current->curr_ret_stack; 56 56 #endif 57 57 do { 58 58 int ret = unwind_frame(NULL, &frame);
+1 -9
arch/arm64/kernel/traps.c
··· 57 57 "Error" 58 58 }; 59 59 60 - int show_unhandled_signals = 1; 60 + int show_unhandled_signals = 0; 61 61 62 62 static void dump_backtrace_entry(unsigned long where) 63 63 { ··· 525 525 return ret; 526 526 } 527 527 #endif 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 528 537 529 return sys_ni_syscall(); 538 530 }
+10
arch/arm64/mm/mmu.c
··· 933 933 { 934 934 pgprot_t sect_prot = __pgprot(PUD_TYPE_SECT | 935 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 941 BUG_ON(phys & ~PUD_MASK); 937 942 set_pud(pudp, pfn_pud(__phys_to_pfn(phys), sect_prot)); 938 943 return 1; ··· 947 942 { 948 943 pgprot_t sect_prot = __pgprot(PMD_TYPE_SECT | 949 944 pgprot_val(mk_sect_prot(prot))); 945 + 946 + /* ioremap_page_range doesn't honour BBM */ 947 + if (pmd_present(READ_ONCE(*pmdp))) 948 + return 0; 949 + 950 950 BUG_ON(phys & ~PMD_MASK); 951 951 set_pmd(pmdp, pfn_pmd(__phys_to_pfn(phys), sect_prot)); 952 952 return 1;
+61 -77
drivers/perf/arm_pmu.c
··· 17 17 #include <linux/export.h> 18 18 #include <linux/kernel.h> 19 19 #include <linux/perf/arm_pmu.h> 20 - #include <linux/platform_device.h> 21 20 #include <linux/slab.h> 22 21 #include <linux/sched/clock.h> 23 22 #include <linux/spinlock.h> ··· 24 25 #include <linux/irqdesc.h> 25 26 26 27 #include <asm/irq_regs.h> 28 + 29 + static DEFINE_PER_CPU(struct arm_pmu *, cpu_armpmu); 30 + static DEFINE_PER_CPU(int, cpu_irq); 27 31 28 32 static int 29 33 armpmu_map_cache_event(const unsigned (*cache_map) ··· 322 320 return 0; 323 321 } 324 322 325 - static struct arm_pmu_platdata *armpmu_get_platdata(struct arm_pmu *armpmu) 326 - { 327 - struct platform_device *pdev = armpmu->plat_device; 328 - 329 - return pdev ? dev_get_platdata(&pdev->dev) : NULL; 330 - } 331 - 332 323 static irqreturn_t armpmu_dispatch_irq(int irq, void *dev) 333 324 { 334 325 struct arm_pmu *armpmu; 335 - struct arm_pmu_platdata *plat; 336 326 int ret; 337 327 u64 start_clock, finish_clock; 338 328 ··· 335 341 * dereference. 336 342 */ 337 343 armpmu = *(void **)dev; 338 - 339 - plat = armpmu_get_platdata(armpmu); 344 + if (WARN_ON_ONCE(!armpmu)) 345 + return IRQ_NONE; 340 346 341 347 start_clock = sched_clock(); 342 - if (plat && plat->handle_irq) 343 - ret = plat->handle_irq(irq, armpmu, armpmu->handle_irq); 344 - else 345 - ret = armpmu->handle_irq(irq, armpmu); 348 + ret = armpmu->handle_irq(irq, armpmu); 346 349 finish_clock = sched_clock(); 347 350 348 351 perf_sample_event_took(finish_clock - start_clock); ··· 522 531 } 523 532 EXPORT_SYMBOL_GPL(perf_num_counters); 524 533 525 - void armpmu_free_irq(struct arm_pmu *armpmu, int cpu) 534 + static int armpmu_count_irq_users(const int irq) 526 535 { 527 - struct pmu_hw_events __percpu *hw_events = armpmu->hw_events; 528 - int irq = per_cpu(hw_events->irq, cpu); 536 + int cpu, count = 0; 529 537 530 - if (!cpumask_test_and_clear_cpu(cpu, &armpmu->active_irqs)) 531 - return; 532 - 533 - if (irq_is_percpu_devid(irq)) { 534 - free_percpu_irq(irq, &hw_events->percpu_pmu); 535 - cpumask_clear(&armpmu->active_irqs); 536 - return; 538 + for_each_possible_cpu(cpu) { 539 + if (per_cpu(cpu_irq, cpu) == irq) 540 + count++; 537 541 } 538 542 539 - free_irq(irq, per_cpu_ptr(&hw_events->percpu_pmu, cpu)); 543 + return count; 540 544 } 541 545 542 - void armpmu_free_irqs(struct arm_pmu *armpmu) 546 + void armpmu_free_irq(int irq, int cpu) 543 547 { 544 - int cpu; 548 + if (per_cpu(cpu_irq, cpu) == 0) 549 + return; 550 + if (WARN_ON(irq != per_cpu(cpu_irq, cpu))) 551 + return; 545 552 546 - for_each_cpu(cpu, &armpmu->supported_cpus) 547 - armpmu_free_irq(armpmu, cpu); 553 + if (!irq_is_percpu_devid(irq)) 554 + free_irq(irq, per_cpu_ptr(&cpu_armpmu, cpu)); 555 + else if (armpmu_count_irq_users(irq) == 1) 556 + free_percpu_irq(irq, &cpu_armpmu); 557 + 558 + per_cpu(cpu_irq, cpu) = 0; 548 559 } 549 560 550 - int armpmu_request_irq(struct arm_pmu *armpmu, int cpu) 561 + int armpmu_request_irq(int irq, int cpu) 551 562 { 552 563 int err = 0; 553 - struct pmu_hw_events __percpu *hw_events = armpmu->hw_events; 554 564 const irq_handler_t handler = armpmu_dispatch_irq; 555 - int irq = per_cpu(hw_events->irq, cpu); 556 565 if (!irq) 557 566 return 0; 558 567 559 - if (irq_is_percpu_devid(irq) && cpumask_empty(&armpmu->active_irqs)) { 560 - err = request_percpu_irq(irq, handler, "arm-pmu", 561 - &hw_events->percpu_pmu); 562 - } else if (irq_is_percpu_devid(irq)) { 563 - int other_cpu = cpumask_first(&armpmu->active_irqs); 564 - int other_irq = per_cpu(hw_events->irq, other_cpu); 565 - 566 - if (irq != other_irq) { 567 - pr_warn("mismatched PPIs detected.\n"); 568 - err = -EINVAL; 569 - goto err_out; 570 - } 571 - } else { 572 - struct arm_pmu_platdata *platdata = armpmu_get_platdata(armpmu); 568 + if (!irq_is_percpu_devid(irq)) { 573 569 unsigned long irq_flags; 574 570 575 571 err = irq_force_affinity(irq, cpumask_of(cpu)); ··· 567 589 goto err_out; 568 590 } 569 591 570 - if (platdata && platdata->irq_flags) { 571 - irq_flags = platdata->irq_flags; 572 - } else { 573 - irq_flags = IRQF_PERCPU | 574 - IRQF_NOBALANCING | 575 - IRQF_NO_THREAD; 576 - } 592 + irq_flags = IRQF_PERCPU | 593 + IRQF_NOBALANCING | 594 + IRQF_NO_THREAD; 577 595 596 + irq_set_status_flags(irq, IRQ_NOAUTOEN); 578 597 err = request_irq(irq, handler, irq_flags, "arm-pmu", 579 - per_cpu_ptr(&hw_events->percpu_pmu, cpu)); 598 + per_cpu_ptr(&cpu_armpmu, cpu)); 599 + } else if (armpmu_count_irq_users(irq) == 0) { 600 + err = request_percpu_irq(irq, handler, "arm-pmu", 601 + &cpu_armpmu); 580 602 } 581 603 582 604 if (err) 583 605 goto err_out; 584 606 585 - cpumask_set_cpu(cpu, &armpmu->active_irqs); 607 + per_cpu(cpu_irq, cpu) = irq; 586 608 return 0; 587 609 588 610 err_out: 589 611 pr_err("unable to request IRQ%d for ARM PMU counters\n", irq); 590 - return err; 591 - } 592 - 593 - int armpmu_request_irqs(struct arm_pmu *armpmu) 594 - { 595 - int cpu, err; 596 - 597 - for_each_cpu(cpu, &armpmu->supported_cpus) { 598 - err = armpmu_request_irq(armpmu, cpu); 599 - if (err) 600 - break; 601 - } 602 - 603 612 return err; 604 613 } 605 614 ··· 612 647 if (pmu->reset) 613 648 pmu->reset(pmu); 614 649 650 + per_cpu(cpu_armpmu, cpu) = pmu; 651 + 615 652 irq = armpmu_get_cpu_irq(pmu, cpu); 616 653 if (irq) { 617 - if (irq_is_percpu_devid(irq)) { 654 + if (irq_is_percpu_devid(irq)) 618 655 enable_percpu_irq(irq, IRQ_TYPE_NONE); 619 - return 0; 620 - } 656 + else 657 + enable_irq(irq); 621 658 } 622 659 623 660 return 0; ··· 634 667 return 0; 635 668 636 669 irq = armpmu_get_cpu_irq(pmu, cpu); 637 - if (irq && irq_is_percpu_devid(irq)) 638 - disable_percpu_irq(irq); 670 + if (irq) { 671 + if (irq_is_percpu_devid(irq)) 672 + disable_percpu_irq(irq); 673 + else 674 + disable_irq(irq); 675 + } 676 + 677 + per_cpu(cpu_armpmu, cpu) = NULL; 639 678 640 679 return 0; 641 680 } ··· 773 800 &cpu_pmu->node); 774 801 } 775 802 776 - struct arm_pmu *armpmu_alloc(void) 803 + static struct arm_pmu *__armpmu_alloc(gfp_t flags) 777 804 { 778 805 struct arm_pmu *pmu; 779 806 int cpu; 780 807 781 - pmu = kzalloc(sizeof(*pmu), GFP_KERNEL); 808 + pmu = kzalloc(sizeof(*pmu), flags); 782 809 if (!pmu) { 783 810 pr_info("failed to allocate PMU device!\n"); 784 811 goto out; 785 812 } 786 813 787 - pmu->hw_events = alloc_percpu(struct pmu_hw_events); 814 + pmu->hw_events = alloc_percpu_gfp(struct pmu_hw_events, flags); 788 815 if (!pmu->hw_events) { 789 816 pr_info("failed to allocate per-cpu PMU data.\n"); 790 817 goto out_free_pmu; ··· 829 856 out: 830 857 return NULL; 831 858 } 859 + 860 + struct arm_pmu *armpmu_alloc(void) 861 + { 862 + return __armpmu_alloc(GFP_KERNEL); 863 + } 864 + 865 + struct arm_pmu *armpmu_alloc_atomic(void) 866 + { 867 + return __armpmu_alloc(GFP_ATOMIC); 868 + } 869 + 832 870 833 871 void armpmu_free(struct arm_pmu *pmu) 834 872 {
+44 -17
drivers/perf/arm_pmu_acpi.c
··· 11 11 #include <linux/acpi.h> 12 12 #include <linux/cpumask.h> 13 13 #include <linux/init.h> 14 + #include <linux/irq.h> 15 + #include <linux/irqdesc.h> 14 16 #include <linux/percpu.h> 15 17 #include <linux/perf/arm_pmu.h> 16 18 ··· 89 87 pr_warn("No ACPI PMU IRQ for CPU%d\n", cpu); 90 88 } 91 89 90 + /* 91 + * Log and request the IRQ so the core arm_pmu code can manage 92 + * it. We'll have to sanity-check IRQs later when we associate 93 + * them with their PMUs. 94 + */ 92 95 per_cpu(pmu_irqs, cpu) = irq; 96 + armpmu_request_irq(irq, cpu); 93 97 } 94 98 95 99 return 0; ··· 135 127 return pmu; 136 128 } 137 129 138 - pmu = armpmu_alloc(); 130 + pmu = armpmu_alloc_atomic(); 139 131 if (!pmu) { 140 132 pr_warn("Unable to allocate PMU for CPU%d\n", 141 133 smp_processor_id()); ··· 145 137 pmu->acpi_cpuid = cpuid; 146 138 147 139 return pmu; 140 + } 141 + 142 + /* 143 + * Check whether the new IRQ is compatible with those already associated with 144 + * the PMU (e.g. we don't have mismatched PPIs). 145 + */ 146 + static bool pmu_irq_matches(struct arm_pmu *pmu, int irq) 147 + { 148 + struct pmu_hw_events __percpu *hw_events = pmu->hw_events; 149 + int cpu; 150 + 151 + if (!irq) 152 + return true; 153 + 154 + for_each_cpu(cpu, &pmu->supported_cpus) { 155 + int other_irq = per_cpu(hw_events->irq, cpu); 156 + if (!other_irq) 157 + continue; 158 + 159 + if (irq == other_irq) 160 + continue; 161 + if (!irq_is_percpu_devid(irq) && !irq_is_percpu_devid(other_irq)) 162 + continue; 163 + 164 + pr_warn("mismatched PPIs detected\n"); 165 + return false; 166 + } 167 + 168 + return true; 148 169 } 149 170 150 171 /* ··· 201 164 if (!pmu) 202 165 return -ENOMEM; 203 166 204 - cpumask_set_cpu(cpu, &pmu->supported_cpus); 205 - 206 167 per_cpu(probed_pmus, cpu) = pmu; 207 168 208 - /* 209 - * Log and request the IRQ so the core arm_pmu code can manage it. In 210 - * some situations (e.g. mismatched PPIs), we may fail to request the 211 - * IRQ. However, it may be too late for us to do anything about it. 212 - * The common ARM PMU code will log a warning in this case. 213 - */ 214 - hw_events = pmu->hw_events; 215 - per_cpu(hw_events->irq, cpu) = irq; 216 - armpmu_request_irq(pmu, cpu); 169 + if (pmu_irq_matches(pmu, irq)) { 170 + hw_events = pmu->hw_events; 171 + per_cpu(hw_events->irq, cpu) = irq; 172 + } 173 + 174 + cpumask_set_cpu(cpu, &pmu->supported_cpus); 217 175 218 176 /* 219 177 * Ideally, we'd probe the PMU here when we find the first matching ··· 279 247 if (acpi_disabled) 280 248 return 0; 281 249 282 - /* 283 - * We can't request IRQs yet, since we don't know the cookie value 284 - * until we know which CPUs share the same logical PMU. We'll handle 285 - * that in arm_pmu_acpi_cpu_starting(). 286 - */ 287 250 ret = arm_pmu_acpi_parse_irqs(); 288 251 if (ret) 289 252 return ret;
+30 -7
drivers/perf/arm_pmu_platform.c
··· 127 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 130 for (i = 0; i < num_irqs; i++) { 138 131 int cpu, irq; 139 132 ··· 155 162 } 156 163 157 164 return 0; 165 + } 166 + 167 + static int armpmu_request_irqs(struct arm_pmu *armpmu) 168 + { 169 + struct pmu_hw_events __percpu *hw_events = armpmu->hw_events; 170 + int cpu, err; 171 + 172 + for_each_cpu(cpu, &armpmu->supported_cpus) { 173 + int irq = per_cpu(hw_events->irq, cpu); 174 + if (!irq) 175 + continue; 176 + 177 + err = armpmu_request_irq(irq, cpu); 178 + if (err) 179 + break; 180 + } 181 + 182 + return err; 183 + } 184 + 185 + static void armpmu_free_irqs(struct arm_pmu *armpmu) 186 + { 187 + int cpu; 188 + struct pmu_hw_events __percpu *hw_events = armpmu->hw_events; 189 + 190 + for_each_cpu(cpu, &armpmu->supported_cpus) { 191 + int irq = per_cpu(hw_events->irq, cpu); 192 + 193 + armpmu_free_irq(irq, cpu); 194 + } 158 195 } 159 196 160 197 int arm_pmu_device_probe(struct platform_device *pdev,
+4 -22
include/linux/perf/arm_pmu.h
··· 14 14 15 15 #include <linux/interrupt.h> 16 16 #include <linux/perf_event.h> 17 + #include <linux/platform_device.h> 17 18 #include <linux/sysfs.h> 18 19 #include <asm/cputype.h> 19 - 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 - */ 31 - struct 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 20 37 21 #ifdef CONFIG_ARM_PMU 38 22 ··· 76 92 77 93 struct arm_pmu { 78 94 struct pmu pmu; 79 - cpumask_t active_irqs; 80 95 cpumask_t supported_cpus; 81 96 char *name; 82 97 irqreturn_t (*handle_irq)(int irq_num, void *dev); ··· 157 174 158 175 /* Internal functions only for core arm_pmu code */ 159 176 struct arm_pmu *armpmu_alloc(void); 177 + struct arm_pmu *armpmu_alloc_atomic(void); 160 178 void armpmu_free(struct arm_pmu *pmu); 161 179 int armpmu_register(struct arm_pmu *pmu); 162 - int armpmu_request_irqs(struct arm_pmu *armpmu); 163 - void armpmu_free_irqs(struct arm_pmu *armpmu); 164 - int armpmu_request_irq(struct arm_pmu *armpmu, int cpu); 165 - void armpmu_free_irq(struct arm_pmu *armpmu, int cpu); 180 + int armpmu_request_irq(int irq, int cpu); 181 + void armpmu_free_irq(int irq, int cpu); 166 182 167 183 #define ARMV8_PMU_PDEV_NAME "armv8-pmu" 168 184