Merge tag 'powerpc-4.14-6' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 3 Nov 2017 16:25:53 +0000 (09:25 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 3 Nov 2017 16:25:53 +0000 (09:25 -0700)
Pull powerpc fixes from Michael Ellerman:
 "Some more powerpc fixes for 4.14.

  This is bigger than I like to send at rc7, but that's at least partly
  because I didn't send any fixes last week. If it wasn't for the IMC
  driver, which is new and getting heavy testing, the diffstat would
  look a bit better. I've also added ftrace on big endian to my test
  suite, so we shouldn't break that again in future.

   - A fix to the handling of misaligned paste instructions (P9 only),
     where a change to a #define has caused the check for the
     instruction to always fail.

   - The preempt handling was unbalanced in the radix THP flush (P9
     only). Though we don't generally use preempt we want to keep it
     working as much as possible.

   - Two fixes for IMC (P9 only), one when booting with restricted
     number of CPUs and one in the error handling when initialisation
     fails due to firmware etc.

   - A revert to fix function_graph on big endian machines, and then a
     rework of the reverted patch to fix kprobes blacklist handling on
     big endian machines.

  Thanks to: Anju T Sudhakar, Guilherme G. Piccoli, Madhavan Srinivasan,
  Naveen N. Rao, Nicholas Piggin, Paul Mackerras"

* tag 'powerpc-4.14-6' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
  powerpc/perf: Fix core-imc hotplug callback failure during imc initialization
  powerpc/kprobes: Dereference function pointers only if the address does not belong to kernel text
  Revert "powerpc64/elfv1: Only dereference function descriptor for non-text symbols"
  powerpc/64s/radix: Fix preempt imbalance in TLB flush
  powerpc: Fix check for copy/paste instructions in alignment handler
  powerpc/perf: Fix IMC allocation routine

arch/powerpc/include/asm/code-patching.h
arch/powerpc/kernel/align.c
arch/powerpc/kernel/kprobes.c
arch/powerpc/mm/tlb-radix.c
arch/powerpc/perf/imc-pmu.c

index 5482928eea1beb64b0f018bc5d7f74a94a998e50..abef812de7f8cb4f7ae5a178c67775f81d4a22f7 100644 (file)
@@ -83,16 +83,8 @@ static inline unsigned long ppc_function_entry(void *func)
         * On PPC64 ABIv1 the function pointer actually points to the
         * function's descriptor. The first entry in the descriptor is the
         * address of the function text.
-        *
-        * However, we may also receive pointer to an assembly symbol. To
-        * detect that, we first check if the function pointer we receive
-        * already points to kernel/module text and we only dereference it
-        * if it doesn't.
         */
-       if (kernel_text_address((unsigned long)func))
-               return (unsigned long)func;
-       else
-               return ((func_descr_t *)func)->entry;
+       return ((func_descr_t *)func)->entry;
 #else
        return (unsigned long)func;
 #endif
index 43ef2515648098f985ff5f7d10a66b2f6d724391..3e6c0744c174a0dc7479219b07c3b4cc26cdd68d 100644 (file)
@@ -332,7 +332,7 @@ int fix_alignment(struct pt_regs *regs)
         * when pasting to a co-processor. Furthermore, paste_last is the
         * synchronisation point for preceding copy/paste sequences.
         */
-       if ((instr & 0xfc0006fe) == PPC_INST_COPY)
+       if ((instr & 0xfc0006fe) == (PPC_INST_COPY & 0xfc0006fe))
                return -EIO;
 
        r = analyse_instr(&op, regs, instr);
index 367494dc67d9e89a34ae7273b737479349987aef..bebc3007a793af02394909f47d29f30ab79c5b86 100644 (file)
@@ -600,7 +600,12 @@ NOKPROBE_SYMBOL(kprobe_fault_handler);
 
 unsigned long arch_deref_entry_point(void *entry)
 {
-       return ppc_global_function_entry(entry);
+#ifdef PPC64_ELF_ABI_v1
+       if (!kernel_text_address((unsigned long)entry))
+               return ppc_global_function_entry(entry);
+       else
+#endif
+               return (unsigned long)entry;
 }
 NOKPROBE_SYMBOL(arch_deref_entry_point);
 
index b3e849c4886e66c883451a59fe603e04132c00c0..d304028641a23377d57b20d102407eff6f566523 100644 (file)
@@ -360,12 +360,14 @@ void radix__flush_tlb_collapsed_pmd(struct mm_struct *mm, unsigned long addr)
 
 
        pid = mm ? mm->context.id : 0;
+       preempt_disable();
        if (unlikely(pid == MMU_NO_CONTEXT))
                goto no_context;
 
        /* 4k page size, just blow the world */
        if (PAGE_SIZE == 0x1000) {
                radix__flush_all_mm(mm);
+               preempt_enable();
                return;
        }
 
index 88126245881b3f8e500ab099bbfa4ebba8bf03d9..36344117c680b9e0500b345c18f98d11cb246134 100644 (file)
@@ -607,6 +607,20 @@ static int ppc_core_imc_cpu_offline(unsigned int cpu)
        if (!cpumask_test_and_clear_cpu(cpu, &core_imc_cpumask))
                return 0;
 
+       /*
+        * Check whether core_imc is registered. We could end up here
+        * if the cpuhotplug callback registration fails. i.e, callback
+        * invokes the offline path for all sucessfully registered cpus.
+        * At this stage, core_imc pmu will not be registered and we
+        * should return here.
+        *
+        * We return with a zero since this is not an offline failure.
+        * And cpuhp_setup_state() returns the actual failure reason
+        * to the caller, which inturn will call the cleanup routine.
+        */
+       if (!core_imc_pmu->pmu.event_init)
+               return 0;
+
        /* Find any online cpu in that core except the current "cpu" */
        ncpu = cpumask_any_but(cpu_sibling_mask(cpu), cpu);
 
@@ -1104,7 +1118,7 @@ static int init_nest_pmu_ref(void)
 
 static void cleanup_all_core_imc_memory(void)
 {
-       int i, nr_cores = num_present_cpus() / threads_per_core;
+       int i, nr_cores = DIV_ROUND_UP(num_present_cpus(), threads_per_core);
        struct imc_mem_info *ptr = core_imc_pmu->mem_info;
        int size = core_imc_pmu->counter_mem_size;
 
@@ -1212,7 +1226,7 @@ static int imc_mem_init(struct imc_pmu *pmu_ptr, struct device_node *parent,
                if (!pmu_ptr->pmu.name)
                        return -ENOMEM;
 
-               nr_cores = num_present_cpus() / threads_per_core;
+               nr_cores = DIV_ROUND_UP(num_present_cpus(), threads_per_core);
                pmu_ptr->mem_info = kcalloc(nr_cores, sizeof(struct imc_mem_info),
                                                                GFP_KERNEL);