Received: by 2002:a5b:505:0:0:0:0:0 with SMTP id o5csp2087864ybp; Thu, 10 Oct 2019 01:59:33 -0700 (PDT) X-Google-Smtp-Source: APXvYqyGbBsrV8rHPYy/zkYs6I4vtWeONVyuxeKFZl6BxVqqzL5HGK8ZnqoG9czNILj5Lv5D9GSE X-Received: by 2002:a05:6402:29a:: with SMTP id l26mr6994298edv.290.1570697973202; Thu, 10 Oct 2019 01:59:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1570697973; cv=none; d=google.com; s=arc-20160816; b=h06RE7DhrziFqDotlvgbv7p0ONrDiIrFVZs5mdG5cZwlZcmalf9F8QXA2F0oMyBkNZ zhAUyjojLnqaSUIUjblbH7TTsvxOIQekuSFcQ34dTZHQMiqiPOmXDV8/u5bWNoyw1zoI tMPGaTmu45/bXN2cZZGL2wgCH1Ifs/MB++FUhER1hOoHPOFyjgFO/OiGs8zlRrXimpTV FdrZOrFgnLH1iZxn86AIIwxDTQSlTQyKaycG+i4fWY8OdOnH2q/XRmlCjzINl8+khutX c568fKClXoXBVk5vHkpkDlMLWaQmsdJJRF0tI+w2vpTZJmPpb2LKbGDg/plR5ezuNGTk IwfA== 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=cWQO3ueZfNQTdqdyeWfzlKpMxKPg3INV3yFDyrbtr9A=; b=C77Ce/pThpZ0NBAUbgw90lU9fLaoMTvSMAc69RvPHbIzGKoJ/A+HujPiFaPF4s/t04 WVxviZ37Inw9ru22s4hvK0g9nG7QpZSbnhna2VuAf2X9e5hP7E+HQx0UHj6TrnYHUpeV hIQSYLcPzsRMS/KhSR/+TvziWxx4yDYj0Q7A8WKyq0RCKJJ8bhluZOzhGZg2Kptnq3yG XRjMKVpscgLHhAtM4FCXE4q0PI32bFMwxT+ls2CX/FaeRDUQ+BsOfdGmJsaP7gSjh7dL 1MT+0s78H6wD22AYUILWswr7wEH/x74J1GPS+1ZIxd4V1rgXCF2J1i8qVZPWCHYL/eYr U5QQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=lnJYoE48; 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 la20si2730418ejb.73.2019.10.10.01.59.10; Thu, 10 Oct 2019 01:59:33 -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=lnJYoE48; 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 S2389039AbfJJIo7 (ORCPT + 99 others); Thu, 10 Oct 2019 04:44:59 -0400 Received: from mail.kernel.org ([198.145.29.99]:50394 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389027AbfJJIo5 (ORCPT ); Thu, 10 Oct 2019 04:44:57 -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 455D321929; Thu, 10 Oct 2019 08:44:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1570697094; bh=yEwwN4aCrDKN7M8R+26m8PSL7h3DXKhMA0QOudOPcF4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lnJYoE48+/WIbedbQcj9BuVdIAzri2S/fwr9A87MmvH4JUkiMGON57X/EXOyBVlPT LRo+n5Fe+qShuIgb7jNr4tqOH4z/cWPNsjZBVs/WwgbSz1tGut8348CGhPhSE2Qory heg5SA6fr+jXEJZmkgPIIyEGlsx7Fdk6qT9R2iS8= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Alexey Kardashevskiy , Michael Ellerman Subject: [PATCH 4.19 017/114] powerpc/powernv/ioda: Fix race in TCE level allocation Date: Thu, 10 Oct 2019 10:35:24 +0200 Message-Id: <20191010083552.110759758@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191010083544.711104709@linuxfoundation.org> References: <20191010083544.711104709@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: Alexey Kardashevskiy commit 56090a3902c80c296e822d11acdb6a101b322c52 upstream. pnv_tce() returns a pointer to a TCE entry and originally a TCE table would be pre-allocated. For the default case of 2GB window the table needs only a single level and that is fine. However if more levels are requested, it is possible to get a race when 2 threads want a pointer to a TCE entry from the same page of TCEs. This adds cmpxchg to handle the race. Note that once TCE is non-zero, it cannot become zero again. Fixes: a68bd1267b72 ("powerpc/powernv/ioda: Allocate indirect TCE levels on demand") CC: stable@vger.kernel.org # v4.19+ Signed-off-by: Alexey Kardashevskiy Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20190718051139.74787-2-aik@ozlabs.ru Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/platforms/powernv/pci-ioda-tce.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) --- a/arch/powerpc/platforms/powernv/pci-ioda-tce.c +++ b/arch/powerpc/platforms/powernv/pci-ioda-tce.c @@ -49,6 +49,9 @@ static __be64 *pnv_alloc_tce_level(int n return addr; } +static void pnv_pci_ioda2_table_do_free_pages(__be64 *addr, + unsigned long size, unsigned int levels); + static __be64 *pnv_tce(struct iommu_table *tbl, bool user, long idx, bool alloc) { __be64 *tmp = user ? tbl->it_userspace : (__be64 *) tbl->it_base; @@ -58,9 +61,9 @@ static __be64 *pnv_tce(struct iommu_tabl while (level) { int n = (idx & mask) >> (level * shift); - unsigned long tce; + unsigned long oldtce, tce = be64_to_cpu(READ_ONCE(tmp[n])); - if (tmp[n] == 0) { + if (!tce) { __be64 *tmp2; if (!alloc) @@ -71,10 +74,15 @@ static __be64 *pnv_tce(struct iommu_tabl if (!tmp2) return NULL; - tmp[n] = cpu_to_be64(__pa(tmp2) | - TCE_PCI_READ | TCE_PCI_WRITE); + tce = __pa(tmp2) | TCE_PCI_READ | TCE_PCI_WRITE; + oldtce = be64_to_cpu(cmpxchg(&tmp[n], 0, + cpu_to_be64(tce))); + if (oldtce) { + pnv_pci_ioda2_table_do_free_pages(tmp2, + ilog2(tbl->it_level_size) + 3, 1); + tce = oldtce; + } } - tce = be64_to_cpu(tmp[n]); tmp = __va(tce & ~(TCE_PCI_READ | TCE_PCI_WRITE)); idx &= ~mask;