]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 15 Nov 2019 06:17:47 +0000 (14:17 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 15 Nov 2019 06:17:47 +0000 (14:17 +0800)
added patches:
powerpc-perf-fix-imc_max_pmu-macro.patch
powerpc-perf-fix-kfree-memory-allocated-for-nest-pmus.patch

queue-4.14/powerpc-perf-fix-imc_max_pmu-macro.patch [new file with mode: 0644]
queue-4.14/powerpc-perf-fix-kfree-memory-allocated-for-nest-pmus.patch [new file with mode: 0644]
queue-4.14/series

diff --git a/queue-4.14/powerpc-perf-fix-imc_max_pmu-macro.patch b/queue-4.14/powerpc-perf-fix-imc_max_pmu-macro.patch
new file mode 100644 (file)
index 0000000..ed2ca82
--- /dev/null
@@ -0,0 +1,123 @@
+From 73ce9aec65b17433e18163d07eb5cb6bf114bd6c Mon Sep 17 00:00:00 2001
+From: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
+Date: Wed, 22 Nov 2017 10:45:39 +0530
+Subject: powerpc/perf: Fix IMC_MAX_PMU macro
+
+From: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
+
+commit 73ce9aec65b17433e18163d07eb5cb6bf114bd6c upstream.
+
+IMC_MAX_PMU is used for static storage (per_nest_pmu_arr) which holds
+nest pmu information. Current value for the macro is 32 based on
+the initial number of nest pmu units supported by the nest microcode.
+But going forward, microcode could support more nest units. Instead
+of static storage, patch to fix the code to dynamically allocate an
+array based on the number of nest imc units found in the device tree.
+
+Fixes:8f95faaac56c1 ('powerpc/powernv: Detect and create IMC device')
+Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Andrew Donnellan <ajd@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/include/asm/imc-pmu.h        |    6 +-----
+ arch/powerpc/perf/imc-pmu.c               |   15 ++++++++++++---
+ arch/powerpc/platforms/powernv/opal-imc.c |   16 ++++++++++++++++
+ 3 files changed, 29 insertions(+), 8 deletions(-)
+
+--- a/arch/powerpc/include/asm/imc-pmu.h
++++ b/arch/powerpc/include/asm/imc-pmu.h
+@@ -21,11 +21,6 @@
+ #include <asm/opal.h>
+ /*
+- * For static allocation of some of the structures.
+- */
+-#define IMC_MAX_PMUS                  32
+-
+-/*
+  * Compatibility macros for IMC devices
+  */
+ #define IMC_DTB_COMPAT                        "ibm,opal-in-memory-counters"
+@@ -125,4 +120,5 @@ enum {
+ extern int init_imc_pmu(struct device_node *parent,
+                               struct imc_pmu *pmu_ptr, int pmu_id);
+ extern void thread_imc_disable(void);
++extern int get_max_nest_dev(void);
+ #endif /* __ASM_POWERPC_IMC_PMU_H */
+--- a/arch/powerpc/perf/imc-pmu.c
++++ b/arch/powerpc/perf/imc-pmu.c
+@@ -26,7 +26,7 @@
+  */
+ static DEFINE_MUTEX(nest_init_lock);
+ static DEFINE_PER_CPU(struct imc_pmu_ref *, local_nest_imc_refc);
+-static struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS];
++static struct imc_pmu **per_nest_pmu_arr;
+ static cpumask_t nest_imc_cpumask;
+ struct imc_pmu_ref *nest_imc_refc;
+ static int nest_pmus;
+@@ -286,13 +286,14 @@ static struct imc_pmu_ref *get_nest_pmu_
+ static void nest_change_cpu_context(int old_cpu, int new_cpu)
+ {
+       struct imc_pmu **pn = per_nest_pmu_arr;
+-      int i;
+       if (old_cpu < 0 || new_cpu < 0)
+               return;
+-      for (i = 0; *pn && i < IMC_MAX_PMUS; i++, pn++)
++      while (*pn) {
+               perf_pmu_migrate_context(&(*pn)->pmu, old_cpu, new_cpu);
++              pn++;
++      }
+ }
+ static int ppc_nest_imc_cpu_offline(unsigned int cpu)
+@@ -1212,6 +1213,7 @@ static void imc_common_cpuhp_mem_free(st
+               kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]->attrs);
+       kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]);
+       kfree(pmu_ptr);
++      kfree(per_nest_pmu_arr);
+       return;
+ }
+@@ -1236,6 +1238,13 @@ static int imc_mem_init(struct imc_pmu *
+                       return -ENOMEM;
+               /* Needed for hotplug/migration */
++              if (!per_nest_pmu_arr) {
++                      per_nest_pmu_arr = kcalloc(get_max_nest_dev() + 1,
++                                              sizeof(struct imc_pmu *),
++                                              GFP_KERNEL);
++                      if (!per_nest_pmu_arr)
++                              return -ENOMEM;
++              }
+               per_nest_pmu_arr[pmu_index] = pmu_ptr;
+               break;
+       case IMC_DOMAIN_CORE:
+--- a/arch/powerpc/platforms/powernv/opal-imc.c
++++ b/arch/powerpc/platforms/powernv/opal-imc.c
+@@ -159,6 +159,22 @@ static void disable_core_pmu_counters(vo
+       put_online_cpus();
+ }
++int get_max_nest_dev(void)
++{
++      struct device_node *node;
++      u32 pmu_units = 0, type;
++
++      for_each_compatible_node(node, NULL, IMC_DTB_UNIT_COMPAT) {
++              if (of_property_read_u32(node, "type", &type))
++                      continue;
++
++              if (type == IMC_TYPE_CHIP)
++                      pmu_units++;
++      }
++
++      return pmu_units;
++}
++
+ static int opal_imc_counters_probe(struct platform_device *pdev)
+ {
+       struct device_node *imc_dev = pdev->dev.of_node;
diff --git a/queue-4.14/powerpc-perf-fix-kfree-memory-allocated-for-nest-pmus.patch b/queue-4.14/powerpc-perf-fix-kfree-memory-allocated-for-nest-pmus.patch
new file mode 100644 (file)
index 0000000..14fd9f0
--- /dev/null
@@ -0,0 +1,79 @@
+From 110df8bd3e418b3476cae80babe8add48a8ea523 Mon Sep 17 00:00:00 2001
+From: Anju T Sudhakar <anju@linux.vnet.ibm.com>
+Date: Thu, 7 Dec 2017 22:53:27 +0530
+Subject: powerpc/perf: Fix kfree memory allocated for nest pmus
+
+From: Anju T Sudhakar <anju@linux.vnet.ibm.com>
+
+commit 110df8bd3e418b3476cae80babe8add48a8ea523 upstream.
+
+imc_common_cpuhp_mem_free() is the common function for all
+IMC (In-memory Collection counters) domains to unregister cpuhotplug
+callback and free memory. Since kfree of memory allocated for
+nest-imc (per_nest_pmu_arr) is in the common code, all
+domains (core/nest/thread) can do the kfree in the failure case.
+
+This could potentially create a call trace as shown below, where
+core(/thread/nest) imc pmu initialization fails and in the failure
+path imc_common_cpuhp_mem_free() free the memory(per_nest_pmu_arr),
+which is allocated by successfully registered nest units.
+
+The call trace is generated in a scenario where core-imc
+initialization is made to fail and a cpuhotplug is performed in a p9
+system. During cpuhotplug ppc_nest_imc_cpu_offline() tries to access
+per_nest_pmu_arr, which is already freed by core-imc.
+
+  NIP [c000000000cb6a94] mutex_lock+0x34/0x90
+  LR [c000000000cb6a88] mutex_lock+0x28/0x90
+  Call Trace:
+    mutex_lock+0x28/0x90 (unreliable)
+    perf_pmu_migrate_context+0x90/0x3a0
+    ppc_nest_imc_cpu_offline+0x190/0x1f0
+    cpuhp_invoke_callback+0x160/0x820
+    cpuhp_thread_fun+0x1bc/0x270
+    smpboot_thread_fn+0x250/0x290
+    kthread+0x1a8/0x1b0
+    ret_from_kernel_thread+0x5c/0x74
+
+To address this scenario do the kfree(per_nest_pmu_arr) only in case
+of nest-imc initialization failure, and when there is no other nest
+units registered.
+
+Fixes: 73ce9aec65b1 ("powerpc/perf: Fix IMC_MAX_PMU macro")
+Signed-off-by: Anju T Sudhakar <anju@linux.vnet.ibm.com>
+Reviewed-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Andrew Donnellan <ajd@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/perf/imc-pmu.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/arch/powerpc/perf/imc-pmu.c
++++ b/arch/powerpc/perf/imc-pmu.c
+@@ -1189,6 +1189,7 @@ static void imc_common_cpuhp_mem_free(st
+               if (nest_pmus == 1) {
+                       cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE);
+                       kfree(nest_imc_refc);
++                      kfree(per_nest_pmu_arr);
+               }
+               if (nest_pmus > 0)
+@@ -1213,7 +1214,6 @@ static void imc_common_cpuhp_mem_free(st
+               kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]->attrs);
+       kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]);
+       kfree(pmu_ptr);
+-      kfree(per_nest_pmu_arr);
+       return;
+ }
+@@ -1327,6 +1327,8 @@ int init_imc_pmu(struct device_node *par
+                       ret = nest_pmu_cpumask_init();
+                       if (ret) {
+                               mutex_unlock(&nest_init_lock);
++                              kfree(nest_imc_refc);
++                              kfree(per_nest_pmu_arr);
+                               goto err_free;
+                       }
+               }
index 8dc6dd70253e8235385b135c2694c062d469706b..0e13f8051b4644bc557a0b334a7f657404871d8d 100644 (file)
@@ -3,3 +3,5 @@ kvm-x86-introduce-is_pae_paging.patch
 mips-bcm63xx-fix-switch-core-reset-on-bcm6368.patch
 scsi-core-handle-drivers-which-set-sg_tablesize-to-zero.patch
 revert-input-synaptics-rmi4-avoid-processing-unknown-irqs.patch
+powerpc-perf-fix-imc_max_pmu-macro.patch
+powerpc-perf-fix-kfree-memory-allocated-for-nest-pmus.patch