Received: by 2002:a25:c593:0:0:0:0:0 with SMTP id v141csp1023080ybe; Wed, 4 Sep 2019 11:17:24 -0700 (PDT) X-Google-Smtp-Source: APXvYqyigZtNhj4LlXKKf25twiqzKMbTmjcKjgJxje1d/iRHpl3h6GrJOGxaUx46tNc26PUZeb/N X-Received: by 2002:a65:690f:: with SMTP id s15mr35201424pgq.432.1567621044677; Wed, 04 Sep 2019 11:17:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1567621044; cv=none; d=google.com; s=arc-20160816; b=0Ca84ykAQI7PsV7B18m/+gaQTeQR3XSmrgW1Kdy8TkXwXFZnt1DljwQv9hM9UMCENf xwh6QSe/+/eZ84Lid3WTXBwm+9fZskCLgCsP+NNXdbNLinInDpRDoY685rqPe4LUsKBD eJ0Ixo2/4k+1uouL0nOHbHmUZAhJlt29HDkFvcM0KjmtbRLVETNaejiFAJArBz+1rV1P nQCib3RNHaGLaNdBhu9tfbVjid7m5H+l1dzWP+kQNWmzBFVambZKJB96QrT4Ag1fwvSy bPMJ9EO0JPoeZ8iRr8y+4/3QCEDqPe2dAVX2Y0ru6w3WXq8WjeHN3bJB99TwHi5bBWxn P5dw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=dSglE/DDokgdMKJ1GMdt6siYkdDUnpLEvwTlrPGy7QA=; b=N7+Q9+6rG+GN/HsVFBaKjNd2jkxp+5BAPAr0E59vC41Akll6V8U056R1UBaRPtAJZ+ kdcb1zCPkPC/n5hguShouQEbibxN7JCRes45VqEdqQvvNMRY3kfz48ZLXmS+Prm4DfI1 vuWYJtV2tbZGfabjWO04VvIp6q3k1dcr7gsgHuzMiJRBEmMd/3KbCmkCVOHXDcLTWTS+ EwRil/bCjg9XOO0IdHouWCcNfaghaXdlGSZBE6Zt7eLiuv9sxie/bbza3uWEnsQ8rVsi GVQCV2i5tU/VczSel4lzStu/XgaEG44kzpehgAVfV+O4i/l4DSW/lrdy5EjY7GPVp622 Tqng== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=MweqImoE; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-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 f12si6806098plt.227.2019.09.04.11.17.08; Wed, 04 Sep 2019 11:17:24 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=MweqImoE; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390970AbfIDSP2 (ORCPT + 99 others); Wed, 4 Sep 2019 14:15:28 -0400 Received: from mail.kernel.org ([198.145.29.99]:32774 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390393AbfIDSP1 (ORCPT ); Wed, 4 Sep 2019 14:15:27 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E9501206BA; Wed, 4 Sep 2019 18:15:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1567620926; bh=0JTnuWsTelDkywrJ0M1VQsfCLhs1bVpfAngi0Bt8z9w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MweqImoEPg3YsLtcDbAnV4A1kEfK7sFk6vBSMBPQXEZLJLFwPfTXi/nPYFaeMatAE JAsS66t2n26Oq8kTYj8mKgWJWFF8IKm/Npc48ECqs9Hf7COCa/t/HBnFSIho6saMhU aoGPUHQW8ekCw2TGTjUfCTutPiCtdVimkvr9SfPk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, John Garry , Wei Xu Subject: [PATCH 5.2 107/143] lib: logic_pio: Fix RCU usage Date: Wed, 4 Sep 2019 19:54:10 +0200 Message-Id: <20190904175318.588086429@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190904175314.206239922@linuxfoundation.org> References: <20190904175314.206239922@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: John Garry commit 06709e81c668f5f56c65b806895b278517bd44e0 upstream. The traversing of io_range_list with list_for_each_entry_rcu() is not properly protected by rcu_read_lock() and rcu_read_unlock(), so add them. These functions mark the critical section scope where the list is protected for the reader, it cannot be "reclaimed". Any updater - in this case, the logical PIO registration functions - cannot update the list until the reader exits this critical section. In addition, the list traversing used in logic_pio_register_range() does not need to use the rcu variant. This is because we are already using io_range_mutex to guarantee mutual exclusion from mutating the list. Cc: stable@vger.kernel.org Fixes: 031e3601869c ("lib: Add generic PIO mapping method") Signed-off-by: John Garry Signed-off-by: Wei Xu Signed-off-by: Greg Kroah-Hartman --- lib/logic_pio.c | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-) --- a/lib/logic_pio.c +++ b/lib/logic_pio.c @@ -46,7 +46,7 @@ int logic_pio_register_range(struct logi end = new_range->hw_start + new_range->size; mutex_lock(&io_range_mutex); - list_for_each_entry_rcu(range, &io_range_list, list) { + list_for_each_entry(range, &io_range_list, list) { if (range->fwnode == new_range->fwnode) { /* range already there */ goto end_register; @@ -108,26 +108,38 @@ end_register: */ struct logic_pio_hwaddr *find_io_range_by_fwnode(struct fwnode_handle *fwnode) { - struct logic_pio_hwaddr *range; + struct logic_pio_hwaddr *range, *found_range = NULL; + rcu_read_lock(); list_for_each_entry_rcu(range, &io_range_list, list) { - if (range->fwnode == fwnode) - return range; + if (range->fwnode == fwnode) { + found_range = range; + break; + } } - return NULL; + rcu_read_unlock(); + + return found_range; } /* Return a registered range given an input PIO token */ static struct logic_pio_hwaddr *find_io_range(unsigned long pio) { - struct logic_pio_hwaddr *range; + struct logic_pio_hwaddr *range, *found_range = NULL; + rcu_read_lock(); list_for_each_entry_rcu(range, &io_range_list, list) { - if (in_range(pio, range->io_start, range->size)) - return range; + if (in_range(pio, range->io_start, range->size)) { + found_range = range; + break; + } } - pr_err("PIO entry token %lx invalid\n", pio); - return NULL; + rcu_read_unlock(); + + if (!found_range) + pr_err("PIO entry token 0x%lx invalid\n", pio); + + return found_range; } /** @@ -180,14 +192,23 @@ unsigned long logic_pio_trans_cpuaddr(re { struct logic_pio_hwaddr *range; + rcu_read_lock(); list_for_each_entry_rcu(range, &io_range_list, list) { if (range->flags != LOGIC_PIO_CPU_MMIO) continue; - if (in_range(addr, range->hw_start, range->size)) - return addr - range->hw_start + range->io_start; + if (in_range(addr, range->hw_start, range->size)) { + unsigned long cpuaddr; + + cpuaddr = addr - range->hw_start + range->io_start; + + rcu_read_unlock(); + return cpuaddr; + } } - pr_err("addr %llx not registered in io_range_list\n", - (unsigned long long) addr); + rcu_read_unlock(); + + pr_err("addr %pa not registered in io_range_list\n", &addr); + return ~0UL; }