From nobody Sat Feb 7 18:20:49 2026 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 47846337BA6 for ; Wed, 12 Nov 2025 19:22:46 +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=1762975367; cv=none; b=fkVlwyf96y5doeaaAMGfuhtlehjNKCJwzzogURzPvj8Btzo7r6obdctdX8344qVooWB8tgRD8daYvxlZnovGn/7xPpZ3nMngrY/b6xqj/6GgIxZ4XKx8taChudclEr7r7dH8V/OgBhOM4gHikdqNWmO1jhlKlWEyiuyJIq1dOrs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975367; c=relaxed/simple; bh=kHKKv2ke2cj+MGan48Gu3BEFyapAdjSg49umcHRC9vA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=EBbr8S8gJh7sdrUEqGm/IhVxEfDgVQviR6yAVlmt+FEh+SHyV3SwDBSEwlMy69cfn5fGpglhL0w8lGAdFsm4TU9qcnl9UCEU3Y6pCLWDay//TjjDUB4QoTk/b14jgH3gxAhOXrsXTfzKipsZh8N1aRnE/mypYLWEA4igJYfy1lM= 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=1+npGwQ3; 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="1+npGwQ3" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7b89ee2c1a4so480467b3a.2 for ; Wed, 12 Nov 2025 11:22:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762975366; x=1763580166; 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=TielaAcMwqrNYs1v2uchxf5jnX6Kggt/DIe0BV32lMw=; b=1+npGwQ39fbkIxeyi70rwjdIW6YuVJ/TvnGB2ZvWcqDloF97am3ND3zhD6X4n846ts ES6MRkQ6f6cfRGjT9Wqxrv/LrzqonTqCDcvFIJsgjN29Ybj46+3lzOX4C96fcFjbSza7 zZogztmU2ZiC+qbS/2LhNdOxqcio6Q0FX+F0oLaIKCQL83UO4IfoutkAV0A0mpHPl5N+ cSviXL7PcbLY0A3LckD7UNul+lFiNha44Gw45LfhcC+jCcbIrlTmHQTz5vXVjArWk+r2 4/K/v93juaGbhbWnABn32ftnRAFTEXLIZzg0bOECh13hvFiT9JVAuovufefQTBPvwbHx w05w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762975366; x=1763580166; 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=TielaAcMwqrNYs1v2uchxf5jnX6Kggt/DIe0BV32lMw=; b=X73HdFkDveWSh2vkRbXwLZ3OCEBSICAn5oJ9rI6l39e3rEakmtEQMmhTFknszntryI vGGh6C3IxlMjuQ8x7OIamUbfMRkb1g4L3T9Bde2/9MwguwBQ9yasxz7T4i7jhQ4SHBEq WU856Lu0JzIiyn5J8rMzQVGrV2UN/fdTjXScYg/9h+hSXeqmaQSuvaQLjzfSPtimDB25 w3hAmul4SvddrTAyvMKW1bZg2M4FE0RIVM7hcRuajCEFyAhE842Qu+jkQaiaP27psjQW +97HwumSJfF9aMPY/3LJl1GFSawWhiMeg1ZZXT8UvK+ryJvyCIxhXR4Dn/PAFuoYmYd8 Tqeg== X-Forwarded-Encrypted: i=1; AJvYcCWHjwJTdIk4pBM0oiGJnrtoT2AlA3K+j6W/IW3D9z2ZLRmwKlrlbdfc58nJ6QH1MMT03TcKkSqAFkPbY4U=@vger.kernel.org X-Gm-Message-State: AOJu0Yye2RjxIWG22+LKjX7YzI/YxRgJBCORykeL+r+bkio6OlY+ixzC GVXGqPYKWD9G93UZoLd+3zyXkvtOowYXKirc3NaHmgpS6eis2iEasfSFYfwl3AThyaqgAwcG170 BF2wG8hj6687uwg== X-Google-Smtp-Source: AGHT+IHuFbrloR0m5blvPVZxF8h+Pqt2VSx6nAyL8MWcwWU6Pe/6lCA8dytMd0H7li6ZJ6bRtnj5aFgRaaAlPQ== X-Received: from pfbbx6.prod.google.com ([2002:a05:6a00:4286:b0:793:b157:af49]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:a109:b0:350:8dd9:7a90 with SMTP id adf61e73a8af0-3590ba1908cmr5304730637.43.1762975365575; Wed, 12 Nov 2025 11:22:45 -0800 (PST) Date: Wed, 12 Nov 2025 19:22:15 +0000 In-Reply-To: <20251112192232.442761-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: <20251112192232.442761-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251112192232.442761-2-dmatlack@google.com> Subject: [PATCH v2 01/18] vfio: selftests: Move run.sh into scripts directory From: David Matlack To: Alex Williamson Cc: Alex Mastro , Alex Williamson , 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. No functional change intended. Signed-off-by: David Matlack Reviewed-by: Alex Mastro Tested-by: Alex Mastro --- tools/testing/selftests/vfio/Makefile | 2 +- tools/testing/selftests/vfio/{ =3D> scripts}/run.sh | 0 2 files changed, 1 insertion(+), 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..155b5ecca6a9 100644 --- a/tools/testing/selftests/vfio/Makefile +++ b/tools/testing/selftests/vfio/Makefile @@ -3,7 +3,7 @@ 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_PROGS_EXTENDED :=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.rc1.455.g30608eb744-goog From nobody Sat Feb 7 18:20:49 2026 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 A553A34B661 for ; Wed, 12 Nov 2025 19:22:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975370; cv=none; b=mybY6nrE5iXPxZ9ecUiWVCkH/j1Wod62xxxWLLPC6SgHpQNX130ginpvSdfryQ1eSfrxxBhXeeVZ2R7g4L/fHgyEzsi6K4ZLCtfErvY/iCn9wtzORIHe2Awk4+KF+x13Bypw8a2x8wVtqkuFjukxSQZFuhrh9geOVN7rT3bI83A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975370; c=relaxed/simple; bh=1Faf6Wu00Gd6HuFkzY8AmSPV/Tu0l2PZME5Uf3FF7qc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=FMd0gU2slAqU2VXRdrJslTVi2eRUIOELUeQitNJwPe+B2ogOi8cGxY8PM1qyun9BmPfZBGqdnfOKpS2DI5sqAbtezlqJRneQyxVrkWeQ9m8b1onU7r6DxTbOtMSEqaBwct6+JN4d4bs7xhwWcLHtwrwgMsrCIkk3Mvlnnz+QiXg= 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=yzwEe9wi; 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="yzwEe9wi" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7b8973c4608so1276498b3a.3 for ; Wed, 12 Nov 2025 11:22:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762975367; x=1763580167; 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=snhFxX7SvMNlxqdH8lTASdqUE+Ovo5DyYy099oDORho=; b=yzwEe9wigua7f5dnHkb+Zk53Yc629m4VShXQabGOhQJ2573wljST29po1Dt7nTdL11 53wRCnnese6Vy88pcQsHxM4fEmbQEBJcgqESDM0SZthPRRiusLuQ8W+vEu1Azen/aUJC o3pEbNJ0K15vPW/Sg8Vu7y/wa8zTgnnCwsEMlUdvOO4iLmOXZvQkotkyX6N92B3lmNRp LZH+AkwU6TfmTGKDLnnCocOeXyo83smISb9pptn3mzkOKPCVp9j+UywT4aNcZlufy7zQ 5AnMU8shmoBJEbxB40KbRnbN3Qv46hDrgtoKoCtZ/puisI2YiiwGpqdvukxEBUH3v4sU 5YmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762975367; x=1763580167; 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=snhFxX7SvMNlxqdH8lTASdqUE+Ovo5DyYy099oDORho=; b=SAMLdRMJco5jXen9rTWKBgg68Z9r3zSRZPznUgWplsaO7OS+610q5k475lz0N0fCsk KMyb5SUMGszTXxMCz2IQcqP1azF/UWVIP09QzYyhO63CTyY7rnJMbkY3Byzw+18Oax3q A6mIX0wglv7x4kWAAYkH0zv/ie5KspWHKLAunPnoRGo7b1eh6Q4dlFbddzuiXTc3GvAm fzNmYF4ekOUZdybonyEy49w6nf1NKqXmsdwIotrw+8hG6UzN6XhqsIj8i3GIpwi4PoUu jgdwdrzkrTrSX7yFdhVsrvfLxrvdksbaGPrvxcFspAwpwM42CmryOTLKD+wfagbnHF+T +gOw== X-Forwarded-Encrypted: i=1; AJvYcCU9KYY/8B+jooshw74BCvl2/VilVE0Ges6gcmCfDM5jXNscxGG8NA8hK6aTOKCh9DbDr6SEAwV7AjR7XmY=@vger.kernel.org X-Gm-Message-State: AOJu0Yzs9vo80FMnvCcS9ZywFGGEJwkBbyeN0JuXncX6qXHsrE2PZLq+ wPdehPDgvqxSI2/3gDQ07VHfcuDL5xr0XMlNmI3slnQ27OQtVPL8UyXk9vXmJzhnrLpXv2ICKjd j8d02hYbAPvqO/Q== X-Google-Smtp-Source: AGHT+IEcZ9l2QGC0mv57HPkzQqdooWIR6H1Skz0x70lmOYoP+/jx0zoK2LwVmKqCYXTIzCQceoduh2Aglorqpg== X-Received: from pfog19.prod.google.com ([2002:aa7:8753:0:b0:7b7:e7aa:df19]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:1823:b0:7ad:9470:27a1 with SMTP id d2e1a72fcca58-7b7a4ede639mr5578383b3a.28.1762975366997; Wed, 12 Nov 2025 11:22:46 -0800 (PST) Date: Wed, 12 Nov 2025 19:22:16 +0000 In-Reply-To: <20251112192232.442761-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: <20251112192232.442761-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251112192232.442761-3-dmatlack@google.com> Subject: [PATCH v2 02/18] vfio: selftests: Split run.sh into separate scripts From: David Matlack To: Alex Williamson Cc: Alex Mastro , Alex Williamson , 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. Signed-off-by: David Matlack Reviewed-by: Alex Mastro Tested-by: Alex Mastro --- tools/testing/selftests/vfio/Makefile | 4 + .../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, 141 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 155b5ecca6a9..e9e5c6dc63b6 100644 --- a/tools/testing/selftests/vfio/Makefile +++ b/tools/testing/selftests/vfio/Makefile @@ -3,7 +3,11 @@ 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 scripts/cleanup.sh +TEST_PROGS_EXTENDED :=3D scripts/lib.sh TEST_PROGS_EXTENDED :=3D scripts/run.sh +TEST_PROGS_EXTENDED :=3D scripts/setup.sh include ../lib.mk include lib/libvfio.mk =20 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.rc1.455.g30608eb744-goog From nobody Sat Feb 7 18:20:49 2026 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.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 36A2F34DB45 for ; Wed, 12 Nov 2025 19:22:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975370; cv=none; b=CvK58oHaEnQwWzFANLipjAuQibw35wfAxp5K2ei7KlFwXNf1IxPEoYYDYUvPAVWyGN42lbVEheV0bL6QyVdwAn975VMoudXHgBjjFpl4s3JakcEt973TS4+1/aH6IIsrnArJH1+HjY3wvC5kAgNp0+tQnHDcqraw/5oHMvImebU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975370; c=relaxed/simple; bh=wV0O/8HRi1COZ2mw6Z5bUrb4p7E7HqI9x5yrKJy0SY0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=d0ZkiW11tkc/hrZ+TU1yC+Mbq7lcpFHP/f++HtLQfnsze2mcAPfhT8kPeEnFBZ2Drx6JPnYQ+zn0SEXx3K1/I3epUMtYID7b7TXTsEQny6wDfEvl0D3jnh5bq3Z16uHC4YlRLcRk2NtDCVW71VDIfTHb3CyulJDDyC6CLsYHsIc= 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=VeyG9xKO; arc=none smtp.client-ip=209.85.215.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="VeyG9xKO" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-b6097ca315bso2372085a12.3 for ; Wed, 12 Nov 2025 11:22:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762975368; x=1763580168; 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=DC4r0ZRTeYB3Y3PVNQCtQJXZ8DKyZ4imVC1cZHVKSpE=; b=VeyG9xKOJ/7ESObNlsQd65RS5Ldzij3yWb30jBJ0g5AghZ6o7rOpTS3BgLwAS/KOo0 ui0NFTpqeh8nyzZTpiRzY8gkCVzACgehanvm4KSDhe8jSNisqOgg9NXcn2z3srZNPOql ZA2XoqH9G+Ys979ZyHgp4LdMAf03880Hs6LpExopg7KpPMm5+yp8ldjlm4Zjqs+n3oAO eACN0vUu5sVOeUOqcBSHkiqEn6p6InGGT8/JahwkdMJtcyYN6zyh+41pCcxVrjTeI5lj kdXKNvC6NpD4Fv29bAtClDwy+KgwQdThBRywMX0/wHyRpkpHeBbhF8/8gSoOWYB8ygGW gGhQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762975368; x=1763580168; 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=DC4r0ZRTeYB3Y3PVNQCtQJXZ8DKyZ4imVC1cZHVKSpE=; b=D/W4Nx0GoN5Pvemi1mZefrc7jINFwMRULVJRNElsf+nTdP5XmJeq9ZaLoP1iyTsdkH xuoR3dzUilokwVhWLqfmBURrm//WbhFI3WPrMd7KippZMObAkHCGcmxVvxWoJABcwWt2 uFArknHeMMCTKthVidA0F9IsZdqrNCaT4WCFyowhHsSdrrUn8e4RUPfAZM0pHwQ/1ura FJ0KpkQq/YBbveukjzbgDtL+CEGe8rDH0ZZDubYktyah+2c9vsQGcA4FK5mxkIb/mFHs uN5/RRH/KSn335G1Qou1As2pNjW6wa2yHQ3a3/4h5ThTNHRvFi6fxmu1/q87VPdM/HuR VqMQ== X-Forwarded-Encrypted: i=1; AJvYcCWux1yloxEwA+HLYUga9xS1+WGVoHQu1XdzBm4lonML1OFitC6dGdm6AGZ2/fnLtZ7etnY2B3TWDPHWRQc=@vger.kernel.org X-Gm-Message-State: AOJu0YzFz/bBEqYziz7NuYLYAUtbjTv406Ieoz88eVAKKHhrF6y4buIQ 0wHr0u5MaYMZeYYpDtlUyUyroyyMP7XqIXqG5i/TF0zXG2S+BM4jhL3kchqwqGBUy7I6vXeVIpL zFpcy5TWigqfRNg== X-Google-Smtp-Source: AGHT+IEi9Ao+07tIZnXl/ITEY6uR3zgoc99jgN6A24D4IjGR3/HEnyP417iqyrKKSiDM+CBTKzZd9afl0c1FAw== X-Received: from pfbbk25.prod.google.com ([2002:aa7:8319:0:b0:7b2:242c:6852]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a21:e081:b0:350:1a0e:7fc5 with SMTP id adf61e73a8af0-3590c224b71mr5330399637.60.1762975368540; Wed, 12 Nov 2025 11:22:48 -0800 (PST) Date: Wed, 12 Nov 2025 19:22:17 +0000 In-Reply-To: <20251112192232.442761-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: <20251112192232.442761-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251112192232.442761-4-dmatlack@google.com> Subject: [PATCH v2 03/18] vfio: selftests: Allow passing multiple BDFs on the command line From: David Matlack To: Alex Williamson Cc: Alex Mastro , Alex Williamson , 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. Signed-off-by: David Matlack Reviewed-by: Alex Mastro Tested-by: Alex Mastro --- .../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.rc1.455.g30608eb744-goog From nobody Sat Feb 7 18:20:49 2026 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 C93EC34DCDE for ; Wed, 12 Nov 2025 19:22:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975372; cv=none; b=c7svu8jyiDm27JcfmcKLA5XW0oB4EsK0kQckSKqBKqvQkt1cokFyRYduDLE5is24I3mRKB7JRVsRAIKtRpeD35gBgEpx4gnmd+uMnJzFe+n7DxEU0ejWo6+s5H56RzleXHZlQ9eVXpvO0K9icWFXRHTu3XoPI6fAADTo+enmhyw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975372; c=relaxed/simple; bh=jeuliBeHLcpyumWj/lzH00ZpBgTEtU6Uh+nasXsIs8w=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=caPSV6VVKRKOphfHqcXOXjmIaBYjmwdjytpK+J2JE63Vils1/zm3zKaJ7AGSOe9JGMUkvBmMec+0ZjjUB6Px+DHMEvQGVGlLBWx4UAhasqwXReejndd1w2ECW+3LXqyPPYG9/6uVrdKK7Uy+I/2QlOXZ8bk977bMm8xeb0hfVU8= 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=FCQe8GP0; 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="FCQe8GP0" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-78117fbda6eso1308348b3a.3 for ; Wed, 12 Nov 2025 11:22:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762975370; x=1763580170; 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=vePzcNAPw6XtIm0Mfoqs8jy8WsyiUI2nOmzMjhNQ5jo=; b=FCQe8GP0wnkBDZe7l2Cbz/LImVFD1K1uFr+4p33t7jbmjXHnquwLRLUs8bq4Ju+XAR avzwxRaZPkb98Rk6egeNhpzQGogMcpVnPY3F7gKTsAtSwjRS/o6zcvF59aefreWIaRwz /PNW4WXsJj6UUXXbDp+BvkNlFkl5zq4cTqJUc83jOm1wgM+Vqv3Z3gNX9xd6nE5pUG7w LBjFhoz8i4GR389DVduQY9cvbky0A3XTsa1a3qF4MAmMjyeyqsddhp7o3CdyT8umkMaI B6kjvqhohH66KOwOPG40KDyixSny0wRTxksPH7ebJG/J0P5MYpFuyWPw+liEhV4g9J9D 5Hwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762975370; x=1763580170; 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=vePzcNAPw6XtIm0Mfoqs8jy8WsyiUI2nOmzMjhNQ5jo=; b=cY8gu8LQ8Iqo4x6gBKARH609mWKdLFad5ackSJbuoZSx87gjdTonn3mCv3a8vwNxMl Dz1odr5ug1pOlSWH18uPuYn4N3XN+gazgFdv0Qoz5CMfVHXR3s9hr5AdfQdVm7KyCCGu eF195Bz1GXV8IMzPbjEZwk+Kynmb3lFokbOCrqkYjWroZnZ+MFpYOe/cyn0e0+8XgHwE p7X++jBe1ISPrQCdXDQancrUApaRZ2uCgSsjgIh0Ew9EycG7AVD9PPLJXgu7R4hckJHt cafumxHcWcla5dqzhGfr8SyMkaYGSEtHwcb5EgnT4R6qkNd+p0xpGja+v2hqGwziPcPx yw4w== X-Forwarded-Encrypted: i=1; AJvYcCUO4yUUh02PRC60uYWWJ7eoMt/8S9XryiSLiuMmvcYXmUcCr4PiLAxNE8jb9XIT3kjsCzYCKIfns6Bv2ho=@vger.kernel.org X-Gm-Message-State: AOJu0YyHx0vFoQIuBzTBzX0A9XXNaKkg2aFWQssZbvYa0u4Mjk1d41Mm MYZ7liTaLxi9+CmSQ7BnbihN3xNGgs/d4grX5pZbvOUvfu6YDex5dbIo4DShZZUgWdo+62RnqKB UorquAYi3eHI8pA== X-Google-Smtp-Source: AGHT+IHgN7CdCgSwD+T6DKsSw/WTcqqtgfIj5GPUg8wxWmMi3fkSdz9zc8oj2o6BP1GGWku6085y8OWdclvulQ== X-Received: from pfbkr8.prod.google.com ([2002:a05:6a00:4b48:b0:7a4:fb59:8199]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:14c9:b0:7ac:69cd:ea0d with SMTP id d2e1a72fcca58-7b7a4afa078mr4267073b3a.19.1762975370068; Wed, 12 Nov 2025 11:22:50 -0800 (PST) Date: Wed, 12 Nov 2025 19:22:18 +0000 In-Reply-To: <20251112192232.442761-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: <20251112192232.442761-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251112192232.442761-5-dmatlack@google.com> Subject: [PATCH v2 04/18] vfio: selftests: Rename struct vfio_iommu_mode to iommu_mode From: David Matlack To: Alex Williamson Cc: Alex Mastro , Alex Williamson , 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. Signed-off-by: David Matlack Reviewed-by: Alex Mastro Tested-by: Alex Mastro --- 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.rc1.455.g30608eb744-goog From nobody Sat Feb 7 18:20:49 2026 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 594C734EF04 for ; Wed, 12 Nov 2025 19:22: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=1762975375; cv=none; b=o4ksZDN8neazLYSpKknFtdKgkakUCAhYpeYaquuFWeP8KMGuGxZFO3rsCJfROlfGET6xEWeyuwUatt/d3uldYYPmIddAMWaHbmsZZDXTRsLXvWbJdCmZ/Z6f3frlxyTTMr16XlInYrdfLKdz2D/FBj9iIW4CWNS+fuwP6w186Is= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975375; c=relaxed/simple; bh=8vby+HCEoNmOJeiU/OAmu3QUCbJihz0zFADhsivjBkU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Ot3xJcTJhZfuP8ZIT1IYxtXgz4pU9cYQNwdeormLHuxdOPY9kb4xxIKaJrr3FCZrd3oZHrGZEWafNuhYHJ96stABxXDS7NHUaK9iRnzgBz5+NX1WTbCSOnlsAALwj+dS0phxjnEIjJMbZDASxJmmoN5JyeN8QXcYi8azlC+sk24= 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=LvNj3XxP; 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="LvNj3XxP" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7ad1e8ab328so976842b3a.0 for ; Wed, 12 Nov 2025 11:22:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762975372; x=1763580172; 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=Zc+91TMBIWOyFgOcp2tX+RcTMQd1o9IFITolzdEG7P4=; b=LvNj3XxP+D9aoBpg5amASobrFoaPXZ4G+GSsuohPSC3s4YM5B4OpixKjG/uBrnomTF vlhW/U9xnrozZy8wVw6BarH1Oj1J4+jlmN1VqIDMxbZz7mbzmKRfhMmZ3iGzCAkjun7Z rKBO5SrjM7MtY+DclrquMuwH3XuX3mqrVHd+1Y+LSLD9lOvF8pc2HD2HUZxNtLhuPkZO ru6emMC2WBUXwnSpEqHPggqStSvTOCB8BNtVYzhCMadVuVj3/7FqbXWga+4SUxOTYzB8 WNocxOBX32yPLcxzu+yVqqwj0Eeq66Epw/zPFJivoNL7qlcpWeMtS9RjIABurdwOSjXS Pw1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762975372; x=1763580172; 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=Zc+91TMBIWOyFgOcp2tX+RcTMQd1o9IFITolzdEG7P4=; b=PYgCtZ0HYc3OA4lta2qbQI2UBAClSTkym5NtPPxLYjFpVwI5MvtRlzuZWqwxVT9ID9 iDP6Jx1iAb4KgdfN3kM+UvNH9wa8KvwJ5oSVW+jFxI76L17AV8QYzhRMJvBhUcKD6tzh Pibl1Qdp0EXsDs8zKbNIqq6oZhGD1lO7cT+c+lqdz/8FaTHMxlsegCGmbsMfsSni/rwe 5zTy6Tr7FeEp7ErZLuCQvMQGu8NuuxtCWaLQvIFiKBaP6Zg+wDM1XjitYvH6wKaeSHAV iVz8uTjGDcl7hS8vBfd/uyh629UdQXtb6pPPPMQswea/SNw88vM6nr6bXFd7DeL4lQ97 EurQ== X-Forwarded-Encrypted: i=1; AJvYcCVebb9BEF7YmJBytNb/KnFZ42yeEA21xl5Eik+S/6M1fWqZ67KyLA633RwJ4Sxb5Gz2t+hxrqDRKavI7y0=@vger.kernel.org X-Gm-Message-State: AOJu0YzUpFYYU+ZdWVFOkJyMa6RyFmpQyUZCiIntJXNwYq7ieKfBOflV +DjvYEGfIuIo7jmvjIrLyvg7mUIZfuf922zlHmzCj2Bclke3N1bBN1BAE/JgWoGNdyxJditxZbp wElxr5OKE6XZMBQ== X-Google-Smtp-Source: AGHT+IHoMgB+dZbPNWY+JGeNK4aOZ/BFgrRUgHQJ7JHZ3hjF+UZlstjSYC0pPg/1VvgkZyLkN8ffpdm1ZYKVMQ== X-Received: from pfbfj2.prod.google.com ([2002:a05:6a00:3a02:b0:76b:651e:a69c]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:23c2:b0:7b7:8aad:99cc with SMTP id d2e1a72fcca58-7b7a2a96cfcmr4390935b3a.3.1762975371623; Wed, 12 Nov 2025 11:22:51 -0800 (PST) Date: Wed, 12 Nov 2025 19:22:19 +0000 In-Reply-To: <20251112192232.442761-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: <20251112192232.442761-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251112192232.442761-6-dmatlack@google.com> Subject: [PATCH v2 05/18] vfio: selftests: Introduce struct iommu From: David Matlack To: Alex Williamson Cc: Alex Mastro , Alex Williamson , 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. Signed-off-by: David Matlack Reviewed-by: Alex Mastro Tested-by: Alex Mastro --- .../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.rc1.455.g30608eb744-goog From nobody Sat Feb 7 18:20:49 2026 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 DC52E34FF4A for ; Wed, 12 Nov 2025 19:22:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975376; cv=none; b=VfX8rKjrqGX8bsmzB9SNymJpmC8TRTvV0O5DV2ts3Tw6XSnqFUMrn13cR0SZHTn8z3tEh89ibF0qHIwmS7MoudC/wX0JJdxGW8okNHAm5SL5+54sgQnWuqq9gLnRBFWoFBJR8r2+pxz3lKJbIh6o0J+02ASPpXSiky+Iz2XVcT0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975376; c=relaxed/simple; bh=O+TIOK/iAwaO6TFx+o1r6IjiMA/A97B4pvvWVKfERog=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=E4sosZ5kiS+ndIZKPdFLNU7s+gmk7gJre5E4+GZfUOB0yf/LflqBLHdn41SDKHiOe1zW3Y42GkMmTlEPRjpBD1KWijhOzwdBgf3DE//3tlLqC0pjtAooE3BXBG+WQVysAe0fC+gsXgEbzIRpseYnlDz8oq59PFKs1iNCCezGmUQ= 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=t9VIEK+4; 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="t9VIEK+4" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7b873532cc8so28505b3a.1 for ; Wed, 12 Nov 2025 11:22:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762975373; x=1763580173; 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=GvVdgWek024XGinlgq5qGtxuPqpoQIVIBhWh494CX2w=; b=t9VIEK+4QjzscFK8etcM231KIViWE1Bo4xGiPUMcS7APlhlCx/jUFlufIyggODrQTz 37D3i2rKZiaOgxg4B/oZ/LxR0FXZaYBhTW1aEdI1MqguQOBlbmRaSY08TXz0ypsHRvNg 3payxv71H9JVwyUB6JK2gJinz5qm+2V78rEu8F3JthQ7cSY2Mz+mzqEZtbtSH2tuaAGQ e3gR7Sa9hpiDGgFsGzaxlYjVnlKVTQn26LzWU5u+pP/P4LfZbj+cIvFqnZDlthm5ZCnn Abgfec78hoiUcBqSmXp2ec/lhysjMW333TPwC979i58VUhjdJkFG+NLe7hDltL4Nd0ox o3DQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762975373; x=1763580173; 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=GvVdgWek024XGinlgq5qGtxuPqpoQIVIBhWh494CX2w=; b=G4lvT7xGx661adhZP6gUqTu/CRzQZZqIFbdyHfpfzn4tYhFQTYZnxDKuIFH35FiRPv A/CxQ3mv0eGSi9UsrIAaxig58APlp51owlV1Hq2RtvbSEb5ubwLN2IDC4AP7iACUNd/G L+uIbIjZ1r79/suX8wshOP6+AE6JuQ2CdIxLaY5VHM9gDw6kxUEeijwd/ymv5zUap9Xi HLYUIi2XRGTZ6+4ApUkSOYT3v/RSV6/tD9SSWav8gfFJ3fP0yJDVS2Tk1G0kWcHUjGS4 7XV4naVM/UvgZT5CMeYiDSUzt5s3KxNvmZp/7k2+oYWyN1CYZa6kc09zMI1yitolqsKq VqFw== X-Forwarded-Encrypted: i=1; AJvYcCUcqvnVbhhbN+HQ8YlUFzBecg4Ofdqyf59MRzCmCfwLdrp2W7C8uFX/SUkLqQyJlp5LAqdUuiAlYUyNmEE=@vger.kernel.org X-Gm-Message-State: AOJu0Yx+b0oPBhSlLg34zrRdMyndKelA+msHQgZtQZ4yLtgg6MqMvTla EpCDjpvJnWK5cImHNhl2zgBowo1mf+whFXKm59I7CqA7SRftn8eevfEbLl1n7FpLu4cVzKcUbSG raOKwLZWSjQhjbw== X-Google-Smtp-Source: AGHT+IEJO4+Ny9s10fiUbNof0hKyVQVr31lhSgeKpAEIhCMw0EuHDM2D0vtX3vLC+WFkf3xOHugXLiNJiTe8lg== X-Received: from pfbfa15.prod.google.com ([2002:a05:6a00:2d0f:b0:7b0:bc2e:959b]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:2ea9:b0:7a2:7c48:e34a with SMTP id d2e1a72fcca58-7b8e197cc7emr610300b3a.13.1762975373143; Wed, 12 Nov 2025 11:22:53 -0800 (PST) Date: Wed, 12 Nov 2025 19:22:20 +0000 In-Reply-To: <20251112192232.442761-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: <20251112192232.442761-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251112192232.442761-7-dmatlack@google.com> Subject: [PATCH v2 06/18] vfio: selftests: Support multiple devices in the same container/iommufd From: David Matlack To: Alex Williamson Cc: Alex Mastro , Alex Williamson , 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. Signed-off-by: David Matlack Reviewed-by: Alex Mastro Tested-by: Alex Mastro --- .../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.rc1.455.g30608eb744-goog From nobody Sat Feb 7 18:20:49 2026 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 73C7035028E for ; Wed, 12 Nov 2025 19:22:55 +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=1762975377; cv=none; b=PxoUe6qDlGgrcUOhzVnGtIodQKGdirlpMd5l2dfd3p7L8yjaNbHZTwhjEQdWKbc9FAsMcp64FbzgDvJM/j0oVBHqJ4klHRL7CXuzZ5nUKo8ltRU+qvb4UzsnwCVPkOmDNITOf1AYA2qhytwktAZog8b4GUVXabPbB3E5jE7BI/k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975377; c=relaxed/simple; bh=j/qVMd3MvTUa/awqSQUVlSj2s5CofTYFxaDMQ6ETcQE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=t/KrJfP8EY1YbnmF9eQTTClk2W0gfZFX283KoA/eDNBQiCna8RTvbXKrgOISjZ6lWjr3wOggmJ9wfqk77RV9Vup4v6/sLnnSspzCmjf+/0/Ho/N4ecil9Rfx/FIb1HBc/KwKzLHY7b+zhhCfan9tEs3wq+KXK00J32MDq3wx2lk= 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=xJ/3Kpcq; 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="xJ/3Kpcq" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7b895b520a2so501513b3a.0 for ; Wed, 12 Nov 2025 11:22:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762975375; x=1763580175; 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=uiy8tigNPCCZiWR1z0pXaHh2gPneQJv15HEUGvJLWqk=; b=xJ/3KpcqBs0X4k3M+3ipJtsI+tnSa/yk9cTZZQ5MLT3/ZI1hmbi/xeet3jeUznt6mj sEaMowcGVU2vs49ZPiy0aHPcTCpjNYfYhiq9Uq/TPcCRR0WRv7nlctWe20CNeyrozuIP YqX5CSqQpk7Ue1ccdbRV1FBCG2NSnW4ndiffv6ezIwUt1AetyZj3xiN7gDtUPQL1kCxw ks2qyO0lewLw4d85dTUX90/Xybyy28A2vrdd2wZ9D7/jb6DtNv0cTz+PhULKYIk2Tg5m nEZJbY7PGYqfxtOep/ZIHXJ29SQhu4dKdRzT76w5MnX8AQmu2dxTyY/S2/me7YVQm2cq v+Zw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762975375; x=1763580175; 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=uiy8tigNPCCZiWR1z0pXaHh2gPneQJv15HEUGvJLWqk=; b=ADgz9XnWl02GD8NMUTTF6q4K+oj3YqkN11v0RlVsZRm/QWPxeUYHKr2nH7eH4g/qdV DneY5bf8qqAHe2EXB9dlMW8NcwK4R60nxYTiIB1qpT1fYtYjBVyN5Jet69dOgOh8axIU jyefmku7wgLzWixC0KX16g6zNTExfbWmaY0P9ZvRUPWOusMoaEc1S6X18uYTt6mdSL2O H1g8FBdmfCCyLoJtpg/i2+clc+KWaOLCUfWsxTlpktNEHye3acJbhe8Imc50BOul4DbS 96YHQJOBdKLNQPhaMdz2T6Xru/Yj+6OEUqFxG3aaukfrLm7QSnsIj0z5PzhHRion8b8U VCmw== X-Forwarded-Encrypted: i=1; AJvYcCVeaHRY/IBmPrPm4xq41zW2Nkcpst05I16X+HGryQ4b5S+r4NoD1ztw4t/GUE+1lcPOUI64hPnKhB2UGl8=@vger.kernel.org X-Gm-Message-State: AOJu0Yy7p1+VdVAIzem7Ziet3OgKCFlG60aQtVH60PSTBCY19zaNM8ws CKz4fSMbmiCvEVmYPoHbg0k+PlmtC6b9UKH4ytvqqrts5xlnZa+p7SSE2T+ZdRn+vdfRzvSuqhf eZ0O8FKicT4HiQQ== X-Google-Smtp-Source: AGHT+IHTkEQKZW/Nui6RQdGyae0bAnsLjVZr/UbRZUUfe/uM6cYPChsHxARiYwiuw2YD0ipNO5ncGADz8WSHZw== X-Received: from pfbei24.prod.google.com ([2002:a05:6a00:80d8:b0:7b8:2d09:cf]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a21:e083:b0:350:b8e:f99b with SMTP id adf61e73a8af0-3590b51dd7dmr5088842637.45.1762975374835; Wed, 12 Nov 2025 11:22:54 -0800 (PST) Date: Wed, 12 Nov 2025 19:22:21 +0000 In-Reply-To: <20251112192232.442761-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: <20251112192232.442761-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251112192232.442761-8-dmatlack@google.com> Subject: [PATCH v2 07/18] vfio: selftests: Eliminate overly chatty logging From: David Matlack To: Alex Williamson Cc: Alex Mastro , Alex Williamson , 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). Signed-off-by: David Matlack Reviewed-by: Alex Mastro Tested-by: Alex Mastro --- 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.rc1.455.g30608eb744-goog From nobody Sat Feb 7 18:20:49 2026 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 08A3134DB53 for ; Wed, 12 Nov 2025 19:22:57 +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=1762975378; cv=none; b=p+3TFPf179aFLD1LHj5/yS/PrC/9y8IfbmBOyfA8ICnhO9O8uvMYK6suGmVrryVg2YgZuunNh4a6Yw/hzAZVfjgw+OihVwLWHrDDPLwrUlyoIP9qRuQ/U7PyqA0i3obLlJaKb/N4mIx+8YJi9Jc25asTZGPJlYDhWLd4VJdcHtQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975378; c=relaxed/simple; bh=X2z0zYXx4IfeK6I1u0CZBdTx7I9g6VYRrlA6xnWbdPU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=LkgcnPtDu/af3YRVjusSHwcNJCdxA3+NUuMtW+TYadUYHbWd9T4BiVxUNj8Q3JVWFS5ef76SGZS0ri1AzfrzUDcukZgGjZwVaz+Fi3k2nNWn42enRUkfzjxVTB39uBmklNMpHe9v/VigL8nN8Nd2DaWgBF56NK9/w4+WgZ9DS44= 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=cip5GyAc; 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="cip5GyAc" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7a99a5f77e0so2169366b3a.2 for ; Wed, 12 Nov 2025 11:22:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762975376; x=1763580176; 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=ueKETxDM4kJbfqgE66fsmgAr6L0p0+l6thADmsbkETo=; b=cip5GyAcOLDAohdpwhUwRAvruToQeL+heV6cy+o6ZzjZtSgxn7cVCK67sHdk9KVqWh z9s+pfzFj7kwzc6xRXY+XK5z3/DvP5TFSh6hiAPLdF1kiPkU4QstKsJ1qcOYUQ7vEHNo wFgDbhdTaJLkTJFofLbGQ2PSdS5VgYuWx8orGZiA0cIrRqNG96xmDnulW8kbzM8TlbnK 2hA8dbrmgkUphHHFNxKSKMHpLkIYp7BFsfWHq5ifSrgfsFHPYj/P+J8C/8IYwu//pVq2 WIJ/0YzVLjDDR6HvQV0NQqFcHdZHCH3u5FpWc9cni9qbFXq5/XVoQ4rXFwjlEoLDDGxB KGhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762975376; x=1763580176; 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=ueKETxDM4kJbfqgE66fsmgAr6L0p0+l6thADmsbkETo=; b=c8V9nsqVSF30fmN+yB/absobEyXhHNGm8XgJMprwdtf6Ybq+fvZt1z+ss3MuZg0a/l cPDSsEepxnVHPwtY9ebB9VNo5XDbdkJEy0quSwN2/TExlr8mzadyzXCQYy40Sgjf+sil K6bb9bNAc8mGjyA5Y70FyWXYNNNsNgh0XsUnQ4bZSUICZjD8IS0MNTb2Si5fTUmAeBjV WvK/FYaFqVZRHAdjsvcWDTJ4PMw8p3kg47xBNOjfXFGG2beiNhdhfaTjMrz/TEAd0CQi zFSPsFTv970kYppGcde05cLFRwL/kbAMWUQbBtSid7JAVBahxyVDA2i/kzqMa9+0lhHF exgQ== X-Forwarded-Encrypted: i=1; AJvYcCWAdAbRmaeh8o+UqmuZ8zKelesG5xqBC7zhsuXvsk4Tmb52aY9e7wydomSFFVe3kAjAJ0lIMqPwaBfVJBY=@vger.kernel.org X-Gm-Message-State: AOJu0YyVXEXzhJ91PM76g8hd5PUAPNTUGHLGOM1QcL1Dq2OjZbaWYMvJ lpc8q7+nVP1dI2i9wuC/60bZnKnocGTwFyBiSkGmW/wT7idK8GDQqIvm2bVTkChZP+/ci7v09ox CpbywuQ5+I/IBSQ== X-Google-Smtp-Source: AGHT+IEzsM/mNVu+WiWqJPEakH62CIW77qsxfOleVw+6jOlLtlnEJjcytVKVMxooFSZ/VRHPV9LWkhxYkLXOug== X-Received: from pfblb14.prod.google.com ([2002:a05:6a00:4f0e:b0:7b8:d5a9:9eff]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:22c3:b0:7ab:e844:1e52 with SMTP id d2e1a72fcca58-7b7a4fdc065mr4048347b3a.23.1762975376430; Wed, 12 Nov 2025 11:22:56 -0800 (PST) Date: Wed, 12 Nov 2025 19:22:22 +0000 In-Reply-To: <20251112192232.442761-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: <20251112192232.442761-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251112192232.442761-9-dmatlack@google.com> Subject: [PATCH v2 08/18] vfio: selftests: Prefix logs with device BDF where relevant From: David Matlack To: Alex Williamson Cc: Alex Mastro , Alex Williamson , 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. Signed-off-by: David Matlack Reviewed-by: Alex Mastro Tested-by: Alex Mastro --- .../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.rc1.455.g30608eb744-goog From nobody Sat Feb 7 18:20:49 2026 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 8AF4A350A0E for ; Wed, 12 Nov 2025 19:22:58 +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=1762975380; cv=none; b=r6Mpa3gq2T7bijf9k6HEAez4oGF+1rP5GOpykEskDHuCVac3VcbGyjYWBssDkn2kP8+0Lqk2rwzpkHw3Z9Q04qy3ueybcDU06E5mqHgU++Zlc8Kt2eBZOt3MfYnvtgc9WVMzTabJS2LIJbE09rG6DGeAf96FlTpcIBYLTVZDSFg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975380; c=relaxed/simple; bh=4WEWqFLkAyILTnk5IRmplEfehB7Qfwkb9Xc1jBRIVh0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=jcwGgggfXs0YXhP7UCgq35OjezA4gKe6nMNMnF+XvoDj9R2cDk5dxoiBQ4ve++BuHbSGxDo1tA5r07UWdxxbhiS2Bl3cuGDuRGTdDOkkbA/op41+gK43DuOm2acbKPA3puZdkXOyXxfqyQ7IYSNocS59k5mQGufaWp6ucX9GgUs= 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=mto1Mz3S; 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="mto1Mz3S" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7900f597d08so1257669b3a.1 for ; Wed, 12 Nov 2025 11:22:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762975378; x=1763580178; 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=mq/oPHnS+nR1DAAGuM6ciZxbjUUIou+j7/UhE84TOCk=; b=mto1Mz3S6cey2ugi/lZmLCcSeyr/JeDqcaYOguBgBeC9FxeA6K49VL8OJNxSBi9Ti7 f7bTdKXwb0ArUjYTmYpP1L6UXjCzdamosqtmhHiZIpiGEdVxtfcPyOtDYp9kHmBysrsY RvIodXmScdoUUWvq6QAZLDjQIurSTqQsqRP7WEXY10VEEj8kdLvivAUJM94EpTMo/XGe fBcB09B6INIkfdqccQZvRyjlQTqQvb43Bg2ZKT06NKFrUukjnaGPMhCaCuk+WAOpa6rX z4HkR5HVpbVhF+ZYi1wZ0yEFunA/AeEAWDJdwP+X0BSz/9Upep9z6qDhFeL/r0Ptp0r4 /UsQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762975378; x=1763580178; 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=mq/oPHnS+nR1DAAGuM6ciZxbjUUIou+j7/UhE84TOCk=; b=WQWiih4rjZ/It5tipKgdA7BK4lj8Wfpf3K0BlHuCcUIRWNbbXtYXYSeXeYj5LOvdF0 cHGalPNKYnP48qDS2PvVLrh0+q0E/WJcfkhCfiBONt5P9KNX1F0IsY20xtqLswmCPWZP LhZDkgLvNcEEMpzqutx3eBVa8OzEsImp+CvOQDR/XT+la+cQX5TT4ZsVnzFFNT1SuJ9r br2DlbmkR1QEU0z+1iINkuY6SzLQz7XSaGXeyJucbkkwERNFFxNseRion0M0droS0N7I r2iVbIfgg9jpW2AptWvYjvD/Im3FJGi7QV1Gldw05StQRcqnlJRNwAkJHHV2Xypz4WLX y8nQ== X-Forwarded-Encrypted: i=1; AJvYcCWKZsSYzAMz8oiTD7CiQ7ILqBKgglTYJAhQNVsapi8fEB/nH2LrU/WNDVvrcaYmZXOmIVn/ST5N1aA69fg=@vger.kernel.org X-Gm-Message-State: AOJu0Yxn6t5x//6nOBLC88hlsrfNP50nk69A2zMPE9hwQXhj65qvKsUZ rG/js/mQVtEUfrmSi904TTIpn2N37D3zUaOSVFNHDx45mAb+zx3eNvtjIXwql694uEzavLOEHxu MIBTSWTDUfMXpKA== X-Google-Smtp-Source: AGHT+IEd9++8is6wKtQHcfQ6Wkj1e3bbHC3t+bITp5e83+/U0RnUJT78Nw/CRkwOfCVl+NP4rN8DCvD7e+WkmQ== X-Received: from pfbml5.prod.google.com ([2002:a05:6a00:3d85:b0:792:f698:fda2]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:2ea7:b0:7b2:2d85:ae59 with SMTP id d2e1a72fcca58-7b7a2d8d131mr4883446b3a.11.1762975378013; Wed, 12 Nov 2025 11:22:58 -0800 (PST) Date: Wed, 12 Nov 2025 19:22:23 +0000 In-Reply-To: <20251112192232.442761-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: <20251112192232.442761-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251112192232.442761-10-dmatlack@google.com> Subject: [PATCH v2 09/18] vfio: selftests: Upgrade driver logging to dev_err() From: David Matlack To: Alex Williamson Cc: Alex Mastro , Alex Williamson , 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 Signed-off-by: David Matlack Reviewed-by: Alex Mastro Tested-by: Alex Mastro --- 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.rc1.455.g30608eb744-goog From nobody Sat Feb 7 18:20:49 2026 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 4057335292C for ; Wed, 12 Nov 2025 19:23:00 +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=1762975382; cv=none; b=OQdTwOg0O6YLIGlD75mcIxdNxk7FNMlrAl2lWCaluy8wxe9SvmPp12UIwFUwZw7McrsmT2HRVqH86EoxMeAgNfPRNQ/mitp3KRlvUmKRrsLuNUgveZgXQy1q/uOb8TixehpOciwBVkbDoOkdVFLQzpgpSvXoYtT8FzKTG4ZHdtg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975382; c=relaxed/simple; bh=k+h0e9DGqf0UqZUIrxgBUd3HnlRFK4yhRYHVnGolsNg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=fKRQ6e1VzzRynlBz/JDzBIAWFh3GEbPP3fZ06Djg+WdYUObrBn81YMhdPRftkEaGp6MhXSdz0/FOnshK9lLkY2i8zcg3Ze9X6sBXwrnjFjFGLFc7/JkUaBr4i5WZpllXLtqqcCdJJgxHEpJ3C+fSJiBz44oTXtyf5/9BUnRuMSc= 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=FfoHLUic; 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="FfoHLUic" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7ad1e8ab328so976932b3a.0 for ; Wed, 12 Nov 2025 11:23:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762975379; x=1763580179; 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=SClEIRDGqMM6/CDJu3mQTJlAF3rZlqeqRl58NIDI91g=; b=FfoHLUicROa1zGG9apeygIYfM4wzyjoC627aZ/S2iUJ0L0pNpvaO/uKQnvTk/gOFmO h0AatnUScnQNhZuWEaM2kgu6KB1+iDnaRQ+znXqsIWnEaTiIERYbdmnyDwtHjuHB8HVw pZ25Su3qV5/xtGwl19WxCilGp6rQNnDVDzp1s/ZsUQwsefSb4Sgm1ceFu5qmOW9FkNLc Zsn0FPV5t9ihuZhGWfsr7/PUcghnUPRB7NW2WUU+DUUd9K2+KyNItp2I7vgQvUfFLtPI EfNEyxbH7HVNNyzIedrnIHYhN0WYXPrMIl0EsgyUhT+8XiQhFzCWtXpokpb4Q8d/pkBM +hfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762975379; x=1763580179; 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=SClEIRDGqMM6/CDJu3mQTJlAF3rZlqeqRl58NIDI91g=; b=rddz96Z0W4pPTDQuhDvQzibQIozwRrQVAdejQxghOu84QiO+oW9iIEM6JahMUK4bvG EkmH8JJ4Z1C282YxeqotQxlQPVuo+BZ2mkjO82U+FcRxJrI/uttWE1F3QmV5wqWQ44a/ L3KwBzC/w5fZSByD4V+Z8iClztv64pojmVB6W+NBbz/vWblLOPMqRmBGesohdN6sNS6B VZjgP+etnf6WnydkkqVAtAN8pYGrSfQQx0Vj+9LEZE0OTlSt/b5z/RQx6kdSVm2wMX33 h3tvKce7YvtyHWlhg3IJ24fJqYlSwDwNjMsMQcwQD98pN2JE8J0QqKcH0++sEAhPNMjX blFw== X-Forwarded-Encrypted: i=1; AJvYcCVqcS3XgXoR0zicUK1FcHw/ulFV/VyIi7V2PEVEGCqdIrQwyfa3XPzGh6IVUU6IVJpY8I9cHlyR29ZUWbA=@vger.kernel.org X-Gm-Message-State: AOJu0YxHuP4v+wG1y924O2HXMLTytnAT5EDYoTnUgt3Wu2KpQOQk3IvZ xDZT2JsTasfQZtvqKTMJLxIBGgiIAHk1fAoiklHud03Uq7DMXh9xcApbfh+HztemndwB/czONCM +73kXVbEgvpWJjw== X-Google-Smtp-Source: AGHT+IE0RR3NaaZRsX42px2Ui9QqlKLfhYBC7yf3CJtNKth46iGLw6TE7T3Z9+SvRXK+RFn/1Hq1EWdkmDrSvA== X-Received: from pfbfk7.prod.google.com ([2002:a05:6a00:3a87:b0:7af:350d:6082]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:23c4:b0:7a2:1b8a:ca22 with SMTP id d2e1a72fcca58-7b7a52c4d9cmr4929208b3a.25.1762975379566; Wed, 12 Nov 2025 11:22:59 -0800 (PST) Date: Wed, 12 Nov 2025 19:22:24 +0000 In-Reply-To: <20251112192232.442761-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: <20251112192232.442761-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251112192232.442761-11-dmatlack@google.com> Subject: [PATCH v2 10/18] vfio: selftests: Rename struct vfio_dma_region to dma_region From: David Matlack To: Alex Williamson Cc: Alex Mastro , Alex Williamson , 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. Signed-off-by: David Matlack Reviewed-by: Alex Mastro Tested-by: Alex Mastro --- 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.rc1.455.g30608eb744-goog From nobody Sat Feb 7 18:20:49 2026 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 B0996352959 for ; Wed, 12 Nov 2025 19:23:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975384; cv=none; b=FtgCiVkU5t1kvzItFFfha9ymBBL5NuoYgWlqzIbiOzX/Y7tDG+He3SMemKbF5XSMAymk1lRbOBoSLDtLi0FmcCGs4zO27b12FP8fGrmSqZABaLmpE89NE+SNlyVjCINpRPISo2W02lsaCo3J/UG/+42jEfnZf3LAfv/7OB8Mlxo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975384; c=relaxed/simple; bh=dtQ/esAd4TZ6T4p8kue/2BG6WhkLFpOoKx5URB6Dk+Q=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=O5Xuzvi3SGgtRIMAh5U3Sw5xC7HqkSJabQeIhe2xQHK/8p5LY5lATDukWEIs0A/uG8zrSBOHMZHcuQsjZNuRTnb5ENjkLV0DzXYgdYvY5gBkBb5mmkW6dqz4WQbosHYbbbY+YmAtw8pBRqTOVaykp66YgJ9FwCkArnPcuIT1JmM= 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=qIUOhVxh; 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="qIUOhVxh" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-78105c10afdso1329362b3a.1 for ; Wed, 12 Nov 2025 11:23:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762975381; x=1763580181; 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=4L13k918DjDFSBLyfl6JP/gFjq4aUJ6vYGbFQGkOlMA=; b=qIUOhVxhNKwdEKCdJlr+cAIkr5LzSq0effztSYwkFBJj3aRC+PIFiWY6uAL4F0Vw9s +1OFLUFmeMKoec3jw48wZc8LH+RA4ZZDK9Yqjr1z1ADreAfx/Cl6t133DJ61cBvAmIPK D6Y9J3FlFYh5JQ9AewCMIXwdhKeULzPpaJnuM5O3WeHgll+Q8dR7oq0nvOP4hRmAJn3+ XOoGGerSz+ytMCmhUU0d6wMrRkeWeeDnESAC8oqpqFByQFi4/CkWslUk0x4lg8joqA/V I4hzszejJE1lQgss5w3ltc/n2q2sp6/q4fQoMQ/6S4nPdrHEd6uQ01gAaBEshRkwvBQ3 JNTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762975381; x=1763580181; 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=4L13k918DjDFSBLyfl6JP/gFjq4aUJ6vYGbFQGkOlMA=; b=MGOoD7YS3mw9L+cMrCbfFKsklJ3olUTfxVqamX8Bkrgh1uDduNV9IrS4bJAam6lM0L iPsVBpcEqCBAh/ILBrzsCSfMdbWRjoTLZKJOLfzZZLozzTy5e+gB/SI54sb4r1QYV7jj PZsKpMJiJygDv1EjWTDIe5HU4DbsqN27bkpTpMm8ExVawDGwmeA7t6Kv8yM8oWu05F53 McuphD2itI381i9xbzM3T2txSBDd5k/L1pVdnrBP8lLB1BxACCCC6vVixvSdpdvrubJT 3fdULlpKXG58MuZTwk+JoDAK17RE1ZTCZCjM7h/F6TVpnsNZhUqGhV9Xlcs8s4wCtK+U zhXA== X-Forwarded-Encrypted: i=1; AJvYcCXJWDZQHRaUSYGrYnvh6B5wCpWcdO2ieysvOXUeq9XxNcMRugbBwsC3i5VjykPV3Vr+L6eRbOegrN0vyXo=@vger.kernel.org X-Gm-Message-State: AOJu0Yxj65FVq4OgyDAZczYvaF1Ge1Wy9ycz5G0+aA1ZwYIFPJbkGiL+ 5zBhprt2yro+vgdIeBba/j1NDJg5J7VI34W71tVumU5hu4yMWCBUVLdWVksmEPuZ9ef6hvF279S 2Lm5iHiko+fryPg== X-Google-Smtp-Source: AGHT+IFJb6YKHG7FsGctRASU7SN/Xmn11wbzddlOneH7qwzJZxI7iFuP0ArzTQdk/B2z5AMcyD6QMK/6VaIElA== X-Received: from pfmu15.prod.google.com ([2002:aa7:838f:0:b0:7b8:909:1a1a]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:1824:b0:7ac:3529:afbb with SMTP id d2e1a72fcca58-7b7a4bf6d5amr4325970b3a.20.1762975380969; Wed, 12 Nov 2025 11:23:00 -0800 (PST) Date: Wed, 12 Nov 2025 19:22:25 +0000 In-Reply-To: <20251112192232.442761-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: <20251112192232.442761-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251112192232.442761-12-dmatlack@google.com> Subject: [PATCH v2 11/18] vfio: selftests: Move IOMMU library code into iommu.c From: David Matlack To: Alex Williamson Cc: Alex Mastro , Alex Williamson , 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. Signed-off-by: David Matlack Reviewed-by: Alex Mastro Tested-by: Alex Mastro --- .../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.rc1.455.g30608eb744-goog From nobody Sat Feb 7 18:20:49 2026 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 1B25C352FA5 for ; Wed, 12 Nov 2025 19:23:03 +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=1762975384; cv=none; b=o8x/SfMPyGY43GXNhMNNpDbW7odSJMmnci01XAM0RsI7hfIwdPqkhSJEWW2GWNjV/Tci24XZFiMCEaozUgx8q7OfL8Z+BtREeZUr0qzm+4mm5hDZnJK5VX40vxdVZBSIN9PWycy1rP+RInCciEdbPsRhyrOV9h2TuRC4Lm1zjzo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975384; c=relaxed/simple; bh=CkyC4vEq22xK1S2P6qHF080PFKlKoHtyS9Y4y4gmwns=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=jjsIOZqPeWksyNDx2O05RQIr1po3jncGtlYCeZs2ipxxb6/yecErEMfY+qIWih+KYHGVPSliOLa4CkzQVBmisIurrHAQdEwimgtcLapwFayu3PSUg2k3mBh7mOOjk0nfHL3sMhnpCG5mIEbzVUUEtx5KEzkDH6gF2Aje53k/paY= 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=e9GX4Siu; 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="e9GX4Siu" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7a440d38452so1920962b3a.0 for ; Wed, 12 Nov 2025 11:23:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762975382; x=1763580182; 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=/x7TxElv1Y0m6LMl9OrnCN+PJlJwFyshUcn1NViYdY8=; b=e9GX4SiuGpZ4KxxJdYuGGOkaUUkaYN4xL7f8kfZCChu4R2M9EMBb59YHdacXF2+glJ dPSkd8dzYKrAv7psurVDQ3EGTaRZNyGtGOiqmxsJeQhwa4jbD6l1nnT5aYwkA6mePugj SI4vTakuP4t5aJnLFQMOBNaNqjJzHyYe8m1OlBoDmiIFtPh6o+UqIl2tCHPMWe6nsxVX mD5PzUYMe3aBsz/xBnTfpZvZn0ZbIB/xuXs16Re6LHg9tpbOeu1vkRGNOKauvvBipjmn tqDrqGGXe+XYIHWsubrzfTHXHG/T86NBWJhZoDoipCQ+iFSMvQYcsP+gNECVIw8c+uL/ LhoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762975382; x=1763580182; 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=/x7TxElv1Y0m6LMl9OrnCN+PJlJwFyshUcn1NViYdY8=; b=LIc2cuxnsR8T4gnfbeh5uqhB6Qb+pEZIbX3dC63Yd8rwdde3LrodannPscipn5n2XA HsKoBNGnGgzUhneQpAkiCarmwE8akW893iOUX+6KfWjpkZ/Kl6ISQHKPLrdMoHDl/9um AFgatVN75/sSuyVCBK0VQftphjYawxG8FldoBmeeryZ6k4hzzrlHLcGG77CiE81rlcrZ RDnRsY4XZ5BUYQXWf0Q2LrrUo1Wye+8CYvLoBloOWvAfUWNLEfq8e1EMbdt4lVlTZyp3 XwQVCkTIUBSZ/4dRUhNXJA6mVeugss5jDiIyRJNDdsaf2GgObo6JlGSBawzD2r2w1uEa N90g== X-Forwarded-Encrypted: i=1; AJvYcCWg8eRMdIkDKWBMELP+5K6S12z5KemAmRB+U923caXkHHpg56tSvHx+zd6w4UAOUYY2v4ggq8vuOn+ca9w=@vger.kernel.org X-Gm-Message-State: AOJu0YxT2mrwOpuE76O3wL7vJmLzCI6Ff0gVRY+0DhN/F8jwl32lPX6D zQ0gMQbrQ7gCTIyHc6VgQmlaoA5DewS2hImTz1ATh+fYxxLAOgKWVMPMPxod0UBN8Tep+PLiWuC Zos7u6iE9fYA6jw== X-Google-Smtp-Source: AGHT+IHlexuAvDhnFGtg1cjQs73mJGUfm4wmIrjXrh2KvcJRouRaW+y+oFum0/DZIEri+Qoz+nn0V8NIBFvvdQ== X-Received: from pfoc3.prod.google.com ([2002:aa7:8803:0:b0:781:1533:32ab]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:1491:b0:792:5db2:73ac with SMTP id d2e1a72fcca58-7b7a23b3a68mr5122550b3a.7.1762975382516; Wed, 12 Nov 2025 11:23:02 -0800 (PST) Date: Wed, 12 Nov 2025 19:22:26 +0000 In-Reply-To: <20251112192232.442761-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: <20251112192232.442761-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251112192232.442761-13-dmatlack@google.com> Subject: [PATCH v2 12/18] vfio: selftests: Move IOVA allocator into iova_allocator.c From: David Matlack To: Alex Williamson Cc: Alex Mastro , Alex Williamson , 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. Signed-off-by: David Matlack Reviewed-by: Alex Mastro Tested-by: Alex Mastro --- .../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.rc1.455.g30608eb744-goog From nobody Sat Feb 7 18:20:49 2026 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.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 E45EF352FB8 for ; Wed, 12 Nov 2025 19:23:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975387; cv=none; b=MEPKt0L/AhuQilklfGAy0rOzrTUFLTFr36/B5pnig3Dwr3ZeksVbixE6wecnbTe4af6v0fmbBxLcNH8k6VpEldEiKRJAoKV06/t7BoQNH7mxRY0ffNqgcWVjGlWiF8bMxs7o/8h6vS/f3T0AjubC1YRi2w4y6o9lN6fvbtvTbeE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975387; c=relaxed/simple; bh=ziyqjUHtKMrKVd0zgnNDhJCsoHFy7brURyeLh0BmOG4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=JI8p0swybcE2qqgWFReh80xTqSxQ0yxK7B/wJtpZ58AnZ6znRSWr+3tNGwqVnkkSFDiSasOhyjvTgpPfd6ecTVrWxH0xl9CVvhOdQPxz/ez74whiplggx1NvhCQ1/DjGQ2HBNmMcKK5OLT3/O6v3VLoNlSWKEhGmIeDBREoF7BA= 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=DjMejYYJ; arc=none smtp.client-ip=209.85.215.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="DjMejYYJ" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-b55735710f0so2155100a12.2 for ; Wed, 12 Nov 2025 11:23:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762975384; x=1763580184; 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=QDUM2NK15b4A5lvtiNxBQOB3nHinOOh+D9L4COyosKw=; b=DjMejYYJ7ivyQLPWl+f8/P4SKUQ6KHoS7WtzrCJYB31srMxFI0Qgtj1YtlwT3JcyqY jGIBCqjfx5s9QOYGlaTsI1GDhjWPtAC1+u56m5ghbuU/hHPHG0sF+LUX7pNTpZk2tMyl 5JgVBoZFRi5gyXk0XIclqoGr4PEwuejfTFzlitgztPIR5Jp8oHgzj7k6FB3M7p6EnOl9 WBorFGzCUsmeHrfAfpf79JeMxz2AHlJqagjW9Dt6RHZHLzNt6hKCeHqv/PNayqbqh43N UusQsJO6YLY+1CESTev90v0SZ5hk2LvFD3ZA/jDapkAu6n4YgufF8rYQVFS5EfMgM9Cb eTHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762975384; x=1763580184; 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=QDUM2NK15b4A5lvtiNxBQOB3nHinOOh+D9L4COyosKw=; b=KFHmW7OcqWEYy1AYrjOdWEmcNx6B+z4PYo//58brZdKESScD4xozWUWbtjPMcqvLob ex+1qr60B0ZS8ANWGQt4GBJD/+SPaGPG6QytU5UzLEjdglW71LRv1O0lea3Sqque310T yao73DBDCm9oKVhTp3C7cOh0RCXdDh8YmmyBXkyg/wf/yQGHX0YJLlSIkcgfWu63IAZH Hesz6O7vu79Re86VHKp3AcTWShCUFqcExUYa1FGYyXEMT8/5olEO8T28t74rV28xP7Jm k9Mfkm8BxgwBH4fnMoDhy0JSkvWo2cik7cCdid6WfK59LrzrELx22xRWkfdg6SAsCbEB mUnQ== X-Forwarded-Encrypted: i=1; AJvYcCWILdiCv+4Uvd0l2xrRGGvWGDQgaYos2x8i9Zy8HwukPSz72b6wSDS9B2WKbZZYEVYrHulmIAnMKdrca1s=@vger.kernel.org X-Gm-Message-State: AOJu0Yxsmzx7bW5yyPTEGkjT8g/SEulNQW5X4zvHoJEILTjkob76NWDW CfFp5vPub/hW5QbM2Hb3yn0zMy/uibwZ9kzKXTihT6BUi0LpQe/te6SKBZe9GS4N3VLVlto/0Hn KrXrTDv4g1A82Yw== X-Google-Smtp-Source: AGHT+IEMXPRZlnocl6XkYY/pmIh7xcdwjbJWrd6xHc+Z+8UgXczaFCv9IRoJlhqyQP3H4kW5w1K5ojzUHkCJZw== X-Received: from pfuf34.prod.google.com ([2002:a05:6a00:b22:b0:77c:6e29:42af]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:7346:b0:343:3d3c:4685 with SMTP id adf61e73a8af0-3590988af94mr5335213637.18.1762975384015; Wed, 12 Nov 2025 11:23:04 -0800 (PST) Date: Wed, 12 Nov 2025 19:22:27 +0000 In-Reply-To: <20251112192232.442761-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: <20251112192232.442761-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251112192232.442761-14-dmatlack@google.com> Subject: [PATCH v2 13/18] vfio: selftests: Stop passing device for IOMMU operations From: David Matlack To: Alex Williamson Cc: Alex Mastro , Alex Williamson , 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. Signed-off-by: David Matlack Reviewed-by: Alex Mastro Tested-by: Alex Mastro --- .../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.rc1.455.g30608eb744-goog From nobody Sat Feb 7 18:20:49 2026 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.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 75254352FA4 for ; Wed, 12 Nov 2025 19:23:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975388; cv=none; b=jm4IBFbkraTnjjK3EEWYBWogsa9g/Bx9BKH0hGnu1WSqekt8V8DSgdDiJYhDlZ2ZMh2jhG+60lD5B046eipWlU1j8vAnRYtTu0U55eX2ztBcgA+BSU7rJy8CvmjJFUkB+HMFmERVbUQv3jeYbbol1Yb5Y6SSzgCQuTmq11wvA7U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975388; c=relaxed/simple; bh=SlxKyy8oGH9AOgazMhe2QdY/23hnybCjV1OgXyTJ4gE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=jp6YOk/ZInUmCtixVYOgou9sQi4NHKLkJ0C7MHzhKTzMFinFM+wzwaY1CT4eODCdD5EGrnOwLiOXnnilvPz1lK26N2mcR6k9g3SB5vz67Ux6GnLt3YqB9168blFYqFyl2Y4vUGg+gCIrYFU0hjJQQDS8bLS2kHNPwEnSqDJ7Jzg= 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=0C1eI0oX; arc=none smtp.client-ip=209.85.215.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="0C1eI0oX" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-b55735710f0so2155164a12.2 for ; Wed, 12 Nov 2025 11:23:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762975386; x=1763580186; 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=Kl4dnG1uPmBI4Dj/q7R4tdouJJ9NgauEmgKL1z09vYo=; b=0C1eI0oXtzqLpxewyWg/zvLQ5aCcXtxZgCAGJ/by2f4C23YfbcA95PHzaL5/NzJguy 9tmpR/jV//F3koY47MxY3oanlnjqKtYAVPSUkoCacNCTkuhjAT4JLc9/B6wo11r3nxm7 5V3mXsaZ9hp6LK17A2Pyp7+oL2KdvTTKAHfI7a7Ch8qOo7T2gvmcT9CYsDCtyErk88HY EIZ8ECHytnWwl45n1t8IkeqSZtQdcJhzNUgwqJqFovB8n+Hd7tOca1obXl1n075PI/87 YyvDlKGdKvKn8leNOooOS/M0cv836bILlxrt0PsrM7PbqZkfz/UPZd3JZOkWooHpt48r GChA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762975386; x=1763580186; 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=Kl4dnG1uPmBI4Dj/q7R4tdouJJ9NgauEmgKL1z09vYo=; b=hhh1BagE96w/TYah0iVTwfFyOV7gtkNtSbM+DYQkHcC7FUn+X021YUBl8EOQwRO23N rI6CZsxWoloUKU363tBdc8bkRj/v60UDxuo6x1e7+GZ4PiQCo8OhidsqaGWiHoPs6Xv/ E6EjGQ1S2Jw/osS5wOxhSBn3GsZLbaCYlqRKt5Tp+ml32tSF7KnEIg8T9ypQDZVye+OC ypf40e6biIyMs2VVM9fhXJVgSuwYpkfqYAaSKQ9OmSrcbCXHyAD+eWSWc9w7pYxYCqix zDdHnAWylYIfAoZNSNHxkY7bgYAHhp3S61+4IfdNctQz7dHZ1IRkEeeuwwhOu/nwTZ7j eHQQ== X-Forwarded-Encrypted: i=1; AJvYcCVgWSKiD/N44U46c1sHTy4Iu1P63QEGHOxBWQj5guD3E2FnOWnq9RzW3crTb+xU7wGVQwyPA23AAWlWIE8=@vger.kernel.org X-Gm-Message-State: AOJu0YxYi4D84PfsiOrwUzvPc+asNlJyGzYcB17/axiRAu2Wkk+8IQkW XNf1be/HlTIWBKvFQEhXiYg/qYTwrJFc5PLMbBmnwEtEvmBHfdxyMmL+1c08ACNcFjQzMLg8PzU +GAmyqRicCIIz/g== X-Google-Smtp-Source: AGHT+IEZIP9v/Os4raitXR3ccHA+MFQ26VDb0zn4z4lb+kU/9GjiM2FCWiiFc+zk9W9U21/lcYdl5KGclegMGA== X-Received: from pfhx36.prod.google.com ([2002:a05:6a00:18a4:b0:793:b157:af4f]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:6a05:b0:350:7238:7e2b with SMTP id adf61e73a8af0-35909696a00mr5195916637.16.1762975385707; Wed, 12 Nov 2025 11:23:05 -0800 (PST) Date: Wed, 12 Nov 2025 19:22:28 +0000 In-Reply-To: <20251112192232.442761-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: <20251112192232.442761-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251112192232.442761-15-dmatlack@google.com> Subject: [PATCH v2 14/18] vfio: selftests: Rename vfio_util.h to libvfio.h From: David Matlack To: Alex Williamson Cc: Alex Mastro , Alex Williamson , 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. Signed-off-by: David Matlack Reviewed-by: Alex Mastro Tested-by: Alex Mastro --- 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.rc1.455.g30608eb744-goog From nobody Sat Feb 7 18:20:49 2026 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 19EC93538BC for ; Wed, 12 Nov 2025 19:23:07 +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=1762975390; cv=none; b=JgxO3e7X0ib3hPHIQwcD6smi6DW4T01LhwcCtEZVJccgma9PofFsG5BOWL94wk00ZeZnl01YSErmwZRZCzDydvUcl90gRcN7njGQjUI+H7H1mXeQmel0u4I8Zc09Tqi6jNYZhTq9cVtKLBaj61JTda8dh/1qH/81Te4Wm5ekjt4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975390; c=relaxed/simple; bh=Rdjv74PUZl0xOdoDyaNF9pHG4jFNpAG6vGjvds5GMjY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=kMLlLaWqI/UbTHdKKuGnbI01+6siXwawrzoxxADdx8sNErGe8uNIyeCHND/7cmQCJq3vW5y0b2rF60zSmP7jKJA9oKNRzHwaRqFaEbGYWqkM7/9LHHpCjIyeaFjwD95OjVfcFVCMq0tYgt5xfIhiJ/QnHbMIaIbLDNrMPSLJJVs= 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=1DMRTDyZ; 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="1DMRTDyZ" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-29848363458so28111855ad.2 for ; Wed, 12 Nov 2025 11:23:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762975387; x=1763580187; 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=sJH3wdS9hE71Au7KE8+soqhHI3UwfGlKjMtxt+SoduY=; b=1DMRTDyZ61nBQtqhiKnR8Qke8uTnOcsIdbxg+ngyjYZenhviNfpeb728VAdAWfkUA8 9Dfp8xZMvGEeWFXG7sL/hSLZBexBPb6mt1vwbnoamvKhQA8Ql9kJrrZ+w4mmAvzcVQNC kA+oYcd3RGilRlX91m8aevI0Zw64K4psUk41PxNCyMdLyNmT1wzxHTviYTBv8n7tjpui qo+BZFwfgRDzH4Kh1pOI7mdi9SuxfnTb2+G4ezDQjUEkmC0huvXTRl1dHZpw9vueDp+9 cSQ/Fvji7AZoxUZrdkwqN8h26q3C8Pmfod+hRyHapsn1K9kTEUcaezNIO3PkA4aLctlr z5Zg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762975387; x=1763580187; 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=sJH3wdS9hE71Au7KE8+soqhHI3UwfGlKjMtxt+SoduY=; b=suXQKb56rDopN7k/koAe1JWhFUKc/RZ0F+OU+qi98MPK3w/9CAwAbGHfDiih9IhRdq wZt6vPyBMcjyJ6oHO+SzTWqsNnluJHt1M6seJ4wjx8JjiBHtl2Hobm3Ybh+FOqz7UT5u f5fvCh1s4vpGaKRgptIe7TUIsQ+FAp/7yWe0Uw03U96xCr5/OqYEJ31OSKtrsJfKRhDQ zgFuIALMt1p8QsQ+Maae5L8JT/KEusZf5PhA7ojKxWuWaOH5lFmMYu28DKSnKoJ2XRu1 dcXLLlbWshfwwQRFPRURfEeNYqjmee83oS3nmm6RnDHZfL2mxN57DLLDMSKoUijMsSAI 9rDw== X-Forwarded-Encrypted: i=1; AJvYcCXoPvZu/aLPWHm87bbEpW+kzcc14ntBHBsQkwbMSPJKKcB94mZAvu2jjO1SPr27z64bCk79MC1t59uhSfE=@vger.kernel.org X-Gm-Message-State: AOJu0Yz+ve6Y2fHIxIGShHtWZLRecpLRXU9Yz4D8xSspzWdmcRikJhk5 8cas4s2U4XUPcaq8iEWHcPv3jbytEwwUCtX7cE69+YR1LlgQ086540fQsUI2HJkA99NiKM0lMG3 dKE7VZfn6UpoCQw== X-Google-Smtp-Source: AGHT+IE880kIu+pp+tiLqIhvPDZIlY4YUq4eTXnOUsrY4PIHOZ9hOWXDYVMh8sA1Xz2ntVKcURODVdOqUyedwA== X-Received: from ploy7.prod.google.com ([2002:a17:903:1b27:b0:298:57bf:b76e]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:18b:b0:296:4d61:6cdb with SMTP id d9443c01a7336-2984eda429dmr56375075ad.27.1762975387352; Wed, 12 Nov 2025 11:23:07 -0800 (PST) Date: Wed, 12 Nov 2025 19:22:29 +0000 In-Reply-To: <20251112192232.442761-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: <20251112192232.442761-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251112192232.442761-16-dmatlack@google.com> Subject: [PATCH v2 15/18] vfio: selftests: Move vfio_selftests_*() helpers into libvfio.c From: David Matlack To: Alex Williamson Cc: Alex Mastro , Alex Williamson , 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. Signed-off-by: David Matlack Reviewed-by: Alex Mastro Tested-by: Alex Mastro --- 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.rc1.455.g30608eb744-goog From nobody Sat Feb 7 18:20:49 2026 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 8FA08354AC0 for ; Wed, 12 Nov 2025 19:23:09 +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=1762975392; cv=none; b=TNsEQW2bcjZxCznMky83/BDJFHigdomGttA2XBsObrPxWHxsDIgsHjfvJumfEWvOT2n9/vQwkYXqt9c/hXLORqo0OHl0zQf4mq9gM2439kVzg/HZZRcFUeM0g1hq07Hsky+qNeEuIWtAo6eptSz6RgcQBITK5/gqtL3940Nwe/o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975392; c=relaxed/simple; bh=dOViFrR5MBkt+N4V7muo97D+cowN+ArWgG3W7dZSZa4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=rxXzldPgt36de3r4fc86GbGXC3G1EtHlC5TwzwBZnPGfCcm5pwW1q7zKx/9IbFjBkHAf5FPM52U11GjH0Iv5eEnfYXDkFzY3WZP4o2UEv5uVqvfENU75o/zPkZMr6njkMokuJxUzioEVvrRyhXs84MMZ3S9yqsC1GT3NwA7vnuE= 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=PCyBYo9f; 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="PCyBYo9f" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2958c80fcabso27671895ad.0 for ; Wed, 12 Nov 2025 11:23:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762975389; x=1763580189; 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=zUbpJ5H6wYCbysm7/JHQOr1wPR/woklk+zZYwvBWqvI=; b=PCyBYo9fN2ziaIFaU7OkzbbEGUJ6AyarVlWNVs/qDuBN0s5eL8LGikRjqG33tbHKQR edknTnRo/oz2TS/sxvV2hk/xy0vwhQNFjb0q6Fr5gol/BDWWMlWbFD11/drPxC1SQxBT eU0LIOsPqDE4xHX8NTV6m2BC77N5miqe9XUgHz46Lmon2cGcybGRq5qF4YVXqbP9vuwS Pg48Rj9kpqNXzDUDpyH7aVVwQNqONYfmhp112wKtfQTOdJZMHlD5+L+43bzJHwbQ95nv 3dnU847/42JTEKhMgojOvd2nLb37aQq0gVxjSb5l/EHBTrEGoy2ZJu2BTBhWqCPm5rEn ZFQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762975389; x=1763580189; 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=zUbpJ5H6wYCbysm7/JHQOr1wPR/woklk+zZYwvBWqvI=; b=idFPZERO1r+2wbLDA9iHBL3c/QwCY8CayRjDxWQsfvQyOTGY21ZMCFGG+5OZWLLS5E 9JHeWMcSFmhovrnohvUgwY0JnyPwMtPUTQiq2CBULnDtU5YnfbVwK6ohmn3oARSjatBT PrNw1cwMzsJ/ji7QKl1kUXAcAGokFCxxuG4PseidCxQAVXamuE28iKN0oenULT6clnG1 SVrHRIwJRzE0pHbQh1/xNQP7A3mBoaiXojTCik3xT0droumnyS4KNMpf6iYOpol/DV2K rUAh4EJ4FAoIYbxW11hghD/tLq6IX/J/O66pZ3TFhmDmHQ3EMXvkt6potEZdozF8R/kb eQFg== X-Forwarded-Encrypted: i=1; AJvYcCV+LyLMLd/SxkCiO4QQNazlMzUmKd5CGFv3cfl+hUV74odvtmgWghliYkDKBQmEzybVcWHlZ3rgBSaJeCM=@vger.kernel.org X-Gm-Message-State: AOJu0YzSUqNNnkx/S2Iw7eG5g/bDvmV8+HRhVpFfqXANL2BaUpWk/90R pl4FxaZWFP6+odYC/XRRfhhbYAxNl5zmC07lejDvyZsBoXBFVzKC2vZvpKnqyVKSKWHaIpYNPDp jrMZf+2OGTDxo+w== X-Google-Smtp-Source: AGHT+IE0UeIxcvW4sWEmR/bkmgByJwNW8P+A8YevEQyTyTugANoVv2ucJWTtbkx80tloETCejfPW0UGB4/cL2Q== X-Received: from plbmg8.prod.google.com ([2002:a17:903:3488:b0:297:e597:f35b]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:2c04:b0:297:f8dd:4d8e with SMTP id d9443c01a7336-2984ede9532mr49845505ad.30.1762975388905; Wed, 12 Nov 2025 11:23:08 -0800 (PST) Date: Wed, 12 Nov 2025 19:22:30 +0000 In-Reply-To: <20251112192232.442761-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: <20251112192232.442761-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251112192232.442761-17-dmatlack@google.com> Subject: [PATCH v2 16/18] vfio: selftests: Split libvfio.h into separate header files From: David Matlack To: Alex Williamson Cc: Alex Mastro , Alex Williamson , 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. Signed-off-by: David Matlack Reviewed-by: Alex Mastro Tested-by: Alex Mastro --- .../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.rc1.455.g30608eb744-goog From nobody Sat Feb 7 18:20:49 2026 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 0AB1935502F for ; Wed, 12 Nov 2025 19:23: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=1762975393; cv=none; b=ROVcpdcsSaMt8hjvYyWXDs5LjTFbP1t2GC8QQWNkNGlj5HdF2HhlhZexFi0Vp4TELTj8A9EbVOsWhQXo6/ELvdVXuRa4qLmCwxNQdZa73rQiXh3DEn/DCvaXNC8o2L6MoD6UcxlB+rOEOWu8B5bnflv6OmDmfDut3+ggarXc6Fg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975393; c=relaxed/simple; bh=rNjCVJoNwWvayt/bmiXSzISNxmpCcsT2tGf1NIUi/4Q=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=GakeJjQaKMv2shzf30tEZaPLwnj0eJZJyEv3WLHBuFvajDJLyyZODBDPxe4VMnrNNsDnuAAkqoqKtX3gMJZhlVYVeREQJPj601KmLx1Px4lkUQ5mchb8kcpMw8KqunC3hxnir1QiFMVWpwPuyUaCe6Ysu/4eYAHdS/DAszkGfgQ= 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=WQ6bABC/; 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="WQ6bABC/" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7aa148105a2so1123568b3a.1 for ; Wed, 12 Nov 2025 11:23:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762975390; x=1763580190; 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=OKdUfWA8VBozuhxSSZUtzJUgC9/JHS2oDYkkS/YkkQc=; b=WQ6bABC/a1jngvzP34qzEOQVA/j3LFw5ynsoL1xdyUCTJDBhEpWpmvaUGZC27osVzN 0zYAlUFSNMR5kzf5HxSjLQIjyvhIS7ssHcMf2iplmgnNWLpa2ZD6rOQ5bO7Tf9U0pVt5 d0uK73TCjMTrl2jRiffK2WUG4TJntfNcC8kLL9PFPms9cNY/FQqai36ypfD2XL/WRGCa uEBkC/zCe4n2FUrQdMev69plSpBbdhpttJ/EwH771q+iM1nRoXwGryHYNZRjZDMOk71i mULb5rxiSPV9HqYIf/Q56pWWvpjbvKPOGj7FWQbQwZCrfelkeIAVdPK4JMqDEEC06VfH Az6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762975390; x=1763580190; 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=OKdUfWA8VBozuhxSSZUtzJUgC9/JHS2oDYkkS/YkkQc=; b=Ckr4fEifRtGybUzbNuyzuZLp9D8ijX+BuBbyXOuRWQ1VetWD4/H8j6gLHZw7v3aQnP 1NxU/PtZ4S4P237lWyGnKmw2WWdRb4MZKpuSPVPhl5OVZpt5txXZicxGETKmHbjOxwx+ HAhC7pylQTjCfk3Er8j5Cyci3o+/05F9YF5NPZQ2rzicf27p8LxZGApq135aQYlywUqG iInWpbD19AvjFBSVEC9c4suxDSwOa/t5GAk/ZMyA4B38YscJNzm9f1BETp1yctQPrBUZ 5yXP2Rf+x359noqHaGsvvmS/BPpl7KA5KT2nJoYSs5wradqvMBgUVPjep6VrrQLA6myq C4dg== X-Forwarded-Encrypted: i=1; AJvYcCWXoT9kN4uqTu3VlQoFpH14Vgk83f3NiD7l6QfdnfLA9cBe1gll1K2NHi0m4gENTBW+YpzNLm8940GFLrA=@vger.kernel.org X-Gm-Message-State: AOJu0Yyh5ciOdqHS/F90SFayHGqD2mOaDMjw7GUQkvGf3igsnBqliXGi IxWJtY+Ly+Pr6Ja5ndNiHkCDArdLg4cRD/MnmTNf3mKFoGiPG/8A6tzUktOVdc0ZammFF/EMem2 dAL8LSO4wVI2LIA== X-Google-Smtp-Source: AGHT+IFjHf53fSJAaoMvCAese1c2CReJLQvyP5+luooP4uX3A9bXodM94tdWMuD8m4gMAoe/7TUQGi6B8lf6sg== X-Received: from pfwo11.prod.google.com ([2002:a05:6a00:1bcb:b0:7ae:55f2:2f4a]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:3a20:b0:7ab:39a2:919b with SMTP id d2e1a72fcca58-7b7a48f5738mr4337298b3a.20.1762975390455; Wed, 12 Nov 2025 11:23:10 -0800 (PST) Date: Wed, 12 Nov 2025 19:22:31 +0000 In-Reply-To: <20251112192232.442761-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: <20251112192232.442761-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251112192232.442761-18-dmatlack@google.com> Subject: [PATCH v2 17/18] vfio: selftests: Eliminate INVALID_IOVA From: David Matlack To: Alex Williamson Cc: Alex Mastro , Alex Williamson , 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. Signed-off-by: David Matlack Reviewed-by: Alex Mastro Tested-by: Alex Mastro --- .../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.rc1.455.g30608eb744-goog From nobody Sat Feb 7 18:20:49 2026 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 AC9E1355058 for ; Wed, 12 Nov 2025 19:23:12 +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=1762975394; cv=none; b=NIjicbbyWOwOmWxI1BeU5SoBGYzqZ2AzuLPh2ntzqNT6tdUTqvNKItQigEyi/wzw3K8+isT/RQy0DpwGXEfowt8TrohCC9pQrMBhhNEJSMA3GR39CGWja4S5mLQJcuZEXqoGvc+4m4iJ6/pkS4mQFTNcMdG9Nu761XiATFnnrY8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762975394; c=relaxed/simple; bh=91BJdnU91RfIE/hJq59U7COO8d5lVht0pXvEtkmCCmc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=HlJBbzshE226YOjQvbTkjfJGv5CHYrjXxMUcaNXJ25J46UW9+pzCHQg2Qc2SBYZqteE3ETrpV5TM1G2+BwK6Kp5crcIGdYdfUVYu5Jw5XaxUYvr9UdM5nrXoOkSml9FO6APZFR6FtrUzca4ZDe8o3GfUiDWLTAE95iMglP9Gg8Q= 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=j6NksHB8; 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="j6NksHB8" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7b8a12f0cb4so461976b3a.3 for ; Wed, 12 Nov 2025 11:23:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762975392; x=1763580192; 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=o2e+js0Qy7w6O0gL6/BZx4eVZarhnCcJq/+q0M3UtfI=; b=j6NksHB8XILDLfnhzIeKF/vc+U3FFRqipwTXzqQYFgNrgijzd0NVRMQraOJ1miZm3R mFt7M38YZS5OEOLKWiuXKSoaYi0u0aHel9bWSVjybgvnP8jnZzbXuhCZJdBytXjfnxlB c9Q8LSgL4psSu2K/tiera/35A4uTZRx02A3RGGwplfUhSYGFYgn4JN9j8ao6/yNLZ8iu PuT1E0ehsOtO2G5Z2WFOMS/IVKgKmy4W72JHe6b9SiYJXArqcrnQ6Nz4BPXVRuWmvhFp 5qyEWfe482vI28Yt1HFE8L11ZqLpIzumQ+Z6nfkRkPDBoEyht14z3SDTZQO3jutgO0NO ycOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762975392; x=1763580192; 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=o2e+js0Qy7w6O0gL6/BZx4eVZarhnCcJq/+q0M3UtfI=; b=eV01mEh0sQ275E2MCN40ArZt1Ey2WmfOyo+z6exxp+SUKb3Yg+2hvDZ99mlr/jhx1E TTyrZL+hl1mbJYSblZwD0mkxQx1PmqelQFTjqPx8awPvJYCOOtc/uKhbxchs0qwQymZw z57NeFsyVZ4Bw/4fizZb5aamgDAfZJlro2/OiKouJzWcDRam0hL8BcG1V2MMcvH3GKsz bl2+FdMzbMV2RO5vaGzUdX/kqV41lwjoPzDFL7MqvuF3tmLDXlfLuF/KylL8HWHibH+p m828IUVpGy9batFq+IRTI5fKpXA0ngijvkZA1IYVTMJOYm0FYOTtwK7U88NoK7fP/KHZ bp9A== X-Forwarded-Encrypted: i=1; AJvYcCXraNzGwcqjXd35SZ/GJUmlVqKlh+zc2pV0pfVZOy81LlagYirELIJ4YuLHWn1+xRmZIg0pHnPdERwQVv4=@vger.kernel.org X-Gm-Message-State: AOJu0YxiimKjHMMBqAxc8FOHH4B/58+cOOwxc94BYIt7FH8S4TWqnvFm nvSjAGyrB9ZYv6VUFaTEWenHOMUkj70zgabm/8v5ECOTt4Dq2A5gN1sb3bgx8y3O7h0DLBIBBml 1a1ouAVq5GPCunA== X-Google-Smtp-Source: AGHT+IF8kvsYlmSEbjUQ/k2eUYglNUnLyK7Y7SQjAhLBmOM14SOm1bhd8hAnVvjd1DlYsknFTJKiG6sVMJVM+w== X-Received: from pfrj16.prod.google.com ([2002:aa7:8dd0:0:b0:7af:2faf:c3af]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:aa7:88c8:0:b0:7ab:e007:deec with SMTP id d2e1a72fcca58-7b7a53c10cfmr5819330b3a.32.1762975392025; Wed, 12 Nov 2025 11:23:12 -0800 (PST) Date: Wed, 12 Nov 2025 19:22:32 +0000 In-Reply-To: <20251112192232.442761-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: <20251112192232.442761-1-dmatlack@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251112192232.442761-19-dmatlack@google.com> Subject: [PATCH v2 18/18] vfio: selftests: Add vfio_pci_device_init_perf_test From: David Matlack To: Alex Williamson Cc: Alex Mastro , Alex Williamson , 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 Signed-off-by: David Matlack Reviewed-by: Alex Mastro Tested-by: Alex Mastro --- tools/testing/selftests/vfio/Makefile | 3 + .../vfio/vfio_pci_device_init_perf_test.c | 167 ++++++++++++++++++ 2 files changed, 170 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 e9e5c6dc63b6..8bb0b1e2d3a3 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_PROGS_EXTENDED :=3D scripts/cleanup.sh @@ -15,6 +16,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..54e327dadab4 --- /dev/null +++ b/tools/testing/selftests/vfio/vfio_pci_device_init_perf_test.c @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: GPL-2.0-only +#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 + 1000000000LL * (s64)ts.tv_sec; +} + +static struct timespec to_timespec(s64 ns) +{ + struct timespec ts =3D { + .tv_nsec =3D ns % 1000000000LL, + .tv_sec =3D ns / 1000000000LL, + }; + + 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.rc1.455.g30608eb744-goog