From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 0484145DAB; Tue, 26 Nov 2024 16:02:44 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 9078940268; Tue, 26 Nov 2024 16:02:44 +0100 (CET) Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) by mails.dpdk.org (Postfix) with ESMTP id 1CDD04025F for ; Tue, 26 Nov 2024 16:02:41 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1732633363; x=1764169363; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=CiUumxrDO0UqB+GJwnVuZK0zUXS3VMTwjgyQPYU6tyo=; b=KTMfuaMu93xfCdV1oStOBZ88gFh+c8g98e7bwDnWjxBpaJyFoBWtGPrt kg/iYKCuzQXwC8r402ciFIaC1GS9Nirj+XLlvDkPwwpy+iU34EaqqzqC6 d558qHv/fPvUa39pSNKNhePG6hzzMSsAuzvS3DhVfMxwONpt6M97ocpkr CotWwsIUo7dfYk4DRRIZl/uevTB6Y8iAw+vy/W3DBJGDhGE2K0pt8htb6 k76P77Ol3kwlBALvFWkGN6f0TrpPHyBj5nT6jU8ds8iDX6hIwfb7HpcJo btuvFjsLknU9OJzSATgWLoCPYWFJlwKf2HLghiBKl7JReixRz8LDuVTzQ Q==; X-CSE-ConnectionGUID: nhT6knT/TPeQpHotVx5d0Q== X-CSE-MsgGUID: dj1Ex4M/Rc2Iqw79IrbYuA== X-IronPort-AV: E=McAfee;i="6700,10204,11268"; a="43864654" X-IronPort-AV: E=Sophos;i="6.12,186,1728975600"; d="scan'208";a="43864654" Received: from orviesa007.jf.intel.com ([10.64.159.147]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Nov 2024 07:02:41 -0800 X-CSE-ConnectionGUID: dmN9Ht2kQrCI/A8ojpVAiQ== X-CSE-MsgGUID: /hflJTeJTmuNRUMHskrVTw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,186,1728975600"; d="scan'208";a="92048446" Received: from silpixa00401119.ir.intel.com ([10.55.129.167]) by orviesa007.jf.intel.com with ESMTP; 26 Nov 2024 07:02:40 -0800 From: Anatoly Burakov To: dev@dpdk.org, Robin Jarry Subject: [PATCH v2 1/1] usertools/devbind: allow changing UID/GID for VFIO Date: Tue, 26 Nov 2024 15:02:38 +0000 Message-ID: <3dba72cacdb5bc71e743dd84cd44e5dcde77aee7.1732633351.git.anatoly.burakov@intel.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <4cd0282dabfa59e715028ecf255468529655b487.1725285449.git.anatoly.burakov@intel.com> References: <4cd0282dabfa59e715028ecf255468529655b487.1725285449.git.anatoly.burakov@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Currently, when binding a device to VFIO, the UID/GID for the device will always stay as system default (`root`). Yet, when running DPDK as non-root user, one has to change the UID/GID of the device to match the user's UID/GID to use the device. This patch adds an option to `dpdk-devbind.py` to change the UID/GID of the device when binding it to VFIO. Signed-off-by: Anatoly Burakov --- Notes: v1 -> v2: - Replaced hard exit with an error printout usertools/dpdk-devbind.py | 41 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py index f2a2a9a12f..496d0e90e8 100755 --- a/usertools/dpdk-devbind.py +++ b/usertools/dpdk-devbind.py @@ -8,6 +8,8 @@ import subprocess import argparse import platform +import grp +import pwd from glob import glob from os.path import exists, basename @@ -108,6 +110,8 @@ status_flag = False force_flag = False noiommu_flag = False +vfio_uid = "" +vfio_gid = "" args = [] @@ -463,6 +467,22 @@ def bind_one(dev_id, driver, force): % (dev_id, filename, err)) +def own_one(dev_id, uid, gid): + """Set the IOMMU group ownership for a device""" + # find IOMMU group for a particular device + iommu_grp_base_path = os.path.join("/sys/bus/pci/devices", dev_id, "iommu_group") + try: + iommu_grp = os.path.basename(os.readlink(iommu_grp_base_path)) + # we found IOMMU group, now find the device + dev_path = os.path.join("/dev/vfio", iommu_grp) + # set the ownership + _uid = pwd.getpwnam(uid).pw_uid if uid else -1 + _gid = grp.getgrnam(gid).gr_gid if gid else -1 + os.chown(dev_path, _uid, _gid) + except OSError as err: + print(f"Error: failed to read IOMMU group for {dev_id}: {err}") + + def unbind_all(dev_list, force=False): """Unbind method, takes a list of device locations""" @@ -512,7 +532,7 @@ def check_noiommu_mode(): print("Warning: enabling unsafe no IOMMU mode for VFIO drivers") -def bind_all(dev_list, driver, force=False): +def bind_all(dev_list, driver, uid, gid, force=False): """Bind method, takes a list of device locations""" global devices @@ -544,6 +564,9 @@ def bind_all(dev_list, driver, force=False): for d in dev_list: bind_one(d, driver, force) + # if we're binding to vfio-pci, set the IOMMU user/group ownership if one was specified + if driver == "vfio-pci" and (uid or gid): + own_one(d, uid, gid) # For kernels < 3.15 when binding devices to a generic driver # (i.e. one that doesn't have a PCI ID table) using new_id, some devices @@ -697,6 +720,8 @@ def parse_args(): global force_flag global noiommu_flag global args + global vfio_uid + global vfio_gid parser = argparse.ArgumentParser( description='Utility to bind and unbind devices from Linux kernel', @@ -746,6 +771,12 @@ def parse_args(): '--noiommu-mode', action='store_true', help="If IOMMU is not available, enable no IOMMU mode for VFIO drivers") + parser.add_argument( + "-U", "--uid", help="For VFIO, specify the UID to set IOMMU group ownership" + ) + parser.add_argument( + "-G", "--gid", help="For VFIO, specify the GID to set IOMMU group ownership" + ) parser.add_argument( '--force', action='store_true', @@ -778,6 +809,10 @@ def parse_args(): b_flag = opt.bind elif opt.unbind: b_flag = "none" + if opt.uid: + vfio_uid = opt.uid + if opt.gid: + vfio_gid = opt.gid args = opt.devices if not b_flag and not status_flag: @@ -805,11 +840,13 @@ def do_arg_actions(): global status_flag global force_flag global args + global vfio_uid + global vfio_gid if b_flag in ["none", "None"]: unbind_all(args, force_flag) elif b_flag is not None: - bind_all(args, b_flag, force_flag) + bind_all(args, b_flag, vfio_uid, vfio_gid, force_flag) if status_flag: if b_flag is not None: clear_data() -- 2.43.5