From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2155F2FB972 for ; Fri, 22 Aug 2025 17:02:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755882176; cv=none; b=ddsaWVb2Avv5VYL9PrjXMqTRgNoaRshQeJfK8c3/yKsue9WcazrumpMUXl8+HaRQkpao6h86XJSTf/mt57kKctQya0gG3QZDPzSzDyGIbgBOwdEOeh1Zqdv5pLf1FaxJxSTWa5Wn7ohf7emng5oeRgqo0Dd7mgdyt9efQcQ/PjU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755882176; c=relaxed/simple; bh=ZuucnW6PinqPc/na0uDGGc9QXQhV42R8XYfYMLJWSqQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fWYAV9Gs5tS/Zyie99dILpKDBYXTsMhgjedjL/uCvdZznu9fomAqgb1avktX+9M+kQAuqur39fYqQ1jFDOp2KFaoUqirZlxBaKa6ZnLPCcFtz+o/KcKHCLu8LmGpBm5F5F13dmUuWlHgQKsy5CEiZcUudsiDRHi08KnSEdQjS+Y= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=a7oiZVSY; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="a7oiZVSY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 37611C4CEED; Fri, 22 Aug 2025 17:02:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1755882175; bh=ZuucnW6PinqPc/na0uDGGc9QXQhV42R8XYfYMLJWSqQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=a7oiZVSYQ0MrVgZDhV/+/pqhqJBWDNmIfcB3B2xuq9TrbR3E1y6SoziN7XgVTKhvf C96883YqDijiBF4k7CtDIPfJeNYCqdd+9rvXxOKLLJZ+ceHXRsIWzMfNj7uMcLAYOB sPhq+zQfPUNM/jbPX+nwFkJ3hjJ87RFgjRA2ZdU2YtMhZtyruhZfuQi2P89h6wlPoA uTMKhYx0NHUDBdA5c5Os5Unks8JPvfofVcXbiWPYT7T7uN4Ju2BVSmvoueiKvBQiWS dHDf3HI+wcXkkwF2Air9186ExeRj8eGoDB6BXnqEOTfsVu5Ii1PcHYz0q+ZVai0kTl 0vf9DojiY6eEQ== From: Sasha Levin To: stable@vger.kernel.org Cc: Ranjan Kumar , "Martin K. Petersen" , Sasha Levin Subject: [PATCH 5.15.y 2/2] scsi: mpi3mr: Serialize admin queue BAR writes on 32-bit systems Date: Fri, 22 Aug 2025 13:02:38 -0400 Message-ID: <20250822170238.1319698-2-sashal@kernel.org> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250822170238.1319698-1-sashal@kernel.org> References: <2025082106-padding-nucleus-d747@gregkh> <20250822170238.1319698-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Ranjan Kumar [ Upstream commit c91e140c82eb58724c435f623702e51cc7896646 ] On 32-bit systems, 64-bit BAR writes to admin queue registers are performed as two 32-bit writes. Without locking, this can cause partial writes when accessed concurrently. Updated per-queue spinlocks is used to serialize these writes and prevent race conditions. Fixes: 824a156633df ("scsi: mpi3mr: Base driver code") Cc: stable@vger.kernel.org Signed-off-by: Ranjan Kumar Link: https://lore.kernel.org/r/20250627194539.48851-4-ranjan.kumar@broadcom.com Signed-off-by: Martin K. Petersen [ Adapt context in struct mpi3mr_ioc ] Signed-off-by: Sasha Levin --- drivers/scsi/mpi3mr/mpi3mr.h | 4 ++++ drivers/scsi/mpi3mr/mpi3mr_fw.c | 15 +++++++++++---- drivers/scsi/mpi3mr/mpi3mr_os.c | 2 ++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h index b51f8911a630..9283e234700d 100644 --- a/drivers/scsi/mpi3mr/mpi3mr.h +++ b/drivers/scsi/mpi3mr/mpi3mr.h @@ -701,6 +701,8 @@ struct scmd_priv { * @driver_info: Driver, Kernel, OS information to firmware * @change_count: Topology change count * @op_reply_q_offset: Operational reply queue offset with MSIx + * @adm_req_q_bar_writeq_lock: Admin request queue lock + * @adm_reply_q_bar_writeq_lock: Admin reply queue lock */ struct mpi3mr_ioc { struct list_head list; @@ -828,6 +830,8 @@ struct mpi3mr_ioc { struct mpi3_driver_info_layout driver_info; u16 change_count; u16 op_reply_q_offset; + spinlock_t adm_req_q_bar_writeq_lock; + spinlock_t adm_reply_q_bar_writeq_lock; }; /** diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c index 3177953480a1..931d34204717 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c @@ -11,17 +11,22 @@ #include #if defined(writeq) && defined(CONFIG_64BIT) -static inline void mpi3mr_writeq(__u64 b, void __iomem *addr) +static inline void mpi3mr_writeq(__u64 b, void __iomem *addr, + spinlock_t *write_queue_lock) { writeq(b, addr); } #else -static inline void mpi3mr_writeq(__u64 b, void __iomem *addr) +static inline void mpi3mr_writeq(__u64 b, void __iomem *addr, + spinlock_t *write_queue_lock) { __u64 data_out = b; + unsigned long flags; + spin_lock_irqsave(write_queue_lock, flags); writel((u32)(data_out), addr); writel((u32)(data_out >> 32), (addr + 4)); + spin_unlock_irqrestore(write_queue_lock, flags); } #endif @@ -2183,9 +2188,11 @@ static int mpi3mr_setup_admin_qpair(struct mpi3mr_ioc *mrioc) (mrioc->num_admin_req); writel(num_admin_entries, &mrioc->sysif_regs->admin_queue_num_entries); mpi3mr_writeq(mrioc->admin_req_dma, - &mrioc->sysif_regs->admin_request_queue_address); + &mrioc->sysif_regs->admin_request_queue_address, + &mrioc->adm_req_q_bar_writeq_lock); mpi3mr_writeq(mrioc->admin_reply_dma, - &mrioc->sysif_regs->admin_reply_queue_address); + &mrioc->sysif_regs->admin_reply_queue_address, + &mrioc->adm_reply_q_bar_writeq_lock); writel(mrioc->admin_req_pi, &mrioc->sysif_regs->admin_request_queue_pi); writel(mrioc->admin_reply_ci, &mrioc->sysif_regs->admin_reply_queue_ci); return retval; diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c index 8f88e6e202a0..bb3d951d410d 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_os.c +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c @@ -3796,6 +3796,8 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id) spin_lock_init(&mrioc->tgtdev_lock); spin_lock_init(&mrioc->watchdog_lock); spin_lock_init(&mrioc->chain_buf_lock); + spin_lock_init(&mrioc->adm_req_q_bar_writeq_lock); + spin_lock_init(&mrioc->adm_reply_q_bar_writeq_lock); INIT_LIST_HEAD(&mrioc->fwevt_list); INIT_LIST_HEAD(&mrioc->tgtdev_list); -- 2.50.1