From nobody Tue Dec 2 01:05:43 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 6D84C346E46 for ; Fri, 21 Nov 2025 18:14:41 +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=1763748882; cv=none; b=TCgRcl5SlM/YYrAYp5T3XEdUNHqa3rxt2d9eMi0lQwzKIH28fwJhADW1jwHD+MLsHQYUk3x0UuIV+iu67z9HLLu3RksJLaUilDTRn8oCWC9BAcVQbwWXw3DPODzJY/83asS/xNMp1tiZnlOSXHfPSmpnKSS1qcbpc8fmNJUo4f8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748882; c=relaxed/simple; bh=4jbFW755dBJOKS7c/96o53MFewYxrjS3To1SirYDZ6M=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=hieZOBUnP9ZMEsWlNcR2lac0BiUymxi7lHqBMKiPFWSvvG9ORZOSUetwJ0+JWo/AoxaLDBYyAmCaTROsK+w9VEq9/1xtwG903oEW3KxqJHbxYvAgam6cYr3fowgdZLbtFbE/xAfajkZruhh8m8Q5VaKwGj6kWBo+fp+cLu+nagA= 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=OYzqR6UC; 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="OYzqR6UC" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7b895b520a2so2536653b3a.0 for ; Fri, 21 Nov 2025 10:14:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763748881; x=1764353681; 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=QoH2RYvouNfNzcg9XmRj4HJ+/hSocAJqMJ5WG8meLAE=; b=OYzqR6UCBc4m5PQt0gEzKQk6pxbwxjCJ9F7cZ6doxm5+LHPujHVvcuEtZxCuzp9odK 5JVp+Gc4SPV5kD53rf/0doa2Kg2mOnfgcjPoCtzrgx3IUsx9Cj9maGt0Q1xjEJG46OO5 VXSe6V90xX4fGKUk+1OqvgZ99ZVSzFQUMI7JgG/SquODeVOLxMi9dnKKXvZEQ7jHwjdP UL97bQ8oj01pK+Ytstb8t8cxe/BnBXUWd26R0qdGG0QsyqRJte+IesjCQ6SxMfGIdUn/ 29N3dyKVhF19CLDvgCZr6KznCoFAkN6J53lo8jj7uZfTxJMuifJVUQ3GmNMmDHZ/8sd7 nYDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763748881; x=1764353681; 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=QoH2RYvouNfNzcg9XmRj4HJ+/hSocAJqMJ5WG8meLAE=; b=B15hY28MCAlm+19sgzpFhl7TocEHCwEeyvgsLmP/oY0lWl3Umzm8VuwIsmPO6Yg+NB 00QnAAq9ilddiq1zt0MO4jdYAxWvvgHYb1+wGCNtF7hi4nWlzCwAWXx353aRD12MiZ// E97jZlPt3LNbGaeGijVmmgODphiHD6eJUrnRUqk2huZCmJszV6Lv1j5hkaTpqunVQ6zP ItxNN3eBXuVYxZzlxlwpIaItMpmeh2uuLYzaHJ9KyM7X+Fdk3cMnh/QaPO78jsxdmsNW so/SloagHNbbrcQWzOQyOPJHr753tx6RezFRPX+Yi7aI1YWXB3dOJDtLQXFqlxPU9LE3 HJcg== X-Forwarded-Encrypted: i=1; AJvYcCUzCPH7vi0rFN5k36nEnashTVkVYJe+aE5bg4ktqRBSNQ59ZLmGFpcDe+uY20L1rVIso57S9wS3W8xc4g0=@vger.kernel.org X-Gm-Message-State: AOJu0YwmlJs1KZuP1O+zggzErgAO8It8+5BCwX4PnxGlOn4DW0bepP0l ucdB/s9mHlzW1MMictY07eEzDC9N27g5ddKb9fGdpMkf+fC3nfnmjPcXmAQSgeel6ykIk8olW+f N9BfNuGMuTOiKEw== X-Google-Smtp-Source: AGHT+IFYfYykvUE7exbquc/WgJQX81W9GZXkUukUXGA0A/oiKRCw7ky23MadV3qd62uwBzor+3VKId5C5olVdw== X-Received: from pfbey6.prod.google.com ([2002:a05:6a00:38c6:b0:7ba:e377:7797]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:10d1:b0:77f:4a83:8f9 with SMTP id d2e1a72fcca58-7c58c2a730amr3542935b3a.2.1763748880094; Fri, 21 Nov 2025 10:14:40 -0800 (PST) Date: Fri, 21 Nov 2025 18:14:12 +0000 In-Reply-To: <20251121181429.1421717-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: <20251121181429.1421717-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc2.455.g230fcf2819-goog Message-ID: <20251121181429.1421717-2-dmatlack@google.com> Subject: [PATCH v3 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 Signed-off-by: David Matlack Reviewed-by: Raghavendra Rao Ananta --- 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.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:05:43 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 636AB34D922 for ; Fri, 21 Nov 2025 18:14:42 +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=1763748884; cv=none; b=jPtOWvq/yMQ19XSNZFpb5MXWsSzuWl1NVQ/0fB5fmI9tEbAIwxTVeOLRTbfHP/rzHIKFjfA+5+q1FA/NHK7vZfgnuoNNE6PenJVHP0INoRUV+NBiotCKuv6rSssqBYwrz7JFNseQoLnp8wBO4bkDxm3sjrzO0tyVYYct05qgmM4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748884; c=relaxed/simple; bh=NBYuw7yy4LKspTLrTBhSD/VELLAr5jASJVtdtt1JJYc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=EzVONG9G7fV/CUOIQShGab6Zaq+2K5ClAxk/+2it7KBa++iNdkWTnX+SHwJB1oaML7D1Haxr5Lnd3YrD8tK0jDZJlEp3ekbP/18WvdYTzuefCSuv57rzrb3AGKNXP7bYZDrfPEzHJhWloE64SkjcoBkRool7PnTmqSO1RsJFAnI= 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=ytpkJYrM; 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="ytpkJYrM" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7be94e1a073so4898987b3a.2 for ; Fri, 21 Nov 2025 10:14:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763748882; x=1764353682; 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=6xrsU5YxTbW8Se8AB1hlByyJWpMN5aJSRnLmBAm6hgM=; b=ytpkJYrM3LHafma/GdtfzxOcNAhUaZbZ7uwQvs4I2yidWYS8QGwode09QoHExgjCc4 wyqztLodyyJpjJovJRqJkDsRBpntCIOMQ/18sITOlh6PxmFoMuXUYeec0QPttbH1pzSs N2tIsFzMFNp0InjvRbdZQvTgthKkl9RijCptgoXVnqif4D+4TB/9OwIUosFdActW1q5V +8w6092RvXiLgDZEQU7DvneWtOSeCwx8WUKZRWLuV8Iz60Ev8aAa1eRdu4Zv9zFiS6eP /JFP7DE8MR5e5CHywGQp0bFoPxSUx+WtK3lOccQPHJGGc7UiMXcFd7n2pUuzrP8JKzYb rgpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763748882; x=1764353682; 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=6xrsU5YxTbW8Se8AB1hlByyJWpMN5aJSRnLmBAm6hgM=; b=LIakpjBZRap5eZIWnuIGezyvGlv9W/5f6E17CkfrSh8hs76Z4PeE7qkCGaPbuJ+m73 GX30z1u9w2hucMugmg6ruSQup3eX8zTj06x24MbihZqSN8hhyud8Xllowc3kjJeLHJHD X4bpzd5o82Iv8CDx1caP5C8Bb29nAsDiGycOjC2epxiKDe6Okh+DX6/5w/VL87y8By9z u0b0zOPKfj6TXjJEAYveMXN4ZMrxyw2V2t+62xCaBJaZLNjoL+dlEG0HcFk0psc+cfDY 4PxjNtzVxKpjMqqP/ZCW3IchN+RuyayXfCtmCkB4GFSdedWnhW1cGQwLkyRr/ETzy5Y1 SN6g== X-Forwarded-Encrypted: i=1; AJvYcCUO5srgpTfgMLwEyZbgpCBSO6cYHopvVqiyAB7UJbLVN5h1zLhROcCKqYzUpvfmukYsKslu4SBtJOaiJIs=@vger.kernel.org X-Gm-Message-State: AOJu0YzYKfUGBIenczOqGcFrrPkse4q2FcOm+aLYb63DIPYqIq72gL8C GNcBAN8ymBLaFElG80iUEKSp0NKHNTe0A4jbU67gfewS2Vic/9LJWGEeXiDK2klOKfD9U9MevBK nXOk1/NeZSWfpZg== X-Google-Smtp-Source: AGHT+IFIX5BeME7Rt9gMBL5YuP6nIaO/M1fvkPVIfZhb8ixuJWg0WSknC2PSsvUktD+1Rnl5nQyi6UGSXC5yfw== X-Received: from pfbdf10.prod.google.com ([2002:a05:6a00:470a:b0:7a9:ce34:8e4b]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:1ad2:b0:7a2:7237:79ff with SMTP id d2e1a72fcca58-7c58c4a4fe3mr3572247b3a.7.1763748881662; Fri, 21 Nov 2025 10:14:41 -0800 (PST) Date: Fri, 21 Nov 2025 18:14:13 +0000 In-Reply-To: <20251121181429.1421717-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: <20251121181429.1421717-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc2.455.g230fcf2819-goog Message-ID: <20251121181429.1421717-3-dmatlack@google.com> Subject: [PATCH v3 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 Signed-off-by: David Matlack Reviewed-by: Raghavendra Rao Ananta --- 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.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:05:43 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 E83A73502B3 for ; Fri, 21 Nov 2025 18:14:43 +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=1763748885; cv=none; b=MeoEfupt5ZYZv7teSNQMTbqr/z3UZbB2Chr1fwugr5t1Y4c/8AtghiFD7s8EdQkMgN5Zljlxh3BZSVa5fRDzIKNiiLrgS07yDQan2b8CFhvMNMod/eTy0qT4NvD6SEPxIACWyqRQytl3ED2+s8un+zBmdP0g5X3knMUARg6W0iw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748885; c=relaxed/simple; bh=Wjo5S3jm4rIHHKDO95Npld0R/MM3G2rBK7det+W9InI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=NFkF9jCJvwfmS/XW8j77oAA80fXL/6yCN1+tomUOrG2pxSk9PHh+hDHHrDRwrjtopixU+SJAiyXBirKrAqVWnkYpIsKQ8fvOqFzNrzIA3o3MRXW4GLSW/jAfHJU+qVjQ94nvkOQogOdaGXvHb2PIMd66HKYHolt0at7DwGSA1XA= 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=eYnDilA6; 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="eYnDilA6" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7b8973c4608so7110774b3a.3 for ; Fri, 21 Nov 2025 10:14:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763748883; x=1764353683; 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=g124QBzcdvPEK+J/83+56gYFpABGkICYbD/An5ySYhE=; b=eYnDilA6k6/ZEs5TTKKO4ywrCh60P18AKcvg/PZUOHaSsJANIExPmtpcu/NBoabIAO AqJXa6VWjYZznz3oZRUVNBfXByzEcjgVSQM7pBKcOw0cph+BVtt3/JOzOtgB8rKh0Kab msvYoeqlO2u0ICxBY5N7FusUGs9bMkijbz/qjkzy0V7dJ3PNrcbzg2UKJ3zP78dv7aEZ 3QLQJzkiBMqglThs4J/MAq2OdS6b5h7X6ndoSHTRaAB1fVZtToJKqCQHhZ8rIZPkxnrh WDAEt7tEpanqgnuYXOnoZKOoADQBiHVLBCZ0Bl/utpLGbdoyOW5/zNBT5+ay5gJajjD7 UECw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763748883; x=1764353683; 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=g124QBzcdvPEK+J/83+56gYFpABGkICYbD/An5ySYhE=; b=HZh4jsJ6CpkFPZ00jN8+bHaPMDnpXHqr+J8sk6HUGUFEDOSeHeTMjZTqlIkghc2VDm Y3TLzPKfcqC3i1in8dE0q8EPeTxh4OHN2yqD5/CJA2qHJwuyykm4vjAvtFwpfHGCM18t GJVWFc3P4hFqF9fmVHSfe4dQUocOY1u0sRVB+7f9U5zIREG7oiNOJGrvIpa1S2hViH5w ntAOODTzRkc86/rUeEKsNOkNeb9ihjd6mGmW8m1k7phkeIPkD17XQuhIUtAnBnV3PlJD gqDJQluhdEw7c6zosKR+kULTcFWyjE1FLWm9EZwShu36MA+k63DBik+FIpDpysVI8j9j Sl9Q== X-Forwarded-Encrypted: i=1; AJvYcCUG1+2jaVVLUlQUcx5pD1e80Ismf/YO660Jhb+izJ1d2GCqYGRQP4RnrSRA+hW8MbAehVfXCsfsebBaBxY=@vger.kernel.org X-Gm-Message-State: AOJu0YxT3CTt0jpYT4pFusa7kbvu16l/8Z9a5VACdTzPe3+d08I4rx0o PMxhE6qR6YLf0WdynwTbInoLiQdkJ6IMvsZ45g+zdgFj/pj8X6aKlWDgWO1YbB9NKx0LAeqsxjI snv9GeP5j56zCvw== X-Google-Smtp-Source: AGHT+IE6bTYkPneatI//ZdOy1x5PgnIneKQ606XIGGaa0iqn+syJEbxJdH/cKE3PeHga9Qitv+c9GDWTPxOr8g== X-Received: from pfjt15.prod.google.com ([2002:a05:6a00:21cf:b0:7c2:a212:2b32]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:22cb:b0:7b9:d7c2:fdf6 with SMTP id d2e1a72fcca58-7c58e601920mr4056673b3a.24.1763748883301; Fri, 21 Nov 2025 10:14:43 -0800 (PST) Date: Fri, 21 Nov 2025 18:14:14 +0000 In-Reply-To: <20251121181429.1421717-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: <20251121181429.1421717-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc2.455.g230fcf2819-goog Message-ID: <20251121181429.1421717-4-dmatlack@google.com> Subject: [PATCH v3 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 Signed-off-by: David Matlack Reviewed-by: Raghavendra Rao Ananta --- .../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.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:05:43 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 9364F351FBA for ; Fri, 21 Nov 2025 18:14:45 +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=1763748887; cv=none; b=I4BxQ+IvSeGa3iprdWM8jG4urErG0K5EEW5JwExwyHUZw8GA5iRB3cGA9emUyrTKsCwj2p/LPvRQVM9S2+TEJRhm6Q/9sZxvF93LKnqJKatYzIVeYAJbucL3H9wCYqwYyJnGbqM0wYEjrVg7KMbT8yo7z0Yqmi2W8JpXKXdnmac= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748887; c=relaxed/simple; bh=0mpt9DrK2EH+/nszyWzaz56fSuMqVTW+MCo2D/grwGY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Ab03fy9o5QKkIC91Hr64Ivkr5UcJCHchx8c7+RxloPuSqLcVMVcGgfL9sT02sPiEwGT4K+Uo11cy4YVTffPGObH5iNYNBa74fWYbprCdfu38VFsbRTDjONC8NPq4qvuCHHAh70W7lVyYeKLQk6h7OeN+UNGj4ZU8XaeorWBoll8= 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=fCQdLYwT; 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="fCQdLYwT" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-297f587dc2eso55120815ad.2 for ; Fri, 21 Nov 2025 10:14:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763748885; x=1764353685; 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=JxeIo10ZephNiFDx/n6CiZynZejR6x/fiOnvLqPApOE=; b=fCQdLYwTUHNraYZFyFT7SgERnZENyfiIY5r6nUNnn53rGLt9of1C/nVbKFBg2V+v22 zu9njHADo7KN3ROjSimIsKfFw7ra392HSTLbzhyMlKYQ/TIFENQ6AVivl2ysIkYt9Zl5 ynLoGmHWVzEczJY5Zt09jZzC/ticrP9+Fy9eV0ST6v2yUnPxlrpIFQHMsmdtdu7Yty1k ssdKSLdFJW0UHCFPGP9WNubAWeLf0i+zexcEZlr3b49u+FtYtwAHROOVuUMC0j/jTs5w fMsrhAK22hQpTActx2t2v2i09w6RE13bH5de1GryYUtPUBe5oaGKns4Fnqww+UnqCYYc 1wPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763748885; x=1764353685; 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=JxeIo10ZephNiFDx/n6CiZynZejR6x/fiOnvLqPApOE=; b=CC+e+5f7AhwMo1RJKB2Q07M5PMUDAdnS0n8LADMdPq+xpaKVlsMdakNjE2RUbtuzbA QihE2SbAQp68SelI/SW9Z2t43Kz4QGOJ3TvKRE34GEiDmTaqkMaflrJSKwApn/qIsB85 1H2mSL5bfSKPBehlS0iIdO5/l1yaC0Tz/y4UbBmCRUjvDCT+1rKT5Ff+8wJWaAQF5Wa5 FU5LyFvLlCDQM/5EUTR8C2AMM7CwzaG+k344Ppf+Yb5iMHpnVxyYzeA4/ItCNVYLIMbv poUYE6PE8Td3gOUYBW5/SuBUFBkVxApPJevZAU74HJmg0e2U1oorgonBGGkMldG4rUFj ZUzw== X-Forwarded-Encrypted: i=1; AJvYcCUFCYtKCtv+Ditb/Xs5+krbIXctFqjETsUgjfQgM4GxsotuyRgLjjHr8YSpRCQ/lJQfGO2eGAUD9vBM4HY=@vger.kernel.org X-Gm-Message-State: AOJu0Yyq8G8bUGr7TgAAt07jaVWxx44rwnpbnt0vcHa8OIFbxXHDa9fi bqPMFJ+x5xFOHGTjqaINelV07FmY0JWJUiY0RGf+f3e9AC3UWdudjMOKH2grfhydJVUIe2FKYNF 05h3Ru9iwzto/Zw== X-Google-Smtp-Source: AGHT+IFbLTbWF39tJajkynXW4HbedSaaqh39StKC8XEAGbSVy0Ikmggms+4ZG3tLpOCRvQQJzPyHg6COHAgOQA== X-Received: from plbkt13.prod.google.com ([2002:a17:903:88d:b0:292:3da1:8ea8]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:440c:b0:297:d697:41e with SMTP id d9443c01a7336-29b6bf3b588mr42912705ad.37.1763748884880; Fri, 21 Nov 2025 10:14:44 -0800 (PST) Date: Fri, 21 Nov 2025 18:14:15 +0000 In-Reply-To: <20251121181429.1421717-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: <20251121181429.1421717-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc2.455.g230fcf2819-goog Message-ID: <20251121181429.1421717-5-dmatlack@google.com> Subject: [PATCH v3 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 Signed-off-by: David Matlack Reviewed-by: Raghavendra Rao Ananta --- 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.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:05:43 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 261ED352934 for ; Fri, 21 Nov 2025 18:14:47 +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=1763748889; cv=none; b=mV6HXwWI3JEOqixtJKL2QJsYJh/SmKA5McQ/GaPIYMaK60/SEMfom0tFH6+eQ8qCF4SN8774tyZrXHvIjZxlpOJk6c4JtvvgE6EosurQa4kaEEFCMIijcS0hsdmQdCrM/XaVD8hbt6MFABHHz245Xbwo+K4s8AtyOqgjZJvkrX0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748889; c=relaxed/simple; bh=JrMXo1bbH2zD+C9IAEk7RcmFaSXGprQ1nQVRbpRkObI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=CiiBPeoEB+m/E/Akdo1/yV1ntmF98xuc+a9i/VgTwIf9fqqZl2IrpZRaa1/N8H8dBpfEAeKmngh80LyWGM9Dj7hAgTCefF+xqaBph1hvVvBDBz6RqcbAF1t+auPiilekxom32L8+sCxtfcrA7n3tXWXrW5KqXY180Hby3VTzKu0= 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=ydEzlBtR; 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="ydEzlBtR" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-29809acd049so47184565ad.3 for ; Fri, 21 Nov 2025 10:14:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763748886; x=1764353686; 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=blhLd4rrTqtEcsOjOcmqpT/d1FX49t9c289UH0z+u3s=; b=ydEzlBtRIx9xXwM+fagmXbSHYDoWqGT9apATHqsuNxl5SDb74bucN3CAfsMh1SVgUf thI8qq9kS2iGAgcrFUGCDCdihXBAeboyJGavtcH3EaFNPVclFYIxWcTQfDJSZCHQ4TkB mgme/8vfLoktNWnuDMWh5tjxLAai2NVz+2pp7Itb2PY9TV6DIIMbl6qHysJZmRIyRnUT qXU2x5hjdCdl6RraHh6VC0lA8JO05ofKpaLKRcxFSRQZ7fmcqAMxUtIfa7fsM6D6vrjc kjmUi74Y3eaF2XzOKmifbZJphZUmTHyAYBYHCkSw7moqAt2zk/ZkzmyZ2myp/goRSCzf QnHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763748886; x=1764353686; 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=blhLd4rrTqtEcsOjOcmqpT/d1FX49t9c289UH0z+u3s=; b=EkcpAF6pVXlDFLGCFWEuaSLbTUNsDv3P//czmuNeTUGTXoH8z03EUkX6ojq8hdL3P8 +KzPIzxrAZlor6GUtNnB3t6X7lON9vleB+TBjI9AposqUaDQ/quzDXlMmE75hETUy8mL ii4cH2wn9ewbSFl0S9hywp6BC8WB6uMPfF4b3TZARt0MkJFqtcI9v1GHSdjy7rIBCPtm DrcI1hPaMBZ2334bV/YDtOkbwx4I2I43rhiV4AL+1Ay6AEVm/AUUnIHaVxMGufWbeCVA CDYnBnM+FbnqYVWvukivhgvLNCQFd2zMLrvZVjhmG3gxA7GvYBzPKDEkvm64Uq3Eyojn bKSQ== X-Forwarded-Encrypted: i=1; AJvYcCXVrJnMqLmHsWhj7d4bIJdLr/avf/XK7VboZQ2+ac4msPwj+boASSGe38m17zdXiStqKhZzE2pJRlWlwvE=@vger.kernel.org X-Gm-Message-State: AOJu0Yxb9jFEvVMSGAKEJXRkqqvRfVb/wb8RqRIaZnPqYCCc312t4tBv yRuAnpEc793ys/Oy12Pqmnp0JAX6ofvgMc/c264riZ7B8DU9qjK+7r/OOtS+zhyVbhHw/WPgHXd KSPAKsejSnt4C/A== X-Google-Smtp-Source: AGHT+IFDh1Mq0Cq+V8AWErkW1uaQlm6+HEp9I9J8cTlqWejTFalLZIGvnegC1ArG8b6icswYkKT9fTxcj0NSWg== X-Received: from plmk8.prod.google.com ([2002:a17:903:1808:b0:274:6ac2:5f9f]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:f609:b0:274:5030:2906 with SMTP id d9443c01a7336-29b6bf60de3mr47982835ad.46.1763748886454; Fri, 21 Nov 2025 10:14:46 -0800 (PST) Date: Fri, 21 Nov 2025 18:14:16 +0000 In-Reply-To: <20251121181429.1421717-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: <20251121181429.1421717-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc2.455.g230fcf2819-goog Message-ID: <20251121181429.1421717-6-dmatlack@google.com> Subject: [PATCH v3 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 Signed-off-by: David Matlack Reviewed-by: Raghavendra Rao Ananta --- .../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.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:05:43 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 D604B352FAA for ; Fri, 21 Nov 2025 18:14:48 +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=1763748891; cv=none; b=NBtyXouSdFz7IRwRVU1G7fGd5380P/QjINtzusn1DfK+6BKrKc6ErGZe1N7Y+wQtxEaRjgL9YslDZNIRVzJBRURYvQKqmflELAy2leGT68TiU5fDk779ogqfs9c5wCaL3KzXwaKXSCjzrNTUfRciCG8fQax/5bhbckYRh4fn/K4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748891; c=relaxed/simple; bh=A7jugkRVtYaJCqVnCgi+NM96TSclcnrEQHf/mvPMiX0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Ww6Yx3l7joL1JB63PmL3GKA34FEDGaO2HM99YKgo4fkb/3XH+1Ga3UnErw1gZDVgyGbGaWQEzrhMxpWVSiKbsO8bsn4F7nIcm0JjKxNTZJpat3SSVJCOfir9sfTnyDPi3UlVU+ku/r6k+MiL3m5iSd0zW73JYGdipY/vfuPKQyc= 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=vYjuM3/b; 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="vYjuM3/b" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2982b47ce35so25674175ad.2 for ; Fri, 21 Nov 2025 10:14:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763748888; x=1764353688; 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=Rs+v+moIZWOjSmppyXWFm45kengypjO8+D7FGVdC6/c=; b=vYjuM3/bUi/hQmTOeEmFy+oTupMsgRNpQo+9R29MXTovIBWb6l1r237mB2MLIWs1Mj gjyxYvTRej92UMMNy+9v2/v6cmMqVEovgykHPgX6XwFjOlYnBzhCKPcFwW92YPdaGzwQ vROKLQ1pGRmvb64HgzityV2Yw2y1tv/57dIbAXWPPzZohimsx7uqPqgqX8agt592eJqI JQqbJrD9xjOVsJGHoi2matswZ2Yb4vm6eFNqh/zd7ULtuuciKbQJSeyYZDS09bv0TXxO GaOrdo3d5pdt+hHYvsJXYkrR1mcInakysBYlrhHtCDpjrd9/zgGSG3JTz0/7+yNlpbAe XWiw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763748888; x=1764353688; 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=Rs+v+moIZWOjSmppyXWFm45kengypjO8+D7FGVdC6/c=; b=vhkASiOiTeLpQiFJGBBYb6sZsIQrvya/+UgBncCTV0vGMVJagVgxceC8FSfJI5YJeX vRBJucSM183lQxePwecojcPDDzF40dt9MRjalqRI6Mr+MxMLVXEY6VwuPRu6XYZtXihT +oTc8NZfDhb6ES9RzX+cSWYSZ7sWtf0tb+KlAdX7naYbGtuyNfSJXKGkCJ59fd3d72w6 xaiYpOtAhrv637G6y6za68YtUpXD4qdLeIB5V6yvzMUot0XYwNj36q9dpGjxPzHveybr l/VdXA2EeZ9DBi/1a9r9rTeLuwU8HM0fvngPJNKoB+4bBEkOcyk7HA6j6In+jWGUeSQt jHpA== X-Forwarded-Encrypted: i=1; AJvYcCVgqYZvbA7uhNoDJjqQy/OqSqUSDCj7/9pmABZ3jUj355y0WQHB+QVtfD6wRX2WiO9G/hPXadd+B2T9oQ4=@vger.kernel.org X-Gm-Message-State: AOJu0YzhdT5r6vfqGlm8/oHwt4f1NufBJwSZGO6ZkfbUKNfq9/NVnR7V Aql4WUnijhbknwGQ4A8RgaG+YWoBB6ijJo6CIl0Gef0Ul4lWhyRpB3w1/VRuxtxhrLjLk45PvN+ 2MPx9bvnW7+k5Uw== X-Google-Smtp-Source: AGHT+IE1pATFQF9UdtyFovHguUHLVnsKsnw8gA1QF1TIOikrK50GI0dcsV8Jl8U07yBPnTsmphfuERXXE0EI9g== X-Received: from plzw11.prod.google.com ([2002:a17:902:904b:b0:295:70a9:9091]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:2f10:b0:297:f793:fc7e with SMTP id d9443c01a7336-29b6c3e4c3amr37058345ad.19.1763748888157; Fri, 21 Nov 2025 10:14:48 -0800 (PST) Date: Fri, 21 Nov 2025 18:14:17 +0000 In-Reply-To: <20251121181429.1421717-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: <20251121181429.1421717-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc2.455.g230fcf2819-goog Message-ID: <20251121181429.1421717-7-dmatlack@google.com> Subject: [PATCH v3 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 Signed-off-by: David Matlack Reviewed-by: Raghavendra Rao Ananta --- .../selftests/vfio/lib/include/vfio_util.h | 6 +- .../selftests/vfio/lib/vfio_pci_device.c | 102 +++++++++++------- .../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, 105 insertions(+), 49 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..57bdd22573d4 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,32 +795,53 @@ 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); + device->iommu =3D iommu; =20 if (device->iommu->mode->container_path) vfio_pci_container_setup(device, bdf); @@ -853,17 +872,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.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:05:43 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 793C23546E0 for ; Fri, 21 Nov 2025 18:14:50 +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=1763748894; cv=none; b=NwuNI1NFPvSEIT9T788kr3hHhW2y8D4626a+yuuiwXA8KLNe2iHVousAtjF89afbIrl1N1uXsikV9M6CYMUoXdWFCZrEOEsXWIvN52PWECQBf0kyolc7zEeREfTZjRTLQ6Co6VB0rNWA2nD+Inx1VG1JjbHq5NsCA6bd/+i+cTU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748894; c=relaxed/simple; bh=sVQ426YvnoY5iDxUNhuIYEZEVmIjttH0GnYN/e26wNE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=gc3gFtlSMg+K4hNqO/rE59ev/7E+xSfCl5AlAfRFzHUFocEXoFBlmfBYNRvDoiKdS4tqftpLmNfoihFvybsV80qdOCTqGMgKGE7DVkM3EygtGjKkCPwWVJ3o6SXd5gQm7ApTJLwnIGFHYihRXufIujWEAI+VZ82+rzbub38Q2e0= 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=bR+LWki1; 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="bR+LWki1" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7aa9f595688so4407625b3a.2 for ; Fri, 21 Nov 2025 10:14:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763748890; x=1764353690; 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=N3IoouEAfOFQFuW4LZTJBHs1EfAd8fQ12WV4kcywblU=; b=bR+LWki1xCvlVWPn4/9fmPoia/QLUJ5wSSAnBEdogtDrglq7sJ1Fivs6+CVlGzMfKu F3a5X94z+/ZVVMw9DJ8prwrJXWiF0oNGnpmwFcOPtttnAT4PvnQTgr064uSOZpPlb4AC uU+SRa1ndd8ZGX+yJpZmDus7WuQKPJOzkslOBRlxSdwuroPGAhLEz3cC2zkzQBl6aPZI L2VpGB5pUcLD6GMUBk+lx9zCFKbhHw7Fkb0HG0zFG13V89fSwcnvsDm09j17Z/ZwrzbR gjw+zlNGoO+yJnhR0UmzhjJ2WqbVq90nBNDBuxKTnbw4S2rT1eJCZ8NtoMo+bduXlX8S 8cnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763748890; x=1764353690; 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=N3IoouEAfOFQFuW4LZTJBHs1EfAd8fQ12WV4kcywblU=; b=G4s/Tgj8MBYh/rrGBCMm077uumVHDNOKy4SXIquinjX4LKDkSEsE8M3w4A4eB89hTC 2oqbVXz5R0/erCMITK93CCSB1XnLEsM6h9FcaKJGuMJ3un9x1kerc6WnaTgQLJul7T32 ktba1PkTfXLuVtw0HrmxzN5s+TXjZGNT0dxbGmTzSZXtX3GGy74RoQVHuzCiyMqTnR2J oAlxl7iA0uhwWVsz2Si0bJ0r59wpV2RanjdRgqGemvoVZbPIv5bWcSK3bTdR9+XLHQ9v K6+9E+uV9/TCE4hwn3aMzf279RTsZ65mBs2bdT2naR2CVNE4xKjlkrI88NplD/QSaP6y zWlQ== X-Forwarded-Encrypted: i=1; AJvYcCWDimO5Hv+FcoLcJhLGg9ZVCHzCdlxRWMs1AePF6eJ53cE/iVPjLBnwRkaEXGtI7HG1orBC7Kl8AMrqsI0=@vger.kernel.org X-Gm-Message-State: AOJu0Yz1qMhChOzjOPmBdFqXO0EoZQiGvXL/dlxv+dovP3SJF6GQOGp8 fJyfeZwbWbG5R8J2PmX9kBzJpFmg1INc/zQSgQ3wAhBlhPI4MND7BSStTyyuCmRKZlPr2NotsP+ ileZsCuSFNXWhTQ== X-Google-Smtp-Source: AGHT+IE1NvJoMtgdX995mQE53G6pC/BzIkZeaThQXnuZo4WTCvgAe0hcSsMC2aMiqLO8tnbxslTiVRPshpSVCw== X-Received: from pfbjc15.prod.google.com ([2002:a05:6a00:6c8f:b0:7a9:968d:6b38]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:1482:b0:7b6:1c9b:28c with SMTP id d2e1a72fcca58-7c58c2ab14fmr3419317b3a.5.1763748889705; Fri, 21 Nov 2025 10:14:49 -0800 (PST) Date: Fri, 21 Nov 2025 18:14:18 +0000 In-Reply-To: <20251121181429.1421717-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: <20251121181429.1421717-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc2.455.g230fcf2819-goog Message-ID: <20251121181429.1421717-8-dmatlack@google.com> Subject: [PATCH v3 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 Signed-off-by: David Matlack Reviewed-by: Raghavendra Rao Ananta --- 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.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:05:43 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 2B59F34FF73 for ; Fri, 21 Nov 2025 18:14:52 +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=1763748895; cv=none; b=IGHssOHZQQW4qbhmauUoqZldxUkEqNdHpM8OA3jlqF9GoSFmG6LhwAcWTdMfFsu3S3OEqo7E8QXAr+IRRMwyzV/WdQCYA00xtN9fRqyY8+IkoAQq8urGHrmvLoLcUpapfqwUiWKLhval+ECQWxCQBTg/dw7pn7RJn7ewRmdo6OM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748895; c=relaxed/simple; bh=FRJAQ07/YhmKmPddt1eGKBZm0TIjwhbvZt+o9YdlFfs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=C1nkp7UgFcK7ZG82VaiBSJvacA05Ib3/uRQq6PpP7degzKVIOkaAM0ni3TLffZxUhzC71ShNousz7wq2lbjUKA1xtdPx0tvPPgSzWbjYdhgpV6NfU1KYKC+U8SmTiOMrG80yzNWTJDuWsw2yBqbeCS0V8SUFYpsz7npGVMLftU8= 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=24UBOMa0; 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="24UBOMa0" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7b90740249dso4234372b3a.0 for ; Fri, 21 Nov 2025 10:14:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763748891; x=1764353691; 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=xfdqeHDgAK15LR78PCURsTehUUcDYBW4cHOHBjLeoD4=; b=24UBOMa0bBuyFHtY6TFyGKhZAGtFQgMoXefBS+//8eWJGqzKuJTUMeJmIM6OzE8rpc cNqDU07oZpuaoMsxUqvGnrpTmFxU+xrBOluJy9CiXSJ7Kpk1xiepxmKGIBHUjAmWA8oO u+2zM8/vCkmkV5hLw91bC4Mc9nCPXfFU9+W04m0QiN9K4w9LbFpv9gDMx3xUkeiVeGxu +y521uNfZL91ZlCf+KH5+1BtTMk8jYTQg6jVpTBHZrHmDF4c9KxaW2RT7t3WwvJIaqk+ a1Gwkdrqv7pO9u1EoP4mtM7cN0ZxMBQPYx1CC0PdyHNvZPrunEnlF0usl/CRiPjojjRp SgEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763748891; x=1764353691; 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=xfdqeHDgAK15LR78PCURsTehUUcDYBW4cHOHBjLeoD4=; b=Ztek4CpWeGw75JLzVOl8Faw88y/ad7T+SOZJLeh7+ZmKOAQEMSG0SBIdUKTu/hb6R3 hKYSIhlcudAOKOSgQ5zKkNJYAebC8RYMYNNCxfw/1mFgLxm5y8KBuoK+A3TuUH0AAkPb WFLYWdu87jDVOdfWj4V5eFz+/7aGpxK5iFjY4seeuvquXeOdHcbuZDYiHC4jytwNXeHF yt9/GHf4k7E8SGa3hxO9wdPVr1bNYqAagbD9kqbK3IuVJnZjxbR/mAeAd6Jlq5SScQDz +fyUujjfB80UPAiT1eP9Hhi2YLuQY/aEwSA4Nv7jc7ilgY5Ee+kpGF7cyHKH4QIvlL9y eAVw== X-Forwarded-Encrypted: i=1; AJvYcCUphmkoDp+N9zEywAoR55cgd+YbHc0seLNdGzBdEX9peCZbbylmmJxWnjJIGClXg0L2KvqcK4IOwrALgPA=@vger.kernel.org X-Gm-Message-State: AOJu0YwPxjqKR5bkLuEglV1ANUDIeE17SXdlHucKI6yypPljNPwHi+WN LctUoY6B8e5k/aCqZ3Fz//rJpNIdwmCkIgXg6XB5dPzZcJ0Q8OMDaaE8liWnn8SuJtWjakcWUVL IXCESmbM7C3BFEw== X-Google-Smtp-Source: AGHT+IGMlPlgxfy/223nVhigM59dqes2tTw1R0b59UTm2S2VY02fBmW2NNui1T8Me0tYbY3y4vuH6Qg8MoPS9g== X-Received: from pfbcz11.prod.google.com ([2002:aa7:930b:0:b0:7a2:6b90:c18f]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:2d87:b0:7ab:8d8a:1006 with SMTP id d2e1a72fcca58-7c58c2a7372mr3315318b3a.2.1763748891462; Fri, 21 Nov 2025 10:14:51 -0800 (PST) Date: Fri, 21 Nov 2025 18:14:19 +0000 In-Reply-To: <20251121181429.1421717-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: <20251121181429.1421717-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc2.455.g230fcf2819-goog Message-ID: <20251121181429.1421717-9-dmatlack@google.com> Subject: [PATCH v3 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 Signed-off-by: David Matlack Reviewed-by: Raghavendra Rao Ananta --- .../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 57bdd22573d4..f3aea724695d 100644 --- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c +++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c @@ -841,6 +841,7 @@ struct vfio_pci_device *vfio_pci_device_init(const char= *bdf, struct iommu *iomm device =3D calloc(1, sizeof(*device)); VFIO_ASSERT_NOT_NULL(device); =20 + device->bdf =3D bdf; device->iommu =3D iommu; =20 if (device->iommu->mode->container_path) --=20 2.52.0.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:05:43 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 06DA933E341 for ; Fri, 21 Nov 2025 18:14:53 +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=1763748897; cv=none; b=IElqquYHhq7wLC144SkpbtXwJZLXoM2GGG+Et0SKd5I6PfkYvDkTjEKihTB3nfJes2oRud+QkET7kcnbGFuNBXa7ezv59l/Y6WwQM1CGo0MEDLm+fe7Jm9WuKG4WXmMcgetk4HfFItIJXo08BOaHP4ptFb/LuqN0LjZBSynrcyg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748897; c=relaxed/simple; bh=EWzdxi/6D7uOhC0usSXd/odovIK6k2auEMXfrZlT0D4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=E/MLDefcvZIZjxYtmDklq+P7dAHAm5tzwC2c95qVLGgd8Jiv4zZ1sGfUdNEmuMzzf/iuqrr3H1xywDD/Cqnpm36ObEla0UBO6eMQOOX9W+zOajjN326o95Cvoh08RBVmcGY/sYbQ+XXi5oGQRTQwN9TVJmuWI2RXv71FLiiJM6o= 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=XknTcb0z; 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="XknTcb0z" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7b8ed43cd00so2657959b3a.2 for ; Fri, 21 Nov 2025 10:14:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763748893; x=1764353693; 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=gxoRtWy7HuLenxKtZXNeAeuShCDGWTm4ZnN8F9lAoo4=; b=XknTcb0zqQmWJ09IthNfoNSVq43zP7nMCrsQ5FnG+AB8wVB5dhYE7xk0diORJr4ORZ kACjObXTIKmxdN6M14HpcrMTNb6EmVivSiAs4/VcwXFx/1OS3F4a0fbhuL4UXAW42F4t OjctWeXF8SUZ6q4NMuSRhW/To9c2ffiKZu/fNs6JizdrSENOUofmwOFmUWmQ/ycwpMdA huXEvdyESmZrMv14IuJqls4GRwGXcGxHDedYinQIxbjfOpikPn5kJ49csJjg0msLcl6m IIP1tDUfZuameuqnysjXmJSRzcSp9I8Ut5Ofq15LSc41OaayC6pFnrNXjQC6iwrhbRBV Xmfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763748893; x=1764353693; 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=gxoRtWy7HuLenxKtZXNeAeuShCDGWTm4ZnN8F9lAoo4=; b=ZhTsBiI5p+oSRmCPFSG91ACwbsbpq/6rLfagumd6RvGMWPRwuCHmnPVtUewU69TMgf zr4MfVAmdX8vufUiSFqnuNJM9KA4LBzdlyvM/RiWHj4G8Fu8ejkiSMPk15ky3fzfLpXY j22lFksIrivIAalCl/iOTCBnTBL3TQ5MGOVnB7+yaPti4i7DZOVFV5T2k9oqaop78Fpe VCiHg4A9/VMULiEEDRSIJzu7Vh9ICZWYnfEw1gHF/UDamX1aPAtVESH6SyU2ilxdmZjh s+O9ehkVuRmsupgblFRw6JfNa8hi7jRxMTEWl9Nf/iZsDGEzr1sz3xRy15pDuyN0oGID 1WxQ== X-Forwarded-Encrypted: i=1; AJvYcCX0t840B0O2KhwcUUS/Z5JYtZkqhDyUiGJQprnZuLO43uzEvqAWpEavrtL/PSMYCMd2gsN8xrgeYNCMfck=@vger.kernel.org X-Gm-Message-State: AOJu0YwAO+jJUbRxQRWYJNlMylT04qSc4C+xiqLedXZXMf8xtALVMdtc 243qPbqGoajccUXQgmbUC/4MdL4A4hmhh2HYoDwADeai/6R24ofO7kc3inVuQl8DQz1DslQWQxs +BvZonkLuZ+fPGg== X-Google-Smtp-Source: AGHT+IHQn7qr1/J/V6EApoKUiOvFm+H4aq1OEXxG+wD/Rq1YWwhDHIUSbBCfzvmajb9SiXfW7VESioXVGKGKTw== X-Received: from pfih10.prod.google.com ([2002:a05:6a00:218a:b0:7b9:3791:eaee]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:3d12:b0:7b9:df65:93a9 with SMTP id d2e1a72fcca58-7c58eaf27a7mr3961144b3a.32.1763748892978; Fri, 21 Nov 2025 10:14:52 -0800 (PST) Date: Fri, 21 Nov 2025 18:14:20 +0000 In-Reply-To: <20251121181429.1421717-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: <20251121181429.1421717-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc2.455.g230fcf2819-goog Message-ID: <20251121181429.1421717-10-dmatlack@google.com> Subject: [PATCH v3 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 Signed-off-by: David Matlack Reviewed-by: Raghavendra Rao Ananta --- 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.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:05:43 2025 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (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 0589C355038 for ; Fri, 21 Nov 2025 18:14:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748899; cv=none; b=vDSiA0Jt8WE0gU0DQnVenGLicGDlgDUHNwvfaBslb3vyae0nVQfEEks7juLSNI3UdZ01+gYEJQmG73KNdChwL8QvJXkjTXbiSrNUBxk1JqY+tSU6ts/cX62BNlIBZyJO81A8QQ10zvCEoLpJFej0VGy6C5cRHamj9LZ+ESNOE2o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748899; c=relaxed/simple; bh=5+r9tKht6ww+IqzhMEcI27XtdT+trwXLGUM2y9av5Y4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=K+EGYz1fvSGfXxzqygtVrb3+4ZFjvWFKp3ycPqpQmntXN+/3JKduutqDRc610qRoZBd1GB5xN0Hn5cRppbAnwdl1OeAIEaCp3W6bqAPViJaHS/fYs3IGjiLTtVslG4cWShI1VUuqw/LCMaJ4tiuefbaB0VvJwS+6zaotYHHtnjo= 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=f3DXwxhd; arc=none smtp.client-ip=209.85.216.73 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="f3DXwxhd" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-340c261fb38so4277856a91.0 for ; Fri, 21 Nov 2025 10:14:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763748894; x=1764353694; 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=IcgowuhKD7SZv+r4qHVnhttbmNLzYB67hIpXpmKWxiE=; b=f3DXwxhdJQx9hnQIu4jaQDu7vdSIiQxlJNHE77vORU2JFrwpguuexxgB2rMfFXo6sI Onmg9PUYZOxb96Y6I6gqWY8EJo906t3agQVqnTD4HKNZW+k1UddzgdtAaQvnPMQsphUA kmdRuFKSlNZuo15eqAm49TvGaxv83cHTzLCHqVscYUwfmwbxMzgJyv658LAiVC/MCGhT W+f88loqM+zWufhJApmaXf3KvQbtInnYal+uzeTyTfXtAlSbUY2GA7ETOTz1WVPMeRu/ ASDZSymngCpvFz4A8wfMvx0vXodd2lUorpbKFeZzY86JgzqCqB70ZFotPb9cuwVz94CI eBtA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763748894; x=1764353694; 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=IcgowuhKD7SZv+r4qHVnhttbmNLzYB67hIpXpmKWxiE=; b=fOXnB84Nz6BC4tpwBYlXlfz41vJGoXGLS/9Te62sbPrkNvsYCCiFDOb7FPKYWXlwZ0 sK3VLoxzIZ6u130ricEZwfyG+ghvgVdZmrXR0p1MlqcG+sEtH0kiJV6dX+H9CCNyRJhP HIu9+rffzzAOmGZuRRqElhHAfAm8FoNmrFnLEuJkMucWs/UcDzSuTL4JEVr+hE/w5mnn lqmlqEO6BKQ4nRYJd+XsTQ0JqoLZ9xedcZrcKaQN2yKV5S8OxWdxqterBLGyLg937L/0 epZcX4I8ISLQbPy3UEuBuUCeHycDzEqrwVY4iwNcsXkFk2m7EWAH9EI8TlkAB/V+SbMp VbUQ== X-Forwarded-Encrypted: i=1; AJvYcCWztwldEYuCC9qG1splIRdek/TQ2dgqGl8QJlJSG8wMFowdLWRIgwM9LdbaTdvc5qvRkl1d2yHQ8bvPc/o=@vger.kernel.org X-Gm-Message-State: AOJu0Yzil+r/DwDLtpLrtOaW0lMSzdErz2tZg77uG9riIVoui5d485mF mCQjtGJPR28n/IuRhQb2C2gM2GC/+TPU6RbmY8j2WgNxyzVPagE1C0Fs/mTp6ywPdh131elHFty qILow7eZf5kGB6g== X-Google-Smtp-Source: AGHT+IEZu3uRBpM789cZ5tqcDrIxej0byI6xLLeXvIL6Few5RFNFFv6w4Lq7+JNtnRLkvoly5g85/4CuFDVoRA== X-Received: from pjbsk6.prod.google.com ([2002:a17:90b:2dc6:b0:341:7640:eb1e]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3c01:b0:340:cb39:74cd with SMTP id 98e67ed59e1d1-34733f589e8mr3391916a91.32.1763748894507; Fri, 21 Nov 2025 10:14:54 -0800 (PST) Date: Fri, 21 Nov 2025 18:14:21 +0000 In-Reply-To: <20251121181429.1421717-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: <20251121181429.1421717-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc2.455.g230fcf2819-goog Message-ID: <20251121181429.1421717-11-dmatlack@google.com> Subject: [PATCH v3 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 Signed-off-by: David Matlack Reviewed-by: Raghavendra Rao Ananta --- 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 f3aea724695d..877b145cef63 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.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:05:43 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 C900834F259 for ; Fri, 21 Nov 2025 18:14:58 +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=1763748907; cv=none; b=mksQMux82uup/7mC0HVxLwD6/MLuUZ2tDP9s4f3o7zMJIq7LjEWgqhBX9k4PF97BYiBziglHtY+4m5qElf7AyYXIzCLHIAL/2rNX8Ga+Q0ZB4yS5wrCa4foElNxNNM2lOCeOdRevjGHYeYc/9JPkJHojquZA5MqGNcKS9uBpWIY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748907; c=relaxed/simple; bh=5QWyLHu1phcWI4dhLr8Jv3LrRW7M7BN0y3EZCfr1eDA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=peulreSl6M3tpVnwVUZ1KhF7aUaZlsiJuUNDX/RPKqC7T4aL0WUXl9Em3mVbx6abjEB7vwEfCZLy5WKMBQd6+ifhhqpNoFV1xSvf1bNaWCCvHC59+J62JTWrt8ihA71l8q4TocV1dellz9oV7+tgOt4CQukmt+uO5j+QI+ROT44= 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=rrdxpCZ+; 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="rrdxpCZ+" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7baaf371585so2622723b3a.0 for ; Fri, 21 Nov 2025 10:14:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763748896; x=1764353696; 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=SQv/Eq/kl4rfozPWP7rrCSir/JiYGfabG/viWVLGbWc=; b=rrdxpCZ+Noo0uikJ+a5JR8grp3cZv0u4yoCVq81GYswrhBKBuzNWsimnFD4515RJ3Q yUJ31TonjWqZZlqJFsjbC4jhaOGUdUfq7Cp9bFYn/VmqgzuJFS+kkweXMReOQNls8FDG 6vT0I/aMzdIounpHcZWZ96eGjkpLwPtkMz8U8tHwQTqgLHZg40oTFZfkG4OqtAzZDCQ1 iG75t9tdZIwWcfYhzM7BmtviZiZoqEavqTIIA2XpxOe/JjyzYkbwa3n3iIgeHPMjFa87 AZfSs4PjYTa9fdpOoiKoIwKflgJKSnJUnHdOABFYZNdhvaD3+enLkKO1SaZ2sufSWRFv JiqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763748896; x=1764353696; 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=SQv/Eq/kl4rfozPWP7rrCSir/JiYGfabG/viWVLGbWc=; b=Ku3V/HEZvWpiIzt28ZCYeGLvjfEjaJ3H9teoAjNL9Jp0nuPaSYbCgJVH4oNyV0J2BQ UEY3vDBn9+MrOsnKVFHHh371apn6PqNXA2QbHSHcABT0xxVBJonUNbIjpUE2cWZfDj1u jNm1B5ajVcKfwV3oeQQv6LcsMtjpT/2AZmf9GH+YUp/5TGudpaueyAYmWgKKiBJ2qxAA +ntqmsjD4uCfMMjT6Y+YGlluCrtBuY1285kRmo5CGcaGtey2qXXy86+2WBa3yeFJpUM8 VgK6BDhpPD62ZhT58aKeE36fRW7smEYU8ejmjGLRAMsgkmWRTd5h2TP0tZUqJNmkrKF5 cYVQ== X-Forwarded-Encrypted: i=1; AJvYcCXh0utSlorqgN5z+ZM2ZNvhSr6wEILFZAvd1wefRzoo8gnP0eAn/+dbMqxQoSyyqMajlE3Apsv2xtCzLh8=@vger.kernel.org X-Gm-Message-State: AOJu0YwSkKDgP3OOr/B8B/ksdu0MPBjdv2kiMJNNLY0Ua8lJsNPitXZc l1hHcTwqrYj+PQBJRdhx1fe8uRaTnE0SMsMMDQf1yl3y/wPus8lCGXjniBfKllGNNjNWYL+IUB1 SYVG7N3WbI+l93g== X-Google-Smtp-Source: AGHT+IEBQSrctqMadwDKwnb6XaPASUJRA04EZtDN8SrspND/WSF8x6bzYrdqWet+djZJrRonPHO3J1eDdgmHpw== X-Received: from pfny8.prod.google.com ([2002:aa7:8548:0:b0:7ae:309d:349]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:12c3:b0:35e:5055:1ec with SMTP id adf61e73a8af0-3614f4b1871mr4338135637.17.1763748896129; Fri, 21 Nov 2025 10:14:56 -0800 (PST) Date: Fri, 21 Nov 2025 18:14:22 +0000 In-Reply-To: <20251121181429.1421717-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: <20251121181429.1421717-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc2.455.g230fcf2819-goog Message-ID: <20251121181429.1421717-12-dmatlack@google.com> Subject: [PATCH v3 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 Signed-off-by: David Matlack Reviewed-by: Raghavendra Rao Ananta --- .../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 877b145cef63..5e0de10df04e 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; @@ -879,16 +447,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.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:05:43 2025 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (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 6BF70351FDE for ; Fri, 21 Nov 2025 18:15:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748908; cv=none; b=o+7ZIt/+9xh2yW6GlQsiDqfiW3h0D1tWL962jSIl5WII2K9ZvJfK7tjXInP+le8JPuTDJ1cD4LDsBO/t8NFKnernY2fP52+tDGSV0b8PbigOvhVAKO1kDDcI78DidcJPyzIXACrKKxw1EzC4PnhKwlAQO4tdzB9isWfaEZt8PMA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748908; c=relaxed/simple; bh=KYSZvwIYuGqWONSGyW/cf+OrbkOd5CohW/aJh2gqPA4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=a1dkCFKnWoJiESMd3lwBGm46igYlHYJrfRcxyGFJg/dYanVDKzNEb4QJfSyp+r69+ZKnBCde0UtQxh8W0dDtRvwF/Tnuml8VbxUuphuLr4F+W+96GAFdJWmu6uulUvdJHY/fII4OLQNwJz+rCpKfJC82FbTu1Khd5LuGpNexaxk= 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=TVM8pyJe; arc=none smtp.client-ip=209.85.216.73 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="TVM8pyJe" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-340ad9349b3so4822940a91.1 for ; Fri, 21 Nov 2025 10:15:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763748898; x=1764353698; 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=P6NpR6v3M9pBWa8mqzX9JiTE9lvDMmHIPBrLIUR3fl0=; b=TVM8pyJeWP4jICSK4W32NS0AZtf/rlYi1R944/LImVOYN1UKdxAxCuEEmbWhH6drrN IeFHqPLqnsz5wKzqczhNWlmWI4kRsGg1SeGJQ+8q5WlsYOYsA+EoHDZoWrFd68xzn/bh Nt6JcCqWWTcQin8jNVC9+nCtfgX5MXx1PE2rOSMaw34z7IaOvHOxOGneGsbRDDaBsIMJ aHtfuoXDZf1DzKdldMcRtCopaAntTbRreuP/4Q3zAN6fxLl2vcMyuQLD/ZH2ibrKFAFf 6muyXnPCw2+wIRSpBAnj4KMUWk2TBd3F69Gnl+KWF+cH1CH31EnzOXzfI/VFmPcY+jJ7 5Asw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763748898; x=1764353698; 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=P6NpR6v3M9pBWa8mqzX9JiTE9lvDMmHIPBrLIUR3fl0=; b=hHFqKs19qfFsmecPY5v1rrqKQCKp1GvIeDXmKIodl1of9GnkjYzQgSpolaGEvxoChq 6CD7tMcIOa3WYVcva9e5Br5lbaD7XM8LbaSFtoUEFj2zWx6JyaJWgVOP6yX5rNL1Lsj6 ANd7xnaoxxPstIS2dPIk82vVs21+fzGZAOZGbT5GfHPZ5tsflBMVMlelT5KtkZd0M2sx zk/Aje180FlF2kbCT48WofF72XoIk8McE6rg4U2f3cHLBvGTDiWbT8JqZYWuu72cE6rQ Ao9YgumbQVl8cwwOKyg0v8LDtRBr/DxSFmHDkKnL/H7aDmDa6VwbW1CkF6DzeD3VZ3bz WL6g== X-Forwarded-Encrypted: i=1; AJvYcCVpr+e9uXC4YPTQJid32NLJ712VcpCme/qWkjHhhyMV+FgbUOe9YLvnu0ybzhCCc4MNK9qvzNRs+l4+h+g=@vger.kernel.org X-Gm-Message-State: AOJu0Yyk1T63SnXlOsuKhaYmw117hnjOktPtI8x7EtwU/Z137t6yFmzB uX0tCLmlgTrA/Y1wH1PUJ0W2802vJF5Ah3si3IE6OxrVYJ5JU0ELwfaTkV3H67bR77APGBmM8+m Zf5ZytbXOP+Y3YA== X-Google-Smtp-Source: AGHT+IGaxmIgScgBNXnSMh0Y/1HTLLgh3WxboedX5JBI9DISIv1p1rfPRqF9Eq05K/1531C61+/6sE2AMWZStw== X-Received: from pfee15.prod.google.com ([2002:a05:6a00:bc8f:b0:7a3:23d4:f5f9]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:9186:b0:350:1a0e:7fc5 with SMTP id adf61e73a8af0-3614eeb0d8emr4019398637.60.1763748898201; Fri, 21 Nov 2025 10:14:58 -0800 (PST) Date: Fri, 21 Nov 2025 18:14:23 +0000 In-Reply-To: <20251121181429.1421717-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: <20251121181429.1421717-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc2.455.g230fcf2819-goog Message-ID: <20251121181429.1421717-13-dmatlack@google.com> Subject: [PATCH v3 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 Signed-off-by: David Matlack Reviewed-by: Raghavendra Rao Ananta --- .../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 5e0de10df04e..a59c86797897 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.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:05:43 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 0999D275861 for ; Fri, 21 Nov 2025 18:15:01 +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=1763748908; cv=none; b=niCq0vSuLHG6MgfPO4gW7W4Ug3h4eNlqo3RY4LJmTLgchHf32YulQ2/u3KVIA7R8FKY3921/z6JbA3RlLGO//Ii1Aa5hU9QBKnj0RPNbePDVYGzDVYp5vXO6L3/U1LFwVrSDeqV1Z54mUbPm6mkp44p70CRiflWQ2u5VVzoSCk4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748908; c=relaxed/simple; bh=Yprpg142+hgqCGbDmnXILCasHIgMClt/HSupou46ano=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=UFPI69v6rp8CiJm+nS9yzitilkxgbxNgzAIxhW7snSNB27yul70VbdTJ5Aei3ID8kufG2QVI9kEwLbOt35by2bUdZQUKUXw+/R9BTBagRbiIaeLsEyr6FYoVQR/T4OcDrv7QBQRrsn8m3ygAFNBwUke8EZTe6ZMpOlVJ+3LD9Uw= 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=La3pYyVK; 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="La3pYyVK" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-299d221b749so62296905ad.3 for ; Fri, 21 Nov 2025 10:15:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763748900; x=1764353700; 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=fX+LIkvch8B4mDhFv2H89PyCx2HInX0x3VrD2k2o7zM=; b=La3pYyVKveqPcblV+9EZmqeKzfGtKGLyBUjL/4z6rOetCG8+JC9etHVqHbXJ78oMPr 8FIfBXAiHcBZphtKlx7kRrW6cqBhNNJVcmIhN8B+gUBK3rbej2G7gy+IlrYrsCVfzgVk sJyjN/CCrnwv6+Gy4zSBxGOg8/mIYMeltzVwpJ+SL93UfAjFl4M8+sf21jo8epckRO7b oPSVnWKzYLL+QCKkehWFWnUBVSxWILsU0QcsW0RCvYiMWJ5m05VeZnBXiQW8ZJwvbcdz vKGL9PvPVy8UrcoFvTqJbagmnhtMTGHzFq5b9T25tHLB45HWQBDzo8yt1w8jNrwKPlxA 2buw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763748900; x=1764353700; 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=fX+LIkvch8B4mDhFv2H89PyCx2HInX0x3VrD2k2o7zM=; b=ZG/bXkdj75p5WC8gv1wOZlvdi6HYJRFDdRC/lTfKIX7uDvxTpIB1JsuBb9GkHUq2PI FQbdisxeLINru+X4JB2u5hcBDCl5aasaNZU+HVYRSHC+QAiG0dN4Csey9M57T62r3Xp1 TH9O1vbglEtgtiU7pApFWPL3Lm5p2rRw95cybKuc0zwxq7eG7UCR0eKNvkFzC9lOHKb+ ZI2s/6KJ/xKJJWQQ825xRwqF4pFVnOAwhHlajFnygMDGua3X3jz9tesRuVpuDJGGPaNh OSygTUaSsUa5+ganivLIO+k0JUMRCsflPeYT+K1k5FwQB1hJE8Ru6cT+ABMKz6NL9RPb W10g== X-Forwarded-Encrypted: i=1; AJvYcCXLqj1CF9LvTDUs9m+HOi7UfzNIz6QRekXzhDvWchX8dQYsIEJAgGuA8e6eEmIcvAtIWcWkMhxIGOUI1YQ=@vger.kernel.org X-Gm-Message-State: AOJu0Yx4VZyQwensuIcCFe7iIN7VcbBTidE1xMjTx4fARiKjHH0jKWIi aq8Q/nAMOjTTNdb7MiDGxXtM1eYSjE1ZoDEnKalmqruFhy7MatTMHO4j6qQe3rKB0kAY1YJHB3A LG45RRP6DEJPbbw== X-Google-Smtp-Source: AGHT+IEFlzr2Td3psN+QJgedrluhlVDDDTHozKIhSTplt1gl924EQ0xmzvjfDA6b402qfqYTaUsYtgj1UeAT2A== X-Received: from plbjx13.prod.google.com ([2002:a17:903:138d:b0:298:60f:680f]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:2ad0:b0:295:4d97:84dd with SMTP id d9443c01a7336-29b6c6b87d3mr39046725ad.51.1763748899917; Fri, 21 Nov 2025 10:14:59 -0800 (PST) Date: Fri, 21 Nov 2025 18:14:24 +0000 In-Reply-To: <20251121181429.1421717-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: <20251121181429.1421717-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc2.455.g230fcf2819-goog Message-ID: <20251121181429.1421717-14-dmatlack@google.com> Subject: [PATCH v3 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 Signed-off-by: David Matlack Reviewed-by: Raghavendra Rao Ananta --- .../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.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:05:43 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 49887351FB5 for ; Fri, 21 Nov 2025 18:15:04 +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=1763748911; cv=none; b=mgYRZF54tuVnzJLY1572MhGSvT8oPkteoXPm37r8JxzD2OgnXyijF0jsnP6CgTeIHR8kYOnsEB7HAKvf0pi9B4x8ndvr43ThSJiDBd/Kihj5ROkmg3pWFUt/2+mAWbwuWDb6e6ttxL4aP8dzm1P22rNzF++TJPAh0cztWYj10Xc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748911; c=relaxed/simple; bh=84mHi93ZLQ9k4F8REV9zDyggwTKGzmB23eWY4/3qtAM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=HRpZQUfdx/hsBD1r8VkINVpKjzVkGfuLHDFaPdv4bNgdYxNuI/VQtkEmtSh6UXQryip9MApIBmGN5DOvVsHKLSipYyS6gqelB+weawYpGvFL8Qw1qi+4tACEenj67/cgoF8V1fPpZAp9CXTcVE2bNioxutDZsDJ/it2S8ilqi9M= 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=xtP5+IVV; 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="xtP5+IVV" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7bf5cdef41dso5562467b3a.0 for ; Fri, 21 Nov 2025 10:15:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763748901; x=1764353701; 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=khWHJ2LqkboVnevDsr7KLbtVmUyuMR4Ct+IijuBDu4o=; b=xtP5+IVVpdNDAyHiwxVw803PsID3UCtDllsEK/sn8WGpUciofoaiJi9e36waHFPg19 NCJdQBW3aR5fQ1YS8tn0V/eXQ61n5WO/AuQJ8AY7+ViXlhgQyXuv+d/r/NOe/vEzvmA3 wyOhiZdSU8xtcE50ULDWXfOSEQvpL4uthntDjNHDqp63u6zKbVp/FIA867+I/l4o8eU9 Es3+06b4PNJXmAUAk6Bz/fYcsNVTrpaU/9ImfQEYeFcr6y4AIGML1CZn1H9R4PKpmseY vMPDfQkD5kfEvb2SaXNjMv45nK9m4wT2xKFthc53025Mlr/P/u2807Op39M1w/iOi6GT mt4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763748901; x=1764353701; 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=khWHJ2LqkboVnevDsr7KLbtVmUyuMR4Ct+IijuBDu4o=; b=abieTivRvPtcIc6KxCdcoUuahMgqjQYzsIulq62QmNjKoQ6E7tvBQcCk9Bq3hY0sOC pK84FumDp1m4gbx0SaagHLMbtyTFzIaWMOoWRHQ97teP0UpBsvahurmZUaswLL8mS6Oa HWEBPSqLlrzXuBR6/XsF8DvXCz0D+ufRRQPiMa/OUW+yJ2CW6BDBKlyoxVlrdx44XaRu JE9QVaL8r9FMqQJpPWjVAW/oqBFX9vLpwNMb2wZpVPlqYZBPRxlMYVGyEYsU6Uygz5Ja t481h93BazP+6Kay+1XgKv4vGvao6JYwWZhnQnMJPvKpSrABe7mbB/RKKLm9OCPJkBI2 fHmQ== X-Forwarded-Encrypted: i=1; AJvYcCXK4QvHRPiqY6bAz1Sx0FIZlSFnC8EiDX7weefxHgScZzcUzmFwKKii3zE6CauWHy1VyJvKKRJzG01T+fo=@vger.kernel.org X-Gm-Message-State: AOJu0YxCrk/wGDyyHNphg5gyBN+zOiD9kz5hyRHgq16RrNp7VQANzyqI n+9Q2us9+ukU/5J2QUxZYmqBPYY/g++eI8kY6lZDTAKNHXXSdUcxwsqSpx4uhNdPQ49UbLsg3fo FQ0A0RecPNuHbbw== X-Google-Smtp-Source: AGHT+IE/sHqE5MkpF8u8+JSG/iUFG5dj9YeY9VIe7VGm8jPm/U4UHClcjsJ7KBiMY42D4TImrYBUs9DQx8sl0Q== X-Received: from pfvb14.prod.google.com ([2002:a05:6a00:cce:b0:76b:f0d4:ac71]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:a17:b0:77f:2efb:11d5 with SMTP id d2e1a72fcca58-7c58c2ac1bdmr3705759b3a.1.1763748901475; Fri, 21 Nov 2025 10:15:01 -0800 (PST) Date: Fri, 21 Nov 2025 18:14:25 +0000 In-Reply-To: <20251121181429.1421717-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: <20251121181429.1421717-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc2.455.g230fcf2819-goog Message-ID: <20251121181429.1421717-15-dmatlack@google.com> Subject: [PATCH v3 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 Signed-off-by: David Matlack Reviewed-by: Raghavendra Rao Ananta --- 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 a59c86797897..282c14bbdd00 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.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:05:43 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 25EFC2BD5AF for ; Fri, 21 Nov 2025 18:15: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=1763748913; cv=none; b=rIdeRnIyfYAtVD8zF7PK/OPEGuRtAQuplyXOJrUaD0e0roqc++NJmG/oUO+nz25YX2L/GxfVcD5KCyHvzhKkh1u2o8hQKWMZYUXoQF7QIdnFB0Elbq2OheXnB2QzLpxpgU0UJmPx62Q+lmB0gO7usR5L+nDuSjBLLFT38BbCbq0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748913; c=relaxed/simple; bh=O7FYcy0EeK57NXbNCjSJSiTya2snlbNOBcj/IqOunN8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=lmetoPOoTaZBcgsXW5p5g28fPVTXKyUvYpcYccnDYRFiWbstLFgkISAzMnT8t5Or4A14HI6MOqB6RrEQdvLH+Vh2bffwoSjTiLYTGfrnEv7NDyV9knmGzdcaAzRC3JlMY/EByiq1EFyMmQe2Gn0s4iibQJgyFUTY+cBs0KfHdWs= 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=dL5YZ3x5; 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="dL5YZ3x5" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7b9090d9f2eso5199823b3a.0 for ; Fri, 21 Nov 2025 10:15:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763748903; x=1764353703; 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=HMEvwC8Vf1hNFRxW8gMqcv6dRhd2ZJX53eGoUogab78=; b=dL5YZ3x5rJRYegUxbWX/nxb2oyMvi0fp3/rKuqUhWCZ8CPGeCi6+IfyIIC1X4oQq4s 6Xxt4nSAdlpfItG2g3S3Nl1FvOgng522tMCUuJPr7CdQMFs56rXQ8xNPPqXc58l0VBHC a92rhVZd6t9uOTrY3dR8TOwCU+SaAcdEshHerd1zNrF9ikGIfK333nPwfmPAzrHzKW67 nNBlq+xNHz8fB0XtZAARLY8JqukfidKS4zDPOoFRS/mRgrwrYRlQOJBZ4ouxQ6A6ecTX QNMRzeKm3NNdjLfuFBU1PAZ0rFH+YpqjrhqNAIgtPCY++wlFw0hn7XN46ouxg/vr8pgx rd7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763748903; x=1764353703; 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=HMEvwC8Vf1hNFRxW8gMqcv6dRhd2ZJX53eGoUogab78=; b=qLdKdh1ikgyX/urGpg7VEv2r7VnYYGI7fAI3fxfntI8/eQu62itZ7It4iYjMhPDujN HPDBsx/fegLIefc3aUN8MC/TxO40P91QAMda9WqApiVgTxZYqIw18FXk4w2bW5c3R0J+ VggivQm2BtGYytXI0cau26BdAp3TulWPnBlcFY3jKllueQfyQeayZIM6JysdfxnOPU2d jtgtj+OkC5frXUvy6LP34Y1tDc7STmmj+yodsu30liWWUrLKpN2hqPWqT6afIEc6Z30x n2454xbMC8S+LfPZnAgMH3/dtjaR8ggZYDD8weXXXxsmGniv4cQ5sgnj1K0ayimQvPDI wl+w== X-Forwarded-Encrypted: i=1; AJvYcCXTMrNgtz+zpuXxGYAYeQYC+GH+0C4uk3EY/C58ctRhj1BHncrnJRdopPCcD6EdDhqDn33LbmsEaJLwzwU=@vger.kernel.org X-Gm-Message-State: AOJu0Yxu/LXNw5Tt8tIX8ZW/vSPExfGg0NtezYt/Cf6PdFA2nU/AYlGJ HHw145gneX6btgqVnlOqPLxqqdqWERQAyO2mXD3COV7bqzPrbAmlhH39Rj9K9+v8ME0NYF4QVQl kKWsc8F4f4XAGpw== X-Google-Smtp-Source: AGHT+IFvGRUxxpn2Waw2LILGulaRH1HRzh6C//LRS6tJE+9Uj9HoAkeqFoZldrevGeeOCMb1cfx3h1lq8sEcdg== X-Received: from pfny8.prod.google.com ([2002:aa7:8548:0:b0:7ae:309d:349]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:bd13:b0:7b8:d791:2609 with SMTP id d2e1a72fcca58-7c58eff684emr3209161b3a.30.1763748903016; Fri, 21 Nov 2025 10:15:03 -0800 (PST) Date: Fri, 21 Nov 2025 18:14:26 +0000 In-Reply-To: <20251121181429.1421717-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: <20251121181429.1421717-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc2.455.g230fcf2819-goog Message-ID: <20251121181429.1421717-16-dmatlack@google.com> Subject: [PATCH v3 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 Signed-off-by: David Matlack Reviewed-by: Raghavendra Rao Ananta --- 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 282c14bbdd00..3c21f48907b9 100644 --- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c +++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c @@ -375,74 +375,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.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:05:43 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 59FD2351FD1 for ; Fri, 21 Nov 2025 18:15:09 +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=1763748920; cv=none; b=dadTegc8uBBHP7bWv/44jnVYKXFCcpe0bRPdv7ZIGXAJlNEbT1x70qUaRhxcZPSwVZz/Uvl5eb02wLZcK90cB0/2/4Mky/m3HtSSnqPd8zyq+hjotb1MvhTYnYEYX5/ijeTgcTRHekCu+xIqT1mXLk8ErYzlqDQNfCVB4TSMW3U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748920; c=relaxed/simple; bh=TGjtUTqdDntJr3iKr+orwvc0QceXsxTt4wF4dG0SkUw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=BNuVzmXJFyzX2LHka26Knro7wNO2X0BTvl1/dZk6zLc8Hl7+prJSsvQUKQi0EPWuIPZVcILTgULqzZTZHj4GnjvJvs+71mj7aAOzt62+Xr8zHsZiKB/3VZU7RXhpjDSAIlqyJPb4r0ogmUnax51C7O+ny2B+FabU2ptsUmqpTpk= 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=hnfRPbCT; 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="hnfRPbCT" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7bf15b82042so3333378b3a.1 for ; Fri, 21 Nov 2025 10:15:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763748905; x=1764353705; 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=DxOjRq22K00nQGidhUGv/i8d5k46zBqJBpuTzvz60PI=; b=hnfRPbCTDVvlHzorSzh1B0eon5+vp5xGFCLdVBrfdRM3LbLTcTHEAPVrGL7S1g8DYD sJ60RuGIWjo9MrSBON5qk5JTVfAIocuaQGMIzXT3K+AfjxHpXKySuFvPXGH6M4RoKP80 Fps4kOEL4EBZW3WzoxfUCEywqj4oSfBXoTJnlcQsrTLMsBYEXzahO+sX4GvNC+Egl8m2 MB+edohpLPKAv8gXdcD7SVlOW0dh0JqxhAR+7KfbipglNZ1ih2vuBq6RhhG3FAw+O3aW TCoPCBJcDhnglP1ucDR5crO4gBI2h/vJIGLOc0nkxwlqtOAaDVqvOMHO2jTm1BEn/2A8 d/kQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763748905; x=1764353705; 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=DxOjRq22K00nQGidhUGv/i8d5k46zBqJBpuTzvz60PI=; b=uqoT3ROibSxXsxFHWE0DkySZixQi7ykX1sh2GnuUrL5hdJjzPbgpeL2/DpR48kPnxZ hL9tyWn7K6DvtQPex03Q5uHBOWB3NKEcTKpRsC5xuT+wxYbrhL0c75+XMhIgnANLGV5M HzdxQ7uTVWmuPr6Tl52Y29o1/Mb6s5o02tFDgDjrT9364SOqbYOQ4cL+7nlrBSHbJ0uP C85SeOhTputXTFvtthbtmhWa2OCG1Q1NUJ+MKiZvcVVaY5PqYpVbooMweDfBUPKF//q8 7wdu1H3fG3G/ip7KsbMfRmiQbmEIwuzqJacaurLPkvb32fdhLaJOxQic49S94F938wgf 8S9w== X-Forwarded-Encrypted: i=1; AJvYcCVgjQnp3Uy3x38L7/ru6uWQ8ekfFjg1GgwTyM+5GZuPc0tArKQSocEKj0s1lT+Mi1EUMA1XMbzMw1Awt94=@vger.kernel.org X-Gm-Message-State: AOJu0YxhguGJ03lQJqvIvLdjySo+Lo6xVFEFILvEmL4ghWNG6BCIYxfp vZnhEhnFqtNof4MHIyBcy0eNznwb4gK+c+pus44GzYCi8jwW6+GRZrNYsDXO1ax/eL4oAJwKgDS 14zffjw0Mnh4n6g== X-Google-Smtp-Source: AGHT+IEhDRhTqmY3fA1ABrRO7RnR/STFok+Btejj7wY602MlAzdJ/WiDpkdp2smRdX+mdb2nsNwkB0Gqw/odOw== X-Received: from pfbgl1.prod.google.com ([2002:a05:6a00:84c1:b0:7b0:e3d3:f045]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:1481:b0:781:16de:cc1a with SMTP id d2e1a72fcca58-7c58eb01a72mr4025315b3a.32.1763748904682; Fri, 21 Nov 2025 10:15:04 -0800 (PST) Date: Fri, 21 Nov 2025 18:14:27 +0000 In-Reply-To: <20251121181429.1421717-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: <20251121181429.1421717-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc2.455.g230fcf2819-goog Message-ID: <20251121181429.1421717-17-dmatlack@google.com> Subject: [PATCH v3 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 Signed-off-by: David Matlack Reviewed-by: Raghavendra Rao Ananta --- .../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.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:05:43 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 1DCEF34DCD8 for ; Fri, 21 Nov 2025 18:15:10 +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=1763748916; cv=none; b=C+az5+xtZZ6AgNe7IyNxPafeewVpWCcoBdU5B8OZryYD5zXBxm1vzpVGeQceIXgF2HRXhKsnK5s026lCro280rjUXLh2T9UdJGYGyjaMHYQUJEsNYtglDDd3HQUJ2ubsS6CXZS4W8bkuspgv8RNJNIlM/xUjLQnddro4AUC4GKc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748916; c=relaxed/simple; bh=y9f/Tucry1hsY9LeYUBKujhZ6OwShFYUbS5Y4yU0CCw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Ks3j4z8t6hID5yHedrSfudZULlengUFM/BRcidzPk13LHxa6DMoLriaf58IQbCA58LMomw6nDDpHCes4R+h23+3ZKFpLdI+hfRkN0Ul7VqjrcbKuJJb6U5XZNMEQkAQED3LOVTfEBG+UjB5IEWFpLsaL1W7Vv6sh94n1+s7TTZY= 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=s0BiZf0V; 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="s0BiZf0V" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7c1df71b076so5238873b3a.0 for ; Fri, 21 Nov 2025 10:15:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763748906; x=1764353706; 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=aImDlLkdwi5IFhoPbJDPVG9tN+ymVEKJWl0wF/tcJUA=; b=s0BiZf0VvQIDR1SMSXYDNGd0YEXEc1wZsGzkBk6Rc5zyxmHsPjK82WOKHklE295GKB cYdiObuaUwRg3dmpAJMMuC+0GGX1rjShr9VbeL12pR7oDXqsiqU2bzcmg1t09X9mgFx0 HDm5f2ZCZSdEAazzT2KWBF4SSO+bQyrzbQ4qjxql/1DctV5xVwnNHCP0Z+Az9IAshNYh ICadutOgYkiuSuXj9Tm9zZmfZ/cjI+qzfP4XlvENNBmYCbBP/DDcmNojZ6z9Tup+35Si mMP+TzkHge6TZGm8oB3+HRWVhi35YZhvVTsK4ej9EV3O9FdVvnfk7nocfJ7krcfp1xxa nntA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763748906; x=1764353706; 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=aImDlLkdwi5IFhoPbJDPVG9tN+ymVEKJWl0wF/tcJUA=; b=OdWkECSbtlMa1tL+IncK5ZS6etaiVUddKwlutiD764NuzgASuY2rXIzZPfsNis8bBE 9EtFS66AX386TyztgpWFVzZptpXgNI0LSutYDN3s3XG1uCqWbD0vTLVAw6NiO3X6bAGL NShY/9A/nnaQVxV8rddFwcbGE2arZXjNmOLOgIiti9GpCulSCh/g0CCiHhnqnfPuE9LS Yex4Nv6U5FZ4Lm/dLYGabYYZujW5n/WtHz93W6JHjKFkZtzumuovHZTsVZSOfIHnj0RU Hzph7SjnUB6ZTc41Sn47CP6Tgeh4Qyzk35bgGVHO6sXZOxuvvh1O7QhMocvV6y6SUkSG a0eQ== X-Forwarded-Encrypted: i=1; AJvYcCWZZW2GSE0zugpbDlEEO0MO0BwsBPigb6msHr5TMa61ye0e4XFO4FbbNYDHhMIlKBd8tcU33EiFSpxLk6Q=@vger.kernel.org X-Gm-Message-State: AOJu0YwKpnV+rSrFZker4vQh9Q3oJ4TBhQSsYHUztYoT8kSnA7e8sXEK hDHd/2rFgBDS3lIebeSHkD/jRK160iH5bObmLod6yRp3YoJryPrf5NoY97wnGcc5xU/LHiT+Za8 Qk3F4Zf3sZ48lMw== X-Google-Smtp-Source: AGHT+IGZPynVuiLCHAiwBzSdaJErjcxqKMyzgzkXeH80cyVu6Qu3tMgiXJPN+ZnWokCbF5gwN+sv9QgUKOEVQg== X-Received: from pfbdo11.prod.google.com ([2002:a05:6a00:4a0b:b0:7b8:282e:c971]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:8d4:b0:7b8:ac7f:5968 with SMTP id d2e1a72fcca58-7c58e601f29mr3822571b3a.24.1763748906161; Fri, 21 Nov 2025 10:15:06 -0800 (PST) Date: Fri, 21 Nov 2025 18:14:28 +0000 In-Reply-To: <20251121181429.1421717-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: <20251121181429.1421717-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc2.455.g230fcf2819-goog Message-ID: <20251121181429.1421717-18-dmatlack@google.com> Subject: [PATCH v3 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 Signed-off-by: David Matlack Reviewed-by: Raghavendra Rao Ananta --- .../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.rc2.455.g230fcf2819-goog From nobody Tue Dec 2 01:05:43 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 E0E6B35292D for ; Fri, 21 Nov 2025 18:15:11 +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=1763748918; cv=none; b=JfbDTgtlDzoQyHzM8WqlWxMX39JimsUUG+4jNV/m5O8Q9PBuBsRN35fELC6XLFiETCuO/6U708PvR9ZFrwmknTnjyZy5Cu+z2gyrwQUM9a4NPw4O7au6jjHs+XMLA/HcLCxRmolBmQQVctoyH0QyrFIqbfNR23ey/hLhD5wswNE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763748918; c=relaxed/simple; bh=V4XHkK2bSnle1Y5wrDA53Bn139W3GGAfW+sVzBMJc/0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=K6f/8BhQrInOz2BLGshCUBiABZJ3QRNA2LopwbP6RXa20/HMpRU1/oGyvMDll88J7T5ElJ1uxx1V32CCkSykupY08938DBPh0IotGnMXz0RrAUmv0GH4QuOgKBxpOADCHOfotyuem/GnAsEYDtWOm9SERuUY1nLUkIm5HjPloQ8= 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=wTSa69fP; 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="wTSa69fP" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7a26485fc5dso2606028b3a.1 for ; Fri, 21 Nov 2025 10:15:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763748908; x=1764353708; 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=KIDNOWnsgB1X5ZTZsV4DAfAahClNoqJ8rtNtSZXbxtQ=; b=wTSa69fPQcFoELvvGYNW5TH3Jn9BlJTVeM7yeJDUDoGCXy6re/tLfJX2ohlgW44wVv bZiCAQ5RsOWTf+nk7Es1+DzTW+eJ6iU3MR1BxmIsP052U/sbSDzBOfje44e+X2hWkoGA JElTpZ9DqeMuUb7LONr5LsMWhp2mKdAkgVswdeBIWwjk1ioHqKbDNzMnmu3vrwd+beHk iPiyuWbVAgZ5Ieiu7v4NpdUsLNj9MISCFUC13AFDLHuqJolaMWXic/xFx9k3eMuZNHw5 oyTtJxti7dyiVmR63Y4TbXWlHGQowRS5GjRsNw10fLOFILB5eiH0cIRLffoq2ruKYO5K 9f+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763748908; x=1764353708; 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=KIDNOWnsgB1X5ZTZsV4DAfAahClNoqJ8rtNtSZXbxtQ=; b=oSj72nlm04t9IoirLKl9XGKHVzzBytIRdf7thzWtomlYHe/33CrnhurjbLh0P54sNL FmcqZ3Rp72Xvn9uhuE1cI+Z6ygcOss8vKu0c4dPn9e5BltUptrPdzY0D2tHk37OQFscb qNre3XcEbRecgn8Nl522Qaayy9KcRmLBDyslVPgioReuBNOuCVpQkRyh+G2QobBARCpT oMQdZLYJmC5VZP7ILNtTKdqgJOCq0pZgpcCorWLjnVYBvSwnV6T5yxSLMR+s6sa2Cjvx O1F1vTuUUPm0VU3oBJYocjRFwHQeX6+QTNFrU4MT0fy5uXJ5WyfSVKcJr03i8alqviFn qy2g== X-Forwarded-Encrypted: i=1; AJvYcCVvAC5fLGmCzy/ExPDS0Bz4JzcC6FEBdriUqn76260JIEEa+YP3Lr4JNM4pb9IuGPoC5N0SMc9yL8Kxoz0=@vger.kernel.org X-Gm-Message-State: AOJu0Yw4fkBnIjchf51i+o9RRWqlt8Pq1NMHMsSsnKYxpeG9ubcKeb98 ozELfxGF38HcVeWlbZKCyb6s5Ro4OF2cGSZZPJQ7ImcyIySp/3tRLoIel+dTngzeARrUNJta2Gs iODXq52MxTQ8aJw== X-Google-Smtp-Source: AGHT+IFABZs2Jd9R21UXKx2w697+04kRhbUwH2OPtMS6DriemwA5x++r3VjbrjQss9CLbo2vlwmU9jy3U7BxjA== X-Received: from pfwz18.prod.google.com ([2002:a05:6a00:1d92:b0:781:1659:e630]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:aa7:8895:0:b0:7bb:272d:a4a9 with SMTP id d2e1a72fcca58-7c58c2b185cmr3896167b3a.1.1763748907629; Fri, 21 Nov 2025 10:15:07 -0800 (PST) Date: Fri, 21 Nov 2025 18:14:29 +0000 In-Reply-To: <20251121181429.1421717-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: <20251121181429.1421717-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc2.455.g230fcf2819-goog Message-ID: <20251121181429.1421717-19-dmatlack@google.com> Subject: [PATCH v3 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 Signed-off-by: David Matlack Reviewed-by: Raghavendra Rao Ananta --- 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.rc2.455.g230fcf2819-goog