Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755412AbbFCMTA (ORCPT ); Wed, 3 Jun 2015 08:19:00 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:57888 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932667AbbFCMRt (ORCPT ); Wed, 3 Jun 2015 08:17:49 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Mike Turquette , Stephen Boyd , Dong Aisheng Subject: [PATCH 4.0 044/148] clk: add missing lock when call clk_core_enable in clk_set_parent Date: Wed, 3 Jun 2015 21:08:34 +0900 Message-Id: <20150603114207.274955367@linuxfoundation.org> X-Mailer: git-send-email 2.4.2 In-Reply-To: <20150603114205.337615117@linuxfoundation.org> References: <20150603114205.337615117@linuxfoundation.org> User-Agent: quilt/0.64 MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2366 Lines: 76 4.0-stable review patch. If anyone has any objections, please let me know. ------------------ From: Dong Aisheng commit d2a5d46b167a9a8231264daf80165b739aecf1d7 upstream. Before commit 035a61c314eb ("clk: Make clk API return per-user struct clk instances") we acquired the enable_lock in __clk_set_parent_{before,after}() by means of calling clk_enable(). After commit 035a61c314eb we use clk_core_enable() in place of the clk_enable(), and clk_core_enable() doesn't acquire the enable_lock. This opens up a race condition between clk_set_parent() and clk_enable(). Fix it. Fixes: 035a61c314eb ("clk: Make clk API return per-user struct clk instances") Cc: Mike Turquette Cc: Stephen Boyd Signed-off-by: Dong Aisheng Signed-off-by: Stephen Boyd Signed-off-by: Greg Kroah-Hartman --- drivers/clk/clk.c | 8 ++++++++ 1 file changed, 8 insertions(+) --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1443,8 +1443,10 @@ static struct clk_core *__clk_set_parent */ if (clk->prepare_count) { clk_core_prepare(parent); + flags = clk_enable_lock(); clk_core_enable(parent); clk_core_enable(clk); + clk_enable_unlock(flags); } /* update the clk tree topology */ @@ -1459,13 +1461,17 @@ static void __clk_set_parent_after(struc struct clk_core *parent, struct clk_core *old_parent) { + unsigned long flags; + /* * Finish the migration of prepare state and undo the changes done * for preventing a race with clk_enable(). */ if (core->prepare_count) { + flags = clk_enable_lock(); clk_core_disable(core); clk_core_disable(old_parent); + clk_enable_unlock(flags); clk_core_unprepare(old_parent); } } @@ -1489,8 +1495,10 @@ static int __clk_set_parent(struct clk_c clk_enable_unlock(flags); if (clk->prepare_count) { + flags = clk_enable_lock(); clk_core_disable(clk); clk_core_disable(parent); + clk_enable_unlock(flags); clk_core_unprepare(parent); } return ret; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/