From patchwork Mon Jun 18 15:54:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 139034 Delivered-To: patch@linaro.org Received: by 2002:a2e:970d:0:0:0:0:0 with SMTP id r13-v6csp4112671lji; Mon, 18 Jun 2018 08:54:44 -0700 (PDT) X-Google-Smtp-Source: ADUXVKKiQ98+Nu3SyD5KNR1IP8EFQeDfpThWlZ/DnianePqyHBrN5DnqVCUtItRxoWIpOkWNdvt5 X-Received: by 2002:a65:5143:: with SMTP id g3-v6mr11446862pgq.190.1529337284315; Mon, 18 Jun 2018 08:54:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529337284; cv=none; d=google.com; s=arc-20160816; b=VW7LCI6ovRm46c2CxzCPZMV0KXtRtCFv+fwJuT48jt9Jraf9EazhF0kiWmUC9IA3F+ 7OhutXrMOffmhZZx0QFlMUQc6Vp2Zi1Naj24dEqrjzSql5zW5CrzSKVlTvJGOwA/MnB7 gTcd1aTpyfx3/QDmdwCzjWEyPNMN9HhVDelhrSsqxfZCwSIAJBOsREZLSrFeoL8BLgEQ 7H3+Xa22bsa7MbYNg2O6Eoe0thpR7upmq1obpC2xjbasklJplB4Tcsqd2VEWyiTS8Kk7 5YJnPnSqXubixS/uMz5Vd+sehI8lPsf5I5jcwPuW/s9Pr5rqS7bFgSZc+hnASwHIJO5K SzQA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=L4W93LLBQqNetd73WGl0NVazapQAI2XLmvb3F4sxBdE=; b=aaJSAd5HrbXwjbl3EWq07W7q58ib3an2R3G/eWckMig/NKB8Ta5aTq+26wXDXVQS9P oXUE8c8qhrXshAi0tM3R3/EHqwRv0XMyAl8Jve5cD3prEpijAfwWPUVbqSH9/8rXyRBm V2p3l5yaID9Z7G+XljEOC7wQBRiPZSrjfbKCgforW04M3Wx6aJxaO2QD8Png5v5bh6EV HXiUAVbC/0VNf7E0lvJoKXx+0igHh9jM83nKCj/tYz6TR+1hc1dcNrrOXNH9qOrNwpl2 qfsy1CV5T6xLQcMEM6WbZOdm+y4PI1jd+hF4SUJEsWrU1+U+x5198gcX8oi74ZJDnZnL Xngw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 67-v6si10877520pfe.49.2018.06.18.08.54.44; Mon, 18 Jun 2018 08:54:44 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755318AbeFRPym (ORCPT + 10 others); Mon, 18 Jun 2018 11:54:42 -0400 Received: from foss.arm.com ([217.140.101.70]:37304 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753570AbeFRPyk (ORCPT ); Mon, 18 Jun 2018 11:54:40 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id BBCD71529; Mon, 18 Jun 2018 08:54:40 -0700 (PDT) Received: from usa.arm.com (e107155-lin.cambridge.arm.com [10.1.210.28]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 67A213F557; Mon, 18 Jun 2018 08:54:39 -0700 (PDT) From: Sudeep Holla To: Sebastian Reichel , linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Sudeep Holla , Liviu Dudau , Lorenzo Pieralisi , Sebastian Reichel Subject: [PATCH v2] power: vexpress: fix corruption in notifier registration Date: Mon, 18 Jun 2018 16:54:32 +0100 Message-Id: <1529337272-11799-1-git-send-email-sudeep.holla@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1529322007-4637-1-git-send-email-sudeep.holla@arm.com> References: <1529322007-4637-1-git-send-email-sudeep.holla@arm.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Vexpress platforms provide two different restart handlers: SYS_REBOOT that restart the entire system, while DB_RESET only restarts the daughter board containing the CPU. DB_RESET is overridden by SYS_REBOOT if it exists. notifier_chain_register used in register_restart_handler by design relies on notifiers to be registered once only, however vexpress restart notifier can get registered twice. When this happen it corrupts list of notifiers, as result some notifiers can be not called on proper event, traverse on list can be cycled forever, and second unregister can access already freed memory. So far, since this was the only restart handler in the system, no issue was observed even if the same notifier was registered twice. However commit 6c5c0d48b686 ("watchdog: sp805: add restart handler") added support for SP805 restart handlers and since the system under test contains two vexpress restart and two SP805 watchdog instances, it was observed that during the boot traversing the restart handler list looped forever as there's a cycle in that list resulting in boot hang. This patch fixes the issues by ensuring that the notifier is installed only once. Cc: Sebastian Reichel Signed-off-by: Sudeep Holla --- drivers/power/reset/vexpress-poweroff.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) v1->v2: - Updated changelog wordings as suggested by Lorenzo - Dropped unnecessary error variable initialisation on stack -- 2.7.4 diff --git a/drivers/power/reset/vexpress-poweroff.c b/drivers/power/reset/vexpress-poweroff.c index 102f95a09460..e9e749f87517 100644 --- a/drivers/power/reset/vexpress-poweroff.c +++ b/drivers/power/reset/vexpress-poweroff.c @@ -35,6 +35,7 @@ static void vexpress_reset_do(struct device *dev, const char *what) } static struct device *vexpress_power_off_device; +static atomic_t vexpress_restart_nb_refcnt = ATOMIC_INIT(0); static void vexpress_power_off(void) { @@ -99,10 +100,13 @@ static int _vexpress_register_restart_handler(struct device *dev) int err; vexpress_restart_device = dev; - err = register_restart_handler(&vexpress_restart_nb); - if (err) { - dev_err(dev, "cannot register restart handler (err=%d)\n", err); - return err; + if (atomic_inc_return(&vexpress_restart_nb_refcnt) == 1) { + err = register_restart_handler(&vexpress_restart_nb); + if (err) { + dev_err(dev, "cannot register restart handler (err=%d)\n", err); + atomic_dec(&vexpress_restart_nb_refcnt); + return err; + } } device_create_file(dev, &dev_attr_active);