Received: by 2002:a25:6193:0:0:0:0:0 with SMTP id v141csp3916295ybb; Mon, 6 Apr 2020 19:13:55 -0700 (PDT) X-Google-Smtp-Source: APiQypK3lmi9BC81wr8EbNDGx9p2BizcRcj0g3fd/lxN0Ja9PzAn1YLik7iKDWm+ns1M3UUZMujn X-Received: by 2002:a05:6808:605:: with SMTP id y5mr76080oih.172.1586225634998; Mon, 06 Apr 2020 19:13:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1586225634; cv=none; d=google.com; s=arc-20160816; b=TVKoM9LKDkJPMrTxbe8K+Ud8ftPqbbUpG8B4VTOFuyDkvmij7+f7AzD2XaquwYrbXF pe/wIUEB1UT8DOFXusCerAfObEs45Hfb9r79EUeyq+k1X+LdUKO3RL/+IwUXNv5CjI90 TpLzPRCyRJZ9cb9ZSUIPpNtW9uZr3bmEXvKwXzOqSXM+mGHeSr2o1LqmZ6q/xXxdIDCa lsYdBvlJANKPYLYqhnFrKXFC/UEmXSgGgDpAHCYYjbUpbvL1eiwGG60jbQQT/DCnkk+r fAscnmvVj6n+2QWLkdZqLBIVgSdU+w2wIv/MweEtwQ3sP14V1Rtu7O5janhcgugAWv0N D5CQ== 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 :message-id:date:subject:cc:to:from:dkim-signature; bh=BfSGNCe4oEdtp7HObDoUBxiccfhReNwsRhUVxZRTBNI=; b=IBbmD7SdHbiblCSbSuUQ2rIxW2Gu8n7ZSyiqmrVnFEY3hgyLk6BaYtrfDDoEDhXvl3 jt0dsarwg7l+5lbgTQosRl3CUwmA4hm7w4XSv4XQDkWNTlVJ3ypUi8fcBb29cwX3xJ58 b9h9OLmmL6CnTDQ4p3a4RZ/KGVWo1gAzcmfRPFd4twM8DLFEfJxb+cMvux7X7XS3+FaB rlzhnnMK8r1cJo+ILGytRf/UUncFuk1e6H9HspPrzKGiyVzpVnKWuR4uV4iLQrgIKu6E Kh/7dP7xAT2/WKflP9yVpfkUGWv9e3UgHry9pv9H7MqtyUK12VVYPIrLG57etdAJ9Vfr ND8Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lca.pw header.s=google header.b=gewsdy0l; 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 w21si59899oia.257.2020.04.06.19.13.42; Mon, 06 Apr 2020 19:13:54 -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=@lca.pw header.s=google header.b=gewsdy0l; 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 S1726399AbgDGCNI (ORCPT + 99 others); Mon, 6 Apr 2020 22:13:08 -0400 Received: from mail-qv1-f67.google.com ([209.85.219.67]:46126 "EHLO mail-qv1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726287AbgDGCNI (ORCPT ); Mon, 6 Apr 2020 22:13:08 -0400 Received: by mail-qv1-f67.google.com with SMTP id bu9so1104938qvb.13 for ; Mon, 06 Apr 2020 19:13:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lca.pw; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=BfSGNCe4oEdtp7HObDoUBxiccfhReNwsRhUVxZRTBNI=; b=gewsdy0lwajFLCQWWu6WiPH8/MUhlBoR9q+iW9sg17xdjiLFUdivK0Wx6EsixHvSX3 zQwX32w/VKiJHmS0WDQevjVGo8+gfgZi7y7DCOhRzKwmY33py4q+jaMI/YD6QapRyGB7 YbvFsoEbARPUmTaMh0OsJ4hN3wc4UMzH3wf44LZPIUg9X3RkNhnGmhPqB3e4pTBgmVAX Ap0KvmbhVNLE3aN/pIyYdtZUPMIWoWig1fp5mfR3gvXwYRD0zjSjOTsu8gUtTijF9KbD +IoL4EAP58QvN6dW5LppI3EHYc32ZWcZtjxJH3hX7utI7ZcDL02rl5Zpl7eH0XAl+U/x AcbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=BfSGNCe4oEdtp7HObDoUBxiccfhReNwsRhUVxZRTBNI=; b=YOtp2UxBT1qGWNL08ml1Fx8jcbtcjB9WVTyz+T/O8dTJGNQCRSPtyAjJk5WeZcS+u3 6XVQlu/5/QkrjQP5j7qPum9VeMeHZ5aD/btzAYbMe39Svus5lmLHjuNG8e2nuVvKeCxT +pV9k1eu3DNnn/qL8/L/n74GgCfrTVONeKQgP0qzN6sAelSI/K8W9VF25ahmvqo3qslO NVDHzmLObmoVvdSeuJjr0j34LOIf+gimusqORSDG0pdWWqtUyTG8GFpkGzqhlA9WItiO nRk0vxm1xaOjBn2M5TTJzLNmaCuIueeHYE4lbs/iqOAJ6z6/YFLlIMi/pVxAl7k9q8aq K8Fg== X-Gm-Message-State: AGi0PubXQeLsMd4VaZtugQJrWofMm+IX1AFtCouTuNmgXiIzC2J6WPgS D4a5/qP7TYTzwuA2BFvYy1DITLbDHMRpvA== X-Received: by 2002:a0c:b896:: with SMTP id y22mr84351qvf.182.1586225587511; Mon, 06 Apr 2020 19:13:07 -0700 (PDT) Received: from ovpn-66-196.rdu2.redhat.com (pool-71-184-117-43.bstnma.fios.verizon.net. [71.184.117.43]) by smtp.gmail.com with ESMTPSA id d5sm103120qke.14.2020.04.06.19.13.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 06 Apr 2020 19:13:07 -0700 (PDT) From: Qian Cai To: joro@8bytes.org Cc: iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Qian Cai Subject: [RFC PATCH] iommu/amd: fix a race in fetch_pte() Date: Mon, 6 Apr 2020 22:12:46 -0400 Message-Id: <20200407021246.10941-1-cai@lca.pw> X-Mailer: git-send-email 2.21.0 (Apple Git-122.2) MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org fetch_pte() could race with increase_address_space() because it held no lock from iommu_unmap_page(). On the CPU that runs fetch_pte() it could see a stale domain->pt_root and a new increased domain->mode from increase_address_space(). As the result, it could trigger invalid accesses later on. Fix it by using a pair of smp_[w|r]mb in those places. kernel BUG at drivers/iommu/amd_iommu.c:1704! BUG_ON(unmapped && !is_power_of_2(unmapped)); Hardware name: HPE ProLiant DL385 Gen10/ProLiant DL385 Gen10, BIOS A40 07/10/2019 RIP: 0010:amd_iommu_unmap+0x1b2/0x1d0 Call Trace: __iommu_unmap+0x106/0x320 iommu_unmap_fast+0xe/0x10 __iommu_dma_unmap+0xdc/0x1a0 iommu_dma_unmap_sg+0xae/0xd0 scsi_dma_unmap+0xe7/0x150 pqi_raid_io_complete+0x37/0x60 [smartpqi] pqi_irq_handler+0x1fc/0x13f0 [smartpqi] __handle_irq_event_percpu+0x78/0x4f0 handle_irq_event_percpu+0x70/0x100 handle_irq_event+0x5a/0x8b handle_edge_irq+0x10c/0x370 do_IRQ+0x9e/0x1e0 common_interrupt+0xf/0xf Signed-off-by: Qian Cai --- drivers/iommu/amd_iommu.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 20cce366e951..22328a23335f 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -1434,6 +1434,11 @@ static bool increase_address_space(struct protection_domain *domain, *pte = PM_LEVEL_PDE(domain->mode, iommu_virt_to_phys(domain->pt_root)); domain->pt_root = pte; + /* + * Make sure fetch_pte() will see the new domain->pt_root before it + * snapshots domain->mode. + */ + smp_wmb(); domain->mode += 1; ret = true; @@ -1460,6 +1465,8 @@ static u64 *alloc_pte(struct protection_domain *domain, *updated = increase_address_space(domain, address, gfp) || *updated; level = domain->mode - 1; + /* To pair with smp_wmb() in increase_address_space(). */ + smp_rmb(); pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)]; address = PAGE_SIZE_ALIGN(address, page_size); end_lvl = PAGE_SIZE_LEVEL(page_size); @@ -1545,6 +1552,8 @@ static u64 *fetch_pte(struct protection_domain *domain, return NULL; level = domain->mode - 1; + /* To pair with smp_wmb() in increase_address_space(). */ + smp_rmb(); pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)]; *page_size = PTE_LEVEL_PAGE_SIZE(level); -- 2.21.0 (Apple Git-122.2)