From nobody Mon Dec 1 22:03:57 2025 Received: from mail-pl1-f201.google.com (mail-pl1-f201.google.com [209.85.214.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3DB5230215A for ; Wed, 26 Nov 2025 23:17:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199065; cv=none; b=K282+0PJsFPRSSmIFADI4r23oAoKaYJzJ9hL5xNUmnAfudGy9ypk1VC/wvP48jhf2Spg8R1JVS/4jIy0oCWxCCpJO0n2ewJQ6JqSHSuIQHqN1s+E4H3Pb5dKxkJWpkdYVGSP6eVfD5wRPOMQqjJGDRt9w7Y+8bruIgYCf4G7Seo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199065; c=relaxed/simple; bh=syip/vtxgc0scKvCnUJN/SD/jcLGmSspCTDS/9yj+FU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=lVzYrz+7BYeeDIlanMxNA49rquYmZnf1O82RUy/o05Vi4Y/+lwtRmgFhvuMpcyYA33v7YRh/wmo+AOowiKpxjEbwuuaShPTk59R/d60NSbqgugY68y6VnvBkLlpRYkDFX9gvIxQKRIsbJWjCyZ3yKiswK9cjxNNRBk6XWDLimqk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=xcwit3Vd; arc=none smtp.client-ip=209.85.214.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="xcwit3Vd" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-297df52c960so4836765ad.1 for ; Wed, 26 Nov 2025 15:17:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764199064; x=1764803864; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=7657QzqYC5tw1S9kkHW7dfOPGuJbn/ahSFH3Z3YWAgY=; b=xcwit3VdnRnzCsxBGwOarx6fKCa75dUTzjuAs8tuatDMd73PW0rlr3GDGChX/CaLn7 YCqZP9GqCla5CyirXwR/ICBN8ZKFf20sPXjvUAYUmyEjywmfy9MgdEFNLWgqkA1N1ymQ oh2akUXrt73j7dpJDZdQ7T1O4qPzFlw7ucSQ0pjJ5YBg2jAhmCTOQvb7MEwFwX+9IJgy jgIPAv5Ovuw+viR0gZ9SPB250t7xLUnjNvmMhh7o61+dW6Mp7udd0bz0Ydb+txyJew5m ICkV1PqxQJ4NcnrDvgR5wZtIj6ZN9nIKpdCpDc9KLitGkDHP0xa4dy/4s6/z4mGIQulW T6MA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764199064; x=1764803864; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=7657QzqYC5tw1S9kkHW7dfOPGuJbn/ahSFH3Z3YWAgY=; b=mGZhla6rvXIQjawVj8oTjsRAikHwce7Ya+A+ATmm0iUu/8ZUz2ffB8AGpT6x2Q/ZJk Q3jiqVWr1jsYZRYp/kVFL3SwXsegT31wcL3q1VajdYQryoYmkAXBQlP2kpXy0x76HFdH f47oksWVGs3pEd4bqqQpj1CqJAXxWF3INNKrNiU9hBOqsTev3dY18ms6uzgj++ZKstV5 yhwoNaKV+mUys412VAl2dR8PPT2STQcyC9XGPiDAHy5t5MzBSinoWoVqoxR+FyTWYUUN Ejk3jqqgLXL3EgQ9uBg1c997WYaj/KqOkzPEQukCBCl0QhY1ThS/tWpFHVzby5EyrDGa OPuQ== X-Forwarded-Encrypted: i=1; AJvYcCWnJurV1XIypkOKlIGtx7Qp4mnqGxpTNSiczowllln1Unhn0C0Iy6DLvHod19TVr4AVRQX0wfyg9aIViCc=@vger.kernel.org X-Gm-Message-State: AOJu0YxmvB8HTWyz/Lya4FSNdBqPJ+rbJOXCXGrrdT7ZKvMGi7Qj/YCF YNaNz+lJOnJE8By3TjwP5yUGO6O5XpapJ+zitZ90XuHEAHh90mdn/0ay7rU+p6o+Um2w3IPFlxe WhybN7Z3yoKtdOQ== X-Google-Smtp-Source: AGHT+IFrqvW2CE4KsCsRkyATGhzcCKUihm9f3LYFtC7yBj8cCKiJpFrrrqtrKxxf/wwvyfsKZ1awzoJWJb7HZg== X-Received: from plda10.prod.google.com ([2002:a17:902:ee8a:b0:298:38d:87a6]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:b84:b0:290:cd9c:1229 with SMTP id d9443c01a7336-29b6bec4961mr206414255ad.19.1764199063649; Wed, 26 Nov 2025 15:17:43 -0800 (PST) Date: Wed, 26 Nov 2025 23:17:16 +0000 In-Reply-To: <20251126231733.3302983-1-dmatlack@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251126231733.3302983-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.487.g5c8c507ade-goog Message-ID: <20251126231733.3302983-2-dmatlack@google.com> Subject: [PATCH v4 01/18] vfio: selftests: Move run.sh into scripts directory From: David Matlack To: Alex Williamson Cc: Alex Mastro , David Matlack , Jason Gunthorpe , Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Raghavendra Rao Ananta , Vipin Sharma Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Move run.sh in a new sub-directory scripts/. This directory will be used to house various helper scripts to be used by humans and automation for running VFIO selftests. Opportunistically also switch run.sh from TEST_PROGS_EXTENDED to TEST_FILES. The former is for actual test executables that are just not run by default. TEST_FILES is a better fit for helper scripts. No functional change intended. Reviewed-by: Alex Mastro Tested-by: Alex Mastro Reviewed-by: Raghavendra Rao Ananta Signed-off-by: David Matlack --- tools/testing/selftests/vfio/Makefile | 4 +++- tools/testing/selftests/vfio/{ =3D> scripts}/run.sh | 0 2 files changed, 3 insertions(+), 1 deletion(-) rename tools/testing/selftests/vfio/{ =3D> scripts}/run.sh (100%) diff --git a/tools/testing/selftests/vfio/Makefile b/tools/testing/selftest= s/vfio/Makefile index 324ba0175a33..ad7fa4071c20 100644 --- a/tools/testing/selftests/vfio/Makefile +++ b/tools/testing/selftests/vfio/Makefile @@ -3,7 +3,9 @@ TEST_GEN_PROGS +=3D vfio_dma_mapping_test TEST_GEN_PROGS +=3D vfio_iommufd_setup_test TEST_GEN_PROGS +=3D vfio_pci_device_test TEST_GEN_PROGS +=3D vfio_pci_driver_test -TEST_PROGS_EXTENDED :=3D run.sh + +TEST_FILES +=3D scripts/run.sh + include ../lib.mk include lib/libvfio.mk =20 diff --git a/tools/testing/selftests/vfio/run.sh b/tools/testing/selftests/= vfio/scripts/run.sh similarity index 100% rename from tools/testing/selftests/vfio/run.sh rename to tools/testing/selftests/vfio/scripts/run.sh --=20 2.52.0.487.g5c8c507ade-goog From nobody Mon Dec 1 22:03:57 2025 Received: from mail-pf1-f201.google.com (mail-pf1-f201.google.com [209.85.210.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E18B631A069 for ; Wed, 26 Nov 2025 23:17:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199067; cv=none; b=EHsqvRpEtxRlTEGexPI6pqa2d8plSLGA+ObHF0+yehitvMVWMq0limibdy3PLOsVZgTdDadfCSCW02AumGmDa6Mx8vTZjQ6V52qt96UlLoF5oYvG9pxxB/bjAjhQNWjOxo/ApOSShTjxu0kiqGvHFTnJZEsyKYSVTQDmxHjMV/A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199067; c=relaxed/simple; bh=ytX3CBxQB6HM7NBMnooSFk7NJ1C8J9dghwZd8ZNMX3I=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=HQXGRlUaQE66kTgwCTZVxaUKzkiRiE3E1scSu+ICVvzy5TCpVVt/pF0+NnbDymMfV22T2yLZhXWh7KEmmzdsd4dhlD0BAqPBe6TDHOpDXv7CN1AF70w0lqkF9t7wcChWXKDvBO0o4UwwAAD2wBhqjUztLL08+Urj6lUfSLSh0OM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=kX84I2As; arc=none smtp.client-ip=209.85.210.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="kX84I2As" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7c240728e2aso349373b3a.3 for ; Wed, 26 Nov 2025 15:17:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764199065; x=1764803865; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=8Wp2S1X0hew5lZQcMv1NbnHtXE5tMGk6LyL82ko2ZiQ=; b=kX84I2AsXmCq1gftss2oLYteQ1BWfA8liVX197aFLP0aupL6K5e8/yJK5W/S1gwezP cQS0RQzzDOvbg0jeZBOH9N7rLUKffyp2j5s2LAJEBHaQQiaIaDbYG8+UFh43A0y9wUD7 5vfFosVP3txG8Nr7wmHpsOwPn4bKxQp0Z9Vfi6ZxuFU2aw/2YWkAdS4AJVZY0pIcmpV0 Ft3gKSiFEbW8UkrNogR49dK2Z/UZ87fNlTRw+2E8EvDXu1knqmNvc2rly7dYRVNOAU/D kQnNukIchwquN4qqSrkVZ225BVcbnjxw37mhQUVXscP4JM8aKVI6EUxSKGyN1tGerIAG bMhg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764199065; x=1764803865; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=8Wp2S1X0hew5lZQcMv1NbnHtXE5tMGk6LyL82ko2ZiQ=; b=RfSuVHwMSFcpC3JwgPlgizCDcykg8SlXDACT0tXjFDxtV1isk/LnvD26jfsw2fjrMB mnckFgDiULCjYjbrPa1nWHrBrhazpB3QMQYhI+Cxd7W4P0DxkBBlRi0or0K0cFlVzC65 /TQClWVX61Zg1JsX1uH5TrBlyIcMOP7UQzF2QaKsfO1pFvrtgVPjIhnKs8wzLJ0MNyyv QvrzyZkOQURii4HtxLYplHw8XovQvom/u5X89MzH8jkobAgiEJfvfrPaBctCbrq2Gnk0 cF0TmwbwblD3W5AnESED/MK5A+eyxCrtG5MqGzI5wmGpwZ72xVAU2tpRbE4VhHKmtgvc HPcQ== X-Forwarded-Encrypted: i=1; AJvYcCWhmk5vD56VvH5I+X7XEZsBnK4quqSPyn10G9XS3qrST6yrxes0TMueL4Rtd7n7REUeW21X3FAVwQDh7do=@vger.kernel.org X-Gm-Message-State: AOJu0YzDq2AkCtVEmY+U2QeHtp7zTiEmDDpo47N7n9vMf35e9A0123Ui eoBHl25lSGpbBVapHE141Kduu/m1F7qHCDLdak2aeF/rYiGxG5sZdT63uJKRI/hkGpvfzTR96bN Wl8STCaQ9RUnItg== X-Google-Smtp-Source: AGHT+IGbazQZf/QHG81eyMCjbSlrE/uzdGeYHEtqJoKQRqGpn+IKGzk8l6bKvcyAxXvVmw2bCeNKfyIocPBneA== X-Received: from pfbfp10.prod.google.com ([2002:a05:6a00:608a:b0:7b2:242c:6852]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:3d12:b0:7ac:c6f4:abc2 with SMTP id d2e1a72fcca58-7c58eaff95bmr22874258b3a.26.1764199065201; Wed, 26 Nov 2025 15:17:45 -0800 (PST) Date: Wed, 26 Nov 2025 23:17:17 +0000 In-Reply-To: <20251126231733.3302983-1-dmatlack@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251126231733.3302983-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.487.g5c8c507ade-goog Message-ID: <20251126231733.3302983-3-dmatlack@google.com> Subject: [PATCH v4 02/18] vfio: selftests: Split run.sh into separate scripts From: David Matlack To: Alex Williamson Cc: Alex Mastro , David Matlack , Jason Gunthorpe , Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Raghavendra Rao Ananta , Vipin Sharma Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Split run.sh into separate scripts (setup.sh, run.sh, cleanup.sh) to enable multi-device testing, and prepare for VFIO selftests automatically detecting which devices to use for testing by storing device metadata on the filesystem. - setup.sh takes one or more BDFs as arguments and sets up each device. Metadata about each device is stored on the filesystem in the directory: ${TMPDIR:-/tmp}/vfio-selftests-devices Within this directory is a directory for each BDF, and then files in those directories that cleanup.sh uses to cleanup the device. - run.sh runs a selftest by passing it the BDFs of all set up devices. - cleanup.sh takes zero or more BDFs as arguments and cleans up each device. If no BDFs are provided, it cleans up all devices. This split enables multi-device testing by allowing multiple BDFs to be set up and passed into tests: For example: $ tools/testing/selftests/vfio/scripts/setup.sh $ tools/testing/selftests/vfio/scripts/setup.sh $ tools/testing/selftests/vfio/scripts/run.sh echo $ tools/testing/selftests/vfio/scripts/cleanup.sh In the future, VFIO selftests can automatically detect set up devices by inspecting ${TMPDIR:-/tmp}/vfio-selftests-devices. This will avoid the need for the run.sh script. Reviewed-by: Alex Mastro Tested-by: Alex Mastro Reviewed-by: Raghavendra Rao Ananta Signed-off-by: David Matlack --- tools/testing/selftests/vfio/Makefile | 3 + .../testing/selftests/vfio/scripts/cleanup.sh | 41 +++++++ tools/testing/selftests/vfio/scripts/lib.sh | 42 +++++++ tools/testing/selftests/vfio/scripts/run.sh | 105 +----------------- tools/testing/selftests/vfio/scripts/setup.sh | 48 ++++++++ 5 files changed, 140 insertions(+), 99 deletions(-) create mode 100755 tools/testing/selftests/vfio/scripts/cleanup.sh create mode 100755 tools/testing/selftests/vfio/scripts/lib.sh create mode 100755 tools/testing/selftests/vfio/scripts/setup.sh diff --git a/tools/testing/selftests/vfio/Makefile b/tools/testing/selftest= s/vfio/Makefile index ad7fa4071c20..a29f99395206 100644 --- a/tools/testing/selftests/vfio/Makefile +++ b/tools/testing/selftests/vfio/Makefile @@ -4,7 +4,10 @@ TEST_GEN_PROGS +=3D vfio_iommufd_setup_test TEST_GEN_PROGS +=3D vfio_pci_device_test TEST_GEN_PROGS +=3D vfio_pci_driver_test =20 +TEST_FILES +=3D scripts/cleanup.sh +TEST_FILES +=3D scripts/lib.sh TEST_FILES +=3D scripts/run.sh +TEST_FILES +=3D scripts/setup.sh =20 include ../lib.mk include lib/libvfio.mk diff --git a/tools/testing/selftests/vfio/scripts/cleanup.sh b/tools/testin= g/selftests/vfio/scripts/cleanup.sh new file mode 100755 index 000000000000..69c922d8aafb --- /dev/null +++ b/tools/testing/selftests/vfio/scripts/cleanup.sh @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +source $(dirname -- "${BASH_SOURCE[0]}")/lib.sh + +function cleanup_devices() { + local device_bdf + local device_dir + + for device_bdf in "$@"; do + device_dir=3D${DEVICES_DIR}/${device_bdf} + + if [ -f ${device_dir}/vfio-pci ]; then + unbind ${device_bdf} vfio-pci + fi + + if [ -f ${device_dir}/driver_override ]; then + clear_driver_override ${device_bdf} + fi + + if [ -f ${device_dir}/driver ]; then + bind ${device_bdf} $(cat ${device_dir}/driver) + fi + + if [ -f ${device_dir}/sriov_numvfs ]; then + set_sriov_numvfs ${device_bdf} $(cat ${device_dir}/sriov_numvfs) + fi + + rm -rf ${device_dir} + done +} + +function main() { + if [ $# =3D 0 ]; then + cleanup_devices $(ls ${DEVICES_DIR}) + rmdir ${DEVICES_DIR} + else + cleanup_devices "$@" + fi +} + +main "$@" diff --git a/tools/testing/selftests/vfio/scripts/lib.sh b/tools/testing/se= lftests/vfio/scripts/lib.sh new file mode 100755 index 000000000000..9f05f29c7b86 --- /dev/null +++ b/tools/testing/selftests/vfio/scripts/lib.sh @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +readonly DEVICES_DIR=3D"${TMPDIR:-/tmp}/vfio-selftests-devices" + +function write_to() { + # Unfortunately set -x does not show redirects so use echo to manually + # tell the user what commands are being run. + echo "+ echo \"${2}\" > ${1}" + echo "${2}" > ${1} +} + +function get_driver() { + if [ -L /sys/bus/pci/devices/${1}/driver ]; then + basename $(readlink -m /sys/bus/pci/devices/${1}/driver) + fi +} + +function bind() { + write_to /sys/bus/pci/drivers/${2}/bind ${1} +} + +function unbind() { + write_to /sys/bus/pci/drivers/${2}/unbind ${1} +} + +function set_sriov_numvfs() { + write_to /sys/bus/pci/devices/${1}/sriov_numvfs ${2} +} + +function get_sriov_numvfs() { + if [ -f /sys/bus/pci/devices/${1}/sriov_numvfs ]; then + cat /sys/bus/pci/devices/${1}/sriov_numvfs + fi +} + +function set_driver_override() { + write_to /sys/bus/pci/devices/${1}/driver_override ${2} +} + +function clear_driver_override() { + set_driver_override ${1} "" +} diff --git a/tools/testing/selftests/vfio/scripts/run.sh b/tools/testing/se= lftests/vfio/scripts/run.sh index 0476b6d7adc3..91fd38f9f6f6 100755 --- a/tools/testing/selftests/vfio/scripts/run.sh +++ b/tools/testing/selftests/vfio/scripts/run.sh @@ -1,109 +1,16 @@ # SPDX-License-Identifier: GPL-2.0-or-later =20 -# Global variables initialized in main() and then used during cleanup() wh= en -# the script exits. -declare DEVICE_BDF -declare NEW_DRIVER -declare OLD_DRIVER -declare OLD_NUMVFS -declare DRIVER_OVERRIDE - -function write_to() { - # Unfortunately set -x does not show redirects so use echo to manually - # tell the user what commands are being run. - echo "+ echo \"${2}\" > ${1}" - echo "${2}" > ${1} -} - -function bind() { - write_to /sys/bus/pci/drivers/${2}/bind ${1} -} - -function unbind() { - write_to /sys/bus/pci/drivers/${2}/unbind ${1} -} - -function set_sriov_numvfs() { - write_to /sys/bus/pci/devices/${1}/sriov_numvfs ${2} -} - -function set_driver_override() { - write_to /sys/bus/pci/devices/${1}/driver_override ${2} -} - -function clear_driver_override() { - set_driver_override ${1} "" -} - -function cleanup() { - if [ "${NEW_DRIVER}" ]; then unbind ${DEVICE_BDF} ${NEW_DRIVER} ; fi - if [ "${DRIVER_OVERRIDE}" ]; then clear_driver_override ${DEVICE_BDF} ; fi - if [ "${OLD_DRIVER}" ]; then bind ${DEVICE_BDF} ${OLD_DRIVER} ; fi - if [ "${OLD_NUMVFS}" ]; then set_sriov_numvfs ${DEVICE_BDF} ${OLD_NU= MVFS} ; fi -} - -function usage() { - echo "usage: $0 [-d segment:bus:device.function] [-s] [-h] [cmd ...]" >&2 - echo >&2 - echo " -d: The BDF of the device to use for the test (required)" >&2 - echo " -h: Show this help message" >&2 - echo " -s: Drop into a shell rather than running a command" >&2 - echo >&2 - echo " cmd: The command to run and arguments to pass to it." >&2 - echo " Required when not using -s. The SBDF will be " >&2 - echo " appended to the argument list." >&2 - exit 1 -} +source $(dirname -- "${BASH_SOURCE[0]}")/lib.sh =20 function main() { - local shell - - while getopts "d:hs" opt; do - case $opt in - d) DEVICE_BDF=3D"$OPTARG" ;; - s) shell=3Dtrue ;; - *) usage ;; - esac - done - - # Shift past all optional arguments. - shift $((OPTIND - 1)) - - # Check that the user passed in the command to run. - [ ! "${shell}" ] && [ $# =3D 0 ] && usage - - # Check that the user passed in a BDF. - [ "${DEVICE_BDF}" ] || usage - - trap cleanup EXIT - set -e + local device_bdfs=3D$(ls ${DEVICES_DIR}) =20 - test -d /sys/bus/pci/devices/${DEVICE_BDF} - - if [ -f /sys/bus/pci/devices/${DEVICE_BDF}/sriov_numvfs ]; then - OLD_NUMVFS=3D$(cat /sys/bus/pci/devices/${DEVICE_BDF}/sriov_numvfs) - set_sriov_numvfs ${DEVICE_BDF} 0 - fi - - if [ -L /sys/bus/pci/devices/${DEVICE_BDF}/driver ]; then - OLD_DRIVER=3D$(basename $(readlink -m /sys/bus/pci/devices/${DEVICE_BDF}= /driver)) - unbind ${DEVICE_BDF} ${OLD_DRIVER} + if [ -z "${device_bdfs}" ]; then + echo "No devices found, skipping." + exit 4 fi =20 - set_driver_override ${DEVICE_BDF} vfio-pci - DRIVER_OVERRIDE=3Dtrue - - bind ${DEVICE_BDF} vfio-pci - NEW_DRIVER=3Dvfio-pci - - echo - if [ "${shell}" ]; then - echo "Dropping into ${SHELL} with VFIO_SELFTESTS_BDF=3D${DEVICE_BDF}" - VFIO_SELFTESTS_BDF=3D${DEVICE_BDF} ${SHELL} - else - "$@" ${DEVICE_BDF} - fi - echo + "$@" ${device_bdfs} } =20 main "$@" diff --git a/tools/testing/selftests/vfio/scripts/setup.sh b/tools/testing/= selftests/vfio/scripts/setup.sh new file mode 100755 index 000000000000..49a499e51cbe --- /dev/null +++ b/tools/testing/selftests/vfio/scripts/setup.sh @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +set -e + +source $(dirname -- "${BASH_SOURCE[0]}")/lib.sh + +function main() { + local device_bdf + local device_dir + local numvfs + local driver + + if [ $# =3D 0 ]; then + echo "usage: $0 segment:bus:device.function ..." >&2 + exit 1 + fi + + for device_bdf in "$@"; do + test -d /sys/bus/pci/devices/${device_bdf} + + device_dir=3D${DEVICES_DIR}/${device_bdf} + if [ -d "${device_dir}" ]; then + echo "${device_bdf} has already been set up, exiting." + exit 0 + fi + + mkdir -p ${device_dir} + + numvfs=3D$(get_sriov_numvfs ${device_bdf}) + if [ "${numvfs}" ]; then + set_sriov_numvfs ${device_bdf} 0 + echo ${numvfs} > ${device_dir}/sriov_numvfs + fi + + driver=3D$(get_driver ${device_bdf}) + if [ "${driver}" ]; then + unbind ${device_bdf} ${driver} + echo ${driver} > ${device_dir}/driver + fi + + set_driver_override ${device_bdf} vfio-pci + touch ${device_dir}/driver_override + + bind ${device_bdf} vfio-pci + touch ${device_dir}/vfio-pci + done +} + +main "$@" --=20 2.52.0.487.g5c8c507ade-goog From nobody Mon Dec 1 22:03:57 2025 Received: from mail-pf1-f201.google.com (mail-pf1-f201.google.com [209.85.210.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 68C842EE60B for ; Wed, 26 Nov 2025 23:17:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199068; cv=none; b=aegDpTOv+qIGfktyQ9IhtFjdmt5Pv0i0Ayf7GTWiljHrcXo/2vzSDklThRiKPAqBJLU9W1kVy/pDEFqZbXXNoJbDTG1IGqTRTfaeWE2piynGSm+p5beC2nCJCscO+kabcCACVSo8E4vJdTQy468G9PMyGRiPX4PhbRtUnkoX+TI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199068; c=relaxed/simple; bh=AvSFNKiKL+c7A+jWVKE0Bg18iz3X2ZUYRCg6aF1PgR4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=MgD143UtoZSKfSQnf/NLfc43PzuOMZRGKZUV/n1QCGvH+swW/rHth1TMUO8rMLj/XkS17oalqCny1cwd40/DXWf4jvsEC8jDOOeikayDEe7EPbOxfMGtNVU4M59f4Y9sGPlhQe8gShMBaZ/chTNQfEv0vwG74ErbI5wWmwa5m0c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=rLcrkCNb; arc=none smtp.client-ip=209.85.210.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="rLcrkCNb" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7b80de683efso353741b3a.3 for ; Wed, 26 Nov 2025 15:17:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764199067; x=1764803867; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=2NmqlILt/SIZo48TbaGQlmIwJAUYztjRVDmwIOHsj6Y=; b=rLcrkCNb0Qi94JuYAhH244e6Kr3e44p9lGcPro1K2c8iiX0iL88o6qtJqIFYFm1wDh s0C8h8TJHWYh+W5UPgVSkYasPPrPBVSv7yobkQwhE6oN+thUELA8URoZ0Qq1UjL9zyNC uEZ9mrI0TEXEAZ7Zxtl9zemUkdw2RFRt4NkxHLA7OrJhqb+GXbTbCxvHyiFeOTnZ967p GC6N/lTtKx6nEdvC2NVtzoyD2sJKvrwA9KYl4SzfUENpYNf0egcoBWGon5GqsjaEzxgJ P/PgQegCfv31AYb4rx2r4NjLq6nYoY/pU2L5+I+E7vWtRJzM6kd4jFHRiEjj6wExMRjI F0HQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764199067; x=1764803867; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=2NmqlILt/SIZo48TbaGQlmIwJAUYztjRVDmwIOHsj6Y=; b=G8YLilXbRT6U+YkwLdpklQYtqEiJKWA5P3/1q4xo4tInxPZKLhVLttiRkYh6KpgEgW emGpAQLlhijqYYlhQEx0xNArWLbtdR82pEqvoVd8xvuOaW94zBKpWo2mVeAbJOvN7EXA anouU5pNFx+V88NetQfWRrkooSsrTIILlpf2qSIBDV1aIUtEiHTuYwutdNREsO4SYkaJ gqPzN+oC2PCsqVaohdzm8eyxoM9R3uRTNorzEF4SffVZywE6MPce8Y6v/cVy1+IZeOCV fJofn11dOwMtlwzkF8tFZuaVY6w8ONg5Mex3afrDVLxXHM6EC2BcJYAuLmXO+MxzlBOP rV2w== X-Forwarded-Encrypted: i=1; AJvYcCU/pkamOaX4CKar9MovUETc7FsKas5ru3TTHXIvU/AZuTYp4yWkRSgCyze14Ohrd6pFYPob38EA93gv5Nc=@vger.kernel.org X-Gm-Message-State: AOJu0Yyl8Tq4xw5y6d6qjKy7QUVr1J8SdFiQD9ZYDmE/zh2o5o0lMCwf ItexhSP4lqpnxX4DeETs7kw5uxOgo9NQSGJhlDBn9D6o/A4Q5Zvnjn+QNeNFTE3x9MWNHBUsDwx DJYfRmIq7MwVKLQ== X-Google-Smtp-Source: AGHT+IFe/Mo3B5TgFhtPN43rvpR/V3Sb3frYIJR1W12Kqz3wnQ9iJPaORUJ41nbeEG+8jvATbp+GIwQQjnw/uw== X-Received: from pfbhj14.prod.google.com ([2002:a05:6a00:870e:b0:77d:4a42:1179]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:390d:b0:7aa:9e4d:b693 with SMTP id d2e1a72fcca58-7c58e113a8amr24159761b3a.17.1764199066615; Wed, 26 Nov 2025 15:17:46 -0800 (PST) Date: Wed, 26 Nov 2025 23:17:18 +0000 In-Reply-To: <20251126231733.3302983-1-dmatlack@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251126231733.3302983-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.487.g5c8c507ade-goog Message-ID: <20251126231733.3302983-4-dmatlack@google.com> Subject: [PATCH v4 03/18] vfio: selftests: Allow passing multiple BDFs on the command line From: David Matlack To: Alex Williamson Cc: Alex Mastro , David Matlack , Jason Gunthorpe , Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Raghavendra Rao Ananta , Vipin Sharma Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add support for passing multiple device BDFs to a test via the command line. This is a prerequisite for multi-device tests. Single-device tests can continue using vfio_selftests_get_bdf(), which will continue to return argv[argc - 1] (if it is a BDF string), or the environment variable $VFIO_SELFTESTS_BDF otherwise. For multi-device tests, a new helper called vfio_selftests_get_bdfs() is introduced which will return an array of all BDFs found at the end of argv[], as well as the number of BDFs found (passed back to the caller via argument). The array of BDFs returned does not need to be freed by the caller. The environment variable VFIO_SELFTESTS_BDF continues to support only a single BDF for the time being. Reviewed-by: Alex Mastro Tested-by: Alex Mastro Reviewed-by: Raghavendra Rao Ananta Signed-off-by: David Matlack --- .../selftests/vfio/lib/include/vfio_util.h | 2 + .../selftests/vfio/lib/vfio_pci_device.c | 57 +++++++++++++++---- 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/tools/testing/selftests/vfio/lib/include/vfio_util.h b/tools/t= esting/selftests/vfio/lib/include/vfio_util.h index 69ec0c856481..0b9a5628d23e 100644 --- a/tools/testing/selftests/vfio/lib/include/vfio_util.h +++ b/tools/testing/selftests/vfio/lib/include/vfio_util.h @@ -208,6 +208,8 @@ struct iova_allocator { * If BDF cannot be determined then the test will exit with KSFT_SKIP. */ const char *vfio_selftests_get_bdf(int *argc, char *argv[]); +char **vfio_selftests_get_bdfs(int *argc, char *argv[], int *nr_bdfs); + const char *vfio_pci_get_cdev_path(const char *bdf); =20 extern const char *default_iommu_mode; diff --git a/tools/testing/selftests/vfio/lib/vfio_pci_device.c b/tools/tes= ting/selftests/vfio/lib/vfio_pci_device.c index b479a359da12..eda8f14de797 100644 --- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c +++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c @@ -868,29 +868,64 @@ static bool is_bdf(const char *str) return count =3D=3D 4 && length =3D=3D strlen(str); } =20 -const char *vfio_selftests_get_bdf(int *argc, char *argv[]) +static char **get_bdfs_cmdline(int *argc, char *argv[], int *nr_bdfs) { - char *bdf; + int i; =20 - if (*argc > 1 && is_bdf(argv[*argc - 1])) - return argv[--(*argc)]; + for (i =3D *argc - 1; i > 0 && is_bdf(argv[i]); i--) + continue; + + i++; + *nr_bdfs =3D *argc - i; + *argc -=3D *nr_bdfs; + + return *nr_bdfs ? &argv[i] : NULL; +} + +static char *get_bdf_env(void) +{ + char *bdf; =20 bdf =3D getenv("VFIO_SELFTESTS_BDF"); - if (bdf) { - VFIO_ASSERT_TRUE(is_bdf(bdf), "Invalid BDF: %s\n", bdf); - return bdf; + if (!bdf) + return NULL; + + VFIO_ASSERT_TRUE(is_bdf(bdf), "Invalid BDF: %s\n", bdf); + return bdf; +} + +char **vfio_selftests_get_bdfs(int *argc, char *argv[], int *nr_bdfs) +{ + static char *env_bdf; + char **bdfs; + + bdfs =3D get_bdfs_cmdline(argc, argv, nr_bdfs); + if (bdfs) + return bdfs; + + env_bdf =3D get_bdf_env(); + if (env_bdf) { + *nr_bdfs =3D 1; + return &env_bdf; } =20 - fprintf(stderr, "Unable to determine which device to use, skipping test.\= n"); + fprintf(stderr, "Unable to determine which device(s) to use, skipping tes= t.\n"); fprintf(stderr, "\n"); fprintf(stderr, "To pass the device address via environment variable:\n"); fprintf(stderr, "\n"); - fprintf(stderr, " export VFIO_SELFTESTS_BDF=3Dsegment:bus:device.funct= ion\n"); + fprintf(stderr, " export VFIO_SELFTESTS_BDF=3D\"segment:bus:device.fun= ction\"\n"); fprintf(stderr, " %s [options]\n", argv[0]); fprintf(stderr, "\n"); - fprintf(stderr, "To pass the device address via argv:\n"); + fprintf(stderr, "To pass the device address(es) via argv:\n"); fprintf(stderr, "\n"); - fprintf(stderr, " %s [options] segment:bus:device.function\n", argv[0]= ); + fprintf(stderr, " %s [options] segment:bus:device.function ...\n", arg= v[0]); fprintf(stderr, "\n"); exit(KSFT_SKIP); } + +const char *vfio_selftests_get_bdf(int *argc, char *argv[]) +{ + int nr_bdfs; + + return vfio_selftests_get_bdfs(argc, argv, &nr_bdfs)[0]; +} --=20 2.52.0.487.g5c8c507ade-goog From nobody Mon Dec 1 22:03:57 2025 Received: from mail-pf1-f201.google.com (mail-pf1-f201.google.com [209.85.210.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D5EB8342505 for ; Wed, 26 Nov 2025 23:17:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199070; cv=none; b=MqUKGTvLJzyPEQIyfYqGMqXseKpFSbAv39e3XZ1HVQUZKAr5lKEKCc4a+UzBezpYv7vDnG2BBydHLeXkwxVxnlGQTapEi3JESmWIhWWNXy1xpzO20I2lqm0cJYt9AcjZ2Qy80q+mGQvKHsNIKFfjrTS8OpduJDuWPDnUmsYmTPg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199070; c=relaxed/simple; bh=5C61XC0qEnL5WHxXy1SRysK/ERPDMiRaWEn4cSWUS30=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=XEBrLJaY3xp3HZtHMS//1oP5HMDEbQq9rDN4Tsy/ZxukOKi0gER2t9GSoBaS2sAChDKDj7L7O4SEg3ucP/X0TYdUTNSxbg4dPRiu9VO7nVALSePggCN81qJyjJ/SsgJ+A0FvlAb7VEDYFBRaH61MyVEfqcQk16QuUZvKp6xkVBQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Y4zGYOnn; arc=none smtp.client-ip=209.85.210.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Y4zGYOnn" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7bf15b82042so286001b3a.1 for ; Wed, 26 Nov 2025 15:17:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764199068; x=1764803868; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=+OCk24PhXU3C7aoKD1gVeOiWKi7xUeXg11i69m3P0wo=; b=Y4zGYOnnGhx8+siXK2IqhVVAVuPxgHzDLFLGhVWXQkK8aLh7MLuJJ8ziilFR0vYda+ +mU8rGcfCuZWa3Hj0hxX0hfB0QWdlhwXB63f2F7jpwjAPgy46jkq9OinlWssIGKYVS0w yEzADmY9N63wm9wDQe0/7tFpN2DVAMGQBsJg8GriutIVgBM1UZRBonX3Q07hacJphDx/ V4Zy71ZrLajqIz7DnPuAL8Hc04OczaylolGjSo4AwgULf+w0riTvED0Qx+KdzJttEcEK Y5FNpE8bHQ8/AkYhGbyUVeGavoZcGNQbYsCQnPW954GigGKjtcgGcdVQLTGyk1k5JPti HtLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764199068; x=1764803868; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=+OCk24PhXU3C7aoKD1gVeOiWKi7xUeXg11i69m3P0wo=; b=iCyvtjU9Cfwrjz5rjOpNhja0t34cnffWnbddj031zam/kc94ZNLsZHSCPgiom/iHuq 1aTXVEA1yJDTGnY9cMzPKcZg2Qf5g2/sOoZzSxIjgd620nOAOXGye7xzge41HATzP1/z LwBcg10bCjC9HhiwYAwN0/rGUuvjSxC2TTSTWC5bq79loQYR4fldXCZhhXxYMRoUQp6X B5rIbotIkPbDDI2cZACyMm+BW5k8vHXkq6Ib52LIMSKOhDrau+ndYwE7P7QYA8sLKgyw Z0UK6VUDPIYDcH57l/BjUgQ3RYG9jK5sQFjsh+ZQv9DD5KUXS+IeHe14IJZS+QI5jKS0 mo8A== X-Forwarded-Encrypted: i=1; AJvYcCWzNVwKe1+w2QpeR7GwYWWvE+t/XQsYGs19kS9HBXihnNE8FPDeHz91U4+V6zYzFqV1lbpqp4trGGTpNf4=@vger.kernel.org X-Gm-Message-State: AOJu0Yym+vb6Km4Rq0ZjiMoYpnLMZFQ2FWBRK0FutdMULwEa+1IrGOZp XQ3Xcmqy59xHUoO1orRd1rQMH4Bi5loGqQLaIX7TK7CqtpTwseELiCefSYd2EFlWjxIv0Izx7op cq2oE+TIq+biZjg== X-Google-Smtp-Source: AGHT+IF+xlP7ilrt+htOcnUs4big4RY44y1Js5GB/kUN9mSS+cwiEmujjBuGxBoHOGncm0qXFKcnp96ynaItZQ== X-Received: from pggr18.prod.google.com ([2002:a63:d912:0:b0:b98:d6e8:a405]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:729a:b0:34e:1009:4216 with SMTP id adf61e73a8af0-3614ecbf58cmr25661817637.24.1764199068139; Wed, 26 Nov 2025 15:17:48 -0800 (PST) Date: Wed, 26 Nov 2025 23:17:19 +0000 In-Reply-To: <20251126231733.3302983-1-dmatlack@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251126231733.3302983-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.487.g5c8c507ade-goog Message-ID: <20251126231733.3302983-5-dmatlack@google.com> Subject: [PATCH v4 04/18] vfio: selftests: Rename struct vfio_iommu_mode to iommu_mode From: David Matlack To: Alex Williamson Cc: Alex Mastro , David Matlack , Jason Gunthorpe , Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Raghavendra Rao Ananta , Vipin Sharma Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Rename struct vfio_iommu_mode to struct iommu_mode since the mode can include iommufd. This also prepares for splitting out all the IOMMU code into its own structs/helpers/files which are independent from the vfio_pci_device code. No function change intended. Reviewed-by: Alex Mastro Tested-by: Alex Mastro Reviewed-by: Raghavendra Rao Ananta Signed-off-by: David Matlack --- tools/testing/selftests/vfio/lib/include/vfio_util.h | 4 ++-- tools/testing/selftests/vfio/lib/vfio_pci_device.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/vfio/lib/include/vfio_util.h b/tools/t= esting/selftests/vfio/lib/include/vfio_util.h index 0b9a5628d23e..2f5555138d7f 100644 --- a/tools/testing/selftests/vfio/lib/include/vfio_util.h +++ b/tools/testing/selftests/vfio/lib/include/vfio_util.h @@ -50,7 +50,7 @@ VFIO_LOG_AND_EXIT(_fmt, ##__VA_ARGS__); \ } while (0) =20 -struct vfio_iommu_mode { +struct iommu_mode { const char *name; const char *container_path; unsigned long iommu_type; @@ -166,7 +166,7 @@ struct vfio_pci_driver { struct vfio_pci_device { int fd; =20 - const struct vfio_iommu_mode *iommu_mode; + const struct iommu_mode *iommu_mode; int group_fd; int container_fd; =20 diff --git a/tools/testing/selftests/vfio/lib/vfio_pci_device.c b/tools/tes= ting/selftests/vfio/lib/vfio_pci_device.c index eda8f14de797..4a021ff4fc40 100644 --- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c +++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c @@ -713,7 +713,7 @@ const char *vfio_pci_get_cdev_path(const char *bdf) } =20 /* Reminder: Keep in sync with FIXTURE_VARIANT_ADD_ALL_IOMMU_MODES(). */ -static const struct vfio_iommu_mode iommu_modes[] =3D { +static const struct iommu_mode iommu_modes[] =3D { { .name =3D "vfio_type1_iommu", .container_path =3D "/dev/vfio/vfio", @@ -741,7 +741,7 @@ static const struct vfio_iommu_mode iommu_modes[] =3D { =20 const char *default_iommu_mode =3D "iommufd"; =20 -static const struct vfio_iommu_mode *lookup_iommu_mode(const char *iommu_m= ode) +static const struct iommu_mode *lookup_iommu_mode(const char *iommu_mode) { int i; =20 --=20 2.52.0.487.g5c8c507ade-goog From nobody Mon Dec 1 22:03:57 2025 Received: from mail-pf1-f201.google.com (mail-pf1-f201.google.com [209.85.210.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 940E634402B for ; Wed, 26 Nov 2025 23:17:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199072; cv=none; b=QHpdTViaHrJeOEm/D9t9qNnV8ZH98gM3CAZW2xjo9dOjMxyOOUOWOh5LwVUNXOoOYw3qadKI0vWJRlNHj92CZYxIKDw7/gJYccVdHWUz7MJ+LtupYA9TBuKTh1Ea5TNi3STu/WjxG3Zv3eftAGjWoZZz1NyoypSYgClRy82zFsI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199072; c=relaxed/simple; bh=4ctcwjOZpYfjhBgr81oa+ZMQJXqIEiQxp8XLN4bP2ys=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=DHeRA0lMJbIP/3HiHvSQQj3x92GOwnWNc4/koXh4vZr0XpcB8/NnMV9qgaoDQnEYkklxQ9S0cl2uXPxTIQozdjGKuH1Hv3b3xFTUk2xug5GPVmxxS+ENAU7zwAfuA8MRTsA796j9cRbQpeogqSr+xr2jlRwtFyLpvF6KGIXLLyY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=BzzI7MBg; arc=none smtp.client-ip=209.85.210.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="BzzI7MBg" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7b9321b9312so400609b3a.1 for ; Wed, 26 Nov 2025 15:17:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764199070; x=1764803870; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=kbH7teUW9AJZSiPpZ4cl9Q7VSRKbEEWLu0lijd6mElE=; b=BzzI7MBgWwYASfwwLTWHS9fKsKlu7yiT9NkgYGbB42x/GqgPbB3XDdccXPVxo6MmU7 ddhHrcm77no7wbMfeyiidQ/hee9YTP0nOGKAK6K6mScKgK4XrRUPsKFCERG3ozyss3i0 vaIjjTEXRTUgO+525GVBDLGatY5gwQj1RnV5KMZUCz7z8tSMKvdpL6LdP6qPcqdPt9eZ 3FJo3gwpVNQF9nE8O5RcxvZZmcHOmKy+Kj11X+KrxZ1LSn/J3Gj0DqxhRdKS5CCWYe2A sLvzXdGsbiVQjSAmOfU2e1cUqoawzSgSYyBouacumgc2DiXomUEXSebl8Smfmah95YFx TWRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764199070; x=1764803870; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=kbH7teUW9AJZSiPpZ4cl9Q7VSRKbEEWLu0lijd6mElE=; b=Hkkx3F+x6l0Ib9q3HA3oTzGnv5LM/SldfV0Oly2MvqX7tGR9GEanX4K4bopMTaY/EM 7M2qrMHVbSWn8mj9ACPvZNtuaW0EBgDnWJTnqUu0tZM7PQDl12gQ4XQ4GV6PTZwofFD9 ayX0LVqb3dzSWLKXFi0bKpx3LxeSGLOfZPJs0MVNXQ+vZgQkJjTRSew8IiHEpuLpaL/f jjFsKjOUK8lr7vy8N/yTSzjhr9Q3xQfPNXYof+7RZ8kJWr4K2+YFUsyOPhvO3e+rJmCK l07dOoanSLD3i0IzNV7WlscSrvHyv7OgaUr/hc2KbwrQE77WK9FDZUrgimNBfGwrLgKo ZuJQ== X-Forwarded-Encrypted: i=1; AJvYcCWAdHWHQ1knWal/T9hd48dap8AidTrF0oals5Sozjnegc2kNp4XyMXq7rbNpSGwnhBB2f0kvEXEqiB5ma4=@vger.kernel.org X-Gm-Message-State: AOJu0Yz4tnRLZLed12lFCCGpk0kLosaT9PN8REMGwD/0WaaQvSKQU7SZ Jxi6ZEdlAYUrsaYLF+ISBQDz+2W2RSYpH7/CTt1hnsjt7No2YW0NkAdpqNBSKzZSITcoYu+fIxF pNIZhruqaX+Vymw== X-Google-Smtp-Source: AGHT+IEs/72sCxSAjVsycUAtS0UnnCUVTdlRwBfkbycI/Oud/l4DJ5rvVGzu5Cvo4BL3ofWvpQOSijID+Ehxfg== X-Received: from pfht15.prod.google.com ([2002:a62:ea0f:0:b0:77f:68a4:6770]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a21:998b:b0:34f:ec81:bc3a with SMTP id adf61e73a8af0-36150f05ca6mr25468146637.28.1764199069736; Wed, 26 Nov 2025 15:17:49 -0800 (PST) Date: Wed, 26 Nov 2025 23:17:20 +0000 In-Reply-To: <20251126231733.3302983-1-dmatlack@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251126231733.3302983-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.487.g5c8c507ade-goog Message-ID: <20251126231733.3302983-6-dmatlack@google.com> Subject: [PATCH v4 05/18] vfio: selftests: Introduce struct iommu From: David Matlack To: Alex Williamson Cc: Alex Mastro , David Matlack , Jason Gunthorpe , Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Raghavendra Rao Ananta , Vipin Sharma Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Introduce struct iommu, which logically represents either a VFIO container or an iommufd IOAS, depending on which IOMMU mode is used by the test. This will be used in a subsequent commit to allow devices to be added to the same container/iommufd. Reviewed-by: Alex Mastro Tested-by: Alex Mastro Reviewed-by: Raghavendra Rao Ananta Signed-off-by: David Matlack --- .../selftests/vfio/lib/include/vfio_util.h | 16 ++-- .../selftests/vfio/lib/vfio_pci_device.c | 75 ++++++++++--------- 2 files changed, 49 insertions(+), 42 deletions(-) diff --git a/tools/testing/selftests/vfio/lib/include/vfio_util.h b/tools/t= esting/selftests/vfio/lib/include/vfio_util.h index 2f5555138d7f..3160f2d1ea6d 100644 --- a/tools/testing/selftests/vfio/lib/include/vfio_util.h +++ b/tools/testing/selftests/vfio/lib/include/vfio_util.h @@ -163,15 +163,19 @@ struct vfio_pci_driver { int msi; }; =20 +struct iommu { + const struct iommu_mode *mode; + int container_fd; + int iommufd; + u32 ioas_id; + struct list_head dma_regions; +}; + struct vfio_pci_device { int fd; - - const struct iommu_mode *iommu_mode; int group_fd; - int container_fd; =20 - int iommufd; - u32 ioas_id; + struct iommu *iommu; =20 struct vfio_device_info info; struct vfio_region_info config_space; @@ -180,8 +184,6 @@ struct vfio_pci_device { struct vfio_irq_info msi_info; struct vfio_irq_info msix_info; =20 - struct list_head dma_regions; - /* eventfds for MSI and MSI-x interrupts */ int msi_eventfds[PCI_MSIX_FLAGS_QSIZE + 1]; =20 diff --git a/tools/testing/selftests/vfio/lib/vfio_pci_device.c b/tools/tes= ting/selftests/vfio/lib/vfio_pci_device.c index 4a021ff4fc40..e47f3ccf6d49 100644 --- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c +++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c @@ -277,7 +277,7 @@ iova_t __to_iova(struct vfio_pci_device *device, void *= vaddr) { struct vfio_dma_region *region; =20 - list_for_each_entry(region, &device->dma_regions, link) { + list_for_each_entry(region, &device->iommu->dma_regions, link) { if (vaddr < region->vaddr) continue; =20 @@ -397,7 +397,7 @@ static int vfio_iommu_dma_map(struct vfio_pci_device *d= evice, .size =3D region->size, }; =20 - if (ioctl(device->container_fd, VFIO_IOMMU_MAP_DMA, &args)) + if (ioctl(device->iommu->container_fd, VFIO_IOMMU_MAP_DMA, &args)) return -errno; =20 return 0; @@ -414,10 +414,10 @@ static int iommufd_dma_map(struct vfio_pci_device *de= vice, .user_va =3D (u64)region->vaddr, .iova =3D region->iova, .length =3D region->size, - .ioas_id =3D device->ioas_id, + .ioas_id =3D device->iommu->ioas_id, }; =20 - if (ioctl(device->iommufd, IOMMU_IOAS_MAP, &args)) + if (ioctl(device->iommu->iommufd, IOMMU_IOAS_MAP, &args)) return -errno; =20 return 0; @@ -428,7 +428,7 @@ int __vfio_pci_dma_map(struct vfio_pci_device *device, { int ret; =20 - if (device->iommufd) + if (device->iommu->iommufd) ret =3D iommufd_dma_map(device, region); else ret =3D vfio_iommu_dma_map(device, region); @@ -436,7 +436,7 @@ int __vfio_pci_dma_map(struct vfio_pci_device *device, if (ret) return ret; =20 - list_add(®ion->link, &device->dma_regions); + list_add(®ion->link, &device->iommu->dma_regions); =20 return 0; } @@ -484,13 +484,14 @@ int __vfio_pci_dma_unmap(struct vfio_pci_device *devi= ce, { int ret; =20 - if (device->iommufd) - ret =3D iommufd_dma_unmap(device->iommufd, region->iova, - region->size, device->ioas_id, + if (device->iommu->iommufd) + ret =3D iommufd_dma_unmap(device->iommu->iommufd, region->iova, + region->size, device->iommu->ioas_id, unmapped); else - ret =3D vfio_iommu_dma_unmap(device->container_fd, region->iova, - region->size, 0, unmapped); + ret =3D vfio_iommu_dma_unmap(device->iommu->container_fd, + region->iova, region->size, 0, + unmapped); =20 if (ret) return ret; @@ -505,17 +506,17 @@ int __vfio_pci_dma_unmap_all(struct vfio_pci_device *= device, u64 *unmapped) int ret; struct vfio_dma_region *curr, *next; =20 - if (device->iommufd) - ret =3D iommufd_dma_unmap(device->iommufd, 0, UINT64_MAX, - device->ioas_id, unmapped); + if (device->iommu->iommufd) + ret =3D iommufd_dma_unmap(device->iommu->iommufd, 0, UINT64_MAX, + device->iommu->ioas_id, unmapped); else - ret =3D vfio_iommu_dma_unmap(device->container_fd, 0, 0, + ret =3D vfio_iommu_dma_unmap(device->iommu->container_fd, 0, 0, VFIO_DMA_UNMAP_FLAG_ALL, unmapped); =20 if (ret) return ret; =20 - list_for_each_entry_safe(curr, next, &device->dma_regions, link) + list_for_each_entry_safe(curr, next, &device->iommu->dma_regions, link) list_del_init(&curr->link); =20 return 0; @@ -627,28 +628,28 @@ static void vfio_pci_group_setup(struct vfio_pci_devi= ce *device, const char *bdf ioctl_assert(device->group_fd, VFIO_GROUP_GET_STATUS, &group_status); VFIO_ASSERT_TRUE(group_status.flags & VFIO_GROUP_FLAGS_VIABLE); =20 - ioctl_assert(device->group_fd, VFIO_GROUP_SET_CONTAINER, &device->contain= er_fd); + ioctl_assert(device->group_fd, VFIO_GROUP_SET_CONTAINER, &device->iommu->= container_fd); } =20 static void vfio_pci_container_setup(struct vfio_pci_device *device, const= char *bdf) { - unsigned long iommu_type =3D device->iommu_mode->iommu_type; - const char *path =3D device->iommu_mode->container_path; + unsigned long iommu_type =3D device->iommu->mode->iommu_type; + const char *path =3D device->iommu->mode->container_path; int version; int ret; =20 - device->container_fd =3D open(path, O_RDWR); - VFIO_ASSERT_GE(device->container_fd, 0, "open(%s) failed\n", path); + device->iommu->container_fd =3D open(path, O_RDWR); + VFIO_ASSERT_GE(device->iommu->container_fd, 0, "open(%s) failed\n", path); =20 - version =3D ioctl(device->container_fd, VFIO_GET_API_VERSION); + version =3D ioctl(device->iommu->container_fd, VFIO_GET_API_VERSION); VFIO_ASSERT_EQ(version, VFIO_API_VERSION, "Unsupported version: %d\n", ve= rsion); =20 vfio_pci_group_setup(device, bdf); =20 - ret =3D ioctl(device->container_fd, VFIO_CHECK_EXTENSION, iommu_type); + ret =3D ioctl(device->iommu->container_fd, VFIO_CHECK_EXTENSION, iommu_ty= pe); VFIO_ASSERT_GT(ret, 0, "VFIO IOMMU type %lu not supported\n", iommu_type); =20 - ioctl_assert(device->container_fd, VFIO_SET_IOMMU, (void *)iommu_type); + ioctl_assert(device->iommu->container_fd, VFIO_SET_IOMMU, (void *)iommu_t= ype); =20 device->fd =3D ioctl(device->group_fd, VFIO_GROUP_GET_DEVICE_FD, bdf); VFIO_ASSERT_GE(device->fd, 0); @@ -801,12 +802,12 @@ static void vfio_pci_iommufd_setup(struct vfio_pci_de= vice *device, const char *b * used to check if iommufd is enabled. In practice open() will never * return 0 unless stdin is closed. */ - device->iommufd =3D open("/dev/iommu", O_RDWR); - VFIO_ASSERT_GT(device->iommufd, 0); + device->iommu->iommufd =3D open("/dev/iommu", O_RDWR); + VFIO_ASSERT_GT(device->iommu->iommufd, 0); =20 - vfio_device_bind_iommufd(device->fd, device->iommufd); - device->ioas_id =3D iommufd_ioas_alloc(device->iommufd); - vfio_device_attach_iommufd_pt(device->fd, device->ioas_id); + vfio_device_bind_iommufd(device->fd, device->iommu->iommufd); + device->iommu->ioas_id =3D iommufd_ioas_alloc(device->iommu->iommufd); + vfio_device_attach_iommufd_pt(device->fd, device->iommu->ioas_id); } =20 struct vfio_pci_device *vfio_pci_device_init(const char *bdf, const char *= iommu_mode) @@ -816,11 +817,14 @@ struct vfio_pci_device *vfio_pci_device_init(const ch= ar *bdf, const char *iommu_ device =3D calloc(1, sizeof(*device)); VFIO_ASSERT_NOT_NULL(device); =20 - INIT_LIST_HEAD(&device->dma_regions); + device->iommu =3D calloc(1, sizeof(*device->iommu)); + VFIO_ASSERT_NOT_NULL(device->iommu); + + INIT_LIST_HEAD(&device->iommu->dma_regions); =20 - device->iommu_mode =3D lookup_iommu_mode(iommu_mode); + device->iommu->mode =3D lookup_iommu_mode(iommu_mode); =20 - if (device->iommu_mode->container_path) + if (device->iommu->mode->container_path) vfio_pci_container_setup(device, bdf); else vfio_pci_iommufd_setup(device, bdf); @@ -849,13 +853,14 @@ void vfio_pci_device_cleanup(struct vfio_pci_device *= device) VFIO_ASSERT_EQ(close(device->msi_eventfds[i]), 0); } =20 - if (device->iommufd) { - VFIO_ASSERT_EQ(close(device->iommufd), 0); + if (device->iommu->iommufd) { + VFIO_ASSERT_EQ(close(device->iommu->iommufd), 0); } else { VFIO_ASSERT_EQ(close(device->group_fd), 0); - VFIO_ASSERT_EQ(close(device->container_fd), 0); + VFIO_ASSERT_EQ(close(device->iommu->container_fd), 0); } =20 + free(device->iommu); free(device); } =20 --=20 2.52.0.487.g5c8c507ade-goog From nobody Mon Dec 1 22:03:57 2025 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 07DB23451A9 for ; Wed, 26 Nov 2025 23:17:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199074; cv=none; b=CvT9+cOxUp3Were+jxPgFpdm4VfMztsEcjbenKS5DnIvW00lgREmEbjyc+OowS3Z3qgz6gEQUZ15hty+o/QgIAQJzE+dEzPXACywgjIUF+EaSTClKCzu9fvCkQ3/adt2mTMHhTyx5ftqzedKcjl2khE2GkP30TbFshUgJsg4wck= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199074; c=relaxed/simple; bh=YCNp5exW32lVyEKsN3YyKM3EATAsVoygjeI7UsBy2kg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Vmuux+KgD9rIUG2LCkxejTpZKpXneNwv4UT0VcSL5Av2jp7PC27X0cH7N3BuFtQZ4vlGJE+SmdAwwkRBZn7XwyiIKFpFVUMYwRc+jcGog6ekfH5BlnMlZcA7DnifRmNoakL/D0FyIVgeo0QCquSyTwskP3bnr7t/Tj6QoKsRUJ8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=3zVVHfeU; arc=none smtp.client-ip=209.85.210.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="3zVVHfeU" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7b895b520a2so203465b3a.0 for ; Wed, 26 Nov 2025 15:17:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764199071; x=1764803871; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=tp2QfL81HeYkEmybtf3oTnuFNfU89MRDB4ynbfrqFdY=; b=3zVVHfeUFurIbUnLXjEqa8jIPEsSFHzOhEWmVIIsVBWm5gxA7ftO4lMlD88mvEWSbT vnOTrtqhnpAhOXygHRShz2qTl/plcwZ4rEODztLDhuhKnciEiRxDkIux2YVrkcyENb+5 ASkXRwuDfF6IdphiToKHMoyjncpJNA+AWT3AwAmtWU2mAsEerffyQiR29engMuNQLW/p RQb72QzG21IHrWnE2ffl+exoUkd6dgbeiZRUw+dSbWM+s6hqbDvvhLASA2eHGAtwa9OA YFUXLXW4A175vqa+Qi6RtduIvAOs/5i/z4HZp0DZHKLoUNGbStLutLA0eb7FV1PGovbB dKRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764199071; x=1764803871; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=tp2QfL81HeYkEmybtf3oTnuFNfU89MRDB4ynbfrqFdY=; b=rO7OK9nO8dDQuH98tLZR5TS76jfXvQLJ+ZbKTDTQNKBMIR5atQIL4QqxcIeylqLDQ0 RfhZNtb4I8RSQlqCA8ZCgB0WhBDYLAnqczf5SZy7xgaiUpXv2CNeqEvBIP3hnEzK1NFZ T032ZvA6/AoDzeohyDzywv5emr8yqpjQUSMlCZM5s1g12Dp/XNz03G5xHJjm9wv9VAPl TpJ+Y1JfgRKrrzxG9YbRlGg+8Q9h2fY5YQHQGe4R+Mmy4RMdwxQnGiPF9E+p/3o1xbL+ n8EbRpiOkvk9KrOLPKTafH0yFpsldEspeg/45FSjJMjXZYd45FUdqfa9hEism+PtHrtO bGvw== X-Forwarded-Encrypted: i=1; AJvYcCX6m8EOEmBI8FwXrtqdxWIn0vlFRioggjlhKovI3+wponJ4vp+kUdj/WGcQqeFXkUQcPEmexnN5p32ZljE=@vger.kernel.org X-Gm-Message-State: AOJu0YyZJCPqHhikQi7rrCRL3eA9yKGVqTK1gCS0/d0ZJVpqRrD5hhUZ KziNm1pjOHQh4JUaiFzwJTj1+bNGgrVAEN48WGlptGrvaNjvZ3su07ZCr9mr0TJk+Y2sGaggvHH WaPMZHDCwWVqT4g== X-Google-Smtp-Source: AGHT+IHbPo4CIPor/dlQa7CXCwEcAnlLnvqHbzfxTmlxWJm6Fe+s4k8pKv+zsQHhoQaPkkVv6Hs96mZoVwWgBQ== X-Received: from pfbfx22.prod.google.com ([2002:a05:6a00:8216:b0:7cf:2dad:ff8d]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:3c8e:b0:350:66b2:9729 with SMTP id adf61e73a8af0-3637e0dfe43mr8731522637.60.1764199071285; Wed, 26 Nov 2025 15:17:51 -0800 (PST) Date: Wed, 26 Nov 2025 23:17:21 +0000 In-Reply-To: <20251126231733.3302983-1-dmatlack@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251126231733.3302983-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.487.g5c8c507ade-goog Message-ID: <20251126231733.3302983-7-dmatlack@google.com> Subject: [PATCH v4 06/18] vfio: selftests: Support multiple devices in the same container/iommufd From: David Matlack To: Alex Williamson Cc: Alex Mastro , David Matlack , Jason Gunthorpe , Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Raghavendra Rao Ananta , Vipin Sharma Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Support tests that want to add multiple devices to the same container/iommufd by decoupling struct vfio_pci_device from struct iommu. Multi-devices tests can now put multiple devices in the same container/iommufd like so: iommu =3D iommu_init(iommu_mode); device1 =3D vfio_pci_device_init(bdf1, iommu); device2 =3D vfio_pci_device_init(bdf2, iommu); device3 =3D vfio_pci_device_init(bdf3, iommu); ... vfio_pci_device_cleanup(device3); vfio_pci_device_cleanup(device2); vfio_pci_device_cleanup(device1); iommu_cleanup(iommu); To account for the new separation of vfio_pci_device and iommu, update existing tests to initialize and cleanup a struct iommu. Reviewed-by: Alex Mastro Tested-by: Alex Mastro Reviewed-by: Raghavendra Rao Ananta Signed-off-by: David Matlack --- .../selftests/vfio/lib/include/vfio_util.h | 6 +- .../selftests/vfio/lib/vfio_pci_device.c | 105 +++++++++++------- .../selftests/vfio/vfio_dma_mapping_test.c | 10 +- .../selftests/vfio/vfio_pci_device_test.c | 10 +- .../selftests/vfio/vfio_pci_driver_test.c | 26 ++++- 5 files changed, 107 insertions(+), 50 deletions(-) diff --git a/tools/testing/selftests/vfio/lib/include/vfio_util.h b/tools/t= esting/selftests/vfio/lib/include/vfio_util.h index 3160f2d1ea6d..379942dc5357 100644 --- a/tools/testing/selftests/vfio/lib/include/vfio_util.h +++ b/tools/testing/selftests/vfio/lib/include/vfio_util.h @@ -216,8 +216,12 @@ const char *vfio_pci_get_cdev_path(const char *bdf); =20 extern const char *default_iommu_mode; =20 -struct vfio_pci_device *vfio_pci_device_init(const char *bdf, const char *= iommu_mode); +struct iommu *iommu_init(const char *iommu_mode); +void iommu_cleanup(struct iommu *iommu); + +struct vfio_pci_device *vfio_pci_device_init(const char *bdf, struct iommu= *iommu); void vfio_pci_device_cleanup(struct vfio_pci_device *device); + void vfio_pci_device_reset(struct vfio_pci_device *device); =20 struct iommu_iova_range *vfio_pci_iova_ranges(struct vfio_pci_device *devi= ce, diff --git a/tools/testing/selftests/vfio/lib/vfio_pci_device.c b/tools/tes= ting/selftests/vfio/lib/vfio_pci_device.c index e47f3ccf6d49..8f8fed4f384d 100644 --- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c +++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c @@ -86,13 +86,13 @@ static struct vfio_iommu_type1_info *vfio_iommu_get_inf= o(struct vfio_pci_device .argsz =3D sizeof(*info), }; =20 - ioctl_assert(device->container_fd, VFIO_IOMMU_GET_INFO, info); + ioctl_assert(device->iommu->container_fd, VFIO_IOMMU_GET_INFO, info); VFIO_ASSERT_GE(info->argsz, sizeof(*info)); =20 info =3D realloc(info, info->argsz); VFIO_ASSERT_NOT_NULL(info); =20 - ioctl_assert(device->container_fd, VFIO_IOMMU_GET_INFO, info); + ioctl_assert(device->iommu->container_fd, VFIO_IOMMU_GET_INFO, info); VFIO_ASSERT_GE(info->argsz, sizeof(*info)); =20 return info; @@ -142,10 +142,10 @@ static struct iommu_iova_range *iommufd_iova_ranges(s= truct vfio_pci_device *devi =20 struct iommu_ioas_iova_ranges query =3D { .size =3D sizeof(query), - .ioas_id =3D device->ioas_id, + .ioas_id =3D device->iommu->ioas_id, }; =20 - ret =3D ioctl(device->iommufd, IOMMU_IOAS_IOVA_RANGES, &query); + ret =3D ioctl(device->iommu->iommufd, IOMMU_IOAS_IOVA_RANGES, &query); VFIO_ASSERT_EQ(ret, -1); VFIO_ASSERT_EQ(errno, EMSGSIZE); VFIO_ASSERT_GT(query.num_iovas, 0); @@ -155,7 +155,7 @@ static struct iommu_iova_range *iommufd_iova_ranges(str= uct vfio_pci_device *devi =20 query.allowed_iovas =3D (uintptr_t)ranges; =20 - ioctl_assert(device->iommufd, IOMMU_IOAS_IOVA_RANGES, &query); + ioctl_assert(device->iommu->iommufd, IOMMU_IOAS_IOVA_RANGES, &query); *nranges =3D query.num_iovas; =20 return ranges; @@ -180,7 +180,7 @@ struct iommu_iova_range *vfio_pci_iova_ranges(struct vf= io_pci_device *device, { struct iommu_iova_range *ranges; =20 - if (device->iommufd) + if (device->iommu->iommufd) ranges =3D iommufd_iova_ranges(device, nranges); else ranges =3D vfio_iommu_iova_ranges(device, nranges); @@ -633,23 +633,21 @@ static void vfio_pci_group_setup(struct vfio_pci_devi= ce *device, const char *bdf =20 static void vfio_pci_container_setup(struct vfio_pci_device *device, const= char *bdf) { - unsigned long iommu_type =3D device->iommu->mode->iommu_type; - const char *path =3D device->iommu->mode->container_path; - int version; + struct iommu *iommu =3D device->iommu; + unsigned long iommu_type =3D iommu->mode->iommu_type; int ret; =20 - device->iommu->container_fd =3D open(path, O_RDWR); - VFIO_ASSERT_GE(device->iommu->container_fd, 0, "open(%s) failed\n", path); - - version =3D ioctl(device->iommu->container_fd, VFIO_GET_API_VERSION); - VFIO_ASSERT_EQ(version, VFIO_API_VERSION, "Unsupported version: %d\n", ve= rsion); - vfio_pci_group_setup(device, bdf); =20 - ret =3D ioctl(device->iommu->container_fd, VFIO_CHECK_EXTENSION, iommu_ty= pe); + ret =3D ioctl(iommu->container_fd, VFIO_CHECK_EXTENSION, iommu_type); VFIO_ASSERT_GT(ret, 0, "VFIO IOMMU type %lu not supported\n", iommu_type); =20 - ioctl_assert(device->iommu->container_fd, VFIO_SET_IOMMU, (void *)iommu_t= ype); + /* + * Allow multiple threads to race to set the IOMMU type on the + * container. The first will succeed and the rest should fail + * because the IOMMU type is already set. + */ + (void)ioctl(iommu->container_fd, VFIO_SET_IOMMU, (void *)iommu_type); =20 device->fd =3D ioctl(device->group_fd, VFIO_GROUP_GET_DEVICE_FD, bdf); VFIO_ASSERT_GE(device->fd, 0); @@ -797,34 +795,56 @@ static void vfio_pci_iommufd_setup(struct vfio_pci_de= vice *device, const char *b VFIO_ASSERT_GE(device->fd, 0); free((void *)cdev_path); =20 - /* - * Require device->iommufd to be >0 so that a simple non-0 check can be - * used to check if iommufd is enabled. In practice open() will never - * return 0 unless stdin is closed. - */ - device->iommu->iommufd =3D open("/dev/iommu", O_RDWR); - VFIO_ASSERT_GT(device->iommu->iommufd, 0); - vfio_device_bind_iommufd(device->fd, device->iommu->iommufd); - device->iommu->ioas_id =3D iommufd_ioas_alloc(device->iommu->iommufd); vfio_device_attach_iommufd_pt(device->fd, device->iommu->ioas_id); } =20 -struct vfio_pci_device *vfio_pci_device_init(const char *bdf, const char *= iommu_mode) +struct iommu *iommu_init(const char *iommu_mode) +{ + const char *container_path; + struct iommu *iommu; + int version; + + iommu =3D calloc(1, sizeof(*iommu)); + VFIO_ASSERT_NOT_NULL(iommu); + + INIT_LIST_HEAD(&iommu->dma_regions); + + iommu->mode =3D lookup_iommu_mode(iommu_mode); + + container_path =3D iommu->mode->container_path; + if (container_path) { + iommu->container_fd =3D open(container_path, O_RDWR); + VFIO_ASSERT_GE(iommu->container_fd, 0, "open(%s) failed\n", container_pa= th); + + version =3D ioctl(iommu->container_fd, VFIO_GET_API_VERSION); + VFIO_ASSERT_EQ(version, VFIO_API_VERSION, "Unsupported version: %d\n", v= ersion); + } else { + /* + * Require device->iommufd to be >0 so that a simple non-0 check can be + * used to check if iommufd is enabled. In practice open() will never + * return 0 unless stdin is closed. + */ + iommu->iommufd =3D open("/dev/iommu", O_RDWR); + VFIO_ASSERT_GT(iommu->iommufd, 0); + + iommu->ioas_id =3D iommufd_ioas_alloc(iommu->iommufd); + } + + return iommu; +} + +struct vfio_pci_device *vfio_pci_device_init(const char *bdf, struct iommu= *iommu) { struct vfio_pci_device *device; =20 device =3D calloc(1, sizeof(*device)); VFIO_ASSERT_NOT_NULL(device); =20 - device->iommu =3D calloc(1, sizeof(*device->iommu)); - VFIO_ASSERT_NOT_NULL(device->iommu); - - INIT_LIST_HEAD(&device->iommu->dma_regions); - - device->iommu->mode =3D lookup_iommu_mode(iommu_mode); + VFIO_ASSERT_NOT_NULL(iommu); + device->iommu =3D iommu; =20 - if (device->iommu->mode->container_path) + if (iommu->mode->container_path) vfio_pci_container_setup(device, bdf); else vfio_pci_iommufd_setup(device, bdf); @@ -853,17 +873,22 @@ void vfio_pci_device_cleanup(struct vfio_pci_device *= device) VFIO_ASSERT_EQ(close(device->msi_eventfds[i]), 0); } =20 - if (device->iommu->iommufd) { - VFIO_ASSERT_EQ(close(device->iommu->iommufd), 0); - } else { + if (device->group_fd) VFIO_ASSERT_EQ(close(device->group_fd), 0); - VFIO_ASSERT_EQ(close(device->iommu->container_fd), 0); - } =20 - free(device->iommu); free(device); } =20 +void iommu_cleanup(struct iommu *iommu) +{ + if (iommu->iommufd) + VFIO_ASSERT_EQ(close(iommu->iommufd), 0); + else + VFIO_ASSERT_EQ(close(iommu->container_fd), 0); + + free(iommu); +} + static bool is_bdf(const char *str) { unsigned int s, b, d, f; diff --git a/tools/testing/selftests/vfio/vfio_dma_mapping_test.c b/tools/t= esting/selftests/vfio/vfio_dma_mapping_test.c index 102603d4407d..4727feb214c8 100644 --- a/tools/testing/selftests/vfio/vfio_dma_mapping_test.c +++ b/tools/testing/selftests/vfio/vfio_dma_mapping_test.c @@ -94,6 +94,7 @@ static int iommu_mapping_get(const char *bdf, u64 iova, } =20 FIXTURE(vfio_dma_mapping_test) { + struct iommu *iommu; struct vfio_pci_device *device; struct iova_allocator *iova_allocator; }; @@ -119,7 +120,8 @@ FIXTURE_VARIANT_ADD_ALL_IOMMU_MODES(anonymous_hugetlb_1= gb, SZ_1G, MAP_HUGETLB | =20 FIXTURE_SETUP(vfio_dma_mapping_test) { - self->device =3D vfio_pci_device_init(device_bdf, variant->iommu_mode); + self->iommu =3D iommu_init(variant->iommu_mode); + self->device =3D vfio_pci_device_init(device_bdf, self->iommu); self->iova_allocator =3D iova_allocator_init(self->device); } =20 @@ -127,6 +129,7 @@ FIXTURE_TEARDOWN(vfio_dma_mapping_test) { iova_allocator_cleanup(self->iova_allocator); vfio_pci_device_cleanup(self->device); + iommu_cleanup(self->iommu); } =20 TEST_F(vfio_dma_mapping_test, dma_map_unmap) @@ -203,6 +206,7 @@ TEST_F(vfio_dma_mapping_test, dma_map_unmap) } =20 FIXTURE(vfio_dma_map_limit_test) { + struct iommu *iommu; struct vfio_pci_device *device; struct vfio_dma_region region; size_t mmap_size; @@ -235,7 +239,8 @@ FIXTURE_SETUP(vfio_dma_map_limit_test) */ self->mmap_size =3D 2 * region_size; =20 - self->device =3D vfio_pci_device_init(device_bdf, variant->iommu_mode); + self->iommu =3D iommu_init(variant->iommu_mode); + self->device =3D vfio_pci_device_init(device_bdf, self->iommu); region->vaddr =3D mmap(NULL, self->mmap_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); ASSERT_NE(region->vaddr, MAP_FAILED); @@ -253,6 +258,7 @@ FIXTURE_SETUP(vfio_dma_map_limit_test) FIXTURE_TEARDOWN(vfio_dma_map_limit_test) { vfio_pci_device_cleanup(self->device); + iommu_cleanup(self->iommu); ASSERT_EQ(munmap(self->region.vaddr, self->mmap_size), 0); } =20 diff --git a/tools/testing/selftests/vfio/vfio_pci_device_test.c b/tools/te= sting/selftests/vfio/vfio_pci_device_test.c index 7a270698e4d2..e95217933c6b 100644 --- a/tools/testing/selftests/vfio/vfio_pci_device_test.c +++ b/tools/testing/selftests/vfio/vfio_pci_device_test.c @@ -23,17 +23,20 @@ static const char *device_bdf; #define MAX_TEST_MSI 16U =20 FIXTURE(vfio_pci_device_test) { + struct iommu *iommu; struct vfio_pci_device *device; }; =20 FIXTURE_SETUP(vfio_pci_device_test) { - self->device =3D vfio_pci_device_init(device_bdf, default_iommu_mode); + self->iommu =3D iommu_init(default_iommu_mode); + self->device =3D vfio_pci_device_init(device_bdf, self->iommu); } =20 FIXTURE_TEARDOWN(vfio_pci_device_test) { vfio_pci_device_cleanup(self->device); + iommu_cleanup(self->iommu); } =20 #define read_pci_id_from_sysfs(_file) ({ \ @@ -99,6 +102,7 @@ TEST_F(vfio_pci_device_test, validate_bars) } =20 FIXTURE(vfio_pci_irq_test) { + struct iommu *iommu; struct vfio_pci_device *device; }; =20 @@ -116,12 +120,14 @@ FIXTURE_VARIANT_ADD(vfio_pci_irq_test, msix) { =20 FIXTURE_SETUP(vfio_pci_irq_test) { - self->device =3D vfio_pci_device_init(device_bdf, default_iommu_mode); + self->iommu =3D iommu_init(default_iommu_mode); + self->device =3D vfio_pci_device_init(device_bdf, self->iommu); } =20 FIXTURE_TEARDOWN(vfio_pci_irq_test) { vfio_pci_device_cleanup(self->device); + iommu_cleanup(self->iommu); } =20 TEST_F(vfio_pci_irq_test, enable_trigger_disable) diff --git a/tools/testing/selftests/vfio/vfio_pci_driver_test.c b/tools/te= sting/selftests/vfio/vfio_pci_driver_test.c index f69eec8b928d..b0c7d812de1f 100644 --- a/tools/testing/selftests/vfio/vfio_pci_driver_test.c +++ b/tools/testing/selftests/vfio/vfio_pci_driver_test.c @@ -44,6 +44,7 @@ static void region_teardown(struct vfio_pci_device *devic= e, } =20 FIXTURE(vfio_pci_driver_test) { + struct iommu *iommu; struct vfio_pci_device *device; struct iova_allocator *iova_allocator; struct vfio_dma_region memcpy_region; @@ -73,7 +74,8 @@ FIXTURE_SETUP(vfio_pci_driver_test) { struct vfio_pci_driver *driver; =20 - self->device =3D vfio_pci_device_init(device_bdf, variant->iommu_mode); + self->iommu =3D iommu_init(variant->iommu_mode); + self->device =3D vfio_pci_device_init(device_bdf, self->iommu); self->iova_allocator =3D iova_allocator_init(self->device); =20 driver =3D &self->device->driver; @@ -113,6 +115,7 @@ FIXTURE_TEARDOWN(vfio_pci_driver_test) =20 iova_allocator_cleanup(self->iova_allocator); vfio_pci_device_cleanup(self->device); + iommu_cleanup(self->iommu); } =20 TEST_F(vfio_pci_driver_test, init_remove) @@ -231,18 +234,31 @@ TEST_F_TIMEOUT(vfio_pci_driver_test, memcpy_storm, 60) ASSERT_NO_MSI(self->msi_fd); } =20 -int main(int argc, char *argv[]) +static bool device_has_selftests_driver(const char *bdf) { struct vfio_pci_device *device; + struct iommu *iommu; + bool has_driver; + + iommu =3D iommu_init(default_iommu_mode); + device =3D vfio_pci_device_init(device_bdf, iommu); + + has_driver =3D !!device->driver.ops; + + vfio_pci_device_cleanup(device); + iommu_cleanup(iommu); =20 + return has_driver; +} + +int main(int argc, char *argv[]) +{ device_bdf =3D vfio_selftests_get_bdf(&argc, argv); =20 - device =3D vfio_pci_device_init(device_bdf, default_iommu_mode); - if (!device->driver.ops) { + if (!device_has_selftests_driver(device_bdf)) { fprintf(stderr, "No driver found for device %s\n", device_bdf); return KSFT_SKIP; } - vfio_pci_device_cleanup(device); =20 return test_harness_run(argc, argv); } --=20 2.52.0.487.g5c8c507ade-goog From nobody Mon Dec 1 22:03:57 2025 Received: from mail-pf1-f201.google.com (mail-pf1-f201.google.com [209.85.210.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7DC2C345CA3 for ; Wed, 26 Nov 2025 23:17:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199076; cv=none; b=oGpeNDjTlmSvwARw2cKsTQOWVLTSPVBQUqPc3PkIFs+uoQ5MAYmRKMcG4ptXzf9dYXIxGdMqEKO/B+GuSwbSgr/A4pMmosA60d9CLQ6uJONCn0QVhx217CMbm3t4AaWKDOkOxxLxh6CR7/eW/GHpBmsxOkoUHYgiGMRyiktPIPw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199076; c=relaxed/simple; bh=JHnO3koR6MtcgW1mrjyeErLO/KQbfdQegGSHdKrkPgM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=SSP7vHDD7Wl1s9nGKSAIIKtc3PLqlzWs6MGiCHo+4ioF7hR5BmWqcMSVFtE2XiBRY4PQjQ18v0ln6Kuz4guzvxaYFDomq87rkmx6JD1tiuVhPEjFLSVQGUfL1VzYS5wdQVU8vLoz1WRXvAu3pqWqUIVSzu+j4ewxVqRPIu+VEcI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=MGDLe4fU; arc=none smtp.client-ip=209.85.210.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="MGDLe4fU" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7ba9c366057so603600b3a.1 for ; Wed, 26 Nov 2025 15:17:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764199073; x=1764803873; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=EwUBc9dRFUqPZdHB+UIvPAI/agdY5EOkuuJxwmzSkeA=; b=MGDLe4fU3pVUUEhuxBKHp7DCs2zdVkOt2mUGTgxJGEuI+K1Dxz2pA7UVmtyC4ZG+03 YgvdLQZY7I6+7kiOmBrHBPyKPFqwtwDBOXMllHrTojy+w7BapfXLA6Hl9DEfPUbr1QOc W6EtXcbc/ScOP5R4yqFlrKZn5kFJuB1rCZuISihoJh7jQv9KqByK62PL9KLUUCGWTGh1 VX56rtsL27MVglgx974TDbXXIypn5QfUjEeOC8mn1lAw5hFtsR94KeOhiw5Q6+yl8wXm VAVRQFZEtVZaTr+MxOAKw0vJ8wT26vcsTKB5yEE0oBk/z8M/UTuhZ9RJBhtH+1j6HtbZ i0iQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764199073; x=1764803873; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=EwUBc9dRFUqPZdHB+UIvPAI/agdY5EOkuuJxwmzSkeA=; b=pZFqYaWQsVZbF07RZru+HF9yJC6AtSziMxQz3rX2HhGPflF9TabOlSWJpybqjPXPAn fEG7kuizaPXOq2Pr4uVbG0ZB4Ja1T4pPwADI9snBr3BkSua2dSJ9olWc1VnowBVblRge p9Fkt74BO9hRdZwF+e/EDVBLucy2gxsXlSf9eq1nmM7Mb1ZKhJeOyaqWshB2jrE3l7++ MThTWd07/jDEOsjQpeEc9uf4CWeKqNcj5Eq2fXz03k/PHKelv6MuEsqdpbVveN8kzePv Xs58p/5lNyt+NoXR5y53FpVZTOXunifvUW43CglXT0JwD40GUBEBHpuB6gbNBBFV3NTe 5rkQ== X-Forwarded-Encrypted: i=1; AJvYcCVSCsD5mVWvLqdH1zxOaPSS2MwoRpU6ofqiW5hO5/GPqbrFuI0EuqxoEg0ogD30qHOqJ6kZqIFEH5ol0lc=@vger.kernel.org X-Gm-Message-State: AOJu0Yzpd/9gv4NuHe+ylp+0inU7q7M59WsBWRqiS/rwAQQTQbeZPABH T8a3ch97X3rVFoK6+S2U4PaWtOoi4buJjle6u7O7U2yvkUNUsT54WnH/c21VPSFMH8KuoDoOeXT z5onYTLyr7l7F2A== X-Google-Smtp-Source: AGHT+IFm4sH1ZXQuEmtE0xbNl954CjkawYuUdXUg10ZoaftL/Uqduh+oNqyjicfbmxei5yPTlHJJwCBMW+B2Yg== X-Received: from pfie24.prod.google.com ([2002:a62:ee18:0:b0:77f:61e8:fabd]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:914a:b0:35d:8881:e6bb with SMTP id adf61e73a8af0-3637db7a71dmr9590225637.22.1764199072920; Wed, 26 Nov 2025 15:17:52 -0800 (PST) Date: Wed, 26 Nov 2025 23:17:22 +0000 In-Reply-To: <20251126231733.3302983-1-dmatlack@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251126231733.3302983-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.487.g5c8c507ade-goog Message-ID: <20251126231733.3302983-8-dmatlack@google.com> Subject: [PATCH v4 07/18] vfio: selftests: Eliminate overly chatty logging From: David Matlack To: Alex Williamson Cc: Alex Mastro , David Matlack , Jason Gunthorpe , Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Raghavendra Rao Ananta , Vipin Sharma Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Eliminate overly chatty logs that are printed during almost every test. These logs are adding more noise than value. If a test cares about this information it can log it itself. This is especially true as the VFIO selftests gains support for multiple devices in a single test (which multiplies all these logs). Reviewed-by: Alex Mastro Tested-by: Alex Mastro Reviewed-by: Raghavendra Rao Ananta Signed-off-by: David Matlack --- tools/testing/selftests/vfio/lib/vfio_pci_driver.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/tools/testing/selftests/vfio/lib/vfio_pci_driver.c b/tools/tes= ting/selftests/vfio/lib/vfio_pci_driver.c index e5e8723ecb41..abb7a62a03ea 100644 --- a/tools/testing/selftests/vfio/lib/vfio_pci_driver.c +++ b/tools/testing/selftests/vfio/lib/vfio_pci_driver.c @@ -1,6 +1,4 @@ // SPDX-License-Identifier: GPL-2.0-only -#include - #include "../../../kselftest.h" #include =20 @@ -29,7 +27,6 @@ void vfio_pci_driver_probe(struct vfio_pci_device *device) if (ops->probe(device)) continue; =20 - printf("Driver found: %s\n", ops->name); device->driver.ops =3D ops; } } @@ -58,17 +55,6 @@ void vfio_pci_driver_init(struct vfio_pci_device *device) driver->ops->init(device); =20 driver->initialized =3D true; - - printf("%s: region: vaddr %p, iova 0x%lx, size 0x%lx\n", - driver->ops->name, - driver->region.vaddr, - driver->region.iova, - driver->region.size); - - printf("%s: max_memcpy_size 0x%lx, max_memcpy_count 0x%lx\n", - driver->ops->name, - driver->max_memcpy_size, - driver->max_memcpy_count); } =20 void vfio_pci_driver_remove(struct vfio_pci_device *device) --=20 2.52.0.487.g5c8c507ade-goog From nobody Mon Dec 1 22:03:57 2025 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 23086345CCC for ; Wed, 26 Nov 2025 23:17:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199076; cv=none; b=c5irwtsohXcL7yCK9Iw7X8hiHLbpMJPIRwtauZ+VLd/AoA9fakD8eiMRKeeQF7AebGir79GBZQO0vRUi46mghmIeYaNgorWuJY+fLlyf2+raxmJny8qurOo0am0DoW3isgSDOsA1FFZYkOBjw9GGI3RuEY3ISB3+rV+ePwf52qo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199076; c=relaxed/simple; bh=KxTfth2LiC+qzfu6/CGY4Lzqbc98GbylpFUphDP8NeU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=RssinZcKAo2hzzfGjLVHz7WGogBhDL1kmjubFThpy/DcGLx+klYhz0EAe9zxiVtFV8JHW9mr18vYpYk8jWJHyXNE9Z1BgE6pDZ4BxcqiCdwrEW8Y2O6iBNCxIS5+Z4quQoghauaQeODX7uUvUo8blIgQ/GcCIGx7YWu8Ormrzxc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=A2wpbWwn; arc=none smtp.client-ip=209.85.210.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="A2wpbWwn" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7b952a966d7so364372b3a.3 for ; Wed, 26 Nov 2025 15:17:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764199074; x=1764803874; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=fbnANw2nV+Hjijn1Te7nfl7yW9KM2Nn8PxD/zuD33I8=; b=A2wpbWwnsnw2jbLcML0gzGOdlh4oNW+yb7mkgyqS8eFHk2Zq+rmoDDeFfhpNrSlMXa 7BI44XVC+eSbhuQkORlYvnz7MBBJ8FyGltN99DoruVQ/mh+nHgBQWQ0oIyxISr4qj2+2 yDaZ4UuBhAeJLdGvECmhc4KTfV7b9wd7AQZY+A5lU7BeGtHXPcsn3HjS/FLiq7OrvgsY ONHar6DkOJLQSdaZ2Ok7RZLS6hkbuEzidH1bSjMK0YsJpCmMwApTTOuRJtM2YdgIKQkk i44XlFuvg283k0V0N3mBHyG09fXffArUMT76BxmYSql7ErP6YceNGpTGrx8cHL2LlnM1 1pTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764199074; x=1764803874; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=fbnANw2nV+Hjijn1Te7nfl7yW9KM2Nn8PxD/zuD33I8=; b=bSAkjQ56Xcr0w+yZgIfdjX2x+z8M60sODLFZhkez/phcva07dAdNpJnXMnMHHOj83P cJjAThvyZ0OSXCCu5rvctJwqL1YrnZw+wtjp8UhNgBMXbgN70XblGUJRU40yW1/SgIuD RU0EvILcNqaSyFh/YrhedCsJVatlc+6YpWg7VTJzYiINRa6G/w1x0PZKxxuvoSoPWlg/ D/DnD6rzSAHLfgu/99BiLmXpRHlwqS+hHV/wvJ13+4CSiYa4q6JTOTUU5YvOPqIyVQAr 5361jq1pJkRNZ5j+eHuVO9QJiS9SjW+Wa2Mj7yKbuGKWsJTFvi9b9e3nHF/aibQkHwwD lSTQ== X-Forwarded-Encrypted: i=1; AJvYcCXngUEz64XzxfAJ+WvgEIbqCm/P9pRmdkR/HGkGCA2Qd07F7q7IopnmucU9j2dvil5uchrYDltQnScz9Ck=@vger.kernel.org X-Gm-Message-State: AOJu0Yy31pPIqaZmC0mcD7UtpHxNerXNWFSE090W1tZd55YdvubgmCuc Ga2x1C75yHLhSmZzEVaXAop+KqqVLQmwE7F6xLeZadolge0p3l+NNwBoznQU8FgvrtGpsDZhPrO XFHTbmrI2ddCE3A== X-Google-Smtp-Source: AGHT+IERDDysJurYwyfN72ycgKf3NTfFwzB800hcP5sf7Hnd0l0m0SZU3Ypa0vhU8ZHeNgQfG+QvJrHe83HMMA== X-Received: from pfhz4.prod.google.com ([2002:a05:6a00:2404:b0:7ad:9a99:34d]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:6a27:b0:350:d523:808d with SMTP id adf61e73a8af0-36150e6b162mr24955523637.15.1764199074425; Wed, 26 Nov 2025 15:17:54 -0800 (PST) Date: Wed, 26 Nov 2025 23:17:23 +0000 In-Reply-To: <20251126231733.3302983-1-dmatlack@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251126231733.3302983-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.487.g5c8c507ade-goog Message-ID: <20251126231733.3302983-9-dmatlack@google.com> Subject: [PATCH v4 08/18] vfio: selftests: Prefix logs with device BDF where relevant From: David Matlack To: Alex Williamson Cc: Alex Mastro , David Matlack , Jason Gunthorpe , Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Raghavendra Rao Ananta , Vipin Sharma Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Prefix log messages with the device's BDF where relevant. This will help understanding VFIO selftests logs when tests are run with multiple devices. Reviewed-by: Alex Mastro Tested-by: Alex Mastro Reviewed-by: Raghavendra Rao Ananta Signed-off-by: David Matlack --- .../selftests/vfio/lib/drivers/dsa/dsa.c | 34 +++++++++---------- .../selftests/vfio/lib/drivers/ioat/ioat.c | 16 ++++----- .../selftests/vfio/lib/include/vfio_util.h | 4 +++ .../selftests/vfio/lib/vfio_pci_device.c | 1 + 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/tools/testing/selftests/vfio/lib/drivers/dsa/dsa.c b/tools/tes= ting/selftests/vfio/lib/drivers/dsa/dsa.c index 0ca2cbc2a316..8d667be80229 100644 --- a/tools/testing/selftests/vfio/lib/drivers/dsa/dsa.c +++ b/tools/testing/selftests/vfio/lib/drivers/dsa/dsa.c @@ -70,7 +70,7 @@ static int dsa_probe(struct vfio_pci_device *device) return -EINVAL; =20 if (dsa_int_handle_request_required(device)) { - printf("Device requires requesting interrupt handles\n"); + dev_info(device, "Device requires requesting interrupt handles\n"); return -EINVAL; } =20 @@ -91,23 +91,23 @@ static void dsa_check_sw_err(struct vfio_pci_device *de= vice) return; } =20 - fprintf(stderr, "SWERR: 0x%016lx 0x%016lx 0x%016lx 0x%016lx\n", + dev_err(device, "SWERR: 0x%016lx 0x%016lx 0x%016lx 0x%016lx\n", err.bits[0], err.bits[1], err.bits[2], err.bits[3]); =20 - fprintf(stderr, " valid: 0x%x\n", err.valid); - fprintf(stderr, " overflow: 0x%x\n", err.overflow); - fprintf(stderr, " desc_valid: 0x%x\n", err.desc_valid); - fprintf(stderr, " wq_idx_valid: 0x%x\n", err.wq_idx_valid); - fprintf(stderr, " batch: 0x%x\n", err.batch); - fprintf(stderr, " fault_rw: 0x%x\n", err.fault_rw); - fprintf(stderr, " priv: 0x%x\n", err.priv); - fprintf(stderr, " error: 0x%x\n", err.error); - fprintf(stderr, " wq_idx: 0x%x\n", err.wq_idx); - fprintf(stderr, " operation: 0x%x\n", err.operation); - fprintf(stderr, " pasid: 0x%x\n", err.pasid); - fprintf(stderr, " batch_idx: 0x%x\n", err.batch_idx); - fprintf(stderr, " invalid_flags: 0x%x\n", err.invalid_flags); - fprintf(stderr, " fault_addr: 0x%lx\n", err.fault_addr); + dev_err(device, " valid: 0x%x\n", err.valid); + dev_err(device, " overflow: 0x%x\n", err.overflow); + dev_err(device, " desc_valid: 0x%x\n", err.desc_valid); + dev_err(device, " wq_idx_valid: 0x%x\n", err.wq_idx_valid); + dev_err(device, " batch: 0x%x\n", err.batch); + dev_err(device, " fault_rw: 0x%x\n", err.fault_rw); + dev_err(device, " priv: 0x%x\n", err.priv); + dev_err(device, " error: 0x%x\n", err.error); + dev_err(device, " wq_idx: 0x%x\n", err.wq_idx); + dev_err(device, " operation: 0x%x\n", err.operation); + dev_err(device, " pasid: 0x%x\n", err.pasid); + dev_err(device, " batch_idx: 0x%x\n", err.batch_idx); + dev_err(device, " invalid_flags: 0x%x\n", err.invalid_flags); + dev_err(device, " fault_addr: 0x%lx\n", err.fault_addr); =20 VFIO_FAIL("Software Error Detected!\n"); } @@ -256,7 +256,7 @@ static int dsa_completion_wait(struct vfio_pci_device *= device, if (status =3D=3D DSA_COMP_SUCCESS) return 0; =20 - printf("Error detected during memcpy operation: 0x%x\n", status); + dev_info(device, "Error detected during memcpy operation: 0x%x\n", status= ); return -1; } =20 diff --git a/tools/testing/selftests/vfio/lib/drivers/ioat/ioat.c b/tools/t= esting/selftests/vfio/lib/drivers/ioat/ioat.c index c3b91d9b1f59..e04dce1d544c 100644 --- a/tools/testing/selftests/vfio/lib/drivers/ioat/ioat.c +++ b/tools/testing/selftests/vfio/lib/drivers/ioat/ioat.c @@ -51,7 +51,7 @@ static int ioat_probe(struct vfio_pci_device *device) r =3D 0; break; default: - printf("ioat: Unsupported version: 0x%x\n", version); + dev_info(device, "ioat: Unsupported version: 0x%x\n", version); r =3D -EINVAL; } return r; @@ -135,13 +135,13 @@ static void ioat_handle_error(struct vfio_pci_device = *device) { void *registers =3D ioat_channel_registers(device); =20 - printf("Error detected during memcpy operation!\n" - " CHANERR: 0x%x\n" - " CHANERR_INT: 0x%x\n" - " DMAUNCERRSTS: 0x%x\n", - readl(registers + IOAT_CHANERR_OFFSET), - vfio_pci_config_readl(device, IOAT_PCI_CHANERR_INT_OFFSET), - vfio_pci_config_readl(device, IOAT_PCI_DMAUNCERRSTS_OFFSET)); + dev_info(device, "Error detected during memcpy operation!\n" + " CHANERR: 0x%x\n" + " CHANERR_INT: 0x%x\n" + " DMAUNCERRSTS: 0x%x\n", + readl(registers + IOAT_CHANERR_OFFSET), + vfio_pci_config_readl(device, IOAT_PCI_CHANERR_INT_OFFSET), + vfio_pci_config_readl(device, IOAT_PCI_DMAUNCERRSTS_OFFSET)); =20 ioat_reset(device); } diff --git a/tools/testing/selftests/vfio/lib/include/vfio_util.h b/tools/t= esting/selftests/vfio/lib/include/vfio_util.h index 379942dc5357..babbf90688e8 100644 --- a/tools/testing/selftests/vfio/lib/include/vfio_util.h +++ b/tools/testing/selftests/vfio/lib/include/vfio_util.h @@ -50,6 +50,9 @@ VFIO_LOG_AND_EXIT(_fmt, ##__VA_ARGS__); \ } while (0) =20 +#define dev_info(_dev, _fmt, ...) printf("%s: " _fmt, (_dev)->bdf, ##__VA_= ARGS__) +#define dev_err(_dev, _fmt, ...) fprintf(stderr, "%s: " _fmt, (_dev)->bdf,= ##__VA_ARGS__) + struct iommu_mode { const char *name; const char *container_path; @@ -172,6 +175,7 @@ struct iommu { }; =20 struct vfio_pci_device { + const char *bdf; int fd; int group_fd; =20 diff --git a/tools/testing/selftests/vfio/lib/vfio_pci_device.c b/tools/tes= ting/selftests/vfio/lib/vfio_pci_device.c index 8f8fed4f384d..f0cf18d3de55 100644 --- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c +++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c @@ -843,6 +843,7 @@ struct vfio_pci_device *vfio_pci_device_init(const char= *bdf, struct iommu *iomm =20 VFIO_ASSERT_NOT_NULL(iommu); device->iommu =3D iommu; + device->bdf =3D bdf; =20 if (iommu->mode->container_path) vfio_pci_container_setup(device, bdf); --=20 2.52.0.487.g5c8c507ade-goog From nobody Mon Dec 1 22:03:57 2025 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 998FE346775 for ; Wed, 26 Nov 2025 23:17:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199078; cv=none; b=JB0GMTOvSVFbNvMb3CRIelZXRjeiDxdZz6nWBAC7XBMBDh86/F65UAqnEEvRsTQ7nHnWcrGfrxF3PO3hIaH2VsTyVRK8l0hFD75UGmgYaHpClQ0BJ2WDeocb+6XZH5XohMPxuTI0lrAqYSFwLVYSSTFcCfQ6LA9DRsYZXAgP5QA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199078; c=relaxed/simple; bh=k1tQIewzaCgltNFiSSWL8XaCn9LhRqqy5e6y7F2p37c=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=XwGxR6QbYj9gwRSF+yQ9HZFd5sXvDkQMqoMkNN0gD4Vl589vwQ7quy4jKfvTK7vd36iZSRvDsMow6Gz5k28m53v4vUzT6fyMWNkE4GBW8sWSpgnyBIcqFf0CNv+Jwvc328a9raAdPl7/mR9HQwYp+l0EGA0M76XKfs4byhbxJ50= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=PHI/IxXt; arc=none smtp.client-ip=209.85.210.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="PHI/IxXt" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7b8ed43cd00so206572b3a.2 for ; Wed, 26 Nov 2025 15:17:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764199076; x=1764803876; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=lOfh0ZHCrUDr+83C96eRTcOw/RRmvXPhkUJkr4j0xPg=; b=PHI/IxXtn4VtAj2XcOXS2zJeFshcM5kaSA1f6uyOXgLGSH7WzTgj7l5WxNRUn3zV8L YK+PUAmRfJ5qNhGQxVwTBAKS6tQbe9MdaPG0OJtc4HNW2WH6iNLJ3grlfWatQQ4tFFOy eNJhIAllpgS+USnI7wkehL4C1XLMS0yh1yeZl7eXTPVMbgF6HZQrYZ4KMEvQ+Bxl+mJa gsN7a53J1JiLleulPLh/9SMKjaPkSKnXMAHSTgwb/ed1MnO3z1/zg3LDRjn7zT0iBx1H VvVFgRUCo61fzYjwcUfhYVvaCdd+LaIX0SAASbNb3CmoS8y4YAIVlzhEHreKkOlXzX3h aXTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764199076; x=1764803876; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=lOfh0ZHCrUDr+83C96eRTcOw/RRmvXPhkUJkr4j0xPg=; b=CQ7kvC3iwvQPAmpVI2gZUwpuav/Zfiy2lQzX4b8QUEhV0itZjktmxZ3JDqBKxAKnmV MHZ7hFcyHHb5GUaDTc0xe1wFCKrY8TnpLTRJAEvWirdz8ahdxO/1TYs/Hi2yUFu1um1a PTad8iNWQ/upk80Ut16a48PiUjswTz9extd01XG8qhC7WH8jAcp6MCbXKV5EdPkosAJp ebn32W+h7dXjZdC0AXdxHoXMTbU/hNncU0ryJXK2UFQ76gf7A+H2qbgZWbtxZHd50TXp PWwppycl1/oHGh+zuh1MGm4iEvVwit8sOA9Fy+k4NVrGz/8axK41YQ6xpi6umPq/l3XN xKjw== X-Forwarded-Encrypted: i=1; AJvYcCW6M+L9KOGwVWj5bMl6SWbQbvRY0T4X6Y57txF6wuTwujbDMYMd8VJKW9RwseLjjbLL0AX6QIFTz/p9CBI=@vger.kernel.org X-Gm-Message-State: AOJu0Ywgm+jJag+rB+MSL3WD0s3EQ1kRkHHGp0qMvSr6D1Flhj+oIe0N 3wBpohBGkvJVqobGo3g7GslO87TOuL5HP1NaeLIJYC5ynefs1x8u0qExynKlwot/mnULa3Dc98Q 0elQZhpM7TvLqwA== X-Google-Smtp-Source: AGHT+IHmJ+fr7Q1GH3an9MkfupTo7jjLnNjtNTKwF96iEI+a/Vr8k305CwqmodTnaoeO8QrvLpRa9pV1P1XcMA== X-Received: from pfxx5.prod.google.com ([2002:a05:6a00:105:b0:7a2:d31:34ef]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a21:32a2:b0:340:db9b:cfe8 with SMTP id adf61e73a8af0-36150e1fc11mr23928810637.12.1764199075933; Wed, 26 Nov 2025 15:17:55 -0800 (PST) Date: Wed, 26 Nov 2025 23:17:24 +0000 In-Reply-To: <20251126231733.3302983-1-dmatlack@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251126231733.3302983-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.487.g5c8c507ade-goog Message-ID: <20251126231733.3302983-10-dmatlack@google.com> Subject: [PATCH v4 09/18] vfio: selftests: Upgrade driver logging to dev_err() From: David Matlack To: Alex Williamson Cc: Alex Mastro , David Matlack , Jason Gunthorpe , Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Raghavendra Rao Ananta , Vipin Sharma Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Upgrade various logging in the VFIO selftests drivers from dev_info() to dev_err(). All of these logs indicate scenarios that may be unexpected. For example, the logging during probing indicates matching devices but that aren't supported by the driver. And the memcpy errors can indicate a problem if the caller was not trying to do something like exercise I/O fault handling. Exercising I/O fault handling is certainly a valid thing to do, but the driver can't infer the caller's expectations, so better to just log with dev_err(). Suggested-by: Raghavendra Rao Ananta Reviewed-by: Alex Mastro Tested-by: Alex Mastro Reviewed-by: Raghavendra Rao Ananta Signed-off-by: David Matlack --- tools/testing/selftests/vfio/lib/drivers/dsa/dsa.c | 4 ++-- tools/testing/selftests/vfio/lib/drivers/ioat/ioat.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/vfio/lib/drivers/dsa/dsa.c b/tools/tes= ting/selftests/vfio/lib/drivers/dsa/dsa.c index 8d667be80229..0afbab0d82de 100644 --- a/tools/testing/selftests/vfio/lib/drivers/dsa/dsa.c +++ b/tools/testing/selftests/vfio/lib/drivers/dsa/dsa.c @@ -70,7 +70,7 @@ static int dsa_probe(struct vfio_pci_device *device) return -EINVAL; =20 if (dsa_int_handle_request_required(device)) { - dev_info(device, "Device requires requesting interrupt handles\n"); + dev_err(device, "Device requires requesting interrupt handles\n"); return -EINVAL; } =20 @@ -256,7 +256,7 @@ static int dsa_completion_wait(struct vfio_pci_device *= device, if (status =3D=3D DSA_COMP_SUCCESS) return 0; =20 - dev_info(device, "Error detected during memcpy operation: 0x%x\n", status= ); + dev_err(device, "Error detected during memcpy operation: 0x%x\n", status); return -1; } =20 diff --git a/tools/testing/selftests/vfio/lib/drivers/ioat/ioat.c b/tools/t= esting/selftests/vfio/lib/drivers/ioat/ioat.c index e04dce1d544c..c6db311ce64d 100644 --- a/tools/testing/selftests/vfio/lib/drivers/ioat/ioat.c +++ b/tools/testing/selftests/vfio/lib/drivers/ioat/ioat.c @@ -51,7 +51,7 @@ static int ioat_probe(struct vfio_pci_device *device) r =3D 0; break; default: - dev_info(device, "ioat: Unsupported version: 0x%x\n", version); + dev_err(device, "ioat: Unsupported version: 0x%x\n", version); r =3D -EINVAL; } return r; @@ -135,7 +135,7 @@ static void ioat_handle_error(struct vfio_pci_device *d= evice) { void *registers =3D ioat_channel_registers(device); =20 - dev_info(device, "Error detected during memcpy operation!\n" + dev_err(device, "Error detected during memcpy operation!\n" " CHANERR: 0x%x\n" " CHANERR_INT: 0x%x\n" " DMAUNCERRSTS: 0x%x\n", --=20 2.52.0.487.g5c8c507ade-goog From nobody Mon Dec 1 22:03:57 2025 Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 35B1E346A18 for ; Wed, 26 Nov 2025 23:17:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199079; cv=none; b=n4p5wuWK9wi5mRV0Rvxkf/aoBTrvuL6w/eMSKYdV1oeWf6AkSQBH5rSDpleqHp2ZhQox1fidlfHzHOeS9WJOAkjGRfj3WzzVttu7IakggitmBqr+ACE9LENXQbpFdnRU2qwXHFR2y0FfBp/AVP9UOCn5OYLfHJwoQoroz2YGV8g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199079; c=relaxed/simple; bh=5/SCuudTnVJVagXzmpq8FqpR4LPOkZ4AQaSUVZpAyeA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=m8LMTyipMymMwX94k4M/zccGFttzM1Cqo2nJWwHnJ9sJJevNBkNsvWjyucFFy8UICw7xcVDvti46b0v91eP5aO8GPSPzzeg5bndtJfzO/tT5f1dyxQUC9bUSke/7325JCaIOOGXJb/XVmjzxaWHelwK72lXQdvoPeKc+25JAoXg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=oW1hvqn1; arc=none smtp.client-ip=209.85.216.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="oW1hvqn1" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-340c261fb38so384796a91.0 for ; Wed, 26 Nov 2025 15:17:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764199077; x=1764803877; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=2a9D5jJ9FB8GiVn7bo2b0SNxBhehEjQAFnObT7UgTmQ=; b=oW1hvqn1a71LL3ffufvUkUSm1WF1QIMuNMroMzuZp4Mg9oOD/kV/6I5O34MHXE4t5v WhlvsuI2PubNNuRiBORT2rjCwksbHlMn1K/9KUVkWZjKpYuKe352PqSv0aMmrc5yOzpG 3HRlbruKsqmHTUP7sqsNFhFqdxwTHFqbaHIsV/ZkUvWLFry0ilgf2i2gz89X0eWLZ1EE D2p8KBS8MbgC9hetmfohaplvoEMP78tb9zc+0uVQhDpwlmxCREfi0/20r8cBJdZLZfTg 9bV8h/AcIXcAYm0QDjeF6nJyI3aesUaaBSbQyP5NEptivNnWNhVXbBleH2TNm3Gl0ilU lVCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764199077; x=1764803877; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=2a9D5jJ9FB8GiVn7bo2b0SNxBhehEjQAFnObT7UgTmQ=; b=UpeYTjtpIZIpbzRs+sBS2o6VYmUDYYQYCyGKfEQ4HE56NkhyAPvwRg40zYWQy3tOYU 6VwSzLvm85RoJhbq9dSnGtMMSA7wRqGvEgCIScju0VKlm3PfB693pe8iZPMumTWMeYqQ KIo6/E98nf0vyqFq74bKi3HfF8Y6m7lhw+0pgWtUYZ1a8v45xbqKjlV8/rWdga6IdK/w UjLQAQzKeNtmosW0TYaS4zMimrUYyeDQ9u4YmUvM/MxbMHZTvg+ZR4QFl8Hcdhxd5P3p okAup3bZVJ/tYr/QTVWZUTScToCjP6kJenqfe7St75eBgCJc9RgIpzJAqBr6BJvHOO/J zW0g== X-Forwarded-Encrypted: i=1; AJvYcCVng9GlwDYPIdQX9uEU3yNyzc40YMrsG3Inj3r6igocS8he1ii7d6nqQIirsL69lEF78j3stROicFII9/w=@vger.kernel.org X-Gm-Message-State: AOJu0YyzasCiAte96E6AcMb45G5/VD8qXKVJCuooKvZeIlTzkbS+I5yS /sBxrc+PuK/qUwiQNcJuLsgQ/6OUMEb4VamI/T2Q82c3xgYNWTaG79+i+6qu4j8ISlcV3KU2wr9 LPihYQoxcgyQ/Aw== X-Google-Smtp-Source: AGHT+IHuIShD6RC7Uglwv6GJggqqApaqxy3RkM9V/d+JZpaS74r3sOttZlNtCq4H6+fs9d4t2pHOQSUCma4m6Q== X-Received: from pjbmt14.prod.google.com ([2002:a17:90b:230e:b0:33b:d40a:d93a]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3d85:b0:32d:f352:f764 with SMTP id 98e67ed59e1d1-34733e6caa6mr15630962a91.2.1764199077598; Wed, 26 Nov 2025 15:17:57 -0800 (PST) Date: Wed, 26 Nov 2025 23:17:25 +0000 In-Reply-To: <20251126231733.3302983-1-dmatlack@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251126231733.3302983-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.487.g5c8c507ade-goog Message-ID: <20251126231733.3302983-11-dmatlack@google.com> Subject: [PATCH v4 10/18] vfio: selftests: Rename struct vfio_dma_region to dma_region From: David Matlack To: Alex Williamson Cc: Alex Mastro , David Matlack , Jason Gunthorpe , Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Raghavendra Rao Ananta , Vipin Sharma Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Rename struct vfio_dma_region to dma_region. This is in preparation for separating the VFIO PCI device library code from the IOMMU library code. This name change also better reflects the fact that DMA mappings can be managed by either VFIO or IOMMUFD. i.e. the "vfio_" prefix is misleading. Reviewed-by: Alex Mastro Tested-by: Alex Mastro Reviewed-by: Raghavendra Rao Ananta Signed-off-by: David Matlack --- tools/testing/selftests/vfio/lib/include/vfio_util.h | 12 ++++++------ tools/testing/selftests/vfio/lib/vfio_pci_device.c | 12 ++++++------ tools/testing/selftests/vfio/vfio_dma_mapping_test.c | 12 ++++++------ tools/testing/selftests/vfio/vfio_pci_driver_test.c | 6 +++--- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/tools/testing/selftests/vfio/lib/include/vfio_util.h b/tools/t= esting/selftests/vfio/lib/include/vfio_util.h index babbf90688e8..7784422116de 100644 --- a/tools/testing/selftests/vfio/lib/include/vfio_util.h +++ b/tools/testing/selftests/vfio/lib/include/vfio_util.h @@ -80,7 +80,7 @@ typedef u64 iova_t; =20 #define INVALID_IOVA UINT64_MAX =20 -struct vfio_dma_region { +struct dma_region { struct list_head link; void *vaddr; iova_t iova; @@ -154,7 +154,7 @@ struct vfio_pci_driver { bool memcpy_in_progress; =20 /* Region to be used by the driver (e.g. for in-memory descriptors) */ - struct vfio_dma_region region; + struct dma_region region; =20 /* The maximum size that can be passed to memcpy_start(). */ u64 max_memcpy_size; @@ -236,20 +236,20 @@ void iova_allocator_cleanup(struct iova_allocator *al= locator); iova_t iova_allocator_alloc(struct iova_allocator *allocator, size_t size); =20 int __vfio_pci_dma_map(struct vfio_pci_device *device, - struct vfio_dma_region *region); + struct dma_region *region); int __vfio_pci_dma_unmap(struct vfio_pci_device *device, - struct vfio_dma_region *region, + struct dma_region *region, u64 *unmapped); int __vfio_pci_dma_unmap_all(struct vfio_pci_device *device, u64 *unmapped= ); =20 static inline void vfio_pci_dma_map(struct vfio_pci_device *device, - struct vfio_dma_region *region) + struct dma_region *region) { VFIO_ASSERT_EQ(__vfio_pci_dma_map(device, region), 0); } =20 static inline void vfio_pci_dma_unmap(struct vfio_pci_device *device, - struct vfio_dma_region *region) + struct dma_region *region) { VFIO_ASSERT_EQ(__vfio_pci_dma_unmap(device, region, NULL), 0); } diff --git a/tools/testing/selftests/vfio/lib/vfio_pci_device.c b/tools/tes= ting/selftests/vfio/lib/vfio_pci_device.c index f0cf18d3de55..422ad8dfad95 100644 --- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c +++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c @@ -275,7 +275,7 @@ iova_t iova_allocator_alloc(struct iova_allocator *allo= cator, size_t size) =20 iova_t __to_iova(struct vfio_pci_device *device, void *vaddr) { - struct vfio_dma_region *region; + struct dma_region *region; =20 list_for_each_entry(region, &device->iommu->dma_regions, link) { if (vaddr < region->vaddr) @@ -387,7 +387,7 @@ static void vfio_pci_irq_get(struct vfio_pci_device *de= vice, u32 index, } =20 static int vfio_iommu_dma_map(struct vfio_pci_device *device, - struct vfio_dma_region *region) + struct dma_region *region) { struct vfio_iommu_type1_dma_map args =3D { .argsz =3D sizeof(args), @@ -404,7 +404,7 @@ static int vfio_iommu_dma_map(struct vfio_pci_device *d= evice, } =20 static int iommufd_dma_map(struct vfio_pci_device *device, - struct vfio_dma_region *region) + struct dma_region *region) { struct iommu_ioas_map args =3D { .size =3D sizeof(args), @@ -424,7 +424,7 @@ static int iommufd_dma_map(struct vfio_pci_device *devi= ce, } =20 int __vfio_pci_dma_map(struct vfio_pci_device *device, - struct vfio_dma_region *region) + struct dma_region *region) { int ret; =20 @@ -480,7 +480,7 @@ static int iommufd_dma_unmap(int fd, u64 iova, u64 leng= th, u32 ioas_id, } =20 int __vfio_pci_dma_unmap(struct vfio_pci_device *device, - struct vfio_dma_region *region, u64 *unmapped) + struct dma_region *region, u64 *unmapped) { int ret; =20 @@ -504,7 +504,7 @@ int __vfio_pci_dma_unmap(struct vfio_pci_device *device, int __vfio_pci_dma_unmap_all(struct vfio_pci_device *device, u64 *unmapped) { int ret; - struct vfio_dma_region *curr, *next; + struct dma_region *curr, *next; =20 if (device->iommu->iommufd) ret =3D iommufd_dma_unmap(device->iommu->iommufd, 0, UINT64_MAX, diff --git a/tools/testing/selftests/vfio/vfio_dma_mapping_test.c b/tools/t= esting/selftests/vfio/vfio_dma_mapping_test.c index 4727feb214c8..289af4665803 100644 --- a/tools/testing/selftests/vfio/vfio_dma_mapping_test.c +++ b/tools/testing/selftests/vfio/vfio_dma_mapping_test.c @@ -136,7 +136,7 @@ TEST_F(vfio_dma_mapping_test, dma_map_unmap) { const u64 size =3D variant->size ?: getpagesize(); const int flags =3D variant->mmap_flags; - struct vfio_dma_region region; + struct dma_region region; struct iommu_mapping mapping; u64 mapping_size =3D size; u64 unmapped; @@ -208,7 +208,7 @@ TEST_F(vfio_dma_mapping_test, dma_map_unmap) FIXTURE(vfio_dma_map_limit_test) { struct iommu *iommu; struct vfio_pci_device *device; - struct vfio_dma_region region; + struct dma_region region; size_t mmap_size; }; =20 @@ -227,7 +227,7 @@ FIXTURE_VARIANT_ADD_ALL_IOMMU_MODES(); =20 FIXTURE_SETUP(vfio_dma_map_limit_test) { - struct vfio_dma_region *region =3D &self->region; + struct dma_region *region =3D &self->region; struct iommu_iova_range *ranges; u64 region_size =3D getpagesize(); iova_t last_iova; @@ -264,7 +264,7 @@ FIXTURE_TEARDOWN(vfio_dma_map_limit_test) =20 TEST_F(vfio_dma_map_limit_test, unmap_range) { - struct vfio_dma_region *region =3D &self->region; + struct dma_region *region =3D &self->region; u64 unmapped; int rc; =20 @@ -278,7 +278,7 @@ TEST_F(vfio_dma_map_limit_test, unmap_range) =20 TEST_F(vfio_dma_map_limit_test, unmap_all) { - struct vfio_dma_region *region =3D &self->region; + struct dma_region *region =3D &self->region; u64 unmapped; int rc; =20 @@ -292,7 +292,7 @@ TEST_F(vfio_dma_map_limit_test, unmap_all) =20 TEST_F(vfio_dma_map_limit_test, overflow) { - struct vfio_dma_region *region =3D &self->region; + struct dma_region *region =3D &self->region; int rc; =20 region->iova =3D ~(iova_t)0 & ~(region->size - 1); diff --git a/tools/testing/selftests/vfio/vfio_pci_driver_test.c b/tools/te= sting/selftests/vfio/vfio_pci_driver_test.c index b0c7d812de1f..057aa9bbe13e 100644 --- a/tools/testing/selftests/vfio/vfio_pci_driver_test.c +++ b/tools/testing/selftests/vfio/vfio_pci_driver_test.c @@ -20,7 +20,7 @@ static const char *device_bdf; =20 static void region_setup(struct vfio_pci_device *device, struct iova_allocator *iova_allocator, - struct vfio_dma_region *region, u64 size) + struct dma_region *region, u64 size) { const int flags =3D MAP_SHARED | MAP_ANONYMOUS; const int prot =3D PROT_READ | PROT_WRITE; @@ -37,7 +37,7 @@ static void region_setup(struct vfio_pci_device *device, } =20 static void region_teardown(struct vfio_pci_device *device, - struct vfio_dma_region *region) + struct dma_region *region) { vfio_pci_dma_unmap(device, region); VFIO_ASSERT_EQ(munmap(region->vaddr, region->size), 0); @@ -47,7 +47,7 @@ FIXTURE(vfio_pci_driver_test) { struct iommu *iommu; struct vfio_pci_device *device; struct iova_allocator *iova_allocator; - struct vfio_dma_region memcpy_region; + struct dma_region memcpy_region; void *vaddr; int msi_fd; =20 --=20 2.52.0.487.g5c8c507ade-goog From nobody Mon Dec 1 22:03:57 2025 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CAF54347BB9 for ; Wed, 26 Nov 2025 23:17:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199082; cv=none; b=Cithk+PjWy2kV8CLpXD3aZRaaRmvDepvCPgP34QLbXSiiv4ZKxYgYxASaYn7tuEN2MfiCJFCkRk+lbCXIau5Lik+1qVjJRpsFbUF5MKrP41NH+BxPK5Ap8TebxPGuYjr8+EfafCtVhoiLVdCEgDbQFtJUl72hJ5nhuiRpp+xqTo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199082; c=relaxed/simple; bh=T5iM/jn+gEAw6xdUVBY7eQtcRsPFbyXY1T6+O/mET3Q=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=kuh3S/FfR9PY3CcoMoH5Asy/owGvb84lSYIWfOWuDE2zVw+90l/j6MOP/zoW/89nW4f0/y85VmM0yVlG7cQgIlyiV3xxGfuvFdcJwbFJhwSSwDIeqILOkOyBZcye5i/xIcIJKHIXdrT0TkAHgF9Nx4RXGXy4Wnbb6u+uFpaz30g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=gS3T7VdI; arc=none smtp.client-ip=209.85.210.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="gS3T7VdI" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7b9c91b814cso649042b3a.2 for ; Wed, 26 Nov 2025 15:17:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764199079; x=1764803879; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=i21+YoY7Q+KNbCFBTzX46LioB1ZUMHUsqKfP5Y1Z30Y=; b=gS3T7VdIc16OtBOcRRg1KfHKcrj/WsGT6pXBNnzIIgWRJ4V1wgzJAl3mlssysbTRyK Zv1p9XlsdZp046A7cQF0IPncwMJBuKunGZRQTs1sUA4nK+VCXwRI+WOh+06PpZjQXREE X7i0O82S5Aef6Yze5JkYq6vD+phADIGHHpAGtDFvJUHyzrvlbdpPe4n+ZuB/V/ui7E+H L/bWaumvPOS97YoyW5TDvk7YB9p4RtrIBd+VMOpwxNgMqERCUOC0tEV575OHW2AkPNNr yl0U8B9TQq/pu8PlWHzIz+jaC3VWqIRnZpcfV0sZfBmTYzyOv43wOWbI9di4IJT8eGuU GV0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764199079; x=1764803879; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=i21+YoY7Q+KNbCFBTzX46LioB1ZUMHUsqKfP5Y1Z30Y=; b=gV3brxSqFhs0m8bcUspXoNQk3grFTgkg0kNLA2RH+1LSNsF98wBiRR8rAlfa95hPlc 3oCUt0T+AndVk8nCZ4BWOxEB89uIyAZF7X8OVwMZa8FwIadL+DDT8Pmh6xBow1rZeKlh 7vhXEQEERZZ+Z/i2mfVi7kN7b95WgE+22ZTp5LH+a62ZiON/VFBIkjswjSU7+X9NlxO7 NLJ06nod9DGWtGE7pXC2/LYnyffYfA+dQZ4RQ62EJ2m4CeWxfIZQ7zQrsxcMdMBKTvlk /XDVXQqXxlpravYWCYCc7LOj2W+dCcsL+tUk6p8KQROuMAmOgd9bpafYRd87idJXWASE kd6Q== X-Forwarded-Encrypted: i=1; AJvYcCVAWDeJwAnoFoHkEINua0OmQlqN9Bpm2brbipgasPLf6UZ4qyb3ciGH8HQTel9INNNQYooZ7YJ2o0IFGjQ=@vger.kernel.org X-Gm-Message-State: AOJu0YxDbjWg6OiZMZd34Ep6DjHPQ7Z/3adT6bC0yvY66UYFLN2R+S5L ko8JE/QfrxgCfR715WuqkvlIOLreIOPhK8e6aV/PVwIhBcbZsS6urTYPZ1YPYneAPaSwmAwfzYV R8NxN8WvswVNvWg== X-Google-Smtp-Source: AGHT+IE9N/+TaEzjkPjfZfEH/oWXSzgo38MmG1+/bnSvZP5VzyVIf/9mho/62knJRPKDvFVImfnLuRcF5pZigw== X-Received: from pfblu1.prod.google.com ([2002:a05:6a00:7481:b0:7ba:6768:fe53]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:12dd:b0:7b9:420:cc0f with SMTP id d2e1a72fcca58-7ca87ec9a06mr10423422b3a.14.1764199079179; Wed, 26 Nov 2025 15:17:59 -0800 (PST) Date: Wed, 26 Nov 2025 23:17:26 +0000 In-Reply-To: <20251126231733.3302983-1-dmatlack@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251126231733.3302983-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.487.g5c8c507ade-goog Message-ID: <20251126231733.3302983-12-dmatlack@google.com> Subject: [PATCH v4 11/18] vfio: selftests: Move IOMMU library code into iommu.c From: David Matlack To: Alex Williamson Cc: Alex Mastro , David Matlack , Jason Gunthorpe , Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Raghavendra Rao Ananta , Vipin Sharma Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Move all the IOMMU related library code into their own file iommu.c. This provides a better separation between the vfio_pci_device helper code and the iommu code. No function change intended. Reviewed-by: Alex Mastro Tested-by: Alex Mastro Reviewed-by: Raghavendra Rao Ananta Signed-off-by: David Matlack --- .../selftests/vfio/lib/include/vfio_util.h | 74 ++- tools/testing/selftests/vfio/lib/iommu.c | 461 ++++++++++++++++++ tools/testing/selftests/vfio/lib/libvfio.mk | 3 +- .../selftests/vfio/lib/vfio_pci_device.c | 442 ----------------- 4 files changed, 527 insertions(+), 453 deletions(-) create mode 100644 tools/testing/selftests/vfio/lib/iommu.c diff --git a/tools/testing/selftests/vfio/lib/include/vfio_util.h b/tools/t= esting/selftests/vfio/lib/include/vfio_util.h index 7784422116de..f67915d9443e 100644 --- a/tools/testing/selftests/vfio/lib/include/vfio_util.h +++ b/tools/testing/selftests/vfio/lib/include/vfio_util.h @@ -50,6 +50,12 @@ VFIO_LOG_AND_EXIT(_fmt, ##__VA_ARGS__); \ } while (0) =20 +#define ioctl_assert(_fd, _op, _arg) do { \ + void *__arg =3D (_arg); \ + int __ret =3D ioctl((_fd), (_op), (__arg)); \ + VFIO_ASSERT_EQ(__ret, 0, "ioctl(%s, %s, %s) returned %d\n", #_fd, #_op, #= _arg, __ret); \ +} while (0) + #define dev_info(_dev, _fmt, ...) printf("%s: " _fmt, (_dev)->bdf, ##__VA_= ARGS__) #define dev_err(_dev, _fmt, ...) fprintf(stderr, "%s: " _fmt, (_dev)->bdf,= ##__VA_ARGS__) =20 @@ -223,24 +229,52 @@ extern const char *default_iommu_mode; struct iommu *iommu_init(const char *iommu_mode); void iommu_cleanup(struct iommu *iommu); =20 +int __iommu_map(struct iommu *iommu, struct dma_region *region); + +static inline void iommu_map(struct iommu *iommu, struct dma_region *regio= n) +{ + VFIO_ASSERT_EQ(__iommu_map(iommu, region), 0); +} + +int __iommu_unmap(struct iommu *iommu, struct dma_region *region, u64 *unm= apped); + +static inline void iommu_unmap(struct iommu *iommu, struct dma_region *reg= ion) +{ + VFIO_ASSERT_EQ(__iommu_unmap(iommu, region, NULL), 0); +} + +int __iommu_unmap_all(struct iommu *iommu, u64 *unmapped); + +static inline void iommu_unmap_all(struct iommu *iommu) +{ + VFIO_ASSERT_EQ(__iommu_unmap_all(iommu, NULL), 0); +} + +iova_t __iommu_hva2iova(struct iommu *iommu, void *vaddr); +iova_t iommu_hva2iova(struct iommu *iommu, void *vaddr); + +struct iommu_iova_range *iommu_iova_ranges(struct iommu *iommu, u32 *nrang= es); + struct vfio_pci_device *vfio_pci_device_init(const char *bdf, struct iommu= *iommu); void vfio_pci_device_cleanup(struct vfio_pci_device *device); =20 void vfio_pci_device_reset(struct vfio_pci_device *device); =20 -struct iommu_iova_range *vfio_pci_iova_ranges(struct vfio_pci_device *devi= ce, - u32 *nranges); +static inline struct iommu_iova_range *vfio_pci_iova_ranges(struct vfio_pc= i_device *device, + u32 *nranges) +{ + return iommu_iova_ranges(device->iommu, nranges); +} =20 struct iova_allocator *iova_allocator_init(struct vfio_pci_device *device); void iova_allocator_cleanup(struct iova_allocator *allocator); iova_t iova_allocator_alloc(struct iova_allocator *allocator, size_t size); =20 -int __vfio_pci_dma_map(struct vfio_pci_device *device, - struct dma_region *region); -int __vfio_pci_dma_unmap(struct vfio_pci_device *device, - struct dma_region *region, - u64 *unmapped); -int __vfio_pci_dma_unmap_all(struct vfio_pci_device *device, u64 *unmapped= ); +static inline int __vfio_pci_dma_map(struct vfio_pci_device *device, + struct dma_region *region) +{ + return __iommu_map(device->iommu, region); +} =20 static inline void vfio_pci_dma_map(struct vfio_pci_device *device, struct dma_region *region) @@ -248,12 +282,25 @@ static inline void vfio_pci_dma_map(struct vfio_pci_d= evice *device, VFIO_ASSERT_EQ(__vfio_pci_dma_map(device, region), 0); } =20 +static inline int __vfio_pci_dma_unmap(struct vfio_pci_device *device, + struct dma_region *region, + u64 *unmapped) +{ + return __iommu_unmap(device->iommu, region, unmapped); +} + static inline void vfio_pci_dma_unmap(struct vfio_pci_device *device, struct dma_region *region) { VFIO_ASSERT_EQ(__vfio_pci_dma_unmap(device, region, NULL), 0); } =20 +static inline int __vfio_pci_dma_unmap_all(struct vfio_pci_device *device, + u64 *unmapped) +{ + return __iommu_unmap_all(device->iommu, unmapped); +} + static inline void vfio_pci_dma_unmap_all(struct vfio_pci_device *device) { VFIO_ASSERT_EQ(__vfio_pci_dma_unmap_all(device, NULL), 0); @@ -319,8 +366,15 @@ static inline void vfio_pci_msix_disable(struct vfio_p= ci_device *device) vfio_pci_irq_disable(device, VFIO_PCI_MSIX_IRQ_INDEX); } =20 -iova_t __to_iova(struct vfio_pci_device *device, void *vaddr); -iova_t to_iova(struct vfio_pci_device *device, void *vaddr); +static inline iova_t __to_iova(struct vfio_pci_device *device, void *vaddr) +{ + return __iommu_hva2iova(device->iommu, vaddr); +} + +static inline iova_t to_iova(struct vfio_pci_device *device, void *vaddr) +{ + return iommu_hva2iova(device->iommu, vaddr); +} =20 static inline bool vfio_pci_device_match(struct vfio_pci_device *device, u16 vendor_id, u16 device_id) diff --git a/tools/testing/selftests/vfio/lib/iommu.c b/tools/testing/selft= ests/vfio/lib/iommu.c new file mode 100644 index 000000000000..3933079fc419 --- /dev/null +++ b/tools/testing/selftests/vfio/lib/iommu.c @@ -0,0 +1,461 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "../../../kselftest.h" +#include + +const char *default_iommu_mode =3D "iommufd"; + +/* Reminder: Keep in sync with FIXTURE_VARIANT_ADD_ALL_IOMMU_MODES(). */ +static const struct iommu_mode iommu_modes[] =3D { + { + .name =3D "vfio_type1_iommu", + .container_path =3D "/dev/vfio/vfio", + .iommu_type =3D VFIO_TYPE1_IOMMU, + }, + { + .name =3D "vfio_type1v2_iommu", + .container_path =3D "/dev/vfio/vfio", + .iommu_type =3D VFIO_TYPE1v2_IOMMU, + }, + { + .name =3D "iommufd_compat_type1", + .container_path =3D "/dev/iommu", + .iommu_type =3D VFIO_TYPE1_IOMMU, + }, + { + .name =3D "iommufd_compat_type1v2", + .container_path =3D "/dev/iommu", + .iommu_type =3D VFIO_TYPE1v2_IOMMU, + }, + { + .name =3D "iommufd", + }, +}; + +static const struct iommu_mode *lookup_iommu_mode(const char *iommu_mode) +{ + int i; + + if (!iommu_mode) + iommu_mode =3D default_iommu_mode; + + for (i =3D 0; i < ARRAY_SIZE(iommu_modes); i++) { + if (strcmp(iommu_mode, iommu_modes[i].name)) + continue; + + return &iommu_modes[i]; + } + + VFIO_FAIL("Unrecognized IOMMU mode: %s\n", iommu_mode); +} + +iova_t __iommu_hva2iova(struct iommu *iommu, void *vaddr) +{ + struct dma_region *region; + + list_for_each_entry(region, &iommu->dma_regions, link) { + if (vaddr < region->vaddr) + continue; + + if (vaddr >=3D region->vaddr + region->size) + continue; + + return region->iova + (vaddr - region->vaddr); + } + + return INVALID_IOVA; +} + +iova_t iommu_hva2iova(struct iommu *iommu, void *vaddr) +{ + iova_t iova; + + iova =3D __iommu_hva2iova(iommu, vaddr); + VFIO_ASSERT_NE(iova, INVALID_IOVA, "%p is not mapped into IOMMU\n", vaddr= ); + + return iova; +} + +static int vfio_iommu_map(struct iommu *iommu, struct dma_region *region) +{ + struct vfio_iommu_type1_dma_map args =3D { + .argsz =3D sizeof(args), + .flags =3D VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE, + .vaddr =3D (u64)region->vaddr, + .iova =3D region->iova, + .size =3D region->size, + }; + + if (ioctl(iommu->container_fd, VFIO_IOMMU_MAP_DMA, &args)) + return -errno; + + return 0; +} + +static int iommufd_map(struct iommu *iommu, struct dma_region *region) +{ + struct iommu_ioas_map args =3D { + .size =3D sizeof(args), + .flags =3D IOMMU_IOAS_MAP_READABLE | + IOMMU_IOAS_MAP_WRITEABLE | + IOMMU_IOAS_MAP_FIXED_IOVA, + .user_va =3D (u64)region->vaddr, + .iova =3D region->iova, + .length =3D region->size, + .ioas_id =3D iommu->ioas_id, + }; + + if (ioctl(iommu->iommufd, IOMMU_IOAS_MAP, &args)) + return -errno; + + return 0; +} + +int __iommu_map(struct iommu *iommu, struct dma_region *region) +{ + int ret; + + if (iommu->iommufd) + ret =3D iommufd_map(iommu, region); + else + ret =3D vfio_iommu_map(iommu, region); + + if (ret) + return ret; + + list_add(®ion->link, &iommu->dma_regions); + + return 0; +} + +static int __vfio_iommu_unmap(int fd, u64 iova, u64 size, u32 flags, u64 *= unmapped) +{ + struct vfio_iommu_type1_dma_unmap args =3D { + .argsz =3D sizeof(args), + .iova =3D iova, + .size =3D size, + .flags =3D flags, + }; + + if (ioctl(fd, VFIO_IOMMU_UNMAP_DMA, &args)) + return -errno; + + if (unmapped) + *unmapped =3D args.size; + + return 0; +} + +static int vfio_iommu_unmap(struct iommu *iommu, struct dma_region *region, + u64 *unmapped) +{ + return __vfio_iommu_unmap(iommu->container_fd, region->iova, + region->size, 0, unmapped); +} + +static int __iommufd_unmap(int fd, u64 iova, u64 length, u32 ioas_id, u64 = *unmapped) +{ + struct iommu_ioas_unmap args =3D { + .size =3D sizeof(args), + .iova =3D iova, + .length =3D length, + .ioas_id =3D ioas_id, + }; + + if (ioctl(fd, IOMMU_IOAS_UNMAP, &args)) + return -errno; + + if (unmapped) + *unmapped =3D args.length; + + return 0; +} + +static int iommufd_unmap(struct iommu *iommu, struct dma_region *region, + u64 *unmapped) +{ + return __iommufd_unmap(iommu->iommufd, region->iova, region->size, + iommu->ioas_id, unmapped); +} + +int __iommu_unmap(struct iommu *iommu, struct dma_region *region, u64 *unm= apped) +{ + int ret; + + if (iommu->iommufd) + ret =3D iommufd_unmap(iommu, region, unmapped); + else + ret =3D vfio_iommu_unmap(iommu, region, unmapped); + + if (ret) + return ret; + + list_del_init(®ion->link); + + return 0; +} + +int __iommu_unmap_all(struct iommu *iommu, u64 *unmapped) +{ + int ret; + struct dma_region *curr, *next; + + if (iommu->iommufd) + ret =3D __iommufd_unmap(iommu->iommufd, 0, UINT64_MAX, + iommu->ioas_id, unmapped); + else + ret =3D __vfio_iommu_unmap(iommu->container_fd, 0, 0, + VFIO_DMA_UNMAP_FLAG_ALL, unmapped); + + if (ret) + return ret; + + list_for_each_entry_safe(curr, next, &iommu->dma_regions, link) + list_del_init(&curr->link); + + return 0; +} + +static struct vfio_info_cap_header *next_cap_hdr(void *buf, u32 bufsz, + u32 *cap_offset) +{ + struct vfio_info_cap_header *hdr; + + if (!*cap_offset) + return NULL; + + VFIO_ASSERT_LT(*cap_offset, bufsz); + VFIO_ASSERT_GE(bufsz - *cap_offset, sizeof(*hdr)); + + hdr =3D (struct vfio_info_cap_header *)((u8 *)buf + *cap_offset); + *cap_offset =3D hdr->next; + + return hdr; +} + +static struct vfio_info_cap_header *vfio_iommu_info_cap_hdr(struct vfio_io= mmu_type1_info *info, + u16 cap_id) +{ + struct vfio_info_cap_header *hdr; + u32 cap_offset =3D info->cap_offset; + u32 max_depth; + u32 depth =3D 0; + + if (!(info->flags & VFIO_IOMMU_INFO_CAPS)) + return NULL; + + if (cap_offset) + VFIO_ASSERT_GE(cap_offset, sizeof(*info)); + + max_depth =3D (info->argsz - sizeof(*info)) / sizeof(*hdr); + + while ((hdr =3D next_cap_hdr(info, info->argsz, &cap_offset))) { + depth++; + VFIO_ASSERT_LE(depth, max_depth, "Capability chain contains a cycle\n"); + + if (hdr->id =3D=3D cap_id) + return hdr; + } + + return NULL; +} + +/* Return buffer including capability chain, if present. Free with free() = */ +static struct vfio_iommu_type1_info *vfio_iommu_get_info(int container_fd) +{ + struct vfio_iommu_type1_info *info; + + info =3D malloc(sizeof(*info)); + VFIO_ASSERT_NOT_NULL(info); + + *info =3D (struct vfio_iommu_type1_info) { + .argsz =3D sizeof(*info), + }; + + ioctl_assert(container_fd, VFIO_IOMMU_GET_INFO, info); + VFIO_ASSERT_GE(info->argsz, sizeof(*info)); + + info =3D realloc(info, info->argsz); + VFIO_ASSERT_NOT_NULL(info); + + ioctl_assert(container_fd, VFIO_IOMMU_GET_INFO, info); + VFIO_ASSERT_GE(info->argsz, sizeof(*info)); + + return info; +} + +/* + * Return iova ranges for the device's container. Normalize vfio_iommu_typ= e1 to + * report iommufd's iommu_iova_range. Free with free(). + */ +static struct iommu_iova_range *vfio_iommu_iova_ranges(struct iommu *iommu, + u32 *nranges) +{ + struct vfio_iommu_type1_info_cap_iova_range *cap_range; + struct vfio_iommu_type1_info *info; + struct vfio_info_cap_header *hdr; + struct iommu_iova_range *ranges =3D NULL; + + info =3D vfio_iommu_get_info(iommu->container_fd); + hdr =3D vfio_iommu_info_cap_hdr(info, VFIO_IOMMU_TYPE1_INFO_CAP_IOVA_RANG= E); + VFIO_ASSERT_NOT_NULL(hdr); + + cap_range =3D container_of(hdr, struct vfio_iommu_type1_info_cap_iova_ran= ge, header); + VFIO_ASSERT_GT(cap_range->nr_iovas, 0); + + ranges =3D calloc(cap_range->nr_iovas, sizeof(*ranges)); + VFIO_ASSERT_NOT_NULL(ranges); + + for (u32 i =3D 0; i < cap_range->nr_iovas; i++) { + ranges[i] =3D (struct iommu_iova_range){ + .start =3D cap_range->iova_ranges[i].start, + .last =3D cap_range->iova_ranges[i].end, + }; + } + + *nranges =3D cap_range->nr_iovas; + + free(info); + return ranges; +} + +/* Return iova ranges of the device's IOAS. Free with free() */ +static struct iommu_iova_range *iommufd_iova_ranges(struct iommu *iommu, + u32 *nranges) +{ + struct iommu_iova_range *ranges; + int ret; + + struct iommu_ioas_iova_ranges query =3D { + .size =3D sizeof(query), + .ioas_id =3D iommu->ioas_id, + }; + + ret =3D ioctl(iommu->iommufd, IOMMU_IOAS_IOVA_RANGES, &query); + VFIO_ASSERT_EQ(ret, -1); + VFIO_ASSERT_EQ(errno, EMSGSIZE); + VFIO_ASSERT_GT(query.num_iovas, 0); + + ranges =3D calloc(query.num_iovas, sizeof(*ranges)); + VFIO_ASSERT_NOT_NULL(ranges); + + query.allowed_iovas =3D (uintptr_t)ranges; + + ioctl_assert(iommu->iommufd, IOMMU_IOAS_IOVA_RANGES, &query); + *nranges =3D query.num_iovas; + + return ranges; +} + +static int iova_range_comp(const void *a, const void *b) +{ + const struct iommu_iova_range *ra =3D a, *rb =3D b; + + if (ra->start < rb->start) + return -1; + + if (ra->start > rb->start) + return 1; + + return 0; +} + +/* Return sorted IOVA ranges of the device. Free with free(). */ +struct iommu_iova_range *iommu_iova_ranges(struct iommu *iommu, u32 *nrang= es) +{ + struct iommu_iova_range *ranges; + + if (iommu->iommufd) + ranges =3D iommufd_iova_ranges(iommu, nranges); + else + ranges =3D vfio_iommu_iova_ranges(iommu, nranges); + + if (!ranges) + return NULL; + + VFIO_ASSERT_GT(*nranges, 0); + + /* Sort and check that ranges are sane and non-overlapping */ + qsort(ranges, *nranges, sizeof(*ranges), iova_range_comp); + VFIO_ASSERT_LT(ranges[0].start, ranges[0].last); + + for (u32 i =3D 1; i < *nranges; i++) { + VFIO_ASSERT_LT(ranges[i].start, ranges[i].last); + VFIO_ASSERT_LT(ranges[i - 1].last, ranges[i].start); + } + + return ranges; +} + +static u32 iommufd_ioas_alloc(int iommufd) +{ + struct iommu_ioas_alloc args =3D { + .size =3D sizeof(args), + }; + + ioctl_assert(iommufd, IOMMU_IOAS_ALLOC, &args); + return args.out_ioas_id; +} + +struct iommu *iommu_init(const char *iommu_mode) +{ + const char *container_path; + struct iommu *iommu; + int version; + + iommu =3D calloc(1, sizeof(*iommu)); + VFIO_ASSERT_NOT_NULL(iommu); + + INIT_LIST_HEAD(&iommu->dma_regions); + + iommu->mode =3D lookup_iommu_mode(iommu_mode); + + container_path =3D iommu->mode->container_path; + if (container_path) { + iommu->container_fd =3D open(container_path, O_RDWR); + VFIO_ASSERT_GE(iommu->container_fd, 0, "open(%s) failed\n", container_pa= th); + + version =3D ioctl(iommu->container_fd, VFIO_GET_API_VERSION); + VFIO_ASSERT_EQ(version, VFIO_API_VERSION, "Unsupported version: %d\n", v= ersion); + } else { + /* + * Require device->iommufd to be >0 so that a simple non-0 check can be + * used to check if iommufd is enabled. In practice open() will never + * return 0 unless stdin is closed. + */ + iommu->iommufd =3D open("/dev/iommu", O_RDWR); + VFIO_ASSERT_GT(iommu->iommufd, 0); + + iommu->ioas_id =3D iommufd_ioas_alloc(iommu->iommufd); + } + + return iommu; +} + +void iommu_cleanup(struct iommu *iommu) +{ + if (iommu->iommufd) + VFIO_ASSERT_EQ(close(iommu->iommufd), 0); + else + VFIO_ASSERT_EQ(close(iommu->container_fd), 0); + + free(iommu); +} diff --git a/tools/testing/selftests/vfio/lib/libvfio.mk b/tools/testing/se= lftests/vfio/lib/libvfio.mk index 3c0cdac30cb6..7ecf2ad75c67 100644 --- a/tools/testing/selftests/vfio/lib/libvfio.mk +++ b/tools/testing/selftests/vfio/lib/libvfio.mk @@ -3,7 +3,8 @@ ARCH ?=3D $(SUBARCH) =20 LIBVFIO_SRCDIR :=3D $(selfdir)/vfio/lib =20 -LIBVFIO_C :=3D vfio_pci_device.c +LIBVFIO_C :=3D iommu.c +LIBVFIO_C +=3D vfio_pci_device.c LIBVFIO_C +=3D vfio_pci_driver.c =20 ifeq ($(ARCH:x86_64=3Dx86),x86) diff --git a/tools/testing/selftests/vfio/lib/vfio_pci_device.c b/tools/tes= ting/selftests/vfio/lib/vfio_pci_device.c index 422ad8dfad95..10fc016a2a3e 100644 --- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c +++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c @@ -24,184 +24,6 @@ =20 #define PCI_SYSFS_PATH "/sys/bus/pci/devices" =20 -#define ioctl_assert(_fd, _op, _arg) do { \ - void *__arg =3D (_arg); \ - int __ret =3D ioctl((_fd), (_op), (__arg)); \ - VFIO_ASSERT_EQ(__ret, 0, "ioctl(%s, %s, %s) returned %d\n", #_fd, #_op, #= _arg, __ret); \ -} while (0) - -static struct vfio_info_cap_header *next_cap_hdr(void *buf, u32 bufsz, - u32 *cap_offset) -{ - struct vfio_info_cap_header *hdr; - - if (!*cap_offset) - return NULL; - - VFIO_ASSERT_LT(*cap_offset, bufsz); - VFIO_ASSERT_GE(bufsz - *cap_offset, sizeof(*hdr)); - - hdr =3D (struct vfio_info_cap_header *)((u8 *)buf + *cap_offset); - *cap_offset =3D hdr->next; - - return hdr; -} - -static struct vfio_info_cap_header *vfio_iommu_info_cap_hdr(struct vfio_io= mmu_type1_info *info, - u16 cap_id) -{ - struct vfio_info_cap_header *hdr; - u32 cap_offset =3D info->cap_offset; - u32 max_depth; - u32 depth =3D 0; - - if (!(info->flags & VFIO_IOMMU_INFO_CAPS)) - return NULL; - - if (cap_offset) - VFIO_ASSERT_GE(cap_offset, sizeof(*info)); - - max_depth =3D (info->argsz - sizeof(*info)) / sizeof(*hdr); - - while ((hdr =3D next_cap_hdr(info, info->argsz, &cap_offset))) { - depth++; - VFIO_ASSERT_LE(depth, max_depth, "Capability chain contains a cycle\n"); - - if (hdr->id =3D=3D cap_id) - return hdr; - } - - return NULL; -} - -/* Return buffer including capability chain, if present. Free with free() = */ -static struct vfio_iommu_type1_info *vfio_iommu_get_info(struct vfio_pci_d= evice *device) -{ - struct vfio_iommu_type1_info *info; - - info =3D malloc(sizeof(*info)); - VFIO_ASSERT_NOT_NULL(info); - - *info =3D (struct vfio_iommu_type1_info) { - .argsz =3D sizeof(*info), - }; - - ioctl_assert(device->iommu->container_fd, VFIO_IOMMU_GET_INFO, info); - VFIO_ASSERT_GE(info->argsz, sizeof(*info)); - - info =3D realloc(info, info->argsz); - VFIO_ASSERT_NOT_NULL(info); - - ioctl_assert(device->iommu->container_fd, VFIO_IOMMU_GET_INFO, info); - VFIO_ASSERT_GE(info->argsz, sizeof(*info)); - - return info; -} - -/* - * Return iova ranges for the device's container. Normalize vfio_iommu_typ= e1 to - * report iommufd's iommu_iova_range. Free with free(). - */ -static struct iommu_iova_range *vfio_iommu_iova_ranges(struct vfio_pci_dev= ice *device, - u32 *nranges) -{ - struct vfio_iommu_type1_info_cap_iova_range *cap_range; - struct vfio_iommu_type1_info *info; - struct vfio_info_cap_header *hdr; - struct iommu_iova_range *ranges =3D NULL; - - info =3D vfio_iommu_get_info(device); - hdr =3D vfio_iommu_info_cap_hdr(info, VFIO_IOMMU_TYPE1_INFO_CAP_IOVA_RANG= E); - VFIO_ASSERT_NOT_NULL(hdr); - - cap_range =3D container_of(hdr, struct vfio_iommu_type1_info_cap_iova_ran= ge, header); - VFIO_ASSERT_GT(cap_range->nr_iovas, 0); - - ranges =3D calloc(cap_range->nr_iovas, sizeof(*ranges)); - VFIO_ASSERT_NOT_NULL(ranges); - - for (u32 i =3D 0; i < cap_range->nr_iovas; i++) { - ranges[i] =3D (struct iommu_iova_range){ - .start =3D cap_range->iova_ranges[i].start, - .last =3D cap_range->iova_ranges[i].end, - }; - } - - *nranges =3D cap_range->nr_iovas; - - free(info); - return ranges; -} - -/* Return iova ranges of the device's IOAS. Free with free() */ -static struct iommu_iova_range *iommufd_iova_ranges(struct vfio_pci_device= *device, - u32 *nranges) -{ - struct iommu_iova_range *ranges; - int ret; - - struct iommu_ioas_iova_ranges query =3D { - .size =3D sizeof(query), - .ioas_id =3D device->iommu->ioas_id, - }; - - ret =3D ioctl(device->iommu->iommufd, IOMMU_IOAS_IOVA_RANGES, &query); - VFIO_ASSERT_EQ(ret, -1); - VFIO_ASSERT_EQ(errno, EMSGSIZE); - VFIO_ASSERT_GT(query.num_iovas, 0); - - ranges =3D calloc(query.num_iovas, sizeof(*ranges)); - VFIO_ASSERT_NOT_NULL(ranges); - - query.allowed_iovas =3D (uintptr_t)ranges; - - ioctl_assert(device->iommu->iommufd, IOMMU_IOAS_IOVA_RANGES, &query); - *nranges =3D query.num_iovas; - - return ranges; -} - -static int iova_range_comp(const void *a, const void *b) -{ - const struct iommu_iova_range *ra =3D a, *rb =3D b; - - if (ra->start < rb->start) - return -1; - - if (ra->start > rb->start) - return 1; - - return 0; -} - -/* Return sorted IOVA ranges of the device. Free with free(). */ -struct iommu_iova_range *vfio_pci_iova_ranges(struct vfio_pci_device *devi= ce, - u32 *nranges) -{ - struct iommu_iova_range *ranges; - - if (device->iommu->iommufd) - ranges =3D iommufd_iova_ranges(device, nranges); - else - ranges =3D vfio_iommu_iova_ranges(device, nranges); - - if (!ranges) - return NULL; - - VFIO_ASSERT_GT(*nranges, 0); - - /* Sort and check that ranges are sane and non-overlapping */ - qsort(ranges, *nranges, sizeof(*ranges), iova_range_comp); - VFIO_ASSERT_LT(ranges[0].start, ranges[0].last); - - for (u32 i =3D 1; i < *nranges; i++) { - VFIO_ASSERT_LT(ranges[i].start, ranges[i].last); - VFIO_ASSERT_LT(ranges[i - 1].last, ranges[i].start); - } - - return ranges; -} - struct iova_allocator *iova_allocator_init(struct vfio_pci_device *device) { struct iova_allocator *allocator; @@ -273,33 +95,6 @@ iova_t iova_allocator_alloc(struct iova_allocator *allo= cator, size_t size) } } =20 -iova_t __to_iova(struct vfio_pci_device *device, void *vaddr) -{ - struct dma_region *region; - - list_for_each_entry(region, &device->iommu->dma_regions, link) { - if (vaddr < region->vaddr) - continue; - - if (vaddr >=3D region->vaddr + region->size) - continue; - - return region->iova + (vaddr - region->vaddr); - } - - return INVALID_IOVA; -} - -iova_t to_iova(struct vfio_pci_device *device, void *vaddr) -{ - iova_t iova; - - iova =3D __to_iova(device, vaddr); - VFIO_ASSERT_NE(iova, INVALID_IOVA, "%p is not mapped into device.\n", vad= dr); - - return iova; -} - static void vfio_pci_irq_set(struct vfio_pci_device *device, u32 index, u32 vector, u32 count, int *fds) { @@ -386,142 +181,6 @@ static void vfio_pci_irq_get(struct vfio_pci_device *= device, u32 index, ioctl_assert(device->fd, VFIO_DEVICE_GET_IRQ_INFO, irq_info); } =20 -static int vfio_iommu_dma_map(struct vfio_pci_device *device, - struct dma_region *region) -{ - struct vfio_iommu_type1_dma_map args =3D { - .argsz =3D sizeof(args), - .flags =3D VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE, - .vaddr =3D (u64)region->vaddr, - .iova =3D region->iova, - .size =3D region->size, - }; - - if (ioctl(device->iommu->container_fd, VFIO_IOMMU_MAP_DMA, &args)) - return -errno; - - return 0; -} - -static int iommufd_dma_map(struct vfio_pci_device *device, - struct dma_region *region) -{ - struct iommu_ioas_map args =3D { - .size =3D sizeof(args), - .flags =3D IOMMU_IOAS_MAP_READABLE | - IOMMU_IOAS_MAP_WRITEABLE | - IOMMU_IOAS_MAP_FIXED_IOVA, - .user_va =3D (u64)region->vaddr, - .iova =3D region->iova, - .length =3D region->size, - .ioas_id =3D device->iommu->ioas_id, - }; - - if (ioctl(device->iommu->iommufd, IOMMU_IOAS_MAP, &args)) - return -errno; - - return 0; -} - -int __vfio_pci_dma_map(struct vfio_pci_device *device, - struct dma_region *region) -{ - int ret; - - if (device->iommu->iommufd) - ret =3D iommufd_dma_map(device, region); - else - ret =3D vfio_iommu_dma_map(device, region); - - if (ret) - return ret; - - list_add(®ion->link, &device->iommu->dma_regions); - - return 0; -} - -static int vfio_iommu_dma_unmap(int fd, u64 iova, u64 size, u32 flags, - u64 *unmapped) -{ - struct vfio_iommu_type1_dma_unmap args =3D { - .argsz =3D sizeof(args), - .iova =3D iova, - .size =3D size, - .flags =3D flags, - }; - - if (ioctl(fd, VFIO_IOMMU_UNMAP_DMA, &args)) - return -errno; - - if (unmapped) - *unmapped =3D args.size; - - return 0; -} - -static int iommufd_dma_unmap(int fd, u64 iova, u64 length, u32 ioas_id, - u64 *unmapped) -{ - struct iommu_ioas_unmap args =3D { - .size =3D sizeof(args), - .iova =3D iova, - .length =3D length, - .ioas_id =3D ioas_id, - }; - - if (ioctl(fd, IOMMU_IOAS_UNMAP, &args)) - return -errno; - - if (unmapped) - *unmapped =3D args.length; - - return 0; -} - -int __vfio_pci_dma_unmap(struct vfio_pci_device *device, - struct dma_region *region, u64 *unmapped) -{ - int ret; - - if (device->iommu->iommufd) - ret =3D iommufd_dma_unmap(device->iommu->iommufd, region->iova, - region->size, device->iommu->ioas_id, - unmapped); - else - ret =3D vfio_iommu_dma_unmap(device->iommu->container_fd, - region->iova, region->size, 0, - unmapped); - - if (ret) - return ret; - - list_del_init(®ion->link); - - return 0; -} - -int __vfio_pci_dma_unmap_all(struct vfio_pci_device *device, u64 *unmapped) -{ - int ret; - struct dma_region *curr, *next; - - if (device->iommu->iommufd) - ret =3D iommufd_dma_unmap(device->iommu->iommufd, 0, UINT64_MAX, - device->iommu->ioas_id, unmapped); - else - ret =3D vfio_iommu_dma_unmap(device->iommu->container_fd, 0, 0, - VFIO_DMA_UNMAP_FLAG_ALL, unmapped); - - if (ret) - return ret; - - list_for_each_entry_safe(curr, next, &device->iommu->dma_regions, link) - list_del_init(&curr->link); - - return 0; -} - static void vfio_pci_region_get(struct vfio_pci_device *device, int index, struct vfio_region_info *info) { @@ -711,52 +370,6 @@ const char *vfio_pci_get_cdev_path(const char *bdf) return cdev_path; } =20 -/* Reminder: Keep in sync with FIXTURE_VARIANT_ADD_ALL_IOMMU_MODES(). */ -static const struct iommu_mode iommu_modes[] =3D { - { - .name =3D "vfio_type1_iommu", - .container_path =3D "/dev/vfio/vfio", - .iommu_type =3D VFIO_TYPE1_IOMMU, - }, - { - .name =3D "vfio_type1v2_iommu", - .container_path =3D "/dev/vfio/vfio", - .iommu_type =3D VFIO_TYPE1v2_IOMMU, - }, - { - .name =3D "iommufd_compat_type1", - .container_path =3D "/dev/iommu", - .iommu_type =3D VFIO_TYPE1_IOMMU, - }, - { - .name =3D "iommufd_compat_type1v2", - .container_path =3D "/dev/iommu", - .iommu_type =3D VFIO_TYPE1v2_IOMMU, - }, - { - .name =3D "iommufd", - }, -}; - -const char *default_iommu_mode =3D "iommufd"; - -static const struct iommu_mode *lookup_iommu_mode(const char *iommu_mode) -{ - int i; - - if (!iommu_mode) - iommu_mode =3D default_iommu_mode; - - for (i =3D 0; i < ARRAY_SIZE(iommu_modes); i++) { - if (strcmp(iommu_mode, iommu_modes[i].name)) - continue; - - return &iommu_modes[i]; - } - - VFIO_FAIL("Unrecognized IOMMU mode: %s\n", iommu_mode); -} - static void vfio_device_bind_iommufd(int device_fd, int iommufd) { struct vfio_device_bind_iommufd args =3D { @@ -767,16 +380,6 @@ static void vfio_device_bind_iommufd(int device_fd, in= t iommufd) ioctl_assert(device_fd, VFIO_DEVICE_BIND_IOMMUFD, &args); } =20 -static u32 iommufd_ioas_alloc(int iommufd) -{ - struct iommu_ioas_alloc args =3D { - .size =3D sizeof(args), - }; - - ioctl_assert(iommufd, IOMMU_IOAS_ALLOC, &args); - return args.out_ioas_id; -} - static void vfio_device_attach_iommufd_pt(int device_fd, u32 pt_id) { struct vfio_device_attach_iommufd_pt args =3D { @@ -799,41 +402,6 @@ static void vfio_pci_iommufd_setup(struct vfio_pci_dev= ice *device, const char *b vfio_device_attach_iommufd_pt(device->fd, device->iommu->ioas_id); } =20 -struct iommu *iommu_init(const char *iommu_mode) -{ - const char *container_path; - struct iommu *iommu; - int version; - - iommu =3D calloc(1, sizeof(*iommu)); - VFIO_ASSERT_NOT_NULL(iommu); - - INIT_LIST_HEAD(&iommu->dma_regions); - - iommu->mode =3D lookup_iommu_mode(iommu_mode); - - container_path =3D iommu->mode->container_path; - if (container_path) { - iommu->container_fd =3D open(container_path, O_RDWR); - VFIO_ASSERT_GE(iommu->container_fd, 0, "open(%s) failed\n", container_pa= th); - - version =3D ioctl(iommu->container_fd, VFIO_GET_API_VERSION); - VFIO_ASSERT_EQ(version, VFIO_API_VERSION, "Unsupported version: %d\n", v= ersion); - } else { - /* - * Require device->iommufd to be >0 so that a simple non-0 check can be - * used to check if iommufd is enabled. In practice open() will never - * return 0 unless stdin is closed. - */ - iommu->iommufd =3D open("/dev/iommu", O_RDWR); - VFIO_ASSERT_GT(iommu->iommufd, 0); - - iommu->ioas_id =3D iommufd_ioas_alloc(iommu->iommufd); - } - - return iommu; -} - struct vfio_pci_device *vfio_pci_device_init(const char *bdf, struct iommu= *iommu) { struct vfio_pci_device *device; @@ -880,16 +448,6 @@ void vfio_pci_device_cleanup(struct vfio_pci_device *d= evice) free(device); } =20 -void iommu_cleanup(struct iommu *iommu) -{ - if (iommu->iommufd) - VFIO_ASSERT_EQ(close(iommu->iommufd), 0); - else - VFIO_ASSERT_EQ(close(iommu->container_fd), 0); - - free(iommu); -} - static bool is_bdf(const char *str) { unsigned int s, b, d, f; --=20 2.52.0.487.g5c8c507ade-goog From nobody Mon Dec 1 22:03:57 2025 Received: from mail-pf1-f201.google.com (mail-pf1-f201.google.com [209.85.210.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A1DE348468 for ; Wed, 26 Nov 2025 23:18:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199083; cv=none; b=Im31a9J2cogju3fJh/TxMwOKqYAKzFA93p/YtsFHJHHPkpvj4PWNaW8hJsivzo1LNu5xdV8QU4bOKfMbOBl00p2ZS9Ypn5azc/TJbEkXBnai2N3am75E8morZdT82BbDwa0EmCPOyB8Bxl9YahRschwprAJGs2k+weAriu71+Hs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199083; c=relaxed/simple; bh=7PVn76b8rX0MxJTUfhyoehbiKMnipdTAASaM5dmOZs0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=vEft7i++zSSMUXrk6iQNOPNi5YxfiRSCuHHh/AeF3nHGO/LEtEv7/E8TJGfEF5lWoG7wA0BE+v4DE4vzR4lfcXOoQPYuMN+F5dW8WT6vU8hnb8zQpfkCZdtSP7y4UjpU7SQHYFzbNwTjFztYIWxgmO/9UDtwhKcrsAvWdQzoZFY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=3kiLKW8p; arc=none smtp.client-ip=209.85.210.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="3kiLKW8p" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7b8973c4608so638604b3a.3 for ; Wed, 26 Nov 2025 15:18:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764199081; x=1764803881; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=EK277X+oVRo/3waBm9mTxQf5GxrA/dPpZ/zTyzS81bg=; b=3kiLKW8pqKLgErADigkgQQZ8ywsz+TYlrJteNXQKO+14WxQTWiykb6HI8rKJ/4xYQ0 cvja3AMzk+JSNQksyntkiq7Q8eDmxYjFhVqN3DSqHxB0tVYXcaLq+xnKSShtfTT8h+N6 f9Tb31cORdjWphy3y5+E1UFCdn7HErQcxFmw/YR50elXJD/ioQ53wqPAxD+AmSk7owxH SlC6JIzV0qNSMdC5T1tSP7ct9Ep4vGhkm4x5cmhuwl0f1IOUzuIUMctacI+70oGoMukg jAKyFuEcwNGR7OF5G9Cn63T5QMlUnbffEC6JpFTRKeY9TzTwLflPFZc6PbUU3K9GrU/f Od7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764199081; x=1764803881; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=EK277X+oVRo/3waBm9mTxQf5GxrA/dPpZ/zTyzS81bg=; b=nW3/7cpRYFrN/dsjhK/TtLRduYEPBEiNTO9tW2o4Ys19bTo06CnQuoApAbMoycTgVk K9yv7+nzNFoR9XRgALGaZZFe3O6+XNFwflv06SVRPlJknX4YHFpvZ5ejLEVw5L3JuSSL 6hcvb/GE3E+xYuRRRD++U3ihn8s59tXt8uS1Kjv13Ef3QgPgRuvaYQWVLLGUdFJEXiP9 737jBM0Hr0zCXs12mFfqjLZnQmQWFv1N8umB593UswCxrRv3hICuKelQQSShnfZ5cGg9 gShij5p6c6JnAbrCL7nIy9BpMOIsfXIndEdGYta4FqCaok+a/hix81LP/SvgQBtxEFdn T71Q== X-Forwarded-Encrypted: i=1; AJvYcCVmNuyBxjFIbk2vcd+D14eMkFh9NtopnhViNL2Fy1FF0imLu+VVQ1+UJ/9JYqjzdKyVfq/jkzNfxBMM1ec=@vger.kernel.org X-Gm-Message-State: AOJu0YxlDGRgqTVoHhdI/DKE0soJrAORNanfFF9livK1RwjQP3fiKOG7 OxwpWwOv1L3jgRVkewAYPfeVjcJb+i1iYL7l7nJUfETekP/iKpFdn2ILHsx0IjVG3+96xBTnzGb pKi6+9YWsBZ3a4w== X-Google-Smtp-Source: AGHT+IF4HzJU/io7p5u55ySnDmOnh3kDCjx8YWbt0k4JunTmVTYnjTqHIkASsk3cbqu5Mw+7w80+iyJ1PeJs/w== X-Received: from pgbdl10.prod.google.com ([2002:a05:6a02:d0a:b0:b6c:f35f:bae9]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:3c8d:b0:35f:84c7:4031 with SMTP id adf61e73a8af0-3637e0d3593mr9350366637.55.1764199080759; Wed, 26 Nov 2025 15:18:00 -0800 (PST) Date: Wed, 26 Nov 2025 23:17:27 +0000 In-Reply-To: <20251126231733.3302983-1-dmatlack@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251126231733.3302983-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.487.g5c8c507ade-goog Message-ID: <20251126231733.3302983-13-dmatlack@google.com> Subject: [PATCH v4 12/18] vfio: selftests: Move IOVA allocator into iova_allocator.c From: David Matlack To: Alex Williamson Cc: Alex Mastro , David Matlack , Jason Gunthorpe , Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Raghavendra Rao Ananta , Vipin Sharma Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Move the IOVA allocator into its own file, to provide better separation between the allocator and the struct vfio_pci_device helper code. The allocator could go into iommu.c, but it is standalone enough that a separate file seems cleaner. This also continues the trend of having a .c for every major object in VFIO selftests (vfio_pci_device.c, vfio_pci_driver.c, iommu.c, and now iova_allocator.c). No functional change intended. Reviewed-by: Alex Mastro Tested-by: Alex Mastro Reviewed-by: Raghavendra Rao Ananta Signed-off-by: David Matlack --- .../selftests/vfio/lib/iova_allocator.c | 94 +++++++++++++++++++ tools/testing/selftests/vfio/lib/libvfio.mk | 1 + .../selftests/vfio/lib/vfio_pci_device.c | 71 -------------- 3 files changed, 95 insertions(+), 71 deletions(-) create mode 100644 tools/testing/selftests/vfio/lib/iova_allocator.c diff --git a/tools/testing/selftests/vfio/lib/iova_allocator.c b/tools/test= ing/selftests/vfio/lib/iova_allocator.c new file mode 100644 index 000000000000..f03648361ba2 --- /dev/null +++ b/tools/testing/selftests/vfio/lib/iova_allocator.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +struct iova_allocator *iova_allocator_init(struct vfio_pci_device *device) +{ + struct iova_allocator *allocator; + struct iommu_iova_range *ranges; + u32 nranges; + + ranges =3D vfio_pci_iova_ranges(device, &nranges); + VFIO_ASSERT_NOT_NULL(ranges); + + allocator =3D malloc(sizeof(*allocator)); + VFIO_ASSERT_NOT_NULL(allocator); + + *allocator =3D (struct iova_allocator){ + .ranges =3D ranges, + .nranges =3D nranges, + .range_idx =3D 0, + .range_offset =3D 0, + }; + + return allocator; +} + +void iova_allocator_cleanup(struct iova_allocator *allocator) +{ + free(allocator->ranges); + free(allocator); +} + +iova_t iova_allocator_alloc(struct iova_allocator *allocator, size_t size) +{ + VFIO_ASSERT_GT(size, 0, "Invalid size arg, zero\n"); + VFIO_ASSERT_EQ(size & (size - 1), 0, "Invalid size arg, non-power-of-2\n"= ); + + for (;;) { + struct iommu_iova_range *range; + iova_t iova, last; + + VFIO_ASSERT_LT(allocator->range_idx, allocator->nranges, + "IOVA allocator out of space\n"); + + range =3D &allocator->ranges[allocator->range_idx]; + iova =3D range->start + allocator->range_offset; + + /* Check for sufficient space at the current offset */ + if (check_add_overflow(iova, size - 1, &last) || + last > range->last) + goto next_range; + + /* Align iova to size */ + iova =3D last & ~(size - 1); + + /* Check for sufficient space at the aligned iova */ + if (check_add_overflow(iova, size - 1, &last) || + last > range->last) + goto next_range; + + if (last =3D=3D range->last) { + allocator->range_idx++; + allocator->range_offset =3D 0; + } else { + allocator->range_offset =3D last - range->start + 1; + } + + return iova; + +next_range: + allocator->range_idx++; + allocator->range_offset =3D 0; + } +} + diff --git a/tools/testing/selftests/vfio/lib/libvfio.mk b/tools/testing/se= lftests/vfio/lib/libvfio.mk index 7ecf2ad75c67..f15b966877e9 100644 --- a/tools/testing/selftests/vfio/lib/libvfio.mk +++ b/tools/testing/selftests/vfio/lib/libvfio.mk @@ -4,6 +4,7 @@ ARCH ?=3D $(SUBARCH) LIBVFIO_SRCDIR :=3D $(selfdir)/vfio/lib =20 LIBVFIO_C :=3D iommu.c +LIBVFIO_C +=3D iova_allocator.c LIBVFIO_C +=3D vfio_pci_device.c LIBVFIO_C +=3D vfio_pci_driver.c =20 diff --git a/tools/testing/selftests/vfio/lib/vfio_pci_device.c b/tools/tes= ting/selftests/vfio/lib/vfio_pci_device.c index 10fc016a2a3e..aa5b45052c77 100644 --- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c +++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c @@ -24,77 +24,6 @@ =20 #define PCI_SYSFS_PATH "/sys/bus/pci/devices" =20 -struct iova_allocator *iova_allocator_init(struct vfio_pci_device *device) -{ - struct iova_allocator *allocator; - struct iommu_iova_range *ranges; - u32 nranges; - - ranges =3D vfio_pci_iova_ranges(device, &nranges); - VFIO_ASSERT_NOT_NULL(ranges); - - allocator =3D malloc(sizeof(*allocator)); - VFIO_ASSERT_NOT_NULL(allocator); - - *allocator =3D (struct iova_allocator){ - .ranges =3D ranges, - .nranges =3D nranges, - .range_idx =3D 0, - .range_offset =3D 0, - }; - - return allocator; -} - -void iova_allocator_cleanup(struct iova_allocator *allocator) -{ - free(allocator->ranges); - free(allocator); -} - -iova_t iova_allocator_alloc(struct iova_allocator *allocator, size_t size) -{ - VFIO_ASSERT_GT(size, 0, "Invalid size arg, zero\n"); - VFIO_ASSERT_EQ(size & (size - 1), 0, "Invalid size arg, non-power-of-2\n"= ); - - for (;;) { - struct iommu_iova_range *range; - iova_t iova, last; - - VFIO_ASSERT_LT(allocator->range_idx, allocator->nranges, - "IOVA allocator out of space\n"); - - range =3D &allocator->ranges[allocator->range_idx]; - iova =3D range->start + allocator->range_offset; - - /* Check for sufficient space at the current offset */ - if (check_add_overflow(iova, size - 1, &last) || - last > range->last) - goto next_range; - - /* Align iova to size */ - iova =3D last & ~(size - 1); - - /* Check for sufficient space at the aligned iova */ - if (check_add_overflow(iova, size - 1, &last) || - last > range->last) - goto next_range; - - if (last =3D=3D range->last) { - allocator->range_idx++; - allocator->range_offset =3D 0; - } else { - allocator->range_offset =3D last - range->start + 1; - } - - return iova; - -next_range: - allocator->range_idx++; - allocator->range_offset =3D 0; - } -} - static void vfio_pci_irq_set(struct vfio_pci_device *device, u32 index, u32 vector, u32 count, int *fds) { --=20 2.52.0.487.g5c8c507ade-goog From nobody Mon Dec 1 22:03:57 2025 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BBF8D34887C for ; Wed, 26 Nov 2025 23:18:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199084; cv=none; b=jQe7EGwJfG2l02SdWtxN/wgMFiCgXD8tomieoivgdfuMTe4MBoMBTfxs3/lCvbt0nPN8h/PMtzJfx8nP6I/kJhlz1E6rS6HWgUI7+s3ZCWidtonolOR4og7v9qbbk22fte0Vc2FwlCD9mVZGrYhbQkuFQD/zJ/1BUdm78f1f+ek= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199084; c=relaxed/simple; bh=kLSpk5VFHeMFBJ+GwTtilOXQsKSv5ho2z8c5GeFW23k=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=RGrsOJdRfLDMwWdgr4WPkn7m62mhcaGRGkAF/fE9PUFmmXcW++v74e7kMlIoJLWma7nDplx+a6Yn5joM+bttTHm0iNl3C6+y0GrD8xz5XDSs7qEpTzjx6AaPfgJtq9m4Yd/V/nfzHzLgn5DxfN8XKyOk+0bKyLMb0dP7S4AUnlg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=qGETBYWL; arc=none smtp.client-ip=209.85.210.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="qGETBYWL" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7be3d08f863so340600b3a.2 for ; Wed, 26 Nov 2025 15:18:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764199082; x=1764803882; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=x8JEo4qwFAgC4mqRGiFhhIpCUvh9YEL7505XJDWuM1w=; b=qGETBYWLggrmbA5mvGvCwXCLOS1Utiiuteuynz99e9WBwQhiLT8LFRQqQWohKURhSg mYl3b55xSuxt/JSKnbrX3jClX8hiqj2vpD+YQ1zt66ksXU0RRGwQeup0ztGDsz5ZoeA6 it4v6lg4y7FaiZ2CmAEumZzbb+Idmf3jRMdQJG/keShEWcAWesuuFsdcE50ayd7uixSS 9oWEsq2IgHAu2ILfO5Hn4o84dX74Sw16oY2vN9bWCNwpWvwMQ9Y+rhY+ZJp4Y9brjfRT 7JO6QlD/2yYHQbCsLjEK9RrcD3rMMUocNjd6fe83LpW+ygCx4czuUWDc4me9PQaeafSU 61DA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764199082; x=1764803882; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=x8JEo4qwFAgC4mqRGiFhhIpCUvh9YEL7505XJDWuM1w=; b=J+T7wPdbV7l6jUhhb6ZPpWbaIRB0IwL8EfdroG7UPFJEejK4m/xsRJKi4amWVUYXnJ KZYI7NSOlVHbb9ch7FNTLZI/20atB9xCEmaYmnHmYgWU4M+5nahrd7I1+D4xW6F46CJI sKCIvpzvvlzVtKSiX4xaVuAm/357OuZTdOQTZHiXYtaGrdeEUj4ANkdGYLWAXRcZaKXV rQdvr7SglmDk67NUu+T4p/HExvqAR/goy9HiOU8Zzfj9OkdRpK/pb1e20apPn+vYPQfZ 6DSye7mJ6pe+ytmX8Dpif2VLEubv4UV8ylanY0SZ6jAfWMroDvBvg7KNq7nSyooquf9b zANw== X-Forwarded-Encrypted: i=1; AJvYcCVyRTqZG40bBJ8SM8fDNrCdUmAQg7TsBF+ixVpS0VahIpXWx4GA114IPMYspdwRpxsKBJ56JL/w1yB9zxc=@vger.kernel.org X-Gm-Message-State: AOJu0YzJ82K8b1yDiH77E2Vr1FBh4PQ071+1deyVnDHwwHT/KsCDYx+8 1b5N6fF9QcqIyyOmpKLUxf3lZoKUAvchj8qN2j9cKbKUZqTJbACSluMcb3EBxUD7gY4pO10GVQk shaxD0xzjvhHwOQ== X-Google-Smtp-Source: AGHT+IFl22NbQBZgbgr/TKTkVvLlEFJJlyBFNSyJf/VAq6Sml92UZTLp/bHAj/FesXj2d1quZCUi9YxULJg6Aw== X-Received: from pfht15.prod.google.com ([2002:a62:ea0f:0:b0:77f:68a4:6770]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:2789:b0:7bf:1a4b:1675 with SMTP id d2e1a72fcca58-7c58e700286mr23608102b3a.28.1764199082281; Wed, 26 Nov 2025 15:18:02 -0800 (PST) Date: Wed, 26 Nov 2025 23:17:28 +0000 In-Reply-To: <20251126231733.3302983-1-dmatlack@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251126231733.3302983-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.487.g5c8c507ade-goog Message-ID: <20251126231733.3302983-14-dmatlack@google.com> Subject: [PATCH v4 13/18] vfio: selftests: Stop passing device for IOMMU operations From: David Matlack To: Alex Williamson Cc: Alex Mastro , David Matlack , Jason Gunthorpe , Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Raghavendra Rao Ananta , Vipin Sharma Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Drop the struct vfio_pci_device wrappers for IOMMU map/unmap functions and require tests to directly call iommu_map(), iommu_unmap(), etc. This results in more concise code, and also makes it clear the map operations are happening on a struct iommu, not necessarily on a specific device, especially when multi-device tests are introduced. Do the same for iova_allocator_init() as that function only needs the struct iommu, not struct vfio_pci_device. Reviewed-by: Alex Mastro Tested-by: Alex Mastro Reviewed-by: Raghavendra Rao Ananta Signed-off-by: David Matlack --- .../selftests/vfio/lib/include/vfio_util.h | 44 +------------------ .../selftests/vfio/lib/iova_allocator.c | 4 +- .../selftests/vfio/vfio_dma_mapping_test.c | 20 ++++----- .../selftests/vfio/vfio_pci_driver_test.c | 19 ++++---- 4 files changed, 22 insertions(+), 65 deletions(-) diff --git a/tools/testing/selftests/vfio/lib/include/vfio_util.h b/tools/t= esting/selftests/vfio/lib/include/vfio_util.h index f67915d9443e..5224808201fe 100644 --- a/tools/testing/selftests/vfio/lib/include/vfio_util.h +++ b/tools/testing/selftests/vfio/lib/include/vfio_util.h @@ -260,52 +260,10 @@ void vfio_pci_device_cleanup(struct vfio_pci_device *= device); =20 void vfio_pci_device_reset(struct vfio_pci_device *device); =20 -static inline struct iommu_iova_range *vfio_pci_iova_ranges(struct vfio_pc= i_device *device, - u32 *nranges) -{ - return iommu_iova_ranges(device->iommu, nranges); -} - -struct iova_allocator *iova_allocator_init(struct vfio_pci_device *device); +struct iova_allocator *iova_allocator_init(struct iommu *iommu); void iova_allocator_cleanup(struct iova_allocator *allocator); iova_t iova_allocator_alloc(struct iova_allocator *allocator, size_t size); =20 -static inline int __vfio_pci_dma_map(struct vfio_pci_device *device, - struct dma_region *region) -{ - return __iommu_map(device->iommu, region); -} - -static inline void vfio_pci_dma_map(struct vfio_pci_device *device, - struct dma_region *region) -{ - VFIO_ASSERT_EQ(__vfio_pci_dma_map(device, region), 0); -} - -static inline int __vfio_pci_dma_unmap(struct vfio_pci_device *device, - struct dma_region *region, - u64 *unmapped) -{ - return __iommu_unmap(device->iommu, region, unmapped); -} - -static inline void vfio_pci_dma_unmap(struct vfio_pci_device *device, - struct dma_region *region) -{ - VFIO_ASSERT_EQ(__vfio_pci_dma_unmap(device, region, NULL), 0); -} - -static inline int __vfio_pci_dma_unmap_all(struct vfio_pci_device *device, - u64 *unmapped) -{ - return __iommu_unmap_all(device->iommu, unmapped); -} - -static inline void vfio_pci_dma_unmap_all(struct vfio_pci_device *device) -{ - VFIO_ASSERT_EQ(__vfio_pci_dma_unmap_all(device, NULL), 0); -} - void vfio_pci_config_access(struct vfio_pci_device *device, bool write, size_t config, size_t size, void *data); =20 diff --git a/tools/testing/selftests/vfio/lib/iova_allocator.c b/tools/test= ing/selftests/vfio/lib/iova_allocator.c index f03648361ba2..b3b6b27f5d1e 100644 --- a/tools/testing/selftests/vfio/lib/iova_allocator.c +++ b/tools/testing/selftests/vfio/lib/iova_allocator.c @@ -21,13 +21,13 @@ =20 #include =20 -struct iova_allocator *iova_allocator_init(struct vfio_pci_device *device) +struct iova_allocator *iova_allocator_init(struct iommu *iommu) { struct iova_allocator *allocator; struct iommu_iova_range *ranges; u32 nranges; =20 - ranges =3D vfio_pci_iova_ranges(device, &nranges); + ranges =3D iommu_iova_ranges(iommu, &nranges); VFIO_ASSERT_NOT_NULL(ranges); =20 allocator =3D malloc(sizeof(*allocator)); diff --git a/tools/testing/selftests/vfio/vfio_dma_mapping_test.c b/tools/t= esting/selftests/vfio/vfio_dma_mapping_test.c index 289af4665803..c4c2fc36c7b3 100644 --- a/tools/testing/selftests/vfio/vfio_dma_mapping_test.c +++ b/tools/testing/selftests/vfio/vfio_dma_mapping_test.c @@ -122,7 +122,7 @@ FIXTURE_SETUP(vfio_dma_mapping_test) { self->iommu =3D iommu_init(variant->iommu_mode); self->device =3D vfio_pci_device_init(device_bdf, self->iommu); - self->iova_allocator =3D iova_allocator_init(self->device); + self->iova_allocator =3D iova_allocator_init(self->iommu); } =20 FIXTURE_TEARDOWN(vfio_dma_mapping_test) @@ -153,7 +153,7 @@ TEST_F(vfio_dma_mapping_test, dma_map_unmap) region.iova =3D iova_allocator_alloc(self->iova_allocator, size); region.size =3D size; =20 - vfio_pci_dma_map(self->device, ®ion); + iommu_map(self->iommu, ®ion); printf("Mapped HVA %p (size 0x%lx) at IOVA 0x%lx\n", region.vaddr, size, = region.iova); =20 ASSERT_EQ(region.iova, to_iova(self->device, region.vaddr)); @@ -195,7 +195,7 @@ TEST_F(vfio_dma_mapping_test, dma_map_unmap) } =20 unmap: - rc =3D __vfio_pci_dma_unmap(self->device, ®ion, &unmapped); + rc =3D __iommu_unmap(self->iommu, ®ion, &unmapped); ASSERT_EQ(rc, 0); ASSERT_EQ(unmapped, region.size); printf("Unmapped IOVA 0x%lx\n", region.iova); @@ -245,7 +245,7 @@ FIXTURE_SETUP(vfio_dma_map_limit_test) MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); ASSERT_NE(region->vaddr, MAP_FAILED); =20 - ranges =3D vfio_pci_iova_ranges(self->device, &nranges); + ranges =3D iommu_iova_ranges(self->iommu, &nranges); VFIO_ASSERT_NOT_NULL(ranges); last_iova =3D ranges[nranges - 1].last; free(ranges); @@ -268,10 +268,10 @@ TEST_F(vfio_dma_map_limit_test, unmap_range) u64 unmapped; int rc; =20 - vfio_pci_dma_map(self->device, region); + iommu_map(self->iommu, region); ASSERT_EQ(region->iova, to_iova(self->device, region->vaddr)); =20 - rc =3D __vfio_pci_dma_unmap(self->device, region, &unmapped); + rc =3D __iommu_unmap(self->iommu, region, &unmapped); ASSERT_EQ(rc, 0); ASSERT_EQ(unmapped, region->size); } @@ -282,10 +282,10 @@ TEST_F(vfio_dma_map_limit_test, unmap_all) u64 unmapped; int rc; =20 - vfio_pci_dma_map(self->device, region); + iommu_map(self->iommu, region); ASSERT_EQ(region->iova, to_iova(self->device, region->vaddr)); =20 - rc =3D __vfio_pci_dma_unmap_all(self->device, &unmapped); + rc =3D __iommu_unmap_all(self->iommu, &unmapped); ASSERT_EQ(rc, 0); ASSERT_EQ(unmapped, region->size); } @@ -298,10 +298,10 @@ TEST_F(vfio_dma_map_limit_test, overflow) region->iova =3D ~(iova_t)0 & ~(region->size - 1); region->size =3D self->mmap_size; =20 - rc =3D __vfio_pci_dma_map(self->device, region); + rc =3D __iommu_map(self->iommu, region); ASSERT_EQ(rc, -EOVERFLOW); =20 - rc =3D __vfio_pci_dma_unmap(self->device, region, NULL); + rc =3D __iommu_unmap(self->iommu, region, NULL); ASSERT_EQ(rc, -EOVERFLOW); } =20 diff --git a/tools/testing/selftests/vfio/vfio_pci_driver_test.c b/tools/te= sting/selftests/vfio/vfio_pci_driver_test.c index 057aa9bbe13e..229e932a06f8 100644 --- a/tools/testing/selftests/vfio/vfio_pci_driver_test.c +++ b/tools/testing/selftests/vfio/vfio_pci_driver_test.c @@ -18,7 +18,7 @@ static const char *device_bdf; ASSERT_EQ(EAGAIN, errno); \ } while (0) =20 -static void region_setup(struct vfio_pci_device *device, +static void region_setup(struct iommu *iommu, struct iova_allocator *iova_allocator, struct dma_region *region, u64 size) { @@ -33,13 +33,12 @@ static void region_setup(struct vfio_pci_device *device, region->iova =3D iova_allocator_alloc(iova_allocator, size); region->size =3D size; =20 - vfio_pci_dma_map(device, region); + iommu_map(iommu, region); } =20 -static void region_teardown(struct vfio_pci_device *device, - struct dma_region *region) +static void region_teardown(struct iommu *iommu, struct dma_region *region) { - vfio_pci_dma_unmap(device, region); + iommu_unmap(iommu, region); VFIO_ASSERT_EQ(munmap(region->vaddr, region->size), 0); } =20 @@ -76,12 +75,12 @@ FIXTURE_SETUP(vfio_pci_driver_test) =20 self->iommu =3D iommu_init(variant->iommu_mode); self->device =3D vfio_pci_device_init(device_bdf, self->iommu); - self->iova_allocator =3D iova_allocator_init(self->device); + self->iova_allocator =3D iova_allocator_init(self->iommu); =20 driver =3D &self->device->driver; =20 - region_setup(self->device, self->iova_allocator, &self->memcpy_region, SZ= _1G); - region_setup(self->device, self->iova_allocator, &driver->region, SZ_2M); + region_setup(self->iommu, self->iova_allocator, &self->memcpy_region, SZ_= 1G); + region_setup(self->iommu, self->iova_allocator, &driver->region, SZ_2M); =20 /* Any IOVA that doesn't overlap memcpy_region and driver->region. */ self->unmapped_iova =3D iova_allocator_alloc(self->iova_allocator, SZ_1G); @@ -110,8 +109,8 @@ FIXTURE_TEARDOWN(vfio_pci_driver_test) =20 vfio_pci_driver_remove(self->device); =20 - region_teardown(self->device, &self->memcpy_region); - region_teardown(self->device, &driver->region); + region_teardown(self->iommu, &self->memcpy_region); + region_teardown(self->iommu, &driver->region); =20 iova_allocator_cleanup(self->iova_allocator); vfio_pci_device_cleanup(self->device); --=20 2.52.0.487.g5c8c507ade-goog From nobody Mon Dec 1 22:03:57 2025 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 78B45345CCC for ; Wed, 26 Nov 2025 23:18:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199086; cv=none; b=gMK07eX7fQLUlLxlToHAXoSI/vXRtDpurxkkjkY+40mWadNMM+MYHYkYkPsoiGHBNrJTzTeWVB+MKywQQY9S8ZNZZwUzxoUVqeacr0psbLaTnFnNESml7+M3chGzDonv2MKwS04reVLkxRuw4ZESBfWzlrY8j+TKRnDBIPqqHso= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199086; c=relaxed/simple; bh=yDJ+V4vJT+UeNxWHEcNGG5rhGAYPb/61//Lf+3Fvynw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Qq+UFpfsyaDRV0ZdpH8tK93mwmztCv0J4DdkyRjPAQly6UTDkovb7kVAsvOaaogDb1Pxzx3C0qhfkkEdKEaQaULf4Qz+eajpvFp6wnkoBmEYuicF4AiliiM0fQap8mVCPjB/fGum6houpgi8DoQHk7FQbWf9Npj6r13G3K4K+lk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=E8esp4t/; arc=none smtp.client-ip=209.85.214.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="E8esp4t/" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-29557f43d56so2804495ad.3 for ; Wed, 26 Nov 2025 15:18:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764199084; x=1764803884; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=msfafFWYaD0dYRGinq2pU9UGptExPeKvxxBVJh+65mA=; b=E8esp4t/8msD5EdMmRHDgEoakGzj0w+RB3YVIg/i7+Yg2pR5S0mPTFduGY7LN2mkNo kObbb6fGKEMQwEU7TztcSl+ryOkYNKdag2YQAamX8w8aXqFATIW76PrOTCErIzarltSI UpkH8wt7Y9GuvggEszXxn5xezr7j4zZH5q1VWo6JXNA33XcLl2WoUTRzLb19CKC0zjQ+ +PpToX7PjIzRI59QoFqbYdlfAIVk7uDSMBNyhFQxML0TQS256u1Eb4GkvjV+wVqVCCMC btr7XdUnIY4iey93TlzpYYZpuPYAe+nOhtvrQfu18rCHryd8tpue2INNj7Zt2T7/9KEx wnqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764199084; x=1764803884; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=msfafFWYaD0dYRGinq2pU9UGptExPeKvxxBVJh+65mA=; b=D3unlLG9NnakkUGMjsIOu6xeobrCZrpXeczlxyhzsspdvGc0le9Gqkc/I74nucgQmz imYoTUC1JWC3Xsuqhk/AJOXgbNR7Ecm2c4Rg4QUjG/R5ZORxSGwf9EAojjCHgmEEzzFI Yt09e7wvhuKrBJCpGcN9IABIAYmopIK9r6CShQDrvoVx7NGh+HNz75611/VRZob4P07H lKlELxSVLwav7iKjAOqKoHxsWKqQhPAUQiBnO34zlaqTjSs3axpl1xY4KZocVSKQedZ9 JaVEoRGx1CmE00QUZKKG7Hr5/n+F3F6g55Tb3B4gW1cmTfikPuwOMiAZm3ke9ZB6yvr6 NuIg== X-Forwarded-Encrypted: i=1; AJvYcCU2FcIVcBIAzL6dDJLQWwnD9E9VwWxY9eQt0Msy4WtYPZvzCXbTazRI2Y2EejbGMbXP84BA4pd90vCh7qI=@vger.kernel.org X-Gm-Message-State: AOJu0YzeCrSwNdgdMypz3SnlZxpiL0c3G/ZfEtczqfvNVpPL4qi68eAK 8hovgb85t+pIIKjCF6YpY6UX7+VOHwF5dfqWAqThWkFpzN0Hr6/TcVQOU/1HO/Fi+LQKGsClOoa 0hsuc9CAT3SxoPg== X-Google-Smtp-Source: AGHT+IH2SGFtadAdgidkvPbG8Lr4OVhZkJrONXr7INvC7eW3177bBHqIiIjpGg++sxybFvac3GuvD4aPQd376Q== X-Received: from plou3.prod.google.com ([2002:a17:903:1ae3:b0:295:61b:84fa]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:2f4f:b0:295:7453:b58b with SMTP id d9443c01a7336-29baae4569fmr100922005ad.4.1764199083808; Wed, 26 Nov 2025 15:18:03 -0800 (PST) Date: Wed, 26 Nov 2025 23:17:29 +0000 In-Reply-To: <20251126231733.3302983-1-dmatlack@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251126231733.3302983-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.487.g5c8c507ade-goog Message-ID: <20251126231733.3302983-15-dmatlack@google.com> Subject: [PATCH v4 14/18] vfio: selftests: Rename vfio_util.h to libvfio.h From: David Matlack To: Alex Williamson Cc: Alex Mastro , David Matlack , Jason Gunthorpe , Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Raghavendra Rao Ananta , Vipin Sharma Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Rename vfio_util.h to libvfio.h to match the name of libvfio.mk. No functional change intended. Reviewed-by: Alex Mastro Tested-by: Alex Mastro Reviewed-by: Raghavendra Rao Ananta Signed-off-by: David Matlack --- tools/testing/selftests/vfio/lib/drivers/dsa/dsa.c | 2 +- tools/testing/selftests/vfio/lib/drivers/ioat/ioat.c | 2 +- .../selftests/vfio/lib/include/{vfio_util.h =3D> libvfio.h} | 6 +++--- tools/testing/selftests/vfio/lib/iommu.c | 2 +- tools/testing/selftests/vfio/lib/iova_allocator.c | 2 +- tools/testing/selftests/vfio/lib/vfio_pci_device.c | 2 +- tools/testing/selftests/vfio/lib/vfio_pci_driver.c | 2 +- tools/testing/selftests/vfio/vfio_dma_mapping_test.c | 2 +- tools/testing/selftests/vfio/vfio_iommufd_setup_test.c | 2 +- tools/testing/selftests/vfio/vfio_pci_device_test.c | 2 +- tools/testing/selftests/vfio/vfio_pci_driver_test.c | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) rename tools/testing/selftests/vfio/lib/include/{vfio_util.h =3D> libvfio.= h} (98%) diff --git a/tools/testing/selftests/vfio/lib/drivers/dsa/dsa.c b/tools/tes= ting/selftests/vfio/lib/drivers/dsa/dsa.c index 0afbab0d82de..c75045bcab79 100644 --- a/tools/testing/selftests/vfio/lib/drivers/dsa/dsa.c +++ b/tools/testing/selftests/vfio/lib/drivers/dsa/dsa.c @@ -9,7 +9,7 @@ #include #include =20 -#include +#include =20 #include "registers.h" =20 diff --git a/tools/testing/selftests/vfio/lib/drivers/ioat/ioat.c b/tools/t= esting/selftests/vfio/lib/drivers/ioat/ioat.c index c6db311ce64d..a871b935542b 100644 --- a/tools/testing/selftests/vfio/lib/drivers/ioat/ioat.c +++ b/tools/testing/selftests/vfio/lib/drivers/ioat/ioat.c @@ -7,7 +7,7 @@ #include #include =20 -#include +#include =20 #include "hw.h" #include "registers.h" diff --git a/tools/testing/selftests/vfio/lib/include/vfio_util.h b/tools/t= esting/selftests/vfio/lib/include/libvfio.h similarity index 98% rename from tools/testing/selftests/vfio/lib/include/vfio_util.h rename to tools/testing/selftests/vfio/lib/include/libvfio.h index 5224808201fe..3027af15e316 100644 --- a/tools/testing/selftests/vfio/lib/include/vfio_util.h +++ b/tools/testing/selftests/vfio/lib/include/libvfio.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef SELFTESTS_VFIO_LIB_INCLUDE_VFIO_UTIL_H -#define SELFTESTS_VFIO_LIB_INCLUDE_VFIO_UTIL_H +#ifndef SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_H +#define SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_H =20 #include #include @@ -352,4 +352,4 @@ void vfio_pci_driver_memcpy_start(struct vfio_pci_devic= e *device, int vfio_pci_driver_memcpy_wait(struct vfio_pci_device *device); void vfio_pci_driver_send_msi(struct vfio_pci_device *device); =20 -#endif /* SELFTESTS_VFIO_LIB_INCLUDE_VFIO_UTIL_H */ +#endif /* SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_H */ diff --git a/tools/testing/selftests/vfio/lib/iommu.c b/tools/testing/selft= ests/vfio/lib/iommu.c index 3933079fc419..52f9cdf5f171 100644 --- a/tools/testing/selftests/vfio/lib/iommu.c +++ b/tools/testing/selftests/vfio/lib/iommu.c @@ -19,7 +19,7 @@ #include =20 #include "../../../kselftest.h" -#include +#include =20 const char *default_iommu_mode =3D "iommufd"; =20 diff --git a/tools/testing/selftests/vfio/lib/iova_allocator.c b/tools/test= ing/selftests/vfio/lib/iova_allocator.c index b3b6b27f5d1e..a12b0a51e9e6 100644 --- a/tools/testing/selftests/vfio/lib/iova_allocator.c +++ b/tools/testing/selftests/vfio/lib/iova_allocator.c @@ -19,7 +19,7 @@ #include #include =20 -#include +#include =20 struct iova_allocator *iova_allocator_init(struct iommu *iommu) { diff --git a/tools/testing/selftests/vfio/lib/vfio_pci_device.c b/tools/tes= ting/selftests/vfio/lib/vfio_pci_device.c index aa5b45052c77..847e27e1166c 100644 --- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c +++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c @@ -20,7 +20,7 @@ #include =20 #include "../../../kselftest.h" -#include +#include =20 #define PCI_SYSFS_PATH "/sys/bus/pci/devices" =20 diff --git a/tools/testing/selftests/vfio/lib/vfio_pci_driver.c b/tools/tes= ting/selftests/vfio/lib/vfio_pci_driver.c index abb7a62a03ea..ca0e25efbfa1 100644 --- a/tools/testing/selftests/vfio/lib/vfio_pci_driver.c +++ b/tools/testing/selftests/vfio/lib/vfio_pci_driver.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only #include "../../../kselftest.h" -#include +#include =20 #ifdef __x86_64__ extern struct vfio_pci_driver_ops dsa_ops; diff --git a/tools/testing/selftests/vfio/vfio_dma_mapping_test.c b/tools/t= esting/selftests/vfio/vfio_dma_mapping_test.c index c4c2fc36c7b3..213fcd8dcc79 100644 --- a/tools/testing/selftests/vfio/vfio_dma_mapping_test.c +++ b/tools/testing/selftests/vfio/vfio_dma_mapping_test.c @@ -10,7 +10,7 @@ #include #include =20 -#include +#include =20 #include "../kselftest_harness.h" =20 diff --git a/tools/testing/selftests/vfio/vfio_iommufd_setup_test.c b/tools= /testing/selftests/vfio/vfio_iommufd_setup_test.c index 3655106b912d..caf1c6291f3d 100644 --- a/tools/testing/selftests/vfio/vfio_iommufd_setup_test.c +++ b/tools/testing/selftests/vfio/vfio_iommufd_setup_test.c @@ -10,7 +10,7 @@ #include #include =20 -#include +#include #include "../kselftest_harness.h" =20 static const char iommu_dev_path[] =3D "/dev/iommu"; diff --git a/tools/testing/selftests/vfio/vfio_pci_device_test.c b/tools/te= sting/selftests/vfio/vfio_pci_device_test.c index e95217933c6b..ecbb669b3765 100644 --- a/tools/testing/selftests/vfio/vfio_pci_device_test.c +++ b/tools/testing/selftests/vfio/vfio_pci_device_test.c @@ -10,7 +10,7 @@ #include #include =20 -#include +#include =20 #include "../kselftest_harness.h" =20 diff --git a/tools/testing/selftests/vfio/vfio_pci_driver_test.c b/tools/te= sting/selftests/vfio/vfio_pci_driver_test.c index 229e932a06f8..f0ca8310d6a8 100644 --- a/tools/testing/selftests/vfio/vfio_pci_driver_test.c +++ b/tools/testing/selftests/vfio/vfio_pci_driver_test.c @@ -5,7 +5,7 @@ #include #include =20 -#include +#include =20 #include "../kselftest_harness.h" =20 --=20 2.52.0.487.g5c8c507ade-goog From nobody Mon Dec 1 22:03:57 2025 Received: from mail-pf1-f201.google.com (mail-pf1-f201.google.com [209.85.210.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 02B6A34AB1E for ; Wed, 26 Nov 2025 23:18:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199090; cv=none; b=n2R1X6YAg0VbsYqSg7OjAeCDr3jOwseYSL6R+9wlbaP+toTdBZfiAiPDF/peWPG8HQsJwRbjUVxneJmoMMQap4UUUFqaNM1r+q4Dxg4+3EztOmHhYvmqOoa+01+xSDE9BsunEZ2TTwgewLIcLLeH7LOjiwvZfvBhnx4Rto/88wE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199090; c=relaxed/simple; bh=mHWkVELCLixotZVit8t/1VqG3neOYudLJ7M3gFcDoEo=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=NVtEJ+VaZBuZaRg9oGY+5B5H5F2hbshC1fvTczIiumy4dp+9dTmweSwBepgbABY8o2NcYbuD3D78cNygajd1AGKa0W3QBpA9dhEOo9tp1yQI6YX63ksFMNm8HFKlNiWUzNDGLIkCGe5ZscZmALn+rq5f7clqn58B6m3aY6QByLk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=XLURi8/z; arc=none smtp.client-ip=209.85.210.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="XLURi8/z" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7bad1cef9bcso363095b3a.1 for ; Wed, 26 Nov 2025 15:18:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764199085; x=1764803885; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=6reQFbvrUZJXcTjumNZF0meA3bbLjKU7IXXVzkqzCAw=; b=XLURi8/zPB3bIqhjlaNNF/2i43TMBb0vdST9yXVz3m2BtumjKOII8bk5ck8EzzphYz 4OC1HRaqaDw8qilQtMqPFyRXf39kgkcNKdQBmEtVd2whPcHORDso5XpmlgalBgEGiYkm bGpfqJj5+Azes3qMM4TvGFugbr9AEGB708VFu7qBJqTrIFn8A+BSPda/9S/r5HeizLpe OpaDwZtNLlDrStKEEd5+ZDLfbx8+HnVNVO32Ej7i6ccs5XFPfqb9t7T2pT7NXuqql+me kx/CfJibs5Eg5NOwmd8Rcz58yPi1xFkEdZ4y/U5WOUV3nqagdeP97//xj30bZIzm5+LV JKaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764199085; x=1764803885; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=6reQFbvrUZJXcTjumNZF0meA3bbLjKU7IXXVzkqzCAw=; b=n4kSZ0SYzKwDXh+ocdc5OmfjO37FtSt3oapQ3oRpV6ry1kIZWiCOWE95/jxB6FKotx VLqA8062dtezMtTZ4UpmnwzGuxMkZ7Ps6heF3d1HyuLaB7PPUMBMPSl9IhIH9KTWK2KO Q8gJ++iKw11WOwtrYB16frcAaGt9SigaBlM5ttFjTJXnHU8BOVC3KnobyNUJMCuSpe0i ool6aqSE9asnp7MfgssgsfUS9Glb4mW2NQYLBeSGDuGOCUR2wnBmuKW2F4qN3GWzaqIW DRKid83J7QHuzixqbdb46N6i0REFaSLQ4v/7/GTaJ3p/eepkzMZNLMckzEwhZLOf8082 hhNA== X-Forwarded-Encrypted: i=1; AJvYcCUFxPab9NaJTTBMkrLMwbuHL+GfWJaE8PEvifbZulWOOArHwHa85/Vc6MxkOUNBGz5yMEJ6IsJfFqzoHJU=@vger.kernel.org X-Gm-Message-State: AOJu0YyZPoG8jraFAlbgccVBzCeJYqUZSiR/cY8EctWlLy+Aj8ZIV/uz NXrBUFokiMb9HJBAD04X/n+Qdb+TjDiG0BJoF64LVTpN+oRaA+t1UC95tKCpC1OvABWYPaiLGGg J5kwLO6xGjc6DCQ== X-Google-Smtp-Source: AGHT+IG3GxAKkWHj5AWb96zXVeX3HY/XVBXQ75qdWHAYcJ4/MKD78Ict7QBDsMZ6sYSSwfs3VrSNhRFYjzx5fw== X-Received: from pfcy27.prod.google.com ([2002:a05:6a00:93db:b0:7b8:642b:1d94]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:9508:b0:7aa:9ca5:da9c with SMTP id d2e1a72fcca58-7c58e50cc8dmr21906021b3a.22.1764199085213; Wed, 26 Nov 2025 15:18:05 -0800 (PST) Date: Wed, 26 Nov 2025 23:17:30 +0000 In-Reply-To: <20251126231733.3302983-1-dmatlack@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251126231733.3302983-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.487.g5c8c507ade-goog Message-ID: <20251126231733.3302983-16-dmatlack@google.com> Subject: [PATCH v4 15/18] vfio: selftests: Move vfio_selftests_*() helpers into libvfio.c From: David Matlack To: Alex Williamson Cc: Alex Mastro , David Matlack , Jason Gunthorpe , Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Raghavendra Rao Ananta , Vipin Sharma Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Move the vfio_selftests_*() helpers into their own file libvfio.c. These helpers have nothing to do with struct vfio_pci_device, so they don't make sense in vfio_pci_device.c. No functional change intended. Reviewed-by: Alex Mastro Tested-by: Alex Mastro Reviewed-by: Raghavendra Rao Ananta Signed-off-by: David Matlack --- tools/testing/selftests/vfio/lib/libvfio.c | 78 +++++++++++++++++++ tools/testing/selftests/vfio/lib/libvfio.mk | 1 + .../selftests/vfio/lib/vfio_pci_device.c | 71 ----------------- 3 files changed, 79 insertions(+), 71 deletions(-) create mode 100644 tools/testing/selftests/vfio/lib/libvfio.c diff --git a/tools/testing/selftests/vfio/lib/libvfio.c b/tools/testing/sel= ftests/vfio/lib/libvfio.c new file mode 100644 index 000000000000..a23a3cc5be69 --- /dev/null +++ b/tools/testing/selftests/vfio/lib/libvfio.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include + +#include "../../../kselftest.h" +#include + +static bool is_bdf(const char *str) +{ + unsigned int s, b, d, f; + int length, count; + + count =3D sscanf(str, "%4x:%2x:%2x.%2x%n", &s, &b, &d, &f, &length); + return count =3D=3D 4 && length =3D=3D strlen(str); +} + +static char **get_bdfs_cmdline(int *argc, char *argv[], int *nr_bdfs) +{ + int i; + + for (i =3D *argc - 1; i > 0 && is_bdf(argv[i]); i--) + continue; + + i++; + *nr_bdfs =3D *argc - i; + *argc -=3D *nr_bdfs; + + return *nr_bdfs ? &argv[i] : NULL; +} + +static char *get_bdf_env(void) +{ + char *bdf; + + bdf =3D getenv("VFIO_SELFTESTS_BDF"); + if (!bdf) + return NULL; + + VFIO_ASSERT_TRUE(is_bdf(bdf), "Invalid BDF: %s\n", bdf); + return bdf; +} + +char **vfio_selftests_get_bdfs(int *argc, char *argv[], int *nr_bdfs) +{ + static char *env_bdf; + char **bdfs; + + bdfs =3D get_bdfs_cmdline(argc, argv, nr_bdfs); + if (bdfs) + return bdfs; + + env_bdf =3D get_bdf_env(); + if (env_bdf) { + *nr_bdfs =3D 1; + return &env_bdf; + } + + fprintf(stderr, "Unable to determine which device(s) to use, skipping tes= t.\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "To pass the device address via environment variable:\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " export VFIO_SELFTESTS_BDF=3D\"segment:bus:device.fun= ction\"\n"); + fprintf(stderr, " %s [options]\n", argv[0]); + fprintf(stderr, "\n"); + fprintf(stderr, "To pass the device address(es) via argv:\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " %s [options] segment:bus:device.function ...\n", arg= v[0]); + fprintf(stderr, "\n"); + exit(KSFT_SKIP); +} + +const char *vfio_selftests_get_bdf(int *argc, char *argv[]) +{ + int nr_bdfs; + + return vfio_selftests_get_bdfs(argc, argv, &nr_bdfs)[0]; +} diff --git a/tools/testing/selftests/vfio/lib/libvfio.mk b/tools/testing/se= lftests/vfio/lib/libvfio.mk index f15b966877e9..9f47bceed16f 100644 --- a/tools/testing/selftests/vfio/lib/libvfio.mk +++ b/tools/testing/selftests/vfio/lib/libvfio.mk @@ -5,6 +5,7 @@ LIBVFIO_SRCDIR :=3D $(selfdir)/vfio/lib =20 LIBVFIO_C :=3D iommu.c LIBVFIO_C +=3D iova_allocator.c +LIBVFIO_C +=3D libvfio.c LIBVFIO_C +=3D vfio_pci_device.c LIBVFIO_C +=3D vfio_pci_driver.c =20 diff --git a/tools/testing/selftests/vfio/lib/vfio_pci_device.c b/tools/tes= ting/selftests/vfio/lib/vfio_pci_device.c index 847e27e1166c..13fdb4b0b10f 100644 --- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c +++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c @@ -376,74 +376,3 @@ void vfio_pci_device_cleanup(struct vfio_pci_device *d= evice) =20 free(device); } - -static bool is_bdf(const char *str) -{ - unsigned int s, b, d, f; - int length, count; - - count =3D sscanf(str, "%4x:%2x:%2x.%2x%n", &s, &b, &d, &f, &length); - return count =3D=3D 4 && length =3D=3D strlen(str); -} - -static char **get_bdfs_cmdline(int *argc, char *argv[], int *nr_bdfs) -{ - int i; - - for (i =3D *argc - 1; i > 0 && is_bdf(argv[i]); i--) - continue; - - i++; - *nr_bdfs =3D *argc - i; - *argc -=3D *nr_bdfs; - - return *nr_bdfs ? &argv[i] : NULL; -} - -static char *get_bdf_env(void) -{ - char *bdf; - - bdf =3D getenv("VFIO_SELFTESTS_BDF"); - if (!bdf) - return NULL; - - VFIO_ASSERT_TRUE(is_bdf(bdf), "Invalid BDF: %s\n", bdf); - return bdf; -} - -char **vfio_selftests_get_bdfs(int *argc, char *argv[], int *nr_bdfs) -{ - static char *env_bdf; - char **bdfs; - - bdfs =3D get_bdfs_cmdline(argc, argv, nr_bdfs); - if (bdfs) - return bdfs; - - env_bdf =3D get_bdf_env(); - if (env_bdf) { - *nr_bdfs =3D 1; - return &env_bdf; - } - - fprintf(stderr, "Unable to determine which device(s) to use, skipping tes= t.\n"); - fprintf(stderr, "\n"); - fprintf(stderr, "To pass the device address via environment variable:\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " export VFIO_SELFTESTS_BDF=3D\"segment:bus:device.fun= ction\"\n"); - fprintf(stderr, " %s [options]\n", argv[0]); - fprintf(stderr, "\n"); - fprintf(stderr, "To pass the device address(es) via argv:\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " %s [options] segment:bus:device.function ...\n", arg= v[0]); - fprintf(stderr, "\n"); - exit(KSFT_SKIP); -} - -const char *vfio_selftests_get_bdf(int *argc, char *argv[]) -{ - int nr_bdfs; - - return vfio_selftests_get_bdfs(argc, argv, &nr_bdfs)[0]; -} --=20 2.52.0.487.g5c8c507ade-goog From nobody Mon Dec 1 22:03:57 2025 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 814D534AB03 for ; Wed, 26 Nov 2025 23:18:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199091; cv=none; b=b3OdbE3ZAYRAJvBvWOymdpuQbqBBmgmQNMluQkduHnBZRyV1ZoW6A+OWibuZDCd2MHq9gXvOWlJoBxhRUP64MvRUkT5ehBbhyQj/pPvSq3IGw2dOBNiK8SBvkBEZ9xVjFm4CA/X+TkmxbMSCFhjNl0dlrdK3bFlFYrhwVcn7FS8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199091; c=relaxed/simple; bh=/TrWPjFJpzAKd/eC3nMnIVZE1tGlRT4+b3rpa9qc6Ks=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ov6QlBvXCN//Nb++xC7UGISSLSAFaQYkcfRUbvWyEPwgy3D7ekILRV0LvssKqFgu68WzR5utlEKkxH/CyjtYcnxb2Aek2p+MIOXtwrr+1zZqAYv7k7VrMPkKKwHKH9JQMjchNHmzGONDlBlTYscyvRcWc2PkDCO4Y6YIV3pTMMU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=bVeV2V+l; arc=none smtp.client-ip=209.85.210.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="bVeV2V+l" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7a99a5f77e0so315193b3a.2 for ; Wed, 26 Nov 2025 15:18:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764199087; x=1764803887; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=QiCamU4dQtxe/gMD0OOHC4OuJuQ+VgTxlz4+ZQ9ruJE=; b=bVeV2V+lNNyjwfjbAbsmforkQcdxUv1miLe0D/MOCe00l7UfQFm2fBj2KNMeFXDOc2 68sI0Ls19Rq6ubsYfkMDUlafD/w7g9TrZ1h5fUucOzdQPVcvuwsrA5Arv3WSabDj4GKZ DfMx4UwZGu3PocP/mNcJUvVBXIe7CEFuiqcgevWW8DC9mJDcXsqE1KxJX4qD0G4dg0A+ RwLvcHzh5zID59gVNmCuZx3KxmKscaSMYLLKaKydJgL9xMiRlOqbnuul63MNqwJ9yE8V g3SrK1yJPzldvXRuf085EaHtzdF41kolPL68TV9dHZNRNh1pysCXEYof89c6bH102Y6N h7AQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764199087; x=1764803887; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=QiCamU4dQtxe/gMD0OOHC4OuJuQ+VgTxlz4+ZQ9ruJE=; b=WJIGXcLp4spp7/OL+SZYP5tinDkRPynrYCPgOLYBuNDcaufmx3SLUQ+XrWoqI+2hAS FMBPpt7kTZQ3IGEhZ79LplcCSHuTKtNNfP8zSLvePJStH/NHBFjChew/6PTO256qB+EA vDez2hdbQhGqnUSf/kkciZlH6yPneNi8fZn9EjbP6u8EmFByDpz5+W2QMfBbEQckFbw+ C0QpAXxtWbWzrKXTDwjMED3yZCzO2d8AYHKtVuLdZYHb0F5OdYqp+kwNpILVxrVJNOJX zRWRaOO1w615TWze0oNvmZDJ5z+lHSNsoUekT20Y+x8dKJ2YOjycI6l1n4/tLORvetvd AAbA== X-Forwarded-Encrypted: i=1; AJvYcCVDFiJhzx6ayuCkLQP2DctJW79U9oRYEJfwt9Y9X0C3kISWq8VOZmUOj+pRncUBM6B1l8tdgQG9mc/xQ/4=@vger.kernel.org X-Gm-Message-State: AOJu0Yyt7GXVuw3mKsxfycm3+wIjerOvVrtnFvvYedR0+GBxePvUWMsg g2UHlkb55BqlfEtEOkGiv9qeq3bKsdS5lsH/BDm7TNdbfPlSBz9RSwsT05GyYhrImRojsco6nvu ZtmBOZTSmIAiXMA== X-Google-Smtp-Source: AGHT+IEU2lhYpYcS0xYDzJaFtaEmTaTaVAbVheact99D6MBkSZM+EHr0pTzY4o15hDgg5WI8vMOwJHM8LvKGqw== X-Received: from pfbif7.prod.google.com ([2002:a05:6a00:8b07:b0:7b7:c77:a04b]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:12e1:b0:7ba:2efc:7b3f with SMTP id d2e1a72fcca58-7c58beb6412mr20073743b3a.5.1764199086649; Wed, 26 Nov 2025 15:18:06 -0800 (PST) Date: Wed, 26 Nov 2025 23:17:31 +0000 In-Reply-To: <20251126231733.3302983-1-dmatlack@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251126231733.3302983-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.487.g5c8c507ade-goog Message-ID: <20251126231733.3302983-17-dmatlack@google.com> Subject: [PATCH v4 16/18] vfio: selftests: Split libvfio.h into separate header files From: David Matlack To: Alex Williamson Cc: Alex Mastro , David Matlack , Jason Gunthorpe , Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Raghavendra Rao Ananta , Vipin Sharma Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Split out the contents of libvfio.h into separate header files, but keep libvfio.h as the top-level include that all tests can use. Put all new header files into a libvfio/ subdirectory to avoid future name conflicts in include paths when libvfio is used by other selftests like KVM. No functional change intended. Reviewed-by: Alex Mastro Tested-by: Alex Mastro Reviewed-by: Raghavendra Rao Ananta Signed-off-by: David Matlack --- .../selftests/vfio/lib/include/libvfio.h | 339 +----------------- .../vfio/lib/include/libvfio/assert.h | 54 +++ .../vfio/lib/include/libvfio/iommu.h | 77 ++++ .../vfio/lib/include/libvfio/iova_allocator.h | 23 ++ .../lib/include/libvfio/vfio_pci_device.h | 125 +++++++ .../lib/include/libvfio/vfio_pci_driver.h | 97 +++++ 6 files changed, 381 insertions(+), 334 deletions(-) create mode 100644 tools/testing/selftests/vfio/lib/include/libvfio/assert= .h create mode 100644 tools/testing/selftests/vfio/lib/include/libvfio/iommu.h create mode 100644 tools/testing/selftests/vfio/lib/include/libvfio/iova_a= llocator.h create mode 100644 tools/testing/selftests/vfio/lib/include/libvfio/vfio_p= ci_device.h create mode 100644 tools/testing/selftests/vfio/lib/include/libvfio/vfio_p= ci_driver.h diff --git a/tools/testing/selftests/vfio/lib/include/libvfio.h b/tools/tes= ting/selftests/vfio/lib/include/libvfio.h index 3027af15e316..279ddcd70194 100644 --- a/tools/testing/selftests/vfio/lib/include/libvfio.h +++ b/tools/testing/selftests/vfio/lib/include/libvfio.h @@ -2,210 +2,11 @@ #ifndef SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_H #define SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_H =20 -#include -#include - -#include -#include -#include -#include -#include - -#include "../../../kselftest.h" - -#define VFIO_LOG_AND_EXIT(...) do { \ - fprintf(stderr, " " __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - exit(KSFT_FAIL); \ -} while (0) - -#define VFIO_ASSERT_OP(_lhs, _rhs, _op, ...) do { \ - typeof(_lhs) __lhs =3D (_lhs); \ - typeof(_rhs) __rhs =3D (_rhs); \ - \ - if (__lhs _op __rhs) \ - break; \ - \ - fprintf(stderr, "%s:%u: Assertion Failure\n\n", __FILE__, __LINE__); \ - fprintf(stderr, " Expression: " #_lhs " " #_op " " #_rhs "\n"); \ - fprintf(stderr, " Observed: %#lx %s %#lx\n", \ - (u64)__lhs, #_op, (u64)__rhs); \ - fprintf(stderr, " [errno: %d - %s]\n", errno, strerror(errno)); \ - VFIO_LOG_AND_EXIT(__VA_ARGS__); \ -} while (0) - -#define VFIO_ASSERT_EQ(_a, _b, ...) VFIO_ASSERT_OP(_a, _b, =3D=3D, ##__VA_= ARGS__) -#define VFIO_ASSERT_NE(_a, _b, ...) VFIO_ASSERT_OP(_a, _b, !=3D, ##__VA_AR= GS__) -#define VFIO_ASSERT_LT(_a, _b, ...) VFIO_ASSERT_OP(_a, _b, <, ##__VA_ARGS_= _) -#define VFIO_ASSERT_LE(_a, _b, ...) VFIO_ASSERT_OP(_a, _b, <=3D, ##__VA_AR= GS__) -#define VFIO_ASSERT_GT(_a, _b, ...) VFIO_ASSERT_OP(_a, _b, >, ##__VA_ARGS_= _) -#define VFIO_ASSERT_GE(_a, _b, ...) VFIO_ASSERT_OP(_a, _b, >=3D, ##__VA_AR= GS__) -#define VFIO_ASSERT_TRUE(_a, ...) VFIO_ASSERT_NE(false, (_a), ##__VA_ARGS_= _) -#define VFIO_ASSERT_FALSE(_a, ...) VFIO_ASSERT_EQ(false, (_a), ##__VA_ARGS= __) -#define VFIO_ASSERT_NULL(_a, ...) VFIO_ASSERT_EQ(NULL, _a, ##__VA_ARGS__) -#define VFIO_ASSERT_NOT_NULL(_a, ...) VFIO_ASSERT_NE(NULL, _a, ##__VA_ARGS= __) - -#define VFIO_FAIL(_fmt, ...) do { \ - fprintf(stderr, "%s:%u: FAIL\n\n", __FILE__, __LINE__); \ - VFIO_LOG_AND_EXIT(_fmt, ##__VA_ARGS__); \ -} while (0) - -#define ioctl_assert(_fd, _op, _arg) do { \ - void *__arg =3D (_arg); \ - int __ret =3D ioctl((_fd), (_op), (__arg)); \ - VFIO_ASSERT_EQ(__ret, 0, "ioctl(%s, %s, %s) returned %d\n", #_fd, #_op, #= _arg, __ret); \ -} while (0) - -#define dev_info(_dev, _fmt, ...) printf("%s: " _fmt, (_dev)->bdf, ##__VA_= ARGS__) -#define dev_err(_dev, _fmt, ...) fprintf(stderr, "%s: " _fmt, (_dev)->bdf,= ##__VA_ARGS__) - -struct iommu_mode { - const char *name; - const char *container_path; - unsigned long iommu_type; -}; - -/* - * Generator for VFIO selftests fixture variants that replicate across all - * possible IOMMU modes. Tests must define FIXTURE_VARIANT_ADD_IOMMU_MODE() - * which should then use FIXTURE_VARIANT_ADD() to create the variant. - */ -#define FIXTURE_VARIANT_ADD_ALL_IOMMU_MODES(...) \ -FIXTURE_VARIANT_ADD_IOMMU_MODE(vfio_type1_iommu, ##__VA_ARGS__); \ -FIXTURE_VARIANT_ADD_IOMMU_MODE(vfio_type1v2_iommu, ##__VA_ARGS__); \ -FIXTURE_VARIANT_ADD_IOMMU_MODE(iommufd_compat_type1, ##__VA_ARGS__); \ -FIXTURE_VARIANT_ADD_IOMMU_MODE(iommufd_compat_type1v2, ##__VA_ARGS__); \ -FIXTURE_VARIANT_ADD_IOMMU_MODE(iommufd, ##__VA_ARGS__) - -struct vfio_pci_bar { - struct vfio_region_info info; - void *vaddr; -}; - -typedef u64 iova_t; - -#define INVALID_IOVA UINT64_MAX - -struct dma_region { - struct list_head link; - void *vaddr; - iova_t iova; - u64 size; -}; - -struct vfio_pci_device; - -struct vfio_pci_driver_ops { - const char *name; - - /** - * @probe() - Check if the driver supports the given device. - * - * Return: 0 on success, non-0 on failure. - */ - int (*probe)(struct vfio_pci_device *device); - - /** - * @init() - Initialize the driver for @device. - * - * Must be called after device->driver.region has been initialized. - */ - void (*init)(struct vfio_pci_device *device); - - /** - * remove() - Deinitialize the driver for @device. - */ - void (*remove)(struct vfio_pci_device *device); - - /** - * memcpy_start() - Kick off @count repeated memcpy operations from - * [@src, @src + @size) to [@dst, @dst + @size). - * - * Guarantees: - * - The device will attempt DMA reads on [src, src + size). - * - The device will attempt DMA writes on [dst, dst + size). - * - The device will not generate any interrupts. - * - * memcpy_start() returns immediately, it does not wait for the - * copies to complete. - */ - void (*memcpy_start)(struct vfio_pci_device *device, - iova_t src, iova_t dst, u64 size, u64 count); - - /** - * memcpy_wait() - Wait until the memcpy operations started by - * memcpy_start() have finished. - * - * Guarantees: - * - All in-flight DMAs initiated by memcpy_start() are fully complete - * before memcpy_wait() returns. - * - * Returns non-0 if the driver detects that an error occurred during the - * memcpy, 0 otherwise. - */ - int (*memcpy_wait)(struct vfio_pci_device *device); - - /** - * send_msi() - Make the device send the MSI device->driver.msi. - * - * Guarantees: - * - The device will send the MSI once. - */ - void (*send_msi)(struct vfio_pci_device *device); -}; - -struct vfio_pci_driver { - const struct vfio_pci_driver_ops *ops; - bool initialized; - bool memcpy_in_progress; - - /* Region to be used by the driver (e.g. for in-memory descriptors) */ - struct dma_region region; - - /* The maximum size that can be passed to memcpy_start(). */ - u64 max_memcpy_size; - - /* The maximum count that can be passed to memcpy_start(). */ - u64 max_memcpy_count; - - /* The MSI vector the device will signal in ops->send_msi(). */ - int msi; -}; - -struct iommu { - const struct iommu_mode *mode; - int container_fd; - int iommufd; - u32 ioas_id; - struct list_head dma_regions; -}; - -struct vfio_pci_device { - const char *bdf; - int fd; - int group_fd; - - struct iommu *iommu; - - struct vfio_device_info info; - struct vfio_region_info config_space; - struct vfio_pci_bar bars[PCI_STD_NUM_BARS]; - - struct vfio_irq_info msi_info; - struct vfio_irq_info msix_info; - - /* eventfds for MSI and MSI-x interrupts */ - int msi_eventfds[PCI_MSIX_FLAGS_QSIZE + 1]; - - struct vfio_pci_driver driver; -}; - -struct iova_allocator { - struct iommu_iova_range *ranges; - u32 nranges; - u32 range_idx; - u64 range_offset; -}; +#include +#include +#include +#include +#include =20 /* * Return the BDF string of the device that the test should use. @@ -222,134 +23,4 @@ struct iova_allocator { const char *vfio_selftests_get_bdf(int *argc, char *argv[]); char **vfio_selftests_get_bdfs(int *argc, char *argv[], int *nr_bdfs); =20 -const char *vfio_pci_get_cdev_path(const char *bdf); - -extern const char *default_iommu_mode; - -struct iommu *iommu_init(const char *iommu_mode); -void iommu_cleanup(struct iommu *iommu); - -int __iommu_map(struct iommu *iommu, struct dma_region *region); - -static inline void iommu_map(struct iommu *iommu, struct dma_region *regio= n) -{ - VFIO_ASSERT_EQ(__iommu_map(iommu, region), 0); -} - -int __iommu_unmap(struct iommu *iommu, struct dma_region *region, u64 *unm= apped); - -static inline void iommu_unmap(struct iommu *iommu, struct dma_region *reg= ion) -{ - VFIO_ASSERT_EQ(__iommu_unmap(iommu, region, NULL), 0); -} - -int __iommu_unmap_all(struct iommu *iommu, u64 *unmapped); - -static inline void iommu_unmap_all(struct iommu *iommu) -{ - VFIO_ASSERT_EQ(__iommu_unmap_all(iommu, NULL), 0); -} - -iova_t __iommu_hva2iova(struct iommu *iommu, void *vaddr); -iova_t iommu_hva2iova(struct iommu *iommu, void *vaddr); - -struct iommu_iova_range *iommu_iova_ranges(struct iommu *iommu, u32 *nrang= es); - -struct vfio_pci_device *vfio_pci_device_init(const char *bdf, struct iommu= *iommu); -void vfio_pci_device_cleanup(struct vfio_pci_device *device); - -void vfio_pci_device_reset(struct vfio_pci_device *device); - -struct iova_allocator *iova_allocator_init(struct iommu *iommu); -void iova_allocator_cleanup(struct iova_allocator *allocator); -iova_t iova_allocator_alloc(struct iova_allocator *allocator, size_t size); - -void vfio_pci_config_access(struct vfio_pci_device *device, bool write, - size_t config, size_t size, void *data); - -#define vfio_pci_config_read(_device, _offset, _type) ({ \ - _type __data; \ - vfio_pci_config_access((_device), false, _offset, sizeof(__data), &__data= ); \ - __data; \ -}) - -#define vfio_pci_config_readb(_d, _o) vfio_pci_config_read(_d, _o, u8) -#define vfio_pci_config_readw(_d, _o) vfio_pci_config_read(_d, _o, u16) -#define vfio_pci_config_readl(_d, _o) vfio_pci_config_read(_d, _o, u32) - -#define vfio_pci_config_write(_device, _offset, _value, _type) do { \ - _type __data =3D (_value); \ - vfio_pci_config_access((_device), true, _offset, sizeof(_type), &__data);= \ -} while (0) - -#define vfio_pci_config_writeb(_d, _o, _v) vfio_pci_config_write(_d, _o, _= v, u8) -#define vfio_pci_config_writew(_d, _o, _v) vfio_pci_config_write(_d, _o, _= v, u16) -#define vfio_pci_config_writel(_d, _o, _v) vfio_pci_config_write(_d, _o, _= v, u32) - -void vfio_pci_irq_enable(struct vfio_pci_device *device, u32 index, - u32 vector, int count); -void vfio_pci_irq_disable(struct vfio_pci_device *device, u32 index); -void vfio_pci_irq_trigger(struct vfio_pci_device *device, u32 index, u32 v= ector); - -static inline void fcntl_set_nonblock(int fd) -{ - int r; - - r =3D fcntl(fd, F_GETFL, 0); - VFIO_ASSERT_NE(r, -1, "F_GETFL failed for fd %d\n", fd); - - r =3D fcntl(fd, F_SETFL, r | O_NONBLOCK); - VFIO_ASSERT_NE(r, -1, "F_SETFL O_NONBLOCK failed for fd %d\n", fd); -} - -static inline void vfio_pci_msi_enable(struct vfio_pci_device *device, - u32 vector, int count) -{ - vfio_pci_irq_enable(device, VFIO_PCI_MSI_IRQ_INDEX, vector, count); -} - -static inline void vfio_pci_msi_disable(struct vfio_pci_device *device) -{ - vfio_pci_irq_disable(device, VFIO_PCI_MSI_IRQ_INDEX); -} - -static inline void vfio_pci_msix_enable(struct vfio_pci_device *device, - u32 vector, int count) -{ - vfio_pci_irq_enable(device, VFIO_PCI_MSIX_IRQ_INDEX, vector, count); -} - -static inline void vfio_pci_msix_disable(struct vfio_pci_device *device) -{ - vfio_pci_irq_disable(device, VFIO_PCI_MSIX_IRQ_INDEX); -} - -static inline iova_t __to_iova(struct vfio_pci_device *device, void *vaddr) -{ - return __iommu_hva2iova(device->iommu, vaddr); -} - -static inline iova_t to_iova(struct vfio_pci_device *device, void *vaddr) -{ - return iommu_hva2iova(device->iommu, vaddr); -} - -static inline bool vfio_pci_device_match(struct vfio_pci_device *device, - u16 vendor_id, u16 device_id) -{ - return (vendor_id =3D=3D vfio_pci_config_readw(device, PCI_VENDOR_ID)) && - (device_id =3D=3D vfio_pci_config_readw(device, PCI_DEVICE_ID)); -} - -void vfio_pci_driver_probe(struct vfio_pci_device *device); -void vfio_pci_driver_init(struct vfio_pci_device *device); -void vfio_pci_driver_remove(struct vfio_pci_device *device); -int vfio_pci_driver_memcpy(struct vfio_pci_device *device, - iova_t src, iova_t dst, u64 size); -void vfio_pci_driver_memcpy_start(struct vfio_pci_device *device, - iova_t src, iova_t dst, u64 size, - u64 count); -int vfio_pci_driver_memcpy_wait(struct vfio_pci_device *device); -void vfio_pci_driver_send_msi(struct vfio_pci_device *device); - #endif /* SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_H */ diff --git a/tools/testing/selftests/vfio/lib/include/libvfio/assert.h b/to= ols/testing/selftests/vfio/lib/include/libvfio/assert.h new file mode 100644 index 000000000000..f4ebd122d9b6 --- /dev/null +++ b/tools/testing/selftests/vfio/lib/include/libvfio/assert.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_ASSERT_H +#define SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_ASSERT_H + +#include +#include +#include + +#include "../../../../kselftest.h" + +#define VFIO_LOG_AND_EXIT(...) do { \ + fprintf(stderr, " " __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + exit(KSFT_FAIL); \ +} while (0) + +#define VFIO_ASSERT_OP(_lhs, _rhs, _op, ...) do { \ + typeof(_lhs) __lhs =3D (_lhs); \ + typeof(_rhs) __rhs =3D (_rhs); \ + \ + if (__lhs _op __rhs) \ + break; \ + \ + fprintf(stderr, "%s:%u: Assertion Failure\n\n", __FILE__, __LINE__); \ + fprintf(stderr, " Expression: " #_lhs " " #_op " " #_rhs "\n"); \ + fprintf(stderr, " Observed: %#lx %s %#lx\n", \ + (u64)__lhs, #_op, (u64)__rhs); \ + fprintf(stderr, " [errno: %d - %s]\n", errno, strerror(errno)); \ + VFIO_LOG_AND_EXIT(__VA_ARGS__); \ +} while (0) + +#define VFIO_ASSERT_EQ(_a, _b, ...) VFIO_ASSERT_OP(_a, _b, =3D=3D, ##__VA_= ARGS__) +#define VFIO_ASSERT_NE(_a, _b, ...) VFIO_ASSERT_OP(_a, _b, !=3D, ##__VA_AR= GS__) +#define VFIO_ASSERT_LT(_a, _b, ...) VFIO_ASSERT_OP(_a, _b, <, ##__VA_ARGS_= _) +#define VFIO_ASSERT_LE(_a, _b, ...) VFIO_ASSERT_OP(_a, _b, <=3D, ##__VA_AR= GS__) +#define VFIO_ASSERT_GT(_a, _b, ...) VFIO_ASSERT_OP(_a, _b, >, ##__VA_ARGS_= _) +#define VFIO_ASSERT_GE(_a, _b, ...) VFIO_ASSERT_OP(_a, _b, >=3D, ##__VA_AR= GS__) +#define VFIO_ASSERT_TRUE(_a, ...) VFIO_ASSERT_NE(false, (_a), ##__VA_ARGS_= _) +#define VFIO_ASSERT_FALSE(_a, ...) VFIO_ASSERT_EQ(false, (_a), ##__VA_ARGS= __) +#define VFIO_ASSERT_NULL(_a, ...) VFIO_ASSERT_EQ(NULL, _a, ##__VA_ARGS__) +#define VFIO_ASSERT_NOT_NULL(_a, ...) VFIO_ASSERT_NE(NULL, _a, ##__VA_ARGS= __) + +#define VFIO_FAIL(_fmt, ...) do { \ + fprintf(stderr, "%s:%u: FAIL\n\n", __FILE__, __LINE__); \ + VFIO_LOG_AND_EXIT(_fmt, ##__VA_ARGS__); \ +} while (0) + +#define ioctl_assert(_fd, _op, _arg) do { \ + void *__arg =3D (_arg); \ + int __ret =3D ioctl((_fd), (_op), (__arg)); \ + VFIO_ASSERT_EQ(__ret, 0, "ioctl(%s, %s, %s) returned %d\n", #_fd, #_op, #= _arg, __ret); \ +} while (0) + +#endif /* SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_ASSERT_H */ diff --git a/tools/testing/selftests/vfio/lib/include/libvfio/iommu.h b/too= ls/testing/selftests/vfio/lib/include/libvfio/iommu.h new file mode 100644 index 000000000000..e35f13ed3f3c --- /dev/null +++ b/tools/testing/selftests/vfio/lib/include/libvfio/iommu.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_IOMMU_H +#define SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_IOMMU_H + +#include +#include + +#include + +typedef u64 iova_t; +#define INVALID_IOVA UINT64_MAX + +struct iommu_mode { + const char *name; + const char *container_path; + unsigned long iommu_type; +}; + +extern const char *default_iommu_mode; + +struct dma_region { + struct list_head link; + void *vaddr; + iova_t iova; + u64 size; +}; + +struct iommu { + const struct iommu_mode *mode; + int container_fd; + int iommufd; + u32 ioas_id; + struct list_head dma_regions; +}; + +struct iommu *iommu_init(const char *iommu_mode); +void iommu_cleanup(struct iommu *iommu); + +int __iommu_map(struct iommu *iommu, struct dma_region *region); + +static inline void iommu_map(struct iommu *iommu, struct dma_region *regio= n) +{ + VFIO_ASSERT_EQ(__iommu_map(iommu, region), 0); +} + +int __iommu_unmap(struct iommu *iommu, struct dma_region *region, u64 *unm= apped); + +static inline void iommu_unmap(struct iommu *iommu, struct dma_region *reg= ion) +{ + VFIO_ASSERT_EQ(__iommu_unmap(iommu, region, NULL), 0); +} + +int __iommu_unmap_all(struct iommu *iommu, u64 *unmapped); + +static inline void iommu_unmap_all(struct iommu *iommu) +{ + VFIO_ASSERT_EQ(__iommu_unmap_all(iommu, NULL), 0); +} + +iova_t __iommu_hva2iova(struct iommu *iommu, void *vaddr); +iova_t iommu_hva2iova(struct iommu *iommu, void *vaddr); + +struct iommu_iova_range *iommu_iova_ranges(struct iommu *iommu, u32 *nrang= es); + +/* + * Generator for VFIO selftests fixture variants that replicate across all + * possible IOMMU modes. Tests must define FIXTURE_VARIANT_ADD_IOMMU_MODE() + * which should then use FIXTURE_VARIANT_ADD() to create the variant. + */ +#define FIXTURE_VARIANT_ADD_ALL_IOMMU_MODES(...) \ +FIXTURE_VARIANT_ADD_IOMMU_MODE(vfio_type1_iommu, ##__VA_ARGS__); \ +FIXTURE_VARIANT_ADD_IOMMU_MODE(vfio_type1v2_iommu, ##__VA_ARGS__); \ +FIXTURE_VARIANT_ADD_IOMMU_MODE(iommufd_compat_type1, ##__VA_ARGS__); \ +FIXTURE_VARIANT_ADD_IOMMU_MODE(iommufd_compat_type1v2, ##__VA_ARGS__); \ +FIXTURE_VARIANT_ADD_IOMMU_MODE(iommufd, ##__VA_ARGS__) + +#endif /* SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_IOMMU_H */ diff --git a/tools/testing/selftests/vfio/lib/include/libvfio/iova_allocato= r.h b/tools/testing/selftests/vfio/lib/include/libvfio/iova_allocator.h new file mode 100644 index 000000000000..8f1d994e9ea2 --- /dev/null +++ b/tools/testing/selftests/vfio/lib/include/libvfio/iova_allocator.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_IOVA_ALLOCATOR_H +#define SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_IOVA_ALLOCATOR_H + +#include +#include +#include +#include + +#include + +struct iova_allocator { + struct iommu_iova_range *ranges; + u32 nranges; + u32 range_idx; + u64 range_offset; +}; + +struct iova_allocator *iova_allocator_init(struct iommu *iommu); +void iova_allocator_cleanup(struct iova_allocator *allocator); +iova_t iova_allocator_alloc(struct iova_allocator *allocator, size_t size); + +#endif /* SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_IOVA_ALLOCATOR_H */ diff --git a/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_devi= ce.h b/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_device.h new file mode 100644 index 000000000000..160e003131d6 --- /dev/null +++ b/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_device.h @@ -0,0 +1,125 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_VFIO_PCI_DEVICE_H +#define SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_VFIO_PCI_DEVICE_H + +#include +#include +#include + +#include +#include +#include + +struct vfio_pci_bar { + struct vfio_region_info info; + void *vaddr; +}; + +struct vfio_pci_device { + const char *bdf; + int fd; + int group_fd; + + struct iommu *iommu; + + struct vfio_device_info info; + struct vfio_region_info config_space; + struct vfio_pci_bar bars[PCI_STD_NUM_BARS]; + + struct vfio_irq_info msi_info; + struct vfio_irq_info msix_info; + + /* eventfds for MSI and MSI-x interrupts */ + int msi_eventfds[PCI_MSIX_FLAGS_QSIZE + 1]; + + struct vfio_pci_driver driver; +}; + +#define dev_info(_dev, _fmt, ...) printf("%s: " _fmt, (_dev)->bdf, ##__VA_= ARGS__) +#define dev_err(_dev, _fmt, ...) fprintf(stderr, "%s: " _fmt, (_dev)->bdf,= ##__VA_ARGS__) + +struct vfio_pci_device *vfio_pci_device_init(const char *bdf, struct iommu= *iommu); +void vfio_pci_device_cleanup(struct vfio_pci_device *device); + +void vfio_pci_device_reset(struct vfio_pci_device *device); + +void vfio_pci_config_access(struct vfio_pci_device *device, bool write, + size_t config, size_t size, void *data); + +#define vfio_pci_config_read(_device, _offset, _type) ({ \ + _type __data; \ + vfio_pci_config_access((_device), false, _offset, sizeof(__data), &__data= ); \ + __data; \ +}) + +#define vfio_pci_config_readb(_d, _o) vfio_pci_config_read(_d, _o, u8) +#define vfio_pci_config_readw(_d, _o) vfio_pci_config_read(_d, _o, u16) +#define vfio_pci_config_readl(_d, _o) vfio_pci_config_read(_d, _o, u32) + +#define vfio_pci_config_write(_device, _offset, _value, _type) do { \ + _type __data =3D (_value); \ + vfio_pci_config_access((_device), true, _offset, sizeof(_type), &__data);= \ +} while (0) + +#define vfio_pci_config_writeb(_d, _o, _v) vfio_pci_config_write(_d, _o, _= v, u8) +#define vfio_pci_config_writew(_d, _o, _v) vfio_pci_config_write(_d, _o, _= v, u16) +#define vfio_pci_config_writel(_d, _o, _v) vfio_pci_config_write(_d, _o, _= v, u32) + +void vfio_pci_irq_enable(struct vfio_pci_device *device, u32 index, + u32 vector, int count); +void vfio_pci_irq_disable(struct vfio_pci_device *device, u32 index); +void vfio_pci_irq_trigger(struct vfio_pci_device *device, u32 index, u32 v= ector); + +static inline void fcntl_set_nonblock(int fd) +{ + int r; + + r =3D fcntl(fd, F_GETFL, 0); + VFIO_ASSERT_NE(r, -1, "F_GETFL failed for fd %d\n", fd); + + r =3D fcntl(fd, F_SETFL, r | O_NONBLOCK); + VFIO_ASSERT_NE(r, -1, "F_SETFL O_NONBLOCK failed for fd %d\n", fd); +} + +static inline void vfio_pci_msi_enable(struct vfio_pci_device *device, + u32 vector, int count) +{ + vfio_pci_irq_enable(device, VFIO_PCI_MSI_IRQ_INDEX, vector, count); +} + +static inline void vfio_pci_msi_disable(struct vfio_pci_device *device) +{ + vfio_pci_irq_disable(device, VFIO_PCI_MSI_IRQ_INDEX); +} + +static inline void vfio_pci_msix_enable(struct vfio_pci_device *device, + u32 vector, int count) +{ + vfio_pci_irq_enable(device, VFIO_PCI_MSIX_IRQ_INDEX, vector, count); +} + +static inline void vfio_pci_msix_disable(struct vfio_pci_device *device) +{ + vfio_pci_irq_disable(device, VFIO_PCI_MSIX_IRQ_INDEX); +} + +static inline iova_t __to_iova(struct vfio_pci_device *device, void *vaddr) +{ + return __iommu_hva2iova(device->iommu, vaddr); +} + +static inline iova_t to_iova(struct vfio_pci_device *device, void *vaddr) +{ + return iommu_hva2iova(device->iommu, vaddr); +} + +static inline bool vfio_pci_device_match(struct vfio_pci_device *device, + u16 vendor_id, u16 device_id) +{ + return (vendor_id =3D=3D vfio_pci_config_readw(device, PCI_VENDOR_ID)) && + (device_id =3D=3D vfio_pci_config_readw(device, PCI_DEVICE_ID)); +} + +const char *vfio_pci_get_cdev_path(const char *bdf); + +#endif /* SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_VFIO_PCI_DEVICE_H */ diff --git a/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_driv= er.h b/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_driver.h new file mode 100644 index 000000000000..e5ada209b1d1 --- /dev/null +++ b/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_driver.h @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_VFIO_PCI_DRIVER_H +#define SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_VFIO_PCI_DRIVER_H + +#include + +struct vfio_pci_device; + +struct vfio_pci_driver_ops { + const char *name; + + /** + * @probe() - Check if the driver supports the given device. + * + * Return: 0 on success, non-0 on failure. + */ + int (*probe)(struct vfio_pci_device *device); + + /** + * @init() - Initialize the driver for @device. + * + * Must be called after device->driver.region has been initialized. + */ + void (*init)(struct vfio_pci_device *device); + + /** + * remove() - Deinitialize the driver for @device. + */ + void (*remove)(struct vfio_pci_device *device); + + /** + * memcpy_start() - Kick off @count repeated memcpy operations from + * [@src, @src + @size) to [@dst, @dst + @size). + * + * Guarantees: + * - The device will attempt DMA reads on [src, src + size). + * - The device will attempt DMA writes on [dst, dst + size). + * - The device will not generate any interrupts. + * + * memcpy_start() returns immediately, it does not wait for the + * copies to complete. + */ + void (*memcpy_start)(struct vfio_pci_device *device, + iova_t src, iova_t dst, u64 size, u64 count); + + /** + * memcpy_wait() - Wait until the memcpy operations started by + * memcpy_start() have finished. + * + * Guarantees: + * - All in-flight DMAs initiated by memcpy_start() are fully complete + * before memcpy_wait() returns. + * + * Returns non-0 if the driver detects that an error occurred during the + * memcpy, 0 otherwise. + */ + int (*memcpy_wait)(struct vfio_pci_device *device); + + /** + * send_msi() - Make the device send the MSI device->driver.msi. + * + * Guarantees: + * - The device will send the MSI once. + */ + void (*send_msi)(struct vfio_pci_device *device); +}; + +struct vfio_pci_driver { + const struct vfio_pci_driver_ops *ops; + bool initialized; + bool memcpy_in_progress; + + /* Region to be used by the driver (e.g. for in-memory descriptors) */ + struct dma_region region; + + /* The maximum size that can be passed to memcpy_start(). */ + u64 max_memcpy_size; + + /* The maximum count that can be passed to memcpy_start(). */ + u64 max_memcpy_count; + + /* The MSI vector the device will signal in ops->send_msi(). */ + int msi; +}; + +void vfio_pci_driver_probe(struct vfio_pci_device *device); +void vfio_pci_driver_init(struct vfio_pci_device *device); +void vfio_pci_driver_remove(struct vfio_pci_device *device); +int vfio_pci_driver_memcpy(struct vfio_pci_device *device, + iova_t src, iova_t dst, u64 size); +void vfio_pci_driver_memcpy_start(struct vfio_pci_device *device, + iova_t src, iova_t dst, u64 size, + u64 count); +int vfio_pci_driver_memcpy_wait(struct vfio_pci_device *device); +void vfio_pci_driver_send_msi(struct vfio_pci_device *device); + +#endif /* SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_VFIO_PCI_DRIVER_H */ --=20 2.52.0.487.g5c8c507ade-goog From nobody Mon Dec 1 22:03:57 2025 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C47B534A783 for ; Wed, 26 Nov 2025 23:18:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199090; cv=none; b=RSfJ8mC42FabkP95ek4bcwxPeBsm9z4GWnNr/rNBO3AThevzyzayKb3mAINRPkz6n/oW/vkYZQ7NPcWr12SZtVANXEJt66jT0L/Y1E3k8MXCTPe+x78eQjEere6Tu3NJssTfAbnxffPY4H6Qj1VvUEt9qJR3H+exxEjT9TwQaMQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199090; c=relaxed/simple; bh=WpySdpWplIFkyFjdRPH8mjnIr8ZWwugcwAyYN9dmoGA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=PcLeurci9rhNSJwDVVf1h+endi+0TtXUlG9Y9tup2SWCwLMDx/Rys8bK9vSmSiSCPQV/i6Z8gtBgfyIR7e4zxtrQuUwEJO95ujCJ6DkvP+O5BvLUuy/Bw7DY5Dt2aEV5bcdlsIQVYZ38eY1K4GIBlPIhQVh0eWTBReXkjo/v4ZE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=wePGeV1N; arc=none smtp.client-ip=209.85.210.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="wePGeV1N" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7b9321b9312so400887b3a.1 for ; Wed, 26 Nov 2025 15:18:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764199088; x=1764803888; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=W+pnV+aPRrlLst9nvfnueF4Po9qU0QkYO4ZzZSMG/yA=; b=wePGeV1N2xD+JfemPLRC4NW0f3uLCt0Aqy/+wI3XffuXrbwplTY04zEdET/LSxWEBb W2N8G6JxjjrppO0zGXyyTDlDuS/j3HvWqpLMb4MPOY49nIzHEHLe/Epx1gak0bF2XwJ5 6XuDpFHQQ41f891P8kfSwdjANGAwE5x48WGqdR/h8WhjOAIAtO3IxNP/fIIsvyqFMRDX RiRJkUNe0e0K6h/KUuEJLc2UxDPGNPk0b7OESwiRYbdSE0cC0Vd3hl38mqK+s40SwH1n mGi68gwFQO/YwN5v6I17uG2wm89rdnQFKyz4aqxvbBmmTV6n3AzrYZ+EWlYWLtQa5OIC soKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764199088; x=1764803888; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=W+pnV+aPRrlLst9nvfnueF4Po9qU0QkYO4ZzZSMG/yA=; b=LPlHIT9Y6aaoSq5ZYmsVeFmfem+eUFFhvQB/1fPtJhatWeiT+Wc7CaCgx0ILMc2f8H Q7pJI3sdbyW5lszX6Kp6ymkCDc1DtxhwAU/kQZtCcr8D92mGcD1Qx/TgEk5olXZa+3Rf woQ7kkOvAJDRGHsd534VtWOMXVB3LPa5d13ZPpjyPta1lKsUgEcp5TGzZOtMYtF+48Lu RKQioqgAaYDu31L10RiKHvIhGOggbQHd3hCGUajH9hg3o3sRM/vevFt6BuUet8A0GULP pH/vITs7r9HLflkZBJuXfuRQj3vla9Xj1gMvYUjRBmDuGkkqtFLkQUv7r1lk71hnlrLb satQ== X-Forwarded-Encrypted: i=1; AJvYcCVn006zfxOKORE07j0MnCwj9/xrlxi/bLomTKi4vVZIsabeAEdKrO4vfAszZVTX+LbBmy1bA0cKjHoKv0I=@vger.kernel.org X-Gm-Message-State: AOJu0YwWh1UQTtg9ZhAaUERV3gu+zB254w6CfU394+gki/wFyou61bJf kTcoEf+QY3plVfjK0duyuBR/EuPGStL9LaC3yKhLe8Ue4u62ErWNy0KeGX3Phy5HTkL1HreEK+d 1gk6vfA+kw4l1jQ== X-Google-Smtp-Source: AGHT+IFuic0ctn0G24phSOJnRXkr3T8Tckl/kQVJBgvphMjPTbTwnjLR0jMKiGqJ+NLnuaO7uN+8Wbs7AMCmPA== X-Received: from pfbfj11.prod.google.com ([2002:a05:6a00:3a0b:b0:7b0:e3d3:f03e]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:2e82:b0:7aa:9723:3217 with SMTP id d2e1a72fcca58-7c58e40f6dcmr19685166b3a.25.1764199088215; Wed, 26 Nov 2025 15:18:08 -0800 (PST) Date: Wed, 26 Nov 2025 23:17:32 +0000 In-Reply-To: <20251126231733.3302983-1-dmatlack@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251126231733.3302983-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.487.g5c8c507ade-goog Message-ID: <20251126231733.3302983-18-dmatlack@google.com> Subject: [PATCH v4 17/18] vfio: selftests: Eliminate INVALID_IOVA From: David Matlack To: Alex Williamson Cc: Alex Mastro , David Matlack , Jason Gunthorpe , Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Raghavendra Rao Ananta , Vipin Sharma Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Eliminate INVALID_IOVA as there are platforms where UINT64_MAX is a valid iova. Reviewed-by: Alex Mastro Tested-by: Alex Mastro Reviewed-by: Raghavendra Rao Ananta Signed-off-by: David Matlack --- .../selftests/vfio/lib/include/libvfio/iommu.h | 3 +-- .../vfio/lib/include/libvfio/vfio_pci_device.h | 4 ++-- tools/testing/selftests/vfio/lib/iommu.c | 14 +++++++++----- .../testing/selftests/vfio/vfio_dma_mapping_test.c | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/tools/testing/selftests/vfio/lib/include/libvfio/iommu.h b/too= ls/testing/selftests/vfio/lib/include/libvfio/iommu.h index e35f13ed3f3c..5c9b9dc6d993 100644 --- a/tools/testing/selftests/vfio/lib/include/libvfio/iommu.h +++ b/tools/testing/selftests/vfio/lib/include/libvfio/iommu.h @@ -8,7 +8,6 @@ #include =20 typedef u64 iova_t; -#define INVALID_IOVA UINT64_MAX =20 struct iommu_mode { const char *name; @@ -57,7 +56,7 @@ static inline void iommu_unmap_all(struct iommu *iommu) VFIO_ASSERT_EQ(__iommu_unmap_all(iommu, NULL), 0); } =20 -iova_t __iommu_hva2iova(struct iommu *iommu, void *vaddr); +int __iommu_hva2iova(struct iommu *iommu, void *vaddr, iova_t *iova); iova_t iommu_hva2iova(struct iommu *iommu, void *vaddr); =20 struct iommu_iova_range *iommu_iova_ranges(struct iommu *iommu, u32 *nrang= es); diff --git a/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_devi= ce.h b/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_device.h index 160e003131d6..2858885a89bb 100644 --- a/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_device.h +++ b/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_device.h @@ -103,9 +103,9 @@ static inline void vfio_pci_msix_disable(struct vfio_pc= i_device *device) vfio_pci_irq_disable(device, VFIO_PCI_MSIX_IRQ_INDEX); } =20 -static inline iova_t __to_iova(struct vfio_pci_device *device, void *vaddr) +static inline int __to_iova(struct vfio_pci_device *device, void *vaddr, i= ova_t *iova) { - return __iommu_hva2iova(device->iommu, vaddr); + return __iommu_hva2iova(device->iommu, vaddr, iova); } =20 static inline iova_t to_iova(struct vfio_pci_device *device, void *vaddr) diff --git a/tools/testing/selftests/vfio/lib/iommu.c b/tools/testing/selft= ests/vfio/lib/iommu.c index 52f9cdf5f171..8079d43523f3 100644 --- a/tools/testing/selftests/vfio/lib/iommu.c +++ b/tools/testing/selftests/vfio/lib/iommu.c @@ -67,7 +67,7 @@ static const struct iommu_mode *lookup_iommu_mode(const c= har *iommu_mode) VFIO_FAIL("Unrecognized IOMMU mode: %s\n", iommu_mode); } =20 -iova_t __iommu_hva2iova(struct iommu *iommu, void *vaddr) +int __iommu_hva2iova(struct iommu *iommu, void *vaddr, iova_t *iova) { struct dma_region *region; =20 @@ -78,18 +78,22 @@ iova_t __iommu_hva2iova(struct iommu *iommu, void *vadd= r) if (vaddr >=3D region->vaddr + region->size) continue; =20 - return region->iova + (vaddr - region->vaddr); + if (iova) + *iova =3D region->iova + (vaddr - region->vaddr); + + return 0; } =20 - return INVALID_IOVA; + return -ENOENT; } =20 iova_t iommu_hva2iova(struct iommu *iommu, void *vaddr) { iova_t iova; + int ret; =20 - iova =3D __iommu_hva2iova(iommu, vaddr); - VFIO_ASSERT_NE(iova, INVALID_IOVA, "%p is not mapped into IOMMU\n", vaddr= ); + ret =3D __iommu_hva2iova(iommu, vaddr, &iova); + VFIO_ASSERT_EQ(ret, 0, "%p is not mapped into the iommu\n", vaddr); =20 return iova; } diff --git a/tools/testing/selftests/vfio/vfio_dma_mapping_test.c b/tools/t= esting/selftests/vfio/vfio_dma_mapping_test.c index 213fcd8dcc79..5397822c3dd4 100644 --- a/tools/testing/selftests/vfio/vfio_dma_mapping_test.c +++ b/tools/testing/selftests/vfio/vfio_dma_mapping_test.c @@ -199,7 +199,7 @@ TEST_F(vfio_dma_mapping_test, dma_map_unmap) ASSERT_EQ(rc, 0); ASSERT_EQ(unmapped, region.size); printf("Unmapped IOVA 0x%lx\n", region.iova); - ASSERT_EQ(INVALID_IOVA, __to_iova(self->device, region.vaddr)); + ASSERT_NE(0, __to_iova(self->device, region.vaddr, NULL)); ASSERT_NE(0, iommu_mapping_get(device_bdf, region.iova, &mapping)); =20 ASSERT_TRUE(!munmap(region.vaddr, size)); --=20 2.52.0.487.g5c8c507ade-goog From nobody Mon Dec 1 22:03:57 2025 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5C2A3340277 for ; Wed, 26 Nov 2025 23:18:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199092; cv=none; b=jKOqTDpfUBhi5YXE7Cyn1Hl5OkebFce2L6lQOPRPpo+QMmSZBo+YU91O9bJ4K0RpA7tISmsR82Dgm+BHPSzXJF+oR9BFHdkwc4MDgITKrLx3N5VPmMItB1nk3VqEbZsIwuKnrMEBwHJvTDKd3m5+M+fGNCfQhIIWZWoSexWhCls= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764199092; c=relaxed/simple; bh=M6/7abdf2MC2Xy1le80ucuSHzCbihEHYWHlnyVXgAu8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=mM2F8lkoH6NxK8aGgUmeHTYvdN7C3k8+AVxtbfb3yAK+6mldLD+cXvWBhkqSwHUcP8G/zoO4osaEfDxU6FR2EKrE8CpVCqHuCwzfp8NxpVFq2JodZcsSOor5Pc27nfSI1kWwUVM8jfy2W6uPS5rwfCfx7ul1VH0lux1YoacmXFI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=QT8nFuzK; arc=none smtp.client-ip=209.85.210.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="QT8nFuzK" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7b8a12f0cb4so179374b3a.3 for ; Wed, 26 Nov 2025 15:18:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764199090; x=1764803890; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=s516YdCf56L10Nf5ouIlScriBpKh0xtdZsdOxgkhbv8=; b=QT8nFuzKcMuaIzUCnzdN6GYSGGiVDfFkxhVXxTaJXN6l1yVtL4q3UZDg++7VgE8Qvd /VgHIV5P5kIVOSBwxrygBO0KW9UlI2xtJgwKpuubdF2QQ3IHjl7FdWupqEnd1Hi3OQlo NCOWui6wuV5nhsPK3SdUFxyeKA/5AFKxUHswTMOIYreNsz4hypiDLTTxiZ8HfpYr0o4U u2N+1CXK1Kz6zBtW7LgEOs4cbF0FTeaYkbqqRbDdV4RlcHGidsFHTDdGOcXmehUWHzvF wv8ZL6tfU/KlaTp9B3mElV44rnJiJr8Mab+14QYp+iM1kn21p2UjGR119VqNpkFpN6L1 Lavg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764199090; x=1764803890; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=s516YdCf56L10Nf5ouIlScriBpKh0xtdZsdOxgkhbv8=; b=JlnJl3xne2sY/GOzjyAEj0nB7a1CWQzhoFlBpoZoH1sXtk1h16HnZR4mQhLLgF7zqa TpHngyHUXwNqksuiJr5l2aX4JqAWcjhdj1hJM0nrSnLDr8IaPQWUfuj4hqFYQIU6b81x ZkGPWaiTaKW65pepQxWZvllGs6k9yM/NHiT+8eb+wrNRgS6Ufm9KVqQqZpgMVy7i85Xj s5IR+AUFV8STGbvGIgpgwp3yWFxenyJIurT2pRkdfTaAlX/VKBeiInpC38ZuSf1auran XPgegPNJh72u6SR8vn/XMv9OHsjZeg10v9RILEbRAj+il1E9nZAqIlSTnGWhrmLNMFCK mKCQ== X-Forwarded-Encrypted: i=1; AJvYcCUqIJmPmB6fAJmd5hOMdx+GowYm5/Ro07H43nYq4Vx38TJZ2U/JoYySvpgbYrwFxn8KRckbjytSVEXCmks=@vger.kernel.org X-Gm-Message-State: AOJu0YxYdlM95Cp/na4Czgq10M3qTJwPTKZAIxzHk9EVd3CmzL+DfHoV wi1L4p223e4vJpmSHFaKXTuIG/cAcrd34kGSqE7S6/AqTjfmShWY5sWzi2PFvJHbZt7s/puppKG 3aigHWUMOYPU3Cg== X-Google-Smtp-Source: AGHT+IExT2hyCx/ABRiZGBH/ZPh6lmfNqDj7pyzpnnmcR8EGeKqBBtjsR5K8Vh7A3OLg1AxtSt+YgWER3wFxug== X-Received: from pfbfu4.prod.google.com ([2002:a05:6a00:6104:b0:7ba:1df4:a383]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:3a1c:b0:7ad:1082:fdf0 with SMTP id d2e1a72fcca58-7ca8b597625mr9836178b3a.31.1764199089757; Wed, 26 Nov 2025 15:18:09 -0800 (PST) Date: Wed, 26 Nov 2025 23:17:33 +0000 In-Reply-To: <20251126231733.3302983-1-dmatlack@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251126231733.3302983-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.487.g5c8c507ade-goog Message-ID: <20251126231733.3302983-19-dmatlack@google.com> Subject: [PATCH v4 18/18] vfio: selftests: Add vfio_pci_device_init_perf_test From: David Matlack To: Alex Williamson Cc: Alex Mastro , David Matlack , Jason Gunthorpe , Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Raghavendra Rao Ananta , Vipin Sharma , Aaron Lewis Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a new VFIO selftest for measuring the time it takes to run vfio_pci_device_init() in parallel for one or more devices. This test serves as manual regression test for the performance improvement of commit e908f58b6beb ("vfio/pci: Separate SR-IOV VF dev_set"). For example, when running this test with 64 VFs under the same PF: Before: $ ./vfio_pci_device_init_perf_test -r vfio_pci_device_init_perf_test.iomm= ufd.init 0000:1a:00.0 0000:1a:00.1 ... ... Wall time: 6.653234463s Min init time (per device): 0.101215344s Max init time (per device): 6.652755941s Avg init time (per device): 3.377609608s After: $ ./vfio_pci_device_init_perf_test -r vfio_pci_device_init_perf_test.iomm= ufd.init 0000:1a:00.0 0000:1a:00.1 ... ... Wall time: 0.122978332s Min init time (per device): 0.108121915s Max init time (per device): 0.122762761s Avg init time (per device): 0.113816748s This test does not make any assertions about performance, since any such assertion is likely to be flaky due to system differences and random noise. However this test can be fed into automation to detect regressions, and can be used by developers in the future to measure performance optimizations. Suggested-by: Aaron Lewis Reviewed-by: Alex Mastro Tested-by: Alex Mastro Reviewed-by: Raghavendra Rao Ananta Signed-off-by: David Matlack --- tools/testing/selftests/vfio/Makefile | 3 + .../vfio/vfio_pci_device_init_perf_test.c | 168 ++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 tools/testing/selftests/vfio/vfio_pci_device_init_perf_= test.c diff --git a/tools/testing/selftests/vfio/Makefile b/tools/testing/selftest= s/vfio/Makefile index a29f99395206..3c796ca99a50 100644 --- a/tools/testing/selftests/vfio/Makefile +++ b/tools/testing/selftests/vfio/Makefile @@ -2,6 +2,7 @@ CFLAGS =3D $(KHDR_INCLUDES) TEST_GEN_PROGS +=3D vfio_dma_mapping_test TEST_GEN_PROGS +=3D vfio_iommufd_setup_test TEST_GEN_PROGS +=3D vfio_pci_device_test +TEST_GEN_PROGS +=3D vfio_pci_device_init_perf_test TEST_GEN_PROGS +=3D vfio_pci_driver_test =20 TEST_FILES +=3D scripts/cleanup.sh @@ -16,6 +17,8 @@ CFLAGS +=3D -I$(top_srcdir)/tools/include CFLAGS +=3D -MD CFLAGS +=3D $(EXTRA_CFLAGS) =20 +LDFLAGS +=3D -pthread + $(TEST_GEN_PROGS): %: %.o $(LIBVFIO_O) $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $< $(LIBVFIO_O) $(LDLIBS) -o $@ =20 diff --git a/tools/testing/selftests/vfio/vfio_pci_device_init_perf_test.c = b/tools/testing/selftests/vfio/vfio_pci_device_init_perf_test.c new file mode 100644 index 000000000000..33b0c31fe2ed --- /dev/null +++ b/tools/testing/selftests/vfio/vfio_pci_device_init_perf_test.c @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include + +#include +#include +#include + +#include + +#include "../kselftest_harness.h" + +static char **device_bdfs; +static int nr_devices; + +struct thread_args { + struct iommu *iommu; + int device_index; + struct timespec start; + struct timespec end; + pthread_barrier_t *barrier; +}; + +FIXTURE(vfio_pci_device_init_perf_test) { + pthread_t *threads; + pthread_barrier_t barrier; + struct thread_args *thread_args; + struct iommu *iommu; +}; + +FIXTURE_VARIANT(vfio_pci_device_init_perf_test) { + const char *iommu_mode; +}; + +#define FIXTURE_VARIANT_ADD_IOMMU_MODE(_iommu_mode) \ +FIXTURE_VARIANT_ADD(vfio_pci_device_init_perf_test, _iommu_mode) { \ + .iommu_mode =3D #_iommu_mode, \ +} + +FIXTURE_VARIANT_ADD_ALL_IOMMU_MODES(); + +FIXTURE_SETUP(vfio_pci_device_init_perf_test) +{ + int i; + + self->iommu =3D iommu_init(variant->iommu_mode); + self->threads =3D calloc(nr_devices, sizeof(self->threads[0])); + self->thread_args =3D calloc(nr_devices, sizeof(self->thread_args[0])); + + pthread_barrier_init(&self->barrier, NULL, nr_devices); + + for (i =3D 0; i < nr_devices; i++) { + self->thread_args[i].iommu =3D self->iommu; + self->thread_args[i].barrier =3D &self->barrier; + self->thread_args[i].device_index =3D i; + } +} + +FIXTURE_TEARDOWN(vfio_pci_device_init_perf_test) +{ + iommu_cleanup(self->iommu); + free(self->threads); + free(self->thread_args); +} + +static s64 to_ns(struct timespec ts) +{ + return (s64)ts.tv_nsec + NSEC_PER_SEC * (s64)ts.tv_sec; +} + +static struct timespec to_timespec(s64 ns) +{ + struct timespec ts =3D { + .tv_nsec =3D ns % NSEC_PER_SEC, + .tv_sec =3D ns / NSEC_PER_SEC, + }; + + return ts; +} + +static struct timespec timespec_sub(struct timespec a, struct timespec b) +{ + return to_timespec(to_ns(a) - to_ns(b)); +} + +static struct timespec timespec_min(struct timespec a, struct timespec b) +{ + return to_ns(a) < to_ns(b) ? a : b; +} + +static struct timespec timespec_max(struct timespec a, struct timespec b) +{ + return to_ns(a) > to_ns(b) ? a : b; +} + +static void *thread_main(void *__args) +{ + struct thread_args *args =3D __args; + struct vfio_pci_device *device; + + pthread_barrier_wait(args->barrier); + + clock_gettime(CLOCK_MONOTONIC, &args->start); + device =3D vfio_pci_device_init(device_bdfs[args->device_index], args->io= mmu); + clock_gettime(CLOCK_MONOTONIC, &args->end); + + pthread_barrier_wait(args->barrier); + + vfio_pci_device_cleanup(device); + return NULL; +} + +TEST_F(vfio_pci_device_init_perf_test, init) +{ + struct timespec start =3D to_timespec(INT64_MAX), end =3D {}; + struct timespec min =3D to_timespec(INT64_MAX); + struct timespec max =3D {}; + struct timespec avg =3D {}; + struct timespec wall_time; + s64 thread_ns =3D 0; + int i; + + for (i =3D 0; i < nr_devices; i++) { + pthread_create(&self->threads[i], NULL, thread_main, + &self->thread_args[i]); + } + + for (i =3D 0; i < nr_devices; i++) { + struct thread_args *args =3D &self->thread_args[i]; + struct timespec init_time; + + pthread_join(self->threads[i], NULL); + + start =3D timespec_min(start, args->start); + end =3D timespec_max(end, args->end); + + init_time =3D timespec_sub(args->end, args->start); + min =3D timespec_min(min, init_time); + max =3D timespec_max(max, init_time); + thread_ns +=3D to_ns(init_time); + } + + avg =3D to_timespec(thread_ns / nr_devices); + wall_time =3D timespec_sub(end, start); + + printf("Wall time: %lu.%09lus\n", + wall_time.tv_sec, wall_time.tv_nsec); + printf("Min init time (per device): %lu.%09lus\n", + min.tv_sec, min.tv_nsec); + printf("Max init time (per device): %lu.%09lus\n", + max.tv_sec, max.tv_nsec); + printf("Avg init time (per device): %lu.%09lus\n", + avg.tv_sec, avg.tv_nsec); +} + +int main(int argc, char *argv[]) +{ + int i; + + device_bdfs =3D vfio_selftests_get_bdfs(&argc, argv, &nr_devices); + + printf("Testing parallel initialization of %d devices:\n", nr_devices); + for (i =3D 0; i < nr_devices; i++) + printf(" %s\n", device_bdfs[i]); + + return test_harness_run(argc, argv); +} --=20 2.52.0.487.g5c8c507ade-goog