From patchwork Tue Nov 21 07:06:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saeed Mahameed X-Patchwork-Id: 167512 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2b07:b0:403:3b70:6f57 with SMTP id io7csp444483vqb; Mon, 20 Nov 2023 23:08:31 -0800 (PST) X-Google-Smtp-Source: AGHT+IHqiK+7zZ9s0lCzUTDOC8NpL+ozy803bPZ6YUl1daugT0X8ql2oWdeWAv31ZhEjoP7tJOrp X-Received: by 2002:a9d:7513:0:b0:6c4:9fda:a1e2 with SMTP id r19-20020a9d7513000000b006c49fdaa1e2mr8277797otk.4.1700550510717; Mon, 20 Nov 2023 23:08:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1700550510; cv=none; d=google.com; s=arc-20160816; b=fw20j/qPviKlNqIMNK+A98KTWOaAJU9geO45Hx3/uzQgl3ph25SQCI6GZb9q+xoon9 fHt1s1thX9iFH3c1+GrsRtYbRg+p+TOWB34uhM8iuqX6iE0lRSufo8trxT6PAlcIxlOG zbiwrqU9WZ5KA/yS/CeCpUVez/Rk3Yc+rijcObphJTzolNsJTvcO4sHW5do3RpzFAFPx GaY7gRRSMaa6d7BaG8LRUUsZy2ZwZrnVmO6qPar4V3Axa/j3vnLsv9r+ySfysTyD+nwd 8ASc48XMKgENIWlWoPE4GNfyGzAb7GdMJAApMi7nc1SP/qkwJTGi8Rr7q2wF+YYi+8PF 2iEQ== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=u1g/Wx6GaThkltrOG+lJw94k90XjWcLjYnwHLVdxlnw=; fh=X0hOMbpOU1raqJinhHHPFdyR1sBFq2lMGBVOqO0x1pk=; b=zqbIYYkQUV25UpvQVUsoaCCtvvYV7tuwpE3DK485PW9wjAvH8+ot7mcGxefFQH9D1J TYbioQ2thpS1GP2mat4VaTAY0XV3lsA14sCoj2mAJRXmaApyhMYaLZI3BxGcycOMC0Qw nIBNseCfVlV5VTfKsdXIzIEuY5NGkwCMU+vMNyCQJRHsA411ygRayU5QH6FZQDCQfOx+ OJ8CxY6izyobl/LX9wnbppOzRhcWj/Q2rpZp5OVyi4DWbvOObf7GTDCUJwMHEdoXyEAr 2put9tLx78cusboiVLuXif63YdUVb3m2jwnJIHFDnBZklnM1tTru6UVw+o7V2ok6yfH4 VQBw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=DoxnnLt2; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from snail.vger.email (snail.vger.email. [2620:137:e000::3:7]) by mx.google.com with ESMTPS id c14-20020a6566ce000000b005bdd6caa886si9349577pgw.76.2023.11.20.23.08.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Nov 2023 23:08:30 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) client-ip=2620:137:e000::3:7; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=DoxnnLt2; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 67A2A80DEA73; Mon, 20 Nov 2023 23:06:41 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229785AbjKUHGe (ORCPT + 99 others); Tue, 21 Nov 2023 02:06:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48436 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229470AbjKUHGb (ORCPT ); Tue, 21 Nov 2023 02:06:31 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CE203F5 for ; Mon, 20 Nov 2023 23:06:27 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5F2DFC433C8; Tue, 21 Nov 2023 07:06:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1700550387; bh=fRBJjZFPTR6OGb7k2gGjja7sHzz884j46t7cYBYv3r8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DoxnnLt2h5sAHOExSrhg3cR5/5BXtrkiCv0ZiwrqokF+RY1/ZVSCXFSXEipTWeVDU CAReITvBovf9yexbC2/k6T/KVelOR2M4ZBunk3OWncJsqOUYMbHJSM1mUS17xGBsVC XzsUsT7eqkbSj935jcVGBo5T4i4r9r5tTqtxaVsQRCwZi1GvD+ZuEaqqLgx6vnyaO1 dGcdw8jho1cA589iON0MXnXHMVP6hn3nLFn//ASvI7T3w7KToSi3AbT6a8XSR2qFFE HucyxZECGiG1SI2F97NjolLsj192AOtolxBv3kB4hQJhZ0iHLoaArh7R5aDVEmqIz/ AyOP/+R8a1Ngw== From: Saeed Mahameed To: Arnd Bergmann , Greg Kroah-Hartman Cc: Jason Gunthorpe , Leon Romanovsky , Jiri Pirko , Leonid Bloch , Itay Avraham , Jakub Kicinski , linux-kernel@vger.kernel.org, Saeed Mahameed Subject: [PATCH V3 1/5] mlx5: Add aux dev for ctl interface Date: Mon, 20 Nov 2023 23:06:15 -0800 Message-ID: <20231121070619.9836-2-saeed@kernel.org> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231121070619.9836-1-saeed@kernel.org> References: <20231121070619.9836-1-saeed@kernel.org> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Mon, 20 Nov 2023 23:06:41 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1783156452436417021 X-GMAIL-MSGID: 1783156452436417021 From: Saeed Mahameed Allow ctl protocol interface auxiliary driver in mlx5. Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/dev.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/dev.c index cf0477f53dc4..753c11f7050d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/dev.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/dev.c @@ -228,8 +228,14 @@ enum { MLX5_INTERFACE_PROTOCOL_VNET, MLX5_INTERFACE_PROTOCOL_DPLL, + MLX5_INTERFACE_PROTOCOL_CTL, }; +static bool is_ctl_supported(struct mlx5_core_dev *dev) +{ + return MLX5_CAP_GEN(dev, uctx_cap); +} + static const struct mlx5_adev_device { const char *suffix; bool (*is_supported)(struct mlx5_core_dev *dev); @@ -252,6 +258,8 @@ static const struct mlx5_adev_device { .is_supported = &is_mp_supported }, [MLX5_INTERFACE_PROTOCOL_DPLL] = { .suffix = "dpll", .is_supported = &is_dpll_supported }, + [MLX5_INTERFACE_PROTOCOL_CTL] = { .suffix = "ctl", + .is_supported = &is_ctl_supported }, }; int mlx5_adev_idx_alloc(void) From patchwork Tue Nov 21 07:06:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saeed Mahameed X-Patchwork-Id: 167513 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2b07:b0:403:3b70:6f57 with SMTP id io7csp444522vqb; Mon, 20 Nov 2023 23:08:33 -0800 (PST) X-Google-Smtp-Source: AGHT+IGSw77xI20jE8oYUqEuYaaZytXstO9DHSilJ1rwpNeyROeMVxnQvn9gHSf5gv3pO1e7J5n4 X-Received: by 2002:a05:6358:4407:b0:168:d2f8:d2ad with SMTP id z7-20020a056358440700b00168d2f8d2admr9263381rwc.7.1700550513682; Mon, 20 Nov 2023 23:08:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1700550513; cv=none; d=google.com; s=arc-20160816; b=LmExIzcUXiRSzsvyxdNxdyeYulT7KKoo7N8y7CkrPJ3AapwgYi9ZjzDXqOoK2OV7DV 3v8C8/hpnS21EXXehd/R9hJrPosweyMGsGJk8RITPAP8DkzvqN8JJSDW784enxBzGjon /sNmgPwv16bAisblbw23FoacPQd0hyCoDr7Y9rI7mIgMYj+Pzq2WZWhKH+XRajo2QPdF WTGE3l+IcBp5tZjRDsfVl576UKZ99HPZTMG6VNBau74kcEJQQhyXZBjhhbLVFYsT6zjP Cd3IwHiaI9AKONFEYMuWzCu6PGAxGONOzxQaVrOy6xhO0fjW9nPoFIX2nCGaMQieoy4/ Z4mw== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=EFepjdNFszVAVwsSuQXKkHjEKCG82U0NDFT7LoG9fq0=; fh=X0hOMbpOU1raqJinhHHPFdyR1sBFq2lMGBVOqO0x1pk=; b=bTrEvUZFPrOiHT4AchmTtOwFi3C7DZq8LESK50YDatP3zYof9xwgxuKGJTFMOWEUCl p2oJW9nAUeU49x+vAmh/Cd/SIOfeZk2xMJr6UDL4umvO7153oEV2m3c0Qlqz8J7r0rkz h27ko8j1OaJj4+//DpP0lQKP99b1SE3wUekHR83Op8af0LbxcEvd5j12cMxqMDvPxTx+ DP+7RDWoDscnQJPTe6Zdb26y4oNAMzeHhma6eMCBPylsUhGN7Mp3QjrXLbNCFXvI9tki jDc5ylycSvP7SqAQUcC/mVBufk9/O+l6QwdgFHQPEQz9Bdy9ro842keAA1QxaWdIO2iR G5Uw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=mi+Pgl1w; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id 143-20020a630095000000b005bdf596397bsi9672130pga.732.2023.11.20.23.08.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Nov 2023 23:08:33 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=mi+Pgl1w; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id F1C0980DEA64; Mon, 20 Nov 2023 23:06:43 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229536AbjKUHGk (ORCPT + 99 others); Tue, 21 Nov 2023 02:06:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35362 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229754AbjKUHGe (ORCPT ); Tue, 21 Nov 2023 02:06:34 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DF92710C for ; Mon, 20 Nov 2023 23:06:28 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 77D5AC433C8; Tue, 21 Nov 2023 07:06:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1700550388; bh=isJE+4To73RbzPw8SDE1Zz0T/qfFE6bocOEKEudicH0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mi+Pgl1wvwnpVnwtnnEbnNS/+QC1P52sQYHZkYBuCnDBJwAArVD/Kq7fWQomA5Pdu 2CxDukFP8BH6Y0blRhzcNotoC6HuBo+y9S8iTokbJKbELKo14vbyibKX6sF+oKGYBN C/ib9SfRFWM0tf1I50O1GEwR50d8jtOya92JpLYwtyPYv8HoJeBBcMOTTgIrfItWQA nxPmFhEhuTpp670oN2OsvROjbiRfFkFthNa5WInBz+HZPoZ6PdOFr48nyNwhZInwva cH/VfJsmXyg6zLkLmQ/VYmymrjMeYc2Kh0D3ljFR0Nu0Z49kM5tt7hHtkC6hi2qc7o LZz+dTpbWHVlQ== From: Saeed Mahameed To: Arnd Bergmann , Greg Kroah-Hartman Cc: Jason Gunthorpe , Leon Romanovsky , Jiri Pirko , Leonid Bloch , Itay Avraham , Jakub Kicinski , linux-kernel@vger.kernel.org, Saeed Mahameed Subject: [PATCH V3 2/5] misc: mlx5ctl: Add mlx5ctl misc driver Date: Mon, 20 Nov 2023 23:06:16 -0800 Message-ID: <20231121070619.9836-3-saeed@kernel.org> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231121070619.9836-1-saeed@kernel.org> References: <20231121070619.9836-1-saeed@kernel.org> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Mon, 20 Nov 2023 23:06:44 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1783156455098001207 X-GMAIL-MSGID: 1783156455098001207 From: Saeed Mahameed The ConnectX HW family supported by the mlx5 drivers uses an architecture where a FW component executes "mailbox RPCs" issued by the driver to make changes to the device. This results in a complex debugging environment where the FW component has information and low level configuration that needs to be accessed to userspace for debugging purposes. Historically a userspace program was used that accessed the PCI register and config space directly through /sys/bus/pci/.../XXX and could operate these debugging interfaces in parallel with the running driver. This approach is incompatible with secure boot and kernel lockdown so this driver provides a secure and restricted interface to that same data. On open the driver would allocate a special FW UID (user context ID) restrected to debug RPCs only, later in this series all user RPCs will be stamped with this UID. Reviewed-by: Jiri Pirko Reviewed-by: Leon Romanovsky Signed-off-by: Saeed Mahameed Nacked-by: Jakub Kicinski --- MAINTAINERS | 8 + drivers/misc/Kconfig | 1 + drivers/misc/Makefile | 1 + drivers/misc/mlx5ctl/Kconfig | 14 ++ drivers/misc/mlx5ctl/Makefile | 4 + drivers/misc/mlx5ctl/main.c | 314 ++++++++++++++++++++++++++++++++++ 6 files changed, 342 insertions(+) create mode 100644 drivers/misc/mlx5ctl/Kconfig create mode 100644 drivers/misc/mlx5ctl/Makefile create mode 100644 drivers/misc/mlx5ctl/main.c diff --git a/MAINTAINERS b/MAINTAINERS index 97f51d5ec1cf..4b532df16b19 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13835,6 +13835,14 @@ L: virtualization@lists.linux-foundation.org S: Supported F: drivers/vdpa/mlx5/ +MELLANOX MLX5 ConnectX Diag DRIVER +M: Saeed Mahameed +R: Itay Avraham +L: linux-kernel@vger.kernel.org +S: Supported +F: drivers/misc/mlx5ctl/ +F: include/uapi/misc/mlx5ctl.h + MELLANOX MLXCPLD I2C AND MUX DRIVER M: Vadim Pasternak M: Michael Shych diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index f37c4b8380ae..c0e4823648ed 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -579,4 +579,5 @@ source "drivers/misc/cardreader/Kconfig" source "drivers/misc/uacce/Kconfig" source "drivers/misc/pvpanic/Kconfig" source "drivers/misc/mchp_pci1xxxx/Kconfig" +source "drivers/misc/mlx5ctl/Kconfig" endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index f2a4d1ff65d4..49bc4697f498 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -67,3 +67,4 @@ obj-$(CONFIG_TMR_MANAGER) += xilinx_tmr_manager.o obj-$(CONFIG_TMR_INJECT) += xilinx_tmr_inject.o obj-$(CONFIG_TPS6594_ESM) += tps6594-esm.o obj-$(CONFIG_TPS6594_PFSM) += tps6594-pfsm.o +obj-$(CONFIG_MLX5CTL) += mlx5ctl/ diff --git a/drivers/misc/mlx5ctl/Kconfig b/drivers/misc/mlx5ctl/Kconfig new file mode 100644 index 000000000000..faaa1dba2cc2 --- /dev/null +++ b/drivers/misc/mlx5ctl/Kconfig @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0 +# + +config MLX5CTL + tristate "mlx5 ConnectX control misc driver" + depends on MLX5_CORE + help + MLX5CTL provides interface for the user process to access the debug and + configuration registers of the ConnectX hardware family + (NICs, PCI switches and SmartNIC SoCs). + This will allow configuration and debug tools to work out of the box on + mainstream kernel. + + If you don't know what to do here, say N. diff --git a/drivers/misc/mlx5ctl/Makefile b/drivers/misc/mlx5ctl/Makefile new file mode 100644 index 000000000000..b5c7f99e0ab6 --- /dev/null +++ b/drivers/misc/mlx5ctl/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_MLX5CTL) += mlx5ctl.o +mlx5ctl-y := main.o diff --git a/drivers/misc/mlx5ctl/main.c b/drivers/misc/mlx5ctl/main.c new file mode 100644 index 000000000000..8eb150461b80 --- /dev/null +++ b/drivers/misc/mlx5ctl/main.c @@ -0,0 +1,314 @@ +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 +/* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_DESCRIPTION("mlx5 ConnectX control misc driver"); +MODULE_AUTHOR("Saeed Mahameed "); +MODULE_LICENSE("Dual BSD/GPL"); + +struct mlx5ctl_dev { + struct mlx5_core_dev *mdev; + struct miscdevice miscdev; + struct auxiliary_device *adev; + struct list_head fd_list; + spinlock_t fd_list_lock; /* protect list add/del */ + struct rw_semaphore rw_lock; + struct kref refcount; +}; + +struct mlx5ctl_fd { + u16 uctx_uid; + u32 uctx_cap; + u32 ucap; /* user cap */ + struct mlx5ctl_dev *mcdev; + struct list_head list; +}; + +#define mlx5ctl_err(mcdev, format, ...) \ + dev_err(mcdev->miscdev.parent, format, ##__VA_ARGS__) + +#define mlx5ctl_dbg(mcdev, format, ...) \ + dev_dbg(mcdev->miscdev.parent, "PID %d: " format, \ + current->pid, ##__VA_ARGS__) + +enum { + MLX5_UCTX_OBJECT_CAP_RAW_TX = 0x1, + MLX5_UCTX_OBJECT_CAP_INTERNAL_DEVICE_RESOURCES = 0x2, + MLX5_UCTX_OBJECT_CAP_TOOLS_RESOURCES = 0x4, +}; + +static int mlx5ctl_alloc_uid(struct mlx5ctl_dev *mcdev, u32 cap) +{ + u32 out[MLX5_ST_SZ_DW(create_uctx_out)] = {}; + u32 in[MLX5_ST_SZ_DW(create_uctx_in)] = {}; + void *uctx; + int err; + u16 uid; + + uctx = MLX5_ADDR_OF(create_uctx_in, in, uctx); + + mlx5ctl_dbg(mcdev, "MLX5_CMD_OP_CREATE_UCTX: caps 0x%x\n", cap); + MLX5_SET(create_uctx_in, in, opcode, MLX5_CMD_OP_CREATE_UCTX); + MLX5_SET(uctx, uctx, cap, cap); + + err = mlx5_cmd_exec(mcdev->mdev, in, sizeof(in), out, sizeof(out)); + if (err) + return err; + + uid = MLX5_GET(create_uctx_out, out, uid); + mlx5ctl_dbg(mcdev, "allocated uid %d with caps 0x%x\n", uid, cap); + return uid; +} + +static void mlx5ctl_release_uid(struct mlx5ctl_dev *mcdev, u16 uid) +{ + u32 in[MLX5_ST_SZ_DW(destroy_uctx_in)] = {}; + struct mlx5_core_dev *mdev = mcdev->mdev; + int err; + + MLX5_SET(destroy_uctx_in, in, opcode, MLX5_CMD_OP_DESTROY_UCTX); + MLX5_SET(destroy_uctx_in, in, uid, uid); + + err = mlx5_cmd_exec_in(mdev, destroy_uctx, in); + mlx5ctl_dbg(mcdev, "released uid %d err(%d)\n", uid, err); +} + +static void mcdev_get(struct mlx5ctl_dev *mcdev); +static void mcdev_put(struct mlx5ctl_dev *mcdev); + +static int mlx5ctl_open_mfd(struct mlx5ctl_fd *mfd) +{ + struct mlx5_core_dev *mdev = mfd->mcdev->mdev; + struct mlx5ctl_dev *mcdev = mfd->mcdev; + u32 ucap = 0, cap = 0; + int uid; + +#define MLX5_UCTX_CAP(mdev, cap) \ + (MLX5_CAP_GEN(mdev, uctx_cap) & MLX5_UCTX_OBJECT_CAP_##cap) + + if (capable(CAP_NET_RAW) && MLX5_UCTX_CAP(mdev, RAW_TX)) { + ucap |= CAP_NET_RAW; + cap |= MLX5_UCTX_OBJECT_CAP_RAW_TX; + } + + if (capable(CAP_SYS_RAWIO) && MLX5_UCTX_CAP(mdev, INTERNAL_DEVICE_RESOURCES)) { + ucap |= CAP_SYS_RAWIO; + cap |= MLX5_UCTX_OBJECT_CAP_INTERNAL_DEVICE_RESOURCES; + } + + if (capable(CAP_SYS_ADMIN) && MLX5_UCTX_CAP(mdev, TOOLS_RESOURCES)) { + ucap |= CAP_SYS_ADMIN; + cap |= MLX5_UCTX_OBJECT_CAP_TOOLS_RESOURCES; + } + + uid = mlx5ctl_alloc_uid(mcdev, cap); + if (uid < 0) + return uid; + + mfd->uctx_uid = uid; + mfd->uctx_cap = cap; + mfd->ucap = ucap; + mfd->mcdev = mcdev; + + mlx5ctl_dbg(mcdev, "allocated uid %d with uctx caps 0x%x, user cap 0x%x\n", + uid, cap, ucap); + return 0; +} + +static void mlx5ctl_release_mfd(struct mlx5ctl_fd *mfd) +{ + struct mlx5ctl_dev *mcdev = mfd->mcdev; + + mlx5ctl_release_uid(mcdev, mfd->uctx_uid); +} + +static int mlx5ctl_open(struct inode *inode, struct file *file) +{ + struct mlx5_core_dev *mdev; + struct mlx5ctl_dev *mcdev; + struct mlx5ctl_fd *mfd; + int err = 0; + + mcdev = container_of(file->private_data, struct mlx5ctl_dev, miscdev); + mcdev_get(mcdev); + down_read(&mcdev->rw_lock); + mdev = mcdev->mdev; + if (!mdev) { + err = -ENODEV; + goto unlock; + } + + mfd = kzalloc(sizeof(*mfd), GFP_KERNEL_ACCOUNT); + if (!mfd) + return -ENOMEM; + + mfd->mcdev = mcdev; + err = mlx5ctl_open_mfd(mfd); + if (err) + goto unlock; + + spin_lock(&mcdev->fd_list_lock); + list_add_tail(&mfd->list, &mcdev->fd_list); + spin_unlock(&mcdev->fd_list_lock); + + file->private_data = mfd; + +unlock: + up_read(&mcdev->rw_lock); + if (err) { + mcdev_put(mcdev); + kfree(mfd); + } + return err; +} + +static int mlx5ctl_release(struct inode *inode, struct file *file) +{ + struct mlx5ctl_fd *mfd = file->private_data; + struct mlx5ctl_dev *mcdev = mfd->mcdev; + + down_read(&mcdev->rw_lock); + if (!mcdev->mdev) { + pr_debug("[%d] UID %d mlx5ctl: mdev is already released\n", + current->pid, mfd->uctx_uid); + /* All mfds are already released, skip ... */ + goto unlock; + } + + spin_lock(&mcdev->fd_list_lock); + list_del(&mfd->list); + spin_unlock(&mcdev->fd_list_lock); + + mlx5ctl_release_mfd(mfd); + +unlock: + kfree(mfd); + up_read(&mcdev->rw_lock); + mcdev_put(mcdev); + file->private_data = NULL; + return 0; +} + +static const struct file_operations mlx5ctl_fops = { + .owner = THIS_MODULE, + .open = mlx5ctl_open, + .release = mlx5ctl_release, +}; + +static int mlx5ctl_probe(struct auxiliary_device *adev, + const struct auxiliary_device_id *id) + +{ + struct mlx5_adev *madev = container_of(adev, struct mlx5_adev, adev); + struct mlx5_core_dev *mdev = madev->mdev; + struct mlx5ctl_dev *mcdev; + char *devname = NULL; + int err; + + mcdev = kzalloc(sizeof(*mcdev), GFP_KERNEL_ACCOUNT); + if (!mcdev) + return -ENOMEM; + + kref_init(&mcdev->refcount); + INIT_LIST_HEAD(&mcdev->fd_list); + spin_lock_init(&mcdev->fd_list_lock); + init_rwsem(&mcdev->rw_lock); + mcdev->mdev = mdev; + mcdev->adev = adev; + devname = kasprintf(GFP_KERNEL_ACCOUNT, "mlx5ctl-%s", + dev_name(&adev->dev)); + if (!devname) { + err = -ENOMEM; + goto abort; + } + + mcdev->miscdev = (struct miscdevice) { + .minor = MISC_DYNAMIC_MINOR, + .name = devname, + .fops = &mlx5ctl_fops, + .parent = &adev->dev, + }; + + err = misc_register(&mcdev->miscdev); + if (err) { + mlx5ctl_err(mcdev, "mlx5ctl: failed to register misc device err %d\n", err); + goto abort; + } + + mlx5ctl_dbg(mcdev, "probe mdev@%s %s\n", dev_driver_string(mdev->device), dev_name(mdev->device)); + + auxiliary_set_drvdata(adev, mcdev); + + return 0; + +abort: + kfree(devname); + kfree(mcdev); + return err; +} + +static void mlx5ctl_remove(struct auxiliary_device *adev) +{ + struct mlx5ctl_dev *mcdev = auxiliary_get_drvdata(adev); + struct mlx5_core_dev *mdev = mcdev->mdev; + struct mlx5ctl_fd *mfd, *n; + + misc_deregister(&mcdev->miscdev); + down_write(&mcdev->rw_lock); + + list_for_each_entry_safe(mfd, n, &mcdev->fd_list, list) { + mlx5ctl_dbg(mcdev, "UID %d still has open FDs\n", mfd->uctx_uid); + list_del(&mfd->list); + mlx5ctl_release_mfd(mfd); + } + + mlx5ctl_dbg(mcdev, "removed mdev %s %s\n", + dev_driver_string(mdev->device), dev_name(mdev->device)); + + mcdev->mdev = NULL; /* prevent already open fds from accessing the device */ + up_write(&mcdev->rw_lock); + mcdev_put(mcdev); +} + +static void mcdev_free(struct kref *ref) +{ + struct mlx5ctl_dev *mcdev = container_of(ref, struct mlx5ctl_dev, refcount); + + kfree(mcdev->miscdev.name); + kfree(mcdev); +} + +static void mcdev_get(struct mlx5ctl_dev *mcdev) +{ + kref_get(&mcdev->refcount); +} + +static void mcdev_put(struct mlx5ctl_dev *mcdev) +{ + kref_put(&mcdev->refcount, mcdev_free); +} + +static const struct auxiliary_device_id mlx5ctl_id_table[] = { + { .name = MLX5_ADEV_NAME ".ctl", }, + {}, +}; + +MODULE_DEVICE_TABLE(auxiliary, mlx5ctl_id_table); + +static struct auxiliary_driver mlx5ctl_driver = { + .name = "ctl", + .probe = mlx5ctl_probe, + .remove = mlx5ctl_remove, + .id_table = mlx5ctl_id_table, +}; + +module_auxiliary_driver(mlx5ctl_driver); From patchwork Tue Nov 21 07:06:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saeed Mahameed X-Patchwork-Id: 167516 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2b07:b0:403:3b70:6f57 with SMTP id io7csp444761vqb; Mon, 20 Nov 2023 23:09:06 -0800 (PST) X-Google-Smtp-Source: AGHT+IEjBNhp1QXE/FzW1M9N7jY2PGVrubdw4eyRi2gBqpzT1otsg0y5zz8tM6/Hn/GPG90+1QRd X-Received: by 2002:a05:6808:1242:b0:3ae:e79d:79a0 with SMTP id o2-20020a056808124200b003aee79d79a0mr9979677oiv.30.1700550546378; Mon, 20 Nov 2023 23:09:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1700550546; cv=none; d=google.com; s=arc-20160816; b=fWKw6jNVE8+AXG5Ac0kk8Q4AG7msStk75XwdQwEGcR57F5rrhwC8Ou6SzHXPvZogND brsShjYB0E3pQXsRv4XnXX4A4oj9yyYiGWL0F6VX+Iw0O8Rbwu7NjTa6tppGkPFQOOHD DgqsC94vQJ2Rda9SettNWZgdSkK2oOXP609cYjVI5RNwESzkWVqDu/OVlrGujSaj5mhi cAGyFaGpxKXCmZ2otda1BWUhm61Flwd4MK4Gr4jERqkdLwJfCeTZzGP9svzA1wqUg8sW xRLMmliRp1V/0OpTMJvlSVY64mOCmUS3huMB8F2kkeKH5WTlDw+Te87QW9iw3AxQH/he aPHg== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=0wUzY5SNqZ8lI8WbTPsVddzJpG8JPHdmr367knEM8ig=; fh=X0hOMbpOU1raqJinhHHPFdyR1sBFq2lMGBVOqO0x1pk=; b=SVee1eLohig80YptSGomn7Fd7RyTWR7C1P88hMBwnXYxTj/dj8p82r3wTV1gZk8Q7l Qs2ngAooChixcF017fib9am/ZR4GYPOrDEuS4bHUXdzTCxOhSV62OCNu8VG1Ei9Mc4J1 SW2VJKZWamGPv5RhFcmp3J4nrEdxrUEuohXAPAv/m/bVV3cHUFEoOIxHV5CJ0k4wRlu+ o/AKz0P4vWgZsVweBja8snhfWgal9fKnWEWxYg8IISJx7KQ3l+X03tsFPQ5smro6dcjW 2+FdLPETK89/LdPveFfvOnGlqghoT9AkkmYHIKID9rNEzOvlg/V128rjraLccA4MmNmB Lymg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=A7U2fOEZ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.38 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from fry.vger.email (fry.vger.email. [23.128.96.38]) by mx.google.com with ESMTPS id bm22-20020a656e96000000b005bdf5961633si10202786pgb.21.2023.11.20.23.09.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Nov 2023 23:09:06 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.38 as permitted sender) client-ip=23.128.96.38; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=A7U2fOEZ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.38 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by fry.vger.email (Postfix) with ESMTP id 8D0A3804ADA0; Mon, 20 Nov 2023 23:08:01 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at fry.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232043AbjKUHGm (ORCPT + 99 others); Tue, 21 Nov 2023 02:06:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35368 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229905AbjKUHGe (ORCPT ); Tue, 21 Nov 2023 02:06:34 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EE3DDBC for ; Mon, 20 Nov 2023 23:06:29 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8A9CAC433C9; Tue, 21 Nov 2023 07:06:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1700550389; bh=p6LbyrzBaLsCjAoS9SsNRnPCnmltE2l6oztiZUD2C0A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=A7U2fOEZsuWy1uv4zyWIq1VyTmJWxplU9kRS136V+4Io1AH3nNXv+CKmclItrLpfr 19yb5KBD9b7mh75Tn9Q+Eqzx8TKNi13r2247n/QqBk9qXIIJnqmKE/o3eUKM1ontUg V2WGHNh0s5FXNFaAIuH9hDcqlhsLh9Qd7eEYlHKHCfpI6arJvvgtuZb+Bhawso46IB dX80bOV6gXRQgX+IeribijtPDj1ME5ikTzNDqZDZK8uoPBfbAJog0WEfWooUfDqvs6 EjEFdKrMxq42fiODtzUiNfYwgw5u+TTa3pQz6QgIPQfuyBDiluCSx4mjRScCpGpfks eFK+CDpEUJW5w== From: Saeed Mahameed To: Arnd Bergmann , Greg Kroah-Hartman Cc: Jason Gunthorpe , Leon Romanovsky , Jiri Pirko , Leonid Bloch , Itay Avraham , Jakub Kicinski , linux-kernel@vger.kernel.org, Saeed Mahameed Subject: [PATCH V3 3/5] misc: mlx5ctl: Add info ioctl Date: Mon, 20 Nov 2023 23:06:17 -0800 Message-ID: <20231121070619.9836-4-saeed@kernel.org> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231121070619.9836-1-saeed@kernel.org> References: <20231121070619.9836-1-saeed@kernel.org> MIME-Version: 1.0 X-Spam-Status: No, score=-1.2 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on fry.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (fry.vger.email [0.0.0.0]); Mon, 20 Nov 2023 23:08:01 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1783156489740766026 X-GMAIL-MSGID: 1783156489740766026 From: Saeed Mahameed Implement INFO ioctl to return the allocated UID and the capability flags and some other useful device information such as the underlying ConnectX device. Example: $ sudo ./mlx5ctlu mlx5_core.ctl.0 mlx5dev: 0000:00:04.0 UCTX UID: 1 UCTX CAP: 0x3 DEV UCTX CAP: 0x3 USER CAP: 0x1d Reviewed-by: Jiri Pirko Reviewed-by: Leon Romanovsky Signed-off-by: Saeed Mahameed --- .../userspace-api/ioctl/ioctl-number.rst | 1 + drivers/misc/mlx5ctl/main.c | 71 +++++++++++++++++++ include/uapi/misc/mlx5ctl.h | 24 +++++++ 3 files changed, 96 insertions(+) create mode 100644 include/uapi/misc/mlx5ctl.h diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst index 4ea5b837399a..9faf91ffefff 100644 --- a/Documentation/userspace-api/ioctl/ioctl-number.rst +++ b/Documentation/userspace-api/ioctl/ioctl-number.rst @@ -89,6 +89,7 @@ Code Seq# Include File Comments 0x20 all drivers/cdrom/cm206.h 0x22 all scsi/sg.h 0x3E 00-0F linux/counter.h +0x5c all uapi/misc/mlx5ctl.h Nvidia ConnectX control '!' 00-1F uapi/linux/seccomp.h '#' 00-3F IEEE 1394 Subsystem Block for the entire subsystem diff --git a/drivers/misc/mlx5ctl/main.c b/drivers/misc/mlx5ctl/main.c index 8eb150461b80..6a98b40e4300 100644 --- a/drivers/misc/mlx5ctl/main.c +++ b/drivers/misc/mlx5ctl/main.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -198,10 +199,80 @@ static int mlx5ctl_release(struct inode *inode, struct file *file) return 0; } +static int mlx5ctl_info_ioctl(struct file *file, + struct mlx5ctl_info __user *arg, + size_t usize) +{ + struct mlx5ctl_fd *mfd = file->private_data; + struct mlx5ctl_dev *mcdev = mfd->mcdev; + struct mlx5_core_dev *mdev = mcdev->mdev; + struct mlx5ctl_info *info; + size_t ksize = 0; + int err = 0; + + ksize = max(sizeof(struct mlx5ctl_info), usize); + info = kzalloc(ksize, GFP_KERNEL_ACCOUNT); + if (!info) + return -ENOMEM; + + info->size = sizeof(struct mlx5ctl_info); + + info->dev_uctx_cap = MLX5_CAP_GEN(mdev, uctx_cap); + info->uctx_cap = mfd->uctx_cap; + info->uctx_uid = mfd->uctx_uid; + info->ucap = mfd->ucap; + + strscpy(info->devname, dev_name(&mdev->pdev->dev), + sizeof(info->devname)); + + if (copy_to_user(arg, info, usize)) + err = -EFAULT; + + kfree(info); + return err; +} + +static long mlx5ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct mlx5ctl_fd *mfd = file->private_data; + struct mlx5ctl_dev *mcdev = mfd->mcdev; + void __user *argp = (void __user *)arg; + size_t size = _IOC_SIZE(cmd); + int err = 0; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + mlx5ctl_dbg(mcdev, "ioctl 0x%x type/nr: %d/%d size: %d DIR:%d\n", cmd, + _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd), _IOC_DIR(cmd)); + + down_read(&mcdev->rw_lock); + if (!mcdev->mdev) { + err = -ENODEV; + goto unlock; + } + + switch (cmd) { + case MLX5CTL_IOCTL_INFO: + err = mlx5ctl_info_ioctl(file, argp, size); + break; + + default: + mlx5ctl_dbg(mcdev, "Unknown ioctl %x\n", cmd); + err = -ENOIOCTLCMD; + break; + } +unlock: + up_read(&mcdev->rw_lock); + return err; +} + static const struct file_operations mlx5ctl_fops = { .owner = THIS_MODULE, .open = mlx5ctl_open, .release = mlx5ctl_release, + .unlocked_ioctl = mlx5ctl_ioctl, + .compat_ioctl = compat_ptr_ioctl, }; static int mlx5ctl_probe(struct auxiliary_device *adev, diff --git a/include/uapi/misc/mlx5ctl.h b/include/uapi/misc/mlx5ctl.h new file mode 100644 index 000000000000..37153cc0fc6e --- /dev/null +++ b/include/uapi/misc/mlx5ctl.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 WITH Linux-syscall-note */ +/* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ + +#ifndef __MLX5CTL_IOCTL_H__ +#define __MLX5CTL_IOCTL_H__ + +struct mlx5ctl_info { + __aligned_u64 flags; + __u32 size; + __u8 devname[64]; /* underlaying ConnectX device */ + __u16 uctx_uid; /* current process allocated UCTX UID */ + __u16 reserved1; + __u32 uctx_cap; /* current process effective UCTX cap */ + __u32 dev_uctx_cap; /* device's UCTX capabilities */ + __u32 ucap; /* process user capability */ + __u32 reserved2; +}; + +#define MLX5CTL_IOCTL_MAGIC 0x5c + +#define MLX5CTL_IOCTL_INFO \ + _IOR(MLX5CTL_IOCTL_MAGIC, 0x0, struct mlx5ctl_info) + +#endif /* __MLX5CTL_IOCTL_H__ */ From patchwork Tue Nov 21 07:06:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saeed Mahameed X-Patchwork-Id: 167515 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2b07:b0:403:3b70:6f57 with SMTP id io7csp444746vqb; Mon, 20 Nov 2023 23:09:04 -0800 (PST) X-Google-Smtp-Source: AGHT+IHNomGgeV0HJ5yMFBeibE9fkcOJ/YbBRnO/LRDcpSHX1KLyL5IssYkuYeKU4gG8PJupBFFo X-Received: by 2002:a17:90b:4d8f:b0:271:7cd6:165d with SMTP id oj15-20020a17090b4d8f00b002717cd6165dmr8417964pjb.26.1700550544573; Mon, 20 Nov 2023 23:09:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1700550544; cv=none; d=google.com; s=arc-20160816; b=GNVRnOLUvp/K98scfO+jbDvLkV7utQLxh9mZUm4ZcYBhHpML2uOIx/CGE/Y2wHNFCE Aj3ZLXycRfK0wa5NJ8TWFxGMjIzj6F7tkuZa8ihdcxZ70Gl2QN74MdVx/qFw61OO1XiT JqOWu1F+76xewb5PzvGiYsyJ48+Zth2KtcB2lFjMeaOF2ro0yBtXwN1JJw8jc9xKkH8D eZh5Vv/dnCbc0EMXz6p92TS761PJJfbA2pvUNz/3MyXY5W4cQABB3s8g7dJtouEnPAoR jPnO4yIvzfI3CLJBDb5IO3I1VM2sXimQuY9oRhRh0uJZ3EALaJ4ZgFSJJHm9w4J9MYfc pqsw== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=CrUVM48I25fsVaw2cVIn0WbpB6Ttg9n57juSrwgb7Fw=; fh=X0hOMbpOU1raqJinhHHPFdyR1sBFq2lMGBVOqO0x1pk=; b=Nlp9ykKm3/co0wJ2CltNCg2+sEWYC84Ml/qDGtA8Hl7BkaxibTAQ3384qDFtfjiiNH FKimlQja5AzHf2MGkKRI+LNKfI/E0RilP2eTyRKKJ7gDPNEU29HBm6VanRZjBjZM+44W e5A+QPBWc5/b+EguzSLV53rl7AttjxIh13zS08QdqberLuYjsDLMSGMLdRDUl06vWIwj JPuoSafpGNxPUxBh/J3h6KSS47nq6xfv+f8ven83AUiUBPdg3m9FvW9BDWEaIEyTuKwl NycLhhQGVnEFrcaXzdYlLjqd9xlJM42kDDNcS7bbMp0PJkgNrpjGiwEv2ahHo9nbj/kh h4Hg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=mZgAfpbV; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from snail.vger.email (snail.vger.email. [2620:137:e000::3:7]) by mx.google.com with ESMTPS id qb8-20020a17090b280800b0026d034f6baesi10264104pjb.117.2023.11.20.23.09.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Nov 2023 23:09:04 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) client-ip=2620:137:e000::3:7; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=mZgAfpbV; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 441A680DECF1; Mon, 20 Nov 2023 23:07:02 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233176AbjKUHGr (ORCPT + 99 others); Tue, 21 Nov 2023 02:06:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35356 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230080AbjKUHGj (ORCPT ); Tue, 21 Nov 2023 02:06:39 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 03C38C8 for ; Mon, 20 Nov 2023 23:06:30 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 899DFC433C7; Tue, 21 Nov 2023 07:06:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1700550390; bh=U5lgYFwJwveZX6VvJjduX3a3pzJmocFwMI7ltZ6S+/E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mZgAfpbVELIbYq17PN8dBD+0bxFM89kOkTJqW+3cD/E8t4OLkYtT9mivstfh1CW63 WH7KYghFNd2FEoxu4w8PJpX20RJSvEQOBNrHJy9ldnm1zqpCnTXPBT2FIIzNDqsF7R dAEsoiX5ibla+vDtvHQQOjmhQsaeBYD+rYOQh8E5pgYnWJRmX9A840NXgKXtpdJcPE DFBW5HULSIXq8C67XduWuGbKMRT7mQ7MLUn6nZVToCRbyg5cCbbSFBHXq2j6jLiP3e vhJTUH1orFVUvdU/F2lIrmhcFmzSPbKmTnVdWjzONdmuwPOpbuIR8CARgIFToosYv6 pzS/rLTwM1I0A== From: Saeed Mahameed To: Arnd Bergmann , Greg Kroah-Hartman Cc: Jason Gunthorpe , Leon Romanovsky , Jiri Pirko , Leonid Bloch , Itay Avraham , Jakub Kicinski , linux-kernel@vger.kernel.org, Saeed Mahameed Subject: [PATCH V3 4/5] misc: mlx5ctl: Add command rpc ioctl Date: Mon, 20 Nov 2023 23:06:18 -0800 Message-ID: <20231121070619.9836-5-saeed@kernel.org> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231121070619.9836-1-saeed@kernel.org> References: <20231121070619.9836-1-saeed@kernel.org> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Mon, 20 Nov 2023 23:07:02 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1783156487740990092 X-GMAIL-MSGID: 1783156487740990092 From: Saeed Mahameed Add new IOCTL to allow user space to send device debug rpcs and attach the user's uctx UID to each rpc. In the mlx5 architecture the FW RPC commands are of the format of inbox and outbox buffers. The inbox buffer contains the command rpc layout as described in the ConnectX Programmers Reference Manual (PRM) document and as defined in include/linux/mlx5/mlx5_ifc.h. On success the user outbox buffer will be filled with the device's rpc response. For example to query device capabilities: a user fills out an inbox buffer with the inbox layout: struct mlx5_ifc_query_hca_cap_in_bits and expects an outbox buffer with the layout: struct mlx5_ifc_cmd_hca_cap_bits Reviewed-by: Jiri Pirko Reviewed-by: Leon Romanovsky Signed-off-by: Saeed Mahameed --- drivers/misc/mlx5ctl/main.c | 95 +++++++++++++++++++++++++++++++++++++ include/uapi/misc/mlx5ctl.h | 13 +++++ 2 files changed, 108 insertions(+) diff --git a/drivers/misc/mlx5ctl/main.c b/drivers/misc/mlx5ctl/main.c index 6a98b40e4300..e7776ea4bfca 100644 --- a/drivers/misc/mlx5ctl/main.c +++ b/drivers/misc/mlx5ctl/main.c @@ -232,6 +232,97 @@ static int mlx5ctl_info_ioctl(struct file *file, return err; } +struct mlx5_ifc_mbox_in_hdr_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + + u8 reserved_at_40[0x40]; +}; + +struct mlx5_ifc_mbox_out_hdr_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + + u8 syndrome[0x20]; + + u8 reserved_at_40[0x40]; +}; + +static int mlx5ctl_cmdrpc_ioctl(struct file *file, + struct mlx5ctl_cmdrpc __user *arg, + size_t usize) +{ + struct mlx5ctl_fd *mfd = file->private_data; + struct mlx5ctl_dev *mcdev = mfd->mcdev; + struct mlx5ctl_cmdrpc *rpc = NULL; + void *in = NULL, *out = NULL; + size_t ksize = 0; + int err; + + ksize = max(sizeof(struct mlx5ctl_cmdrpc), usize); + rpc = kzalloc(ksize, GFP_KERNEL_ACCOUNT); + if (!rpc) + return -ENOMEM; + + err = copy_from_user(rpc, arg, usize); + if (err) + goto out; + + mlx5ctl_dbg(mcdev, "[UID %d] cmdrpc: rpc->inlen %d rpc->outlen %d\n", + mfd->uctx_uid, rpc->inlen, rpc->outlen); + + if (rpc->inlen < MLX5_ST_SZ_BYTES(mbox_in_hdr) || + rpc->outlen < MLX5_ST_SZ_BYTES(mbox_out_hdr) || + rpc->inlen > MLX5CTL_MAX_RPC_SIZE || + rpc->outlen > MLX5CTL_MAX_RPC_SIZE) { + err = -EINVAL; + goto out; + } + + if (rpc->flags) { + err = -EOPNOTSUPP; + goto out; + } + + in = memdup_user(u64_to_user_ptr(rpc->in), rpc->inlen); + if (IS_ERR(in)) { + err = PTR_ERR(in); + goto out; + } + + out = kvzalloc(rpc->outlen, GFP_KERNEL_ACCOUNT); + if (!out) { + err = -ENOMEM; + goto out; + } + + mlx5ctl_dbg(mcdev, "[UID %d] cmdif: opcode 0x%x inlen %d outlen %d\n", + mfd->uctx_uid, + MLX5_GET(mbox_in_hdr, in, opcode), rpc->inlen, rpc->outlen); + + MLX5_SET(mbox_in_hdr, in, uid, mfd->uctx_uid); + err = mlx5_cmd_do(mcdev->mdev, in, rpc->inlen, out, rpc->outlen); + mlx5ctl_dbg(mcdev, "[UID %d] cmdif: opcode 0x%x retval %d\n", + mfd->uctx_uid, + MLX5_GET(mbox_in_hdr, in, opcode), err); + + /* -EREMOTEIO means outbox is valid, but out.status is not */ + if (!err || err == -EREMOTEIO) { + err = 0; + if (copy_to_user(u64_to_user_ptr(rpc->out), out, rpc->outlen)) + err = -EFAULT; + } + +out: + kvfree(out); + kfree(in); + kfree(rpc); + return err; +} + static long mlx5ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct mlx5ctl_fd *mfd = file->private_data; @@ -257,6 +348,10 @@ static long mlx5ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg err = mlx5ctl_info_ioctl(file, argp, size); break; + case MLX5CTL_IOCTL_CMDRPC: + err = mlx5ctl_cmdrpc_ioctl(file, argp, size); + break; + default: mlx5ctl_dbg(mcdev, "Unknown ioctl %x\n", cmd); err = -ENOIOCTLCMD; diff --git a/include/uapi/misc/mlx5ctl.h b/include/uapi/misc/mlx5ctl.h index 37153cc0fc6e..3277eaf78a37 100644 --- a/include/uapi/misc/mlx5ctl.h +++ b/include/uapi/misc/mlx5ctl.h @@ -16,9 +16,22 @@ struct mlx5ctl_info { __u32 reserved2; }; +struct mlx5ctl_cmdrpc { + __aligned_u64 in; /* RPC inbox buffer user address */ + __aligned_u64 out; /* RPC outbox buffer user address */ + __u32 inlen; /* inbox buffer length */ + __u32 outlen; /* outbox buffer length */ + __aligned_u64 flags; +}; + +#define MLX5CTL_MAX_RPC_SIZE 8192 + #define MLX5CTL_IOCTL_MAGIC 0x5c #define MLX5CTL_IOCTL_INFO \ _IOR(MLX5CTL_IOCTL_MAGIC, 0x0, struct mlx5ctl_info) +#define MLX5CTL_IOCTL_CMDRPC \ + _IOWR(MLX5CTL_IOCTL_MAGIC, 0x1, struct mlx5ctl_cmdrpc) + #endif /* __MLX5CTL_IOCTL_H__ */ From patchwork Tue Nov 21 07:06:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saeed Mahameed X-Patchwork-Id: 167514 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2b07:b0:403:3b70:6f57 with SMTP id io7csp444727vqb; Mon, 20 Nov 2023 23:09:01 -0800 (PST) X-Google-Smtp-Source: AGHT+IEGi6ROmKI7CdGsjVek7pW9UbUYXKVFQN1g0Fdn/rGPYByIpC9T4DxqVxYW7jYNBCh2fsk+ X-Received: by 2002:a05:6a00:3495:b0:6cb:b7b7:bec4 with SMTP id cp21-20020a056a00349500b006cbb7b7bec4mr2933028pfb.13.1700550541636; Mon, 20 Nov 2023 23:09:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1700550541; cv=none; d=google.com; s=arc-20160816; b=a6Msafz3KOeTAs6tg4sMdQNkWs7KbcdUwpzkSjVXVOIOdxrHGPzgifkj8mWAIHygFx aMr4ZuWxTDmeslmS/TZ6P/MbKTowAxA2SFkbmEWjrTkUQUQ7rr1btMxUvLKzuuFjKrO0 g3vZJE4D+DMCJy/OywnBM4IGDqReIHObLrbGpaHKjDnI5eFNOh89gPcMg7J2gVYvo01Q hpTi2UZZCvi3FvPQ7vmx3anMZI790mlnVW9u5SfuPEicXfbI91bVcUAlqTIzPwM0Fdau wMsDAikpipwrwClwBJBQUP1PLDu7UnmZe7ZM2LL8QYkc+zKsqd+HRg6zBTxc0p3LDKMV 970Q== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=cQqffosB2V+Kmz7YIMs72AJAKvarl/y4JEHJ4vcDij0=; fh=X0hOMbpOU1raqJinhHHPFdyR1sBFq2lMGBVOqO0x1pk=; b=O8skJEGU0e+ash0wi9FGPTNF5YZUIcmcd/7WdmT01A1hKzgS5pUZIywiWTX13lyJpj /uCld1qWzHdkqkCsi+gPHUnzyu/sr1r8zWR+4yj1vAIDrJhcN7S8borxLxcjPttaWyUm P6mmrq32H8S2DNkNvVOIf+NQQYaeYhp8LEOhch+hEuUQdUip+W4uDE4FT1tjSoC6HhDL Wdz6pB8exSSoQDDk/1D7iYs6FliCtOirTULSHjg4De7gqadCIYdniL9hzG0jBxu6QR0L RJByUI5d6jqOFLqt3viegzxWqDQ3IGbGX4SSsoskTLR31TQj58hcV+8fXqEHZkpHXw7d WM8w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Ry9CdzUB; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id y12-20020aa7942c000000b006c507a60e2dsi9523730pfo.177.2023.11.20.23.09.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Nov 2023 23:09:01 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Ry9CdzUB; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 8F81580DECE6; Mon, 20 Nov 2023 23:07:00 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233556AbjKUHGy (ORCPT + 99 others); Tue, 21 Nov 2023 02:06:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35400 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230220AbjKUHGj (ORCPT ); Tue, 21 Nov 2023 02:06:39 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 09B62113 for ; Mon, 20 Nov 2023 23:06:32 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 91E75C433CC; Tue, 21 Nov 2023 07:06:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1700550391; bh=Jtlr6fv2Rmjy8F6VRINbFMiAGnkQMjW/RQtQL1aMuKs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ry9CdzUBJtU6G4CEuZ3nBsxVjKKMBIYzoyu9o7SHBCx6/MuwE+H8R0t5v9gm0bbl3 eRSFgObAP4rmFU0CP1LOw6X6NC+1xKyZRifpZiizy0sQj8opB2FTc4wr+ILXfsEvRp qyM7nBmCpWR4tAphA1XmDNIkQdAfR4NRjoLNl/ORlxBdI15Xd0G1NGB9pUaeyzePgy IBZMtj6PYA2j2NvTXRv/BZsSRXgNDnzfL9r+vQIbDm4G91+G3BkXm8YCrHcdsBFA7L ZLl390nPk4otbUQspcXmrJ/bWYAp1LWUOvfh8XbZ9rIOFPakXG+lbEZEB6X+JvmJC9 f1VpFwspacfVw== From: Saeed Mahameed To: Arnd Bergmann , Greg Kroah-Hartman Cc: Jason Gunthorpe , Leon Romanovsky , Jiri Pirko , Leonid Bloch , Itay Avraham , Jakub Kicinski , linux-kernel@vger.kernel.org, Saeed Mahameed Subject: [PATCH V3 5/5] misc: mlx5ctl: Add umem reg/unreg ioctl Date: Mon, 20 Nov 2023 23:06:19 -0800 Message-ID: <20231121070619.9836-6-saeed@kernel.org> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231121070619.9836-1-saeed@kernel.org> References: <20231121070619.9836-1-saeed@kernel.org> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Mon, 20 Nov 2023 23:07:00 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1783156484925801124 X-GMAIL-MSGID: 1783156484925801124 From: Saeed Mahameed Command rpc outbox buffer is limited in size, which can be very annoying when trying to pull large traces out of the device. Many device rpcs offer the ability to scatter output traces, contexts and logs directly into user space buffers in a single shot. Allow user to register user memory space, so the device may dump information directly into user memory space. The registered memory will be described by a device UMEM object which has a unique umem_id, this umem_id can be later used in the rpc inbox to tell the device where to populate the response output, e.g HW traces and other debug object queries. To do so this patch introduces two ioctls: MLX5CTL_IOCTL_UMEM_REG(va_address, size): - calculate page fragments from the user provided virtual address - pin the pages, and allocate a sg list - dma map the sg list - create a UMEM device object that points to the dma addresses - add a driver umem object to an xarray data base for bookkeeping - return UMEM ID to user so it can be used in subsequent rpcs MLX5CTL_IOCTL_UMEM_UNREG(umem_id): - user provides a pre allocated umem ID - unwinds the above Example usecase, ConnectX device coredump can be as large as 2MB. Using inline rpcs will take thousands of rpcs to get the full coredump which can take multiple seconds. With UMEM, it can be done in a single rpc, using 2MB of umem user buffer. $ ./mlx5ctlu mlx5_core.ctl.0 coredump --umem_size=$(( 2 ** 20 )) 00 00 00 00 01 00 20 00 00 00 00 04 00 00 48 ec 00 00 00 08 00 00 00 00 00 00 00 0c 00 00 00 03 00 00 00 10 00 00 00 00 00 00 00 14 00 00 00 00 .... 00 50 0b 3c 00 00 00 00 00 50 0b 40 00 00 00 00 00 50 0b 44 00 00 00 00 00 50 0b 48 00 00 00 00 00 50 0c 00 00 00 00 00 INFO : Core dump done INFO : Core dump size 831304 INFO : Core dump address 0x0 INFO : Core dump cookie 0x500c04 INFO : More Dump 0 Other usecases are: dynamic HW and FW trace monitoring, high frequency diagnostic counters sampling and batched objects and resource dumps. Reviewed-by: Jiri Pirko Reviewed-by: Leon Romanovsky Signed-off-by: Saeed Mahameed --- drivers/misc/mlx5ctl/Makefile | 1 + drivers/misc/mlx5ctl/main.c | 99 +++++++++++ drivers/misc/mlx5ctl/umem.c | 322 ++++++++++++++++++++++++++++++++++ drivers/misc/mlx5ctl/umem.h | 17 ++ include/uapi/misc/mlx5ctl.h | 22 +++ 5 files changed, 461 insertions(+) create mode 100644 drivers/misc/mlx5ctl/umem.c create mode 100644 drivers/misc/mlx5ctl/umem.h diff --git a/drivers/misc/mlx5ctl/Makefile b/drivers/misc/mlx5ctl/Makefile index b5c7f99e0ab6..f35234e931a8 100644 --- a/drivers/misc/mlx5ctl/Makefile +++ b/drivers/misc/mlx5ctl/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_MLX5CTL) += mlx5ctl.o mlx5ctl-y := main.o +mlx5ctl-y += umem.o diff --git a/drivers/misc/mlx5ctl/main.c b/drivers/misc/mlx5ctl/main.c index e7776ea4bfca..7e6d6da26a79 100644 --- a/drivers/misc/mlx5ctl/main.c +++ b/drivers/misc/mlx5ctl/main.c @@ -12,6 +12,8 @@ #include #include +#include "umem.h" + MODULE_DESCRIPTION("mlx5 ConnectX control misc driver"); MODULE_AUTHOR("Saeed Mahameed "); MODULE_LICENSE("Dual BSD/GPL"); @@ -30,6 +32,8 @@ struct mlx5ctl_fd { u16 uctx_uid; u32 uctx_cap; u32 ucap; /* user cap */ + + struct mlx5ctl_umem_db *umem_db; struct mlx5ctl_dev *mcdev; struct list_head list; }; @@ -115,6 +119,12 @@ static int mlx5ctl_open_mfd(struct mlx5ctl_fd *mfd) if (uid < 0) return uid; + mfd->umem_db = mlx5ctl_umem_db_create(mdev, uid); + if (IS_ERR(mfd->umem_db)) { + mlx5ctl_release_uid(mcdev, uid); + return PTR_ERR(mfd->umem_db); + } + mfd->uctx_uid = uid; mfd->uctx_cap = cap; mfd->ucap = ucap; @@ -129,6 +139,7 @@ static void mlx5ctl_release_mfd(struct mlx5ctl_fd *mfd) { struct mlx5ctl_dev *mcdev = mfd->mcdev; + mlx5ctl_umem_db_destroy(mfd->umem_db); mlx5ctl_release_uid(mcdev, mfd->uctx_uid); } @@ -323,6 +334,86 @@ static int mlx5ctl_cmdrpc_ioctl(struct file *file, return err; } +static int mlx5ctl_ioctl_umem_reg(struct file *file, + struct mlx5ctl_umem_reg __user *arg, + size_t usize) +{ + struct mlx5ctl_fd *mfd = file->private_data; + struct mlx5ctl_umem_reg *umem_reg; + int umem_id, err = 0; + size_t ksize = 0; + + ksize = max(sizeof(struct mlx5ctl_umem_reg), usize); + umem_reg = kzalloc(ksize, GFP_KERNEL_ACCOUNT); + if (!umem_reg) + return -ENOMEM; + + umem_reg->size = sizeof(struct mlx5ctl_umem_reg); + + if (copy_from_user(umem_reg, arg, usize)) { + err = -EFAULT; + goto out; + } + + if (umem_reg->flags || umem_reg->reserved1 || umem_reg->reserved2) { + err = -EOPNOTSUPP; + goto out; + } + + umem_id = mlx5ctl_umem_reg(mfd->umem_db, + (unsigned long)umem_reg->addr, + umem_reg->len); + if (umem_id < 0) { + err = umem_id; + goto out; + } + + umem_reg->umem_id = umem_id; + + if (copy_to_user(arg, umem_reg, usize)) { + mlx5ctl_umem_unreg(mfd->umem_db, umem_id); + err = -EFAULT; + } +out: + kfree(umem_reg); + return err; +} + +static int mlx5ctl_ioctl_umem_unreg(struct file *file, + struct mlx5ctl_umem_unreg __user *arg, + size_t usize) +{ + struct mlx5ctl_fd *mfd = file->private_data; + struct mlx5ctl_umem_unreg *umem_unreg; + size_t ksize = 0; + int err = 0; + + ksize = max(sizeof(struct mlx5ctl_umem_unreg), usize); + umem_unreg = kzalloc(ksize, GFP_KERNEL_ACCOUNT); + if (!umem_unreg) + return -ENOMEM; + + umem_unreg->size = sizeof(struct mlx5ctl_umem_unreg); + + if (copy_from_user(umem_unreg, arg, usize)) { + err = -EFAULT; + goto out; + } + + if (umem_unreg->flags) { + err = -EOPNOTSUPP; + goto out; + } + + err = mlx5ctl_umem_unreg(mfd->umem_db, umem_unreg->umem_id); + + if (!err && copy_to_user(arg, umem_unreg, usize)) + err = -EFAULT; +out: + kfree(umem_unreg); + return err; +} + static long mlx5ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct mlx5ctl_fd *mfd = file->private_data; @@ -352,6 +443,14 @@ static long mlx5ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg err = mlx5ctl_cmdrpc_ioctl(file, argp, size); break; + case MLX5CTL_IOCTL_UMEM_REG: + err = mlx5ctl_ioctl_umem_reg(file, argp, size); + break; + + case MLX5CTL_IOCTL_UMEM_UNREG: + err = mlx5ctl_ioctl_umem_unreg(file, argp, size); + break; + default: mlx5ctl_dbg(mcdev, "Unknown ioctl %x\n", cmd); err = -ENOIOCTLCMD; diff --git a/drivers/misc/mlx5ctl/umem.c b/drivers/misc/mlx5ctl/umem.c new file mode 100644 index 000000000000..e62030dadf51 --- /dev/null +++ b/drivers/misc/mlx5ctl/umem.c @@ -0,0 +1,322 @@ +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 +/* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ + +#include +#include +#include + +#include "umem.h" + +#define MLX5CTL_UMEM_MAX_MB 64 + +static unsigned long umem_num_pages(u64 addr, size_t len) +{ + return DIV_ROUND_UP(addr + len - PAGE_ALIGN_DOWN(addr), PAGE_SIZE); +} + +struct mlx5ctl_umem { + struct sg_table sgt; + unsigned long addr; + size_t size; + size_t offset; + size_t npages; + struct task_struct *source_task; + struct mm_struct *source_mm; + struct user_struct *source_user; + u32 umem_id; + struct page **page_list; +}; + +struct mlx5ctl_umem_db { + struct xarray xarray; + struct mlx5_core_dev *mdev; + u32 uctx_uid; +}; + +static int inc_user_locked_vm(struct mlx5ctl_umem *umem, unsigned long npages) +{ + unsigned long lock_limit; + unsigned long cur_pages; + unsigned long new_pages; + + lock_limit = task_rlimit(umem->source_task, RLIMIT_MEMLOCK) >> + PAGE_SHIFT; + do { + cur_pages = atomic_long_read(&umem->source_user->locked_vm); + new_pages = cur_pages + npages; + if (new_pages > lock_limit) + return -ENOMEM; + } while (atomic_long_cmpxchg(&umem->source_user->locked_vm, cur_pages, + new_pages) != cur_pages); + return 0; +} + +static void dec_user_locked_vm(struct mlx5ctl_umem *umem, unsigned long npages) +{ + if (WARN_ON(atomic_long_read(&umem->source_user->locked_vm) < npages)) + return; + atomic_long_sub(npages, &umem->source_user->locked_vm); +} + +#define PAGES_2_MB(pages) ((pages) >> (20 - PAGE_SHIFT)) + +static struct mlx5ctl_umem *mlx5ctl_umem_pin(struct mlx5ctl_umem_db *umem_db, + unsigned long addr, size_t size) +{ + size_t npages = umem_num_pages(addr, size); + struct mlx5_core_dev *mdev = umem_db->mdev; + unsigned long endaddr = addr + size; + struct mlx5ctl_umem *umem; + struct page **page_list; + int err = -EINVAL; + int pinned = 0; + + dev_dbg(mdev->device, "%s: addr %p size %zu npages %zu\n", + __func__, (void __user *)addr, size, npages); + + /* Avoid integer overflow */ + if (endaddr < addr || PAGE_ALIGN(endaddr) < endaddr) + return ERR_PTR(-EINVAL); + + if (npages == 0 || PAGES_2_MB(npages) > MLX5CTL_UMEM_MAX_MB) + return ERR_PTR(-EINVAL); + + page_list = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL_ACCOUNT); + if (!page_list) + return ERR_PTR(-ENOMEM); + + umem = kzalloc(sizeof(*umem), GFP_KERNEL_ACCOUNT); + if (!umem) { + kvfree(page_list); + return ERR_PTR(-ENOMEM); + } + + umem->addr = addr; + umem->size = size; + umem->offset = addr & ~PAGE_MASK; + umem->npages = npages; + + umem->page_list = page_list; + umem->source_mm = current->mm; + umem->source_task = current->group_leader; + get_task_struct(current->group_leader); + umem->source_user = get_uid(current_user()); + + /* mm and RLIMIT_MEMLOCK user task accounting similar to what is + * being done in iopt_alloc_pages() and do_update_pinned() + * for IOPT_PAGES_ACCOUNT_USER @drivers/iommu/iommufd/pages.c + */ + mmgrab(umem->source_mm); + + pinned = pin_user_pages_fast(addr, npages, FOLL_WRITE, page_list); + if (pinned != npages) { + dev_dbg(mdev->device, "pin_user_pages_fast failed %d\n", pinned); + err = pinned < 0 ? pinned : -ENOMEM; + goto pin_failed; + } + + err = inc_user_locked_vm(umem, npages); + if (err) + goto pin_failed; + + atomic64_add(npages, &umem->source_mm->pinned_vm); + + err = sg_alloc_table_from_pages(&umem->sgt, page_list, npages, 0, + npages << PAGE_SHIFT, GFP_KERNEL_ACCOUNT); + if (err) { + dev_dbg(mdev->device, "sg_alloc_table failed: %d\n", err); + goto sgt_failed; + } + + dev_dbg(mdev->device, "\tsgt: size %zu npages %zu sgt.nents (%d)\n", + size, npages, umem->sgt.nents); + + err = dma_map_sgtable(mdev->device, &umem->sgt, DMA_BIDIRECTIONAL, 0); + if (err) { + dev_dbg(mdev->device, "dma_map_sgtable failed: %d\n", err); + goto dma_failed; + } + + dev_dbg(mdev->device, "\tsgt: dma_nents %d\n", umem->sgt.nents); + return umem; + +dma_failed: +sgt_failed: + sg_free_table(&umem->sgt); + atomic64_sub(npages, &umem->source_mm->pinned_vm); + dec_user_locked_vm(umem, npages); +pin_failed: + if (pinned > 0) + unpin_user_pages(page_list, pinned); + mmdrop(umem->source_mm); + free_uid(umem->source_user); + put_task_struct(umem->source_task); + + kfree(umem); + kvfree(page_list); + return ERR_PTR(err); +} + +static void mlx5ctl_umem_unpin(struct mlx5ctl_umem_db *umem_db, + struct mlx5ctl_umem *umem) +{ + struct mlx5_core_dev *mdev = umem_db->mdev; + + dev_dbg(mdev->device, "%s: addr %p size %zu npages %zu dma_nents %d\n", + __func__, (void *)umem->addr, umem->size, umem->npages, + umem->sgt.nents); + + dma_unmap_sgtable(mdev->device, &umem->sgt, DMA_BIDIRECTIONAL, 0); + sg_free_table(&umem->sgt); + + atomic64_sub(umem->npages, &umem->source_mm->pinned_vm); + dec_user_locked_vm(umem, umem->npages); + unpin_user_pages(umem->page_list, umem->npages); + mmdrop(umem->source_mm); + free_uid(umem->source_user); + put_task_struct(umem->source_task); + + kvfree(umem->page_list); + kfree(umem); +} + +static int mlx5ctl_umem_create(struct mlx5_core_dev *mdev, + struct mlx5ctl_umem *umem, u32 uid) +{ + u32 out[MLX5_ST_SZ_DW(create_umem_out)] = {}; + int err, inlen, i, n = 0; + struct scatterlist *sg; + void *in, *umemptr; + __be64 *mtt; + + inlen = MLX5_ST_SZ_BYTES(create_umem_in) + + umem->npages * MLX5_ST_SZ_BYTES(mtt); + + in = kzalloc(inlen, GFP_KERNEL_ACCOUNT); + if (!in) + return -ENOMEM; + + MLX5_SET(create_umem_in, in, opcode, MLX5_CMD_OP_CREATE_UMEM); + MLX5_SET(create_umem_in, in, uid, uid); + + umemptr = MLX5_ADDR_OF(create_umem_in, in, umem); + + MLX5_SET(umem, umemptr, log_page_size, + PAGE_SHIFT - MLX5_ADAPTER_PAGE_SHIFT); + MLX5_SET64(umem, umemptr, num_of_mtt, umem->npages); + MLX5_SET(umem, umemptr, page_offset, umem->offset); + + dev_dbg(mdev->device, + "UMEM CREATE: log_page_size %d num_of_mtt %lld page_offset %d\n", + MLX5_GET(umem, umemptr, log_page_size), + MLX5_GET64(umem, umemptr, num_of_mtt), + MLX5_GET(umem, umemptr, page_offset)); + + mtt = MLX5_ADDR_OF(create_umem_in, in, umem.mtt); + for_each_sgtable_dma_sg(&umem->sgt, sg, i) { + u64 dma_addr = sg_dma_address(sg); + ssize_t len = sg_dma_len(sg); + + for (; n < umem->npages && len > 0; n++, mtt++) { + *mtt = cpu_to_be64(dma_addr); + MLX5_SET(mtt, mtt, wr_en, 1); + MLX5_SET(mtt, mtt, rd_en, 1); + dma_addr += PAGE_SIZE; + len -= PAGE_SIZE; + } + WARN_ON_ONCE(n == umem->npages && len > 0); + } + + err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out)); + if (err) + goto out; + + umem->umem_id = MLX5_GET(create_umem_out, out, umem_id); + dev_dbg(mdev->device, "\tUMEM CREATED: umem_id %d\n", umem->umem_id); +out: + kfree(in); + return err; +} + +static void mlx5ctl_umem_destroy(struct mlx5_core_dev *mdev, + struct mlx5ctl_umem *umem) +{ + u32 in[MLX5_ST_SZ_DW(destroy_umem_in)] = {}; + + MLX5_SET(destroy_umem_in, in, opcode, MLX5_CMD_OP_DESTROY_UMEM); + MLX5_SET(destroy_umem_in, in, umem_id, umem->umem_id); + + dev_dbg(mdev->device, "UMEM DESTROY: umem_id %d\n", umem->umem_id); + mlx5_cmd_exec_in(mdev, destroy_umem, in); +} + +int mlx5ctl_umem_reg(struct mlx5ctl_umem_db *umem_db, unsigned long addr, + size_t size) +{ + struct mlx5ctl_umem *umem; + void *ret; + int err; + + umem = mlx5ctl_umem_pin(umem_db, addr, size); + if (IS_ERR(umem)) + return PTR_ERR(umem); + + err = mlx5ctl_umem_create(umem_db->mdev, umem, umem_db->uctx_uid); + if (err) + goto umem_create_err; + + ret = xa_store(&umem_db->xarray, umem->umem_id, umem, GFP_KERNEL_ACCOUNT); + if (WARN(xa_is_err(ret), "Failed to store UMEM")) { + err = xa_err(ret); + goto xa_store_err; + } + + return umem->umem_id; + +xa_store_err: + mlx5ctl_umem_destroy(umem_db->mdev, umem); +umem_create_err: + mlx5ctl_umem_unpin(umem_db, umem); + return err; +} + +int mlx5ctl_umem_unreg(struct mlx5ctl_umem_db *umem_db, u32 umem_id) +{ + struct mlx5ctl_umem *umem; + + umem = xa_erase(&umem_db->xarray, umem_id); + if (!umem) + return -ENOENT; + + mlx5ctl_umem_destroy(umem_db->mdev, umem); + mlx5ctl_umem_unpin(umem_db, umem); + return 0; +} + +struct mlx5ctl_umem_db *mlx5ctl_umem_db_create(struct mlx5_core_dev *mdev, + u32 uctx_uid) +{ + struct mlx5ctl_umem_db *umem_db; + + umem_db = kzalloc(sizeof(*umem_db), GFP_KERNEL_ACCOUNT); + if (!umem_db) + return ERR_PTR(-ENOMEM); + + xa_init(&umem_db->xarray); + umem_db->mdev = mdev; + umem_db->uctx_uid = uctx_uid; + + return umem_db; +} + +void mlx5ctl_umem_db_destroy(struct mlx5ctl_umem_db *umem_db) +{ + struct mlx5ctl_umem *umem; + unsigned long index; + + xa_for_each(&umem_db->xarray, index, umem) + mlx5ctl_umem_unreg(umem_db, umem->umem_id); + + xa_destroy(&umem_db->xarray); + kfree(umem_db); +} diff --git a/drivers/misc/mlx5ctl/umem.h b/drivers/misc/mlx5ctl/umem.h new file mode 100644 index 000000000000..9cf62e5e775e --- /dev/null +++ b/drivers/misc/mlx5ctl/umem.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ +/* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ + +#ifndef __MLX5CTL_UMEM_H__ +#define __MLX5CTL_UMEM_H__ + +#include +#include + +struct mlx5ctl_umem_db; + +struct mlx5ctl_umem_db *mlx5ctl_umem_db_create(struct mlx5_core_dev *mdev, u32 uctx_uid); +void mlx5ctl_umem_db_destroy(struct mlx5ctl_umem_db *umem_db); +int mlx5ctl_umem_reg(struct mlx5ctl_umem_db *umem_db, unsigned long addr, size_t size); +int mlx5ctl_umem_unreg(struct mlx5ctl_umem_db *umem_db, u32 umem_id); + +#endif /* __MLX5CTL_UMEM_H__ */ diff --git a/include/uapi/misc/mlx5ctl.h b/include/uapi/misc/mlx5ctl.h index 3277eaf78a37..506aa8db75b4 100644 --- a/include/uapi/misc/mlx5ctl.h +++ b/include/uapi/misc/mlx5ctl.h @@ -24,6 +24,22 @@ struct mlx5ctl_cmdrpc { __aligned_u64 flags; }; +struct mlx5ctl_umem_reg { + __aligned_u64 flags; + __u32 size; + __u32 reserved1; + __aligned_u64 addr; /* user address */ + __aligned_u64 len; /* user buffer length */ + __u32 umem_id; /* returned device's umem ID */ + __u32 reserved2; +}; + +struct mlx5ctl_umem_unreg { + __aligned_u64 flags; + __u32 size; + __u32 umem_id; +}; + #define MLX5CTL_MAX_RPC_SIZE 8192 #define MLX5CTL_IOCTL_MAGIC 0x5c @@ -34,4 +50,10 @@ struct mlx5ctl_cmdrpc { #define MLX5CTL_IOCTL_CMDRPC \ _IOWR(MLX5CTL_IOCTL_MAGIC, 0x1, struct mlx5ctl_cmdrpc) +#define MLX5CTL_IOCTL_UMEM_REG \ + _IOWR(MLX5CTL_IOCTL_MAGIC, 0x2, struct mlx5ctl_umem_reg) + +#define MLX5CTL_IOCTL_UMEM_UNREG \ + _IOWR(MLX5CTL_IOCTL_MAGIC, 0x3, struct mlx5ctl_umem_unreg) + #endif /* __MLX5CTL_IOCTL_H__ */