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 Will Deacon:
"I'd been collecting these whilst we debugged a CPU hotplug failure,
but we ended up diagnosing that one to tglx, who has taken a fix via
the -tip tree separately.

We're seeing some NFS issues that we haven't gotten to the bottom of
yet, and we've uncovered some issues with our backtracing too so there
might be another fixes pull before we're done.

Summary:

- Ensure we have a guard page after the kernel image in vmalloc

- Fix incorrect prefetch stride in copy_page

- Ensure irqs are disabled in die()

- Fix for event group validation in QCOM L2 PMU driver

- Fix requesting of PMU IRQs on AMD Seattle

- Minor cleanups and fixes"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
arm64: mmu: Place guard page after mapping of kernel image
drivers/perf: arm_pmu: Request PMU SPIs with IRQF_PER_CPU
arm64: sysreg: Fix unprotected macro argmuent in write_sysreg
perf: qcom_l2: fix column exclusion check
arm64/lib: copy_page: use consistent prefetch stride
arm64/numa: Drop duplicate message
perf: Convert to using %pOF instead of full_name
arm64: Convert to using %pOF instead of full_name
arm64: traps: disable irq in die()
arm64: atomics: Remove '&' from '+&' asm constraint in lse atomics
arm64: uaccess: Remove redundant __force from addr cast in __range_ok

+84 -61
+1
arch/arm/mach-ux500/cpu-db8500.c
··· 133 133 134 134 static struct arm_pmu_platdata db8500_pmu_platdata = { 135 135 .handle_irq = db8500_pmu_handler, 136 + .irq_flags = IRQF_NOBALANCING | IRQF_NO_THREAD, 136 137 }; 137 138 138 139 static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
+1 -1
arch/arm64/include/asm/atomic_lse.h
··· 435 435 " sub x30, x30, %[ret]\n" 436 436 " cbnz x30, 1b\n" 437 437 "2:") 438 - : [ret] "+&r" (x0), [v] "+Q" (v->counter) 438 + : [ret] "+r" (x0), [v] "+Q" (v->counter) 439 439 : 440 440 : __LL_SC_CLOBBERS, "cc", "memory"); 441 441
+2 -2
arch/arm64/include/asm/sysreg.h
··· 492 492 * the "%x0" template means XZR. 493 493 */ 494 494 #define write_sysreg(v, r) do { \ 495 - u64 __val = (u64)v; \ 495 + u64 __val = (u64)(v); \ 496 496 asm volatile("msr " __stringify(r) ", %x0" \ 497 497 : : "rZ" (__val)); \ 498 498 } while (0) ··· 508 508 }) 509 509 510 510 #define write_sysreg_s(v, r) do { \ 511 - u64 __val = (u64)v; \ 511 + u64 __val = (u64)(v); \ 512 512 asm volatile("msr_s " __stringify(r) ", %x0" : : "rZ" (__val)); \ 513 513 } while (0) 514 514
+1 -1
arch/arm64/include/asm/uaccess.h
··· 69 69 */ 70 70 #define __range_ok(addr, size) \ 71 71 ({ \ 72 - unsigned long __addr = (unsigned long __force)(addr); \ 72 + unsigned long __addr = (unsigned long)(addr); \ 73 73 unsigned long flag, roksum; \ 74 74 __chk_user_ptr(addr); \ 75 75 asm("adds %1, %1, %3; ccmp %1, %4, #2, cc; cset %0, ls" \
+2 -2
arch/arm64/kernel/cpu_ops.c
··· 82 82 * Don't warn spuriously. 83 83 */ 84 84 if (cpu != 0) 85 - pr_err("%s: missing enable-method property\n", 86 - dn->full_name); 85 + pr_err("%pOF: missing enable-method property\n", 86 + dn); 87 87 } 88 88 } else { 89 89 enable_method = acpi_get_enable_method(cpu);
+6 -6
arch/arm64/kernel/smp.c
··· 469 469 */ 470 470 cell = of_get_property(dn, "reg", NULL); 471 471 if (!cell) { 472 - pr_err("%s: missing reg property\n", dn->full_name); 472 + pr_err("%pOF: missing reg property\n", dn); 473 473 return INVALID_HWID; 474 474 } 475 475 ··· 478 478 * Non affinity bits must be set to 0 in the DT 479 479 */ 480 480 if (hwid & ~MPIDR_HWID_BITMASK) { 481 - pr_err("%s: invalid reg property\n", dn->full_name); 481 + pr_err("%pOF: invalid reg property\n", dn); 482 482 return INVALID_HWID; 483 483 } 484 484 return hwid; ··· 627 627 goto next; 628 628 629 629 if (is_mpidr_duplicate(cpu_count, hwid)) { 630 - pr_err("%s: duplicate cpu reg properties in the DT\n", 631 - dn->full_name); 630 + pr_err("%pOF: duplicate cpu reg properties in the DT\n", 631 + dn); 632 632 goto next; 633 633 } 634 634 ··· 640 640 */ 641 641 if (hwid == cpu_logical_map(0)) { 642 642 if (bootcpu_valid) { 643 - pr_err("%s: duplicate boot cpu reg property in DT\n", 644 - dn->full_name); 643 + pr_err("%pOF: duplicate boot cpu reg property in DT\n", 644 + dn); 645 645 goto next; 646 646 } 647 647
+11 -11
arch/arm64/kernel/topology.c
··· 45 45 } 46 46 } 47 47 48 - pr_crit("Unable to find CPU node for %s\n", cpu_node->full_name); 48 + pr_crit("Unable to find CPU node for %pOF\n", cpu_node); 49 49 50 50 of_node_put(cpu_node); 51 51 return -1; ··· 71 71 cpu_topology[cpu].core_id = core_id; 72 72 cpu_topology[cpu].thread_id = i; 73 73 } else { 74 - pr_err("%s: Can't get CPU for thread\n", 75 - t->full_name); 74 + pr_err("%pOF: Can't get CPU for thread\n", 75 + t); 76 76 of_node_put(t); 77 77 return -EINVAL; 78 78 } ··· 84 84 cpu = get_cpu_for_node(core); 85 85 if (cpu >= 0) { 86 86 if (!leaf) { 87 - pr_err("%s: Core has both threads and CPU\n", 88 - core->full_name); 87 + pr_err("%pOF: Core has both threads and CPU\n", 88 + core); 89 89 return -EINVAL; 90 90 } 91 91 92 92 cpu_topology[cpu].cluster_id = cluster_id; 93 93 cpu_topology[cpu].core_id = core_id; 94 94 } else if (leaf) { 95 - pr_err("%s: Can't get CPU for leaf core\n", core->full_name); 95 + pr_err("%pOF: Can't get CPU for leaf core\n", core); 96 96 return -EINVAL; 97 97 } 98 98 ··· 137 137 has_cores = true; 138 138 139 139 if (depth == 0) { 140 - pr_err("%s: cpu-map children should be clusters\n", 141 - c->full_name); 140 + pr_err("%pOF: cpu-map children should be clusters\n", 141 + c); 142 142 of_node_put(c); 143 143 return -EINVAL; 144 144 } ··· 146 146 if (leaf) { 147 147 ret = parse_core(c, cluster_id, core_id++); 148 148 } else { 149 - pr_err("%s: Non-leaf cluster with core %s\n", 150 - cluster->full_name, name); 149 + pr_err("%pOF: Non-leaf cluster with core %s\n", 150 + cluster, name); 151 151 ret = -EINVAL; 152 152 } 153 153 ··· 159 159 } while (c); 160 160 161 161 if (leaf && !has_cores) 162 - pr_warn("%s: empty cluster\n", cluster->full_name); 162 + pr_warn("%pOF: empty cluster\n", cluster); 163 163 164 164 if (leaf) 165 165 cluster_id++;
+6 -2
arch/arm64/kernel/traps.c
··· 274 274 void die(const char *str, struct pt_regs *regs, int err) 275 275 { 276 276 int ret; 277 + unsigned long flags; 278 + 279 + raw_spin_lock_irqsave(&die_lock, flags); 277 280 278 281 oops_enter(); 279 282 280 - raw_spin_lock_irq(&die_lock); 281 283 console_verbose(); 282 284 bust_spinlocks(1); 283 285 ret = __die(str, err, regs); ··· 289 287 290 288 bust_spinlocks(0); 291 289 add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); 292 - raw_spin_unlock_irq(&die_lock); 293 290 oops_exit(); 294 291 295 292 if (in_interrupt()) 296 293 panic("Fatal exception in interrupt"); 297 294 if (panic_on_oops) 298 295 panic("Fatal exception"); 296 + 297 + raw_spin_unlock_irqrestore(&die_lock, flags); 298 + 299 299 if (ret != NOTIFY_STOP) 300 300 do_exit(SIGSEGV); 301 301 }
+5 -4
arch/arm64/lib/copy_page.S
··· 30 30 */ 31 31 ENTRY(copy_page) 32 32 alternative_if ARM64_HAS_NO_HW_PREFETCH 33 - # Prefetch two cache lines ahead. 34 - prfm pldl1strm, [x1, #128] 35 - prfm pldl1strm, [x1, #256] 33 + // Prefetch three cache lines ahead. 34 + prfm pldl1strm, [x1, #128] 35 + prfm pldl1strm, [x1, #256] 36 + prfm pldl1strm, [x1, #384] 36 37 alternative_else_nop_endif 37 38 38 39 ldp x2, x3, [x1] ··· 51 50 subs x18, x18, #128 52 51 53 52 alternative_if ARM64_HAS_NO_HW_PREFETCH 54 - prfm pldl1strm, [x1, #384] 53 + prfm pldl1strm, [x1, #384] 55 54 alternative_else_nop_endif 56 55 57 56 stnp x2, x3, [x0]
+11 -7
arch/arm64/mm/mmu.c
··· 496 496 497 497 static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end, 498 498 pgprot_t prot, struct vm_struct *vma, 499 - int flags) 499 + int flags, unsigned long vm_flags) 500 500 { 501 501 phys_addr_t pa_start = __pa_symbol(va_start); 502 502 unsigned long size = va_end - va_start; ··· 507 507 __create_pgd_mapping(pgd, pa_start, (unsigned long)va_start, size, prot, 508 508 early_pgtable_alloc, flags); 509 509 510 + if (!(vm_flags & VM_NO_GUARD)) 511 + size += PAGE_SIZE; 512 + 510 513 vma->addr = va_start; 511 514 vma->phys_addr = pa_start; 512 515 vma->size = size; 513 - vma->flags = VM_MAP; 516 + vma->flags = VM_MAP | vm_flags; 514 517 vma->caller = __builtin_return_address(0); 515 518 516 519 vm_area_add_early(vma); ··· 544 541 * Only rodata will be remapped with different permissions later on, 545 542 * all other segments are allowed to use contiguous mappings. 546 543 */ 547 - map_kernel_segment(pgd, _text, _etext, text_prot, &vmlinux_text, 0); 544 + map_kernel_segment(pgd, _text, _etext, text_prot, &vmlinux_text, 0, 545 + VM_NO_GUARD); 548 546 map_kernel_segment(pgd, __start_rodata, __inittext_begin, PAGE_KERNEL, 549 - &vmlinux_rodata, NO_CONT_MAPPINGS); 547 + &vmlinux_rodata, NO_CONT_MAPPINGS, VM_NO_GUARD); 550 548 map_kernel_segment(pgd, __inittext_begin, __inittext_end, text_prot, 551 - &vmlinux_inittext, 0); 549 + &vmlinux_inittext, 0, VM_NO_GUARD); 552 550 map_kernel_segment(pgd, __initdata_begin, __initdata_end, PAGE_KERNEL, 553 - &vmlinux_initdata, 0); 554 - map_kernel_segment(pgd, _data, _end, PAGE_KERNEL, &vmlinux_data, 0); 551 + &vmlinux_initdata, 0, VM_NO_GUARD); 552 + map_kernel_segment(pgd, _data, _end, PAGE_KERNEL, &vmlinux_data, 0, 0); 555 553 556 554 if (!pgd_val(*pgd_offset_raw(pgd, FIXADDR_START))) { 557 555 /*
+1 -6
arch/arm64/mm/numa.c
··· 208 208 } 209 209 210 210 node_set(nid, numa_nodes_parsed); 211 - pr_info("Adding memblock [0x%llx - 0x%llx] on node %d\n", 212 - start, (end - 1), nid); 213 211 return ret; 214 212 } 215 213 ··· 221 223 void *nd; 222 224 int tnid; 223 225 224 - if (start_pfn < end_pfn) 225 - pr_info("Initmem setup node %d [mem %#010Lx-%#010Lx]\n", nid, 226 - start_pfn << PAGE_SHIFT, (end_pfn << PAGE_SHIFT) - 1); 227 - else 226 + if (start_pfn >= end_pfn) 228 227 pr_info("Initmem setup node %d [<memory-less node>]\n", nid); 229 228 230 229 nd_pa = memblock_alloc_try_nid(nd_size, SMP_CACHE_BYTES, nid);
+27 -14
drivers/perf/arm_pmu.c
··· 569 569 if (irq != other_irq) { 570 570 pr_warn("mismatched PPIs detected.\n"); 571 571 err = -EINVAL; 572 + goto err_out; 572 573 } 573 574 } else { 574 - err = request_irq(irq, handler, 575 - IRQF_NOBALANCING | IRQF_NO_THREAD, "arm-pmu", 575 + struct arm_pmu_platdata *platdata = armpmu_get_platdata(armpmu); 576 + unsigned long irq_flags; 577 + 578 + err = irq_force_affinity(irq, cpumask_of(cpu)); 579 + 580 + if (err && num_possible_cpus() > 1) { 581 + pr_warn("unable to set irq affinity (irq=%d, cpu=%u)\n", 582 + irq, cpu); 583 + goto err_out; 584 + } 585 + 586 + if (platdata && platdata->irq_flags) { 587 + irq_flags = platdata->irq_flags; 588 + } else { 589 + irq_flags = IRQF_PERCPU | 590 + IRQF_NOBALANCING | 591 + IRQF_NO_THREAD; 592 + } 593 + 594 + err = request_irq(irq, handler, irq_flags, "arm-pmu", 576 595 per_cpu_ptr(&hw_events->percpu_pmu, cpu)); 577 596 } 578 597 579 - if (err) { 580 - pr_err("unable to request IRQ%d for ARM PMU counters\n", 581 - irq); 582 - return err; 583 - } 598 + if (err) 599 + goto err_out; 584 600 585 601 cpumask_set_cpu(cpu, &armpmu->active_irqs); 586 - 587 602 return 0; 603 + 604 + err_out: 605 + pr_err("unable to request IRQ%d for ARM PMU counters\n", irq); 606 + return err; 588 607 } 589 608 590 609 int armpmu_request_irqs(struct arm_pmu *armpmu) ··· 646 627 if (irq_is_percpu(irq)) { 647 628 enable_percpu_irq(irq, IRQ_TYPE_NONE); 648 629 return 0; 649 - } 650 - 651 - if (irq_force_affinity(irq, cpumask_of(cpu)) && 652 - num_possible_cpus() > 1) { 653 - pr_warn("unable to set irq affinity (irq=%d, cpu=%u)\n", 654 - irq, cpu); 655 630 } 656 631 } 657 632
+4 -5
drivers/perf/arm_pmu_platform.c
··· 131 131 } 132 132 133 133 if (!pmu_has_irq_affinity(pdev->dev.of_node)) { 134 - pr_warn("no interrupt-affinity property for %s, guessing.\n", 135 - of_node_full_name(pdev->dev.of_node)); 134 + pr_warn("no interrupt-affinity property for %pOF, guessing.\n", 135 + pdev->dev.of_node); 136 136 } 137 137 138 138 /* ··· 211 211 } 212 212 213 213 if (ret) { 214 - pr_info("%s: failed to probe PMU!\n", of_node_full_name(node)); 214 + pr_info("%pOF: failed to probe PMU!\n", node); 215 215 goto out_free; 216 216 } 217 217 ··· 228 228 out_free_irqs: 229 229 armpmu_free_irqs(pmu); 230 230 out_free: 231 - pr_info("%s: failed to register PMU devices!\n", 232 - of_node_full_name(node)); 231 + pr_info("%pOF: failed to register PMU devices!\n", node); 233 232 armpmu_free(pmu); 234 233 return ret; 235 234 }
+2
drivers/perf/qcom_l2_pmu.c
··· 546 546 } 547 547 548 548 if ((event != event->group_leader) && 549 + !is_software_event(event->group_leader) && 549 550 (L2_EVT_GROUP(event->group_leader->attr.config) == 550 551 L2_EVT_GROUP(event->attr.config))) { 551 552 dev_dbg_ratelimited(&l2cache_pmu->pdev->dev, ··· 559 558 list_for_each_entry(sibling, &event->group_leader->sibling_list, 560 559 group_entry) { 561 560 if ((sibling != event) && 561 + !is_software_event(sibling) && 562 562 (L2_EVT_GROUP(sibling->attr.config) == 563 563 L2_EVT_GROUP(event->attr.config))) { 564 564 dev_dbg_ratelimited(&l2cache_pmu->pdev->dev,
+4
include/linux/perf/arm_pmu.h
··· 24 24 * interrupt and passed the address of the low level handler, 25 25 * and can be used to implement any platform specific handling 26 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. 27 30 */ 28 31 struct arm_pmu_platdata { 29 32 irqreturn_t (*handle_irq)(int irq, void *dev, 30 33 irq_handler_t pmu_handler); 34 + unsigned long irq_flags; 31 35 }; 32 36 33 37 #ifdef CONFIG_ARM_PMU