Received: by 2002:a05:6a10:17d3:0:0:0:0 with SMTP id hz19csp2560448pxb; Mon, 19 Apr 2021 08:26:20 -0700 (PDT) X-Google-Smtp-Source: ABdhPJykWSD93fCEcOtrctn6WhFbM07Pj3qZVoq66ePHJ7jHJHyiqkHTzDFRr2qKN3AcLnbGzN1n X-Received: by 2002:a17:906:3455:: with SMTP id d21mr22463116ejb.11.1618845980567; Mon, 19 Apr 2021 08:26:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1618845980; cv=none; d=google.com; s=arc-20160816; b=jntAz/1JaAxF9YqWlv9u4z8NFpmiuNl1NA2plZGVDGy4DYYa6pMVKsKSxduTiRncIz mRZcUCb1QbCJ57VzO1w4TdpiEDiqepi3/f+EPTNtDnIIHjQu24ZlnQi1DNYH3aggi4t7 uF6ojyj+mMJTBwo743bMOIal8X4biZp1/qPO+gShi+3zgMDdvaj/4Sehnwdkawz9mYwo g1wyLax2tVcicz3ug2ieS9ztUmy9j9IWzlOAdDn9FcPYlBmJVKqOPHX/awht5unhQMYy IVVKgsWRHMD0rIC/BlR23tFzv65A/VupOrZMWqsXt30sLEA2BvtBJiwbBxyekQGe/3iQ fc5g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=7kpUmrKVW8Ps1EVw3eSar5kkkuTbHnN/bYU07Y6iD40=; b=ftKBdUwbukw8t9Aaq4mPNmZ41OU+icR+dV38zX/aZb7qIiCkZzVuS7JB8MnGgauEDc qewRgsqLWM7ER87JkxSy7LLr3J6q1F7DlwdC/3M1ODjpBH3T7ALI+BQi8QH65qiOyKMt doMUxZudHwrp5mrbJWDKs1h+PBnzmhC640GyX3/D2LzortydieDwRxpNsobW6nvap0fp Uwn5j5HKQrPdOPuTv+Ww7jNUqWJ9Q0FsypSBX93zwTw3ddjI8+xRRGNJ3OrPHin+7xvK 1uoTw0LNS7RunF5aNvCj8mj/qbbeVQ1betysjvC1Bb1KKqEaeA2YDVpSvQsysM88w13/ yAWQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=xs2m4pq0; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id s14si4418053edr.554.2021.04.19.08.25.57; Mon, 19 Apr 2021 08:26:20 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=xs2m4pq0; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240375AbhDSNTE (ORCPT + 99 others); Mon, 19 Apr 2021 09:19:04 -0400 Received: from mail.kernel.org ([198.145.29.99]:47128 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240631AbhDSNPy (ORCPT ); Mon, 19 Apr 2021 09:15:54 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 8D205613D1; Mon, 19 Apr 2021 13:13:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1618838012; bh=W2/AfbJ7NmMI+8YoEzFhs6dbIdm37przwfiiI8Aky1Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=xs2m4pq0H7y4FjRijHK+T+vEZYwtEGUeZbv+rB+qCuk9QOFRRbZUe6SsOSK1oGy2q VFn/bTWJ3hIsF9DRwCETjl1g3IfQW+Z3ExbchD8l7nToZBmiE9MXdyN50BC5XE5T7F czPJLpnMWHnQG19pE4SWTPGQlVJc8raJyGe5pacQ= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Shreenivaas Devarajan , Dave Jiang , Vinod Koul , Sasha Levin Subject: [PATCH 5.10 012/103] dmaengine: idxd: fix wq cleanup of WQCFG registers Date: Mon, 19 Apr 2021 15:05:23 +0200 Message-Id: <20210419130528.212402364@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210419130527.791982064@linuxfoundation.org> References: <20210419130527.791982064@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Dave Jiang [ Upstream commit ea9aadc06a9f10ad20a90edc0a484f1147d88a7a ] A pre-release silicon erratum workaround where wq reset does not clear WQCFG registers was leaked into upstream code. Use wq reset command instead of blasting the MMIO region. This also address an issue where we clobber registers in future devices. Fixes: da32b28c95a7 ("dmaengine: idxd: cleanup workqueue config after disabling") Reported-by: Shreenivaas Devarajan Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/161824330020.881560.16375921906426627033.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/dma/idxd/device.c | 35 ++++++++++++++++++++++++----------- drivers/dma/idxd/idxd.h | 1 + drivers/dma/idxd/sysfs.c | 9 ++------- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index a6704838ffcb..459e9fbc2253 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -263,6 +263,22 @@ void idxd_wq_drain(struct idxd_wq *wq) idxd_cmd_exec(idxd, IDXD_CMD_DRAIN_WQ, operand, NULL); } +void idxd_wq_reset(struct idxd_wq *wq) +{ + struct idxd_device *idxd = wq->idxd; + struct device *dev = &idxd->pdev->dev; + u32 operand; + + if (wq->state != IDXD_WQ_ENABLED) { + dev_dbg(dev, "WQ %d in wrong state: %d\n", wq->id, wq->state); + return; + } + + operand = BIT(wq->id % 16) | ((wq->id / 16) << 16); + idxd_cmd_exec(idxd, IDXD_CMD_RESET_WQ, operand, NULL); + wq->state = IDXD_WQ_DISABLED; +} + int idxd_wq_map_portal(struct idxd_wq *wq) { struct idxd_device *idxd = wq->idxd; @@ -291,8 +307,6 @@ void idxd_wq_unmap_portal(struct idxd_wq *wq) void idxd_wq_disable_cleanup(struct idxd_wq *wq) { struct idxd_device *idxd = wq->idxd; - struct device *dev = &idxd->pdev->dev; - int i, wq_offset; lockdep_assert_held(&idxd->dev_lock); memset(wq->wqcfg, 0, idxd->wqcfg_size); @@ -303,14 +317,6 @@ void idxd_wq_disable_cleanup(struct idxd_wq *wq) wq->priority = 0; clear_bit(WQ_FLAG_DEDICATED, &wq->flags); memset(wq->name, 0, WQ_NAME_SIZE); - - for (i = 0; i < WQCFG_STRIDES(idxd); i++) { - wq_offset = WQCFG_OFFSET(idxd, wq->id, i); - iowrite32(0, idxd->reg_base + wq_offset); - dev_dbg(dev, "WQ[%d][%d][%#x]: %#x\n", - wq->id, i, wq_offset, - ioread32(idxd->reg_base + wq_offset)); - } } /* Device control bits */ @@ -560,7 +566,14 @@ static int idxd_wq_config_write(struct idxd_wq *wq) if (!wq->group) return 0; - memset(wq->wqcfg, 0, idxd->wqcfg_size); + /* + * Instead of memset the entire shadow copy of WQCFG, copy from the hardware after + * wq reset. This will copy back the sticky values that are present on some devices. + */ + for (i = 0; i < WQCFG_STRIDES(idxd); i++) { + wq_offset = WQCFG_OFFSET(idxd, wq->id, i); + wq->wqcfg->bits[i] = ioread32(idxd->reg_base + wq_offset); + } /* byte 0-3 */ wq->wqcfg->wq_size = wq->size; diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index 953ef6536aac..1d7849cb9100 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -295,6 +295,7 @@ void idxd_wq_free_resources(struct idxd_wq *wq); int idxd_wq_enable(struct idxd_wq *wq); int idxd_wq_disable(struct idxd_wq *wq); void idxd_wq_drain(struct idxd_wq *wq); +void idxd_wq_reset(struct idxd_wq *wq); int idxd_wq_map_portal(struct idxd_wq *wq); void idxd_wq_unmap_portal(struct idxd_wq *wq); void idxd_wq_disable_cleanup(struct idxd_wq *wq); diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index ad46b3c648af..7566b573d546 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -241,7 +241,6 @@ static void disable_wq(struct idxd_wq *wq) { struct idxd_device *idxd = wq->idxd; struct device *dev = &idxd->pdev->dev; - int rc; mutex_lock(&wq->wq_lock); dev_dbg(dev, "%s removing WQ %s\n", __func__, dev_name(&wq->conf_dev)); @@ -262,17 +261,13 @@ static void disable_wq(struct idxd_wq *wq) idxd_wq_unmap_portal(wq); idxd_wq_drain(wq); - rc = idxd_wq_disable(wq); + idxd_wq_reset(wq); idxd_wq_free_resources(wq); wq->client_count = 0; mutex_unlock(&wq->wq_lock); - if (rc < 0) - dev_warn(dev, "Failed to disable %s: %d\n", - dev_name(&wq->conf_dev), rc); - else - dev_info(dev, "wq %s disabled\n", dev_name(&wq->conf_dev)); + dev_info(dev, "wq %s disabled\n", dev_name(&wq->conf_dev)); } static int idxd_config_bus_remove(struct device *dev) -- 2.30.2