Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp7260084imu; Wed, 14 Nov 2018 14:24:53 -0800 (PST) X-Google-Smtp-Source: AJdET5dnmWaaX1eYuyytCYDd5d+mziirdQqwtlohU6O158O0pMvY/kKoqz4ho/O8ADSC7Q8Ta5PP X-Received: by 2002:a17:902:8214:: with SMTP id x20-v6mr3577833pln.224.1542234293831; Wed, 14 Nov 2018 14:24:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542234293; cv=none; d=google.com; s=arc-20160816; b=XHVvJxjGPt1JEso3HWY8Fbi+Fn2PAf/Qn5Dh1VPWq5txPTdxdnb9M3ca6moaYgc6Kc R82vhFJPFG1yrOnTPw8nb+hRtj+sZD+uX8sO2UoxX4qsxwKMEah6Y+Z2mmL/Fl4FV8We ux5Skn9cdxTjB2idv2ATGuC6oVqlenNZP6ZmDzw1WwzvbZfj9AlHvrWPql7b9IpmnjGh Xv4cbu6OhDhXjIG/KFcw74rIus6APOC1jnvH0wCb7tAI5JkXur/sAbC5hhRYJtaJst0J LPruKciItSDEIxd4oLZeabQTFnDieDFysf5KFS+LkTIQYBLIr6U/16n1M9vrRXtuEXFL jNVg== 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:dkim-signature; bh=qAtEd7IBcJC2N2Nn/4Gpv4+vi7Vy7cBKShU/m+50cMY=; b=TAyc2hAemayFvRRXeai2CJy3vsJEBwPQNC77imfKYZUM8zoLRQvniozt/j1RGBN7Qq PNW9U52ls3zXUy95D07wE6krdnCzPOv2wfBiX8Kej1whZUnNFPlHmZ5ndWfM+djRBO1X 70lSz7/dFCsByUUEy2mLyTJn+zRABslkAdrmhQCmNZJLKmv7wjHYX1u/12YBsRgC9D8B RxVFxUwefg+S2gDK+DccNRyf3aHOFtgU48sLVr+ebatEd3M6tLu9E8qKMwMDnz2XGgYx 8N7VSIJJMzWYMgDn8H/5AgLHu8cM7VkL/KC8wOYiM/zH8x3QIzh40PTPtEVVJd6gPCW1 4TTQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=qHMHeIL6; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h3si1343375pgl.468.2018.11.14.14.24.39; Wed, 14 Nov 2018 14:24:53 -0800 (PST) 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=qHMHeIL6; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387659AbeKOI2W (ORCPT + 99 others); Thu, 15 Nov 2018 03:28:22 -0500 Received: from mail.kernel.org ([198.145.29.99]:34416 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729093AbeKOI12 (ORCPT ); Thu, 15 Nov 2018 03:27:28 -0500 Received: from sasha-vm.mshome.net (unknown [64.114.255.114]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id A62182251A; Wed, 14 Nov 2018 22:22:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1542234144; bh=60MJEDb2GN9Ntw+SChJdZFxyEwXydI23/fO1nKnVCaQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qHMHeIL6YOhGgV1iRVgJ1Xfy39QcR+gWDFYmeoVyn0A3ap8pe18Nm0VAb+PdNA3lY mGzBEK4/qhNlGywvDhu4svpCIqnEFUsdl8dydu3EfGx2pIoaxZD8nQj9mOATVfq3cM t8uKRiwN5RIbv9vuLrf98S1WaG+Gm/0d9WMdpdnk= From: Sasha Levin To: stable@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Dmitry Bogdanov , Igor Russkikh , "David S . Miller" , Sasha Levin Subject: [PATCH AUTOSEL 4.19 67/73] net: aquantia: fix potential IOMMU fault after driver unbind Date: Wed, 14 Nov 2018 17:22:01 -0500 Message-Id: <20181114222207.98701-67-sashal@kernel.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181114222207.98701-1-sashal@kernel.org> References: <20181114222207.98701-1-sashal@kernel.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Dmitry Bogdanov [ Upstream commit 7a1bb49461b12b2e6332a4d054256835f45203f3 ] IOMMU fault may occurr on unbind/bind or if_down/if_up sequence. Although driver disables the rings on down, this is not enough. Due to internal HW design, during subsequent initialization NIC sometimes may reuse RX descriptors cache and write to the host memory from the descriptor cache. That's get catched by IOMMU on host. This patch invalidates the descriptor cache in NIC on interface down to prevent writing to the cached descriptors and to the memory pointed in those descriptors. Signed-off-by: Dmitry Bogdanov Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- .../aquantia/atlantic/hw_atl/hw_atl_b0.c | 6 ++++++ .../aquantia/atlantic/hw_atl/hw_atl_llh.c | 8 ++++++++ .../aquantia/atlantic/hw_atl/hw_atl_llh.h | 3 +++ .../atlantic/hw_atl/hw_atl_llh_internal.h | 18 ++++++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c index 1d44a386e7d3..0271a0fdfee8 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c @@ -915,6 +915,12 @@ static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self) static int hw_atl_b0_hw_stop(struct aq_hw_s *self) { hw_atl_b0_hw_irq_disable(self, HW_ATL_B0_INT_MASK); + + /* Invalidate Descriptor Cache to prevent writing to the cached + * descriptors and to the data pointer of those descriptors + */ + hw_atl_rdm_rx_dma_desc_cache_init_set(self, 1); + return aq_hw_err_from_flags(self); } diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c index 10ba035dadb1..10ec5dc88e24 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c @@ -619,6 +619,14 @@ void hw_atl_rpb_rx_flow_ctl_mode_set(struct aq_hw_s *aq_hw, u32 rx_flow_ctl_mode HW_ATL_RPB_RX_FC_MODE_SHIFT, rx_flow_ctl_mode); } +void hw_atl_rdm_rx_dma_desc_cache_init_set(struct aq_hw_s *aq_hw, u32 init) +{ + aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_ADR, + HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSK, + HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_SHIFT, + init); +} + void hw_atl_rpb_rx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw, u32 rx_pkt_buff_size_per_tc, u32 buffer) { diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h index dfb426f2dc2c..b3bf64b48b93 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h @@ -325,6 +325,9 @@ void hw_atl_rpb_rx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw, u32 rx_pkt_buff_size_per_tc, u32 buffer); +/* set rdm rx dma descriptor cache init */ +void hw_atl_rdm_rx_dma_desc_cache_init_set(struct aq_hw_s *aq_hw, u32 init); + /* set rx xoff enable (per tc) */ void hw_atl_rpb_rx_xoff_en_per_tc_set(struct aq_hw_s *aq_hw, u32 rx_xoff_en_per_tc, u32 buffer); diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h index e0cf70120f1d..e2ecdb1c5a5c 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h @@ -293,6 +293,24 @@ /* default value of bitfield desc{d}_reset */ #define HW_ATL_RDM_DESCDRESET_DEFAULT 0x0 +/* rdm_desc_init_i bitfield definitions + * preprocessor definitions for the bitfield rdm_desc_init_i. + * port="pif_rdm_desc_init_i" + */ + +/* register address for bitfield rdm_desc_init_i */ +#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_ADR 0x00005a00 +/* bitmask for bitfield rdm_desc_init_i */ +#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSK 0xffffffff +/* inverted bitmask for bitfield rdm_desc_init_i */ +#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSKN 0x00000000 +/* lower bit position of bitfield rdm_desc_init_i */ +#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_SHIFT 0 +/* width of bitfield rdm_desc_init_i */ +#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_WIDTH 32 +/* default value of bitfield rdm_desc_init_i */ +#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_DEFAULT 0x0 + /* rx int_desc_wrb_en bitfield definitions * preprocessor definitions for the bitfield "int_desc_wrb_en". * port="pif_rdm_int_desc_wrb_en_i" -- 2.17.1