From: Greg Kroah-Hartman Date: Fri, 15 Nov 2019 06:17:47 +0000 (+0800) Subject: 4.14-stable patches X-Git-Tag: v4.4.202~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e92168875e8e7fc561ddea180347532edae631e1;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: powerpc-perf-fix-imc_max_pmu-macro.patch powerpc-perf-fix-kfree-memory-allocated-for-nest-pmus.patch --- 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 index 00000000000..ed2ca8244ca --- /dev/null +++ b/queue-4.14/powerpc-perf-fix-imc_max_pmu-macro.patch @@ -0,0 +1,123 @@ +From 73ce9aec65b17433e18163d07eb5cb6bf114bd6c Mon Sep 17 00:00:00 2001 +From: Madhavan Srinivasan +Date: Wed, 22 Nov 2017 10:45:39 +0530 +Subject: powerpc/perf: Fix IMC_MAX_PMU macro + +From: Madhavan Srinivasan + +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 +Signed-off-by: Michael Ellerman +Cc: Andrew Donnellan +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + + /* +- * 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 index 00000000000..14fd9f03f9d --- /dev/null +++ b/queue-4.14/powerpc-perf-fix-kfree-memory-allocated-for-nest-pmus.patch @@ -0,0 +1,79 @@ +From 110df8bd3e418b3476cae80babe8add48a8ea523 Mon Sep 17 00:00:00 2001 +From: Anju T Sudhakar +Date: Thu, 7 Dec 2017 22:53:27 +0530 +Subject: powerpc/perf: Fix kfree memory allocated for nest pmus + +From: Anju T Sudhakar + +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 +Reviewed-by: Madhavan Srinivasan +Signed-off-by: Michael Ellerman +Cc: Andrew Donnellan +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } + } diff --git a/queue-4.14/series b/queue-4.14/series index 8dc6dd70253..0e13f8051b4 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -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