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 6B9BD458E8; Mon, 2 Sep 2024 15:57:37 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 56B0240651; Mon, 2 Sep 2024 15:57:37 +0200 (CEST) Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) by mails.dpdk.org (Postfix) with ESMTP id D006C4042C for ; Mon, 2 Sep 2024 15:57:35 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1725285456; x=1756821456; h=from:to:subject:date:message-id:mime-version: content-transfer-encoding; bh=JtY0bLnz85wR/YR8bkm0IiEfZNki3m3i3pEkWx8vo4U=; b=PyeCaHggVDc9vgytm+kwaMcpdLrfQE+Qt4cZrrUcobmqV6MtPpJDbgnd Z7NW0QQRl9rDsbtAnSbG7itTKF0ASF+aUa4kYqrYmVh/XUfPb1fO2u3Y6 EP7UEjDgova6SA+7UG0tvy3WpMBqUtq4G3UDrYm3RMGhZ3ahZdmMs6h6F cxCJHXRZXgFuSzMbfc/d0e0yYEkk68vSy/di6ymk8n6aHtWjBWl3H80QI dEUAQkzbpKinVBHxxntLvBXXgineMEVmDPbjLJOW3zfh7qMlpoJqCdmEQ 6ayb9NAfLfmOdYqtBPp6XAcJvmQqmjrTTMrVNNl4163oHjmxLK0/W/Zad Q==; X-CSE-ConnectionGUID: ZuCjPdqtT1uQYwgV80NXiQ== X-CSE-MsgGUID: 3c8Ytlt2RfuajzNid+XROg== X-IronPort-AV: E=McAfee;i="6700,10204,11183"; a="23743608" X-IronPort-AV: E=Sophos;i="6.10,195,1719903600"; d="scan'208";a="23743608" Received: from fmviesa007.fm.intel.com ([10.60.135.147]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Sep 2024 06:57:35 -0700 X-CSE-ConnectionGUID: Srz6j0bMRWWepRnRPl+xdg== X-CSE-MsgGUID: khaVAyCyRcacE2+nESG8eg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,195,1719903600"; d="scan'208";a="64299900" Received: from silpixa00401119.ir.intel.com ([10.55.129.167]) by fmviesa007.fm.intel.com with ESMTP; 02 Sep 2024 06:57:34 -0700 From: Anatoly Burakov To: dev@dpdk.org, Robin Jarry Subject: [PATCH v1 1/1] usertools/devbind: allow changing UID/GID for VFIO Date: Mon, 2 Sep 2024 14:57:32 +0100 Message-ID: <4cd0282dabfa59e715028ecf255468529655b487.1725285449.git.anatoly.burakov@intel.com> X-Mailer: git-send-email 2.43.5 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 --- 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 078e8c387b..37e2b9972d 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 @@ -107,6 +109,8 @@ b_flag = None status_flag = False force_flag = False +vfio_uid = "" +vfio_gid = "" args = [] @@ -462,6 +466,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: + sys.exit(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""" @@ -482,7 +502,7 @@ def unbind_all(dev_list, force=False): unbind_one(d, force) -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 @@ -510,6 +530,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 @@ -662,6 +685,8 @@ def parse_args(): global status_dev global force_flag global args + global vfio_uid + global vfio_gid parser = argparse.ArgumentParser( description='Utility to bind and unbind devices from Linux kernel', @@ -707,6 +732,12 @@ def parse_args(): '--unbind', action='store_true', help="Unbind a device (equivalent to \"-b none\")") + 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', @@ -737,6 +768,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: @@ -764,11 +799,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