From nobody Tue Dec 16 20:46:00 2025 Received: from mail-oo1-f73.google.com (mail-oo1-f73.google.com [209.85.161.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A1B972868A6 for ; Wed, 10 Dec 2025 18:14:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765390465; cv=none; b=fd/o+yAnu5uYlnCLuT7WiYyT1xke1X2tMPROhF/00b69cUmJy8nmTHSDZEKr0QZ/HIwPEXc43Rn7CKwYFGCXLW+rGuBANpbUHMEoAvetqRTc+aZZbKs4H22FTn0b3Aro4kUah1BD1dr3s0SzDcfzQrLoBulKt1uHJUsfcPd3kbU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765390465; c=relaxed/simple; bh=/ESBV/uLL2EfJ9csOv0gKPED2tI1fK2KD3Shy693wVU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=H37I4Pj+KPYqWTKNHmGAuK7XrTmLagHz0T5gFs+jjIakSbFiO4tIxSSJQsTmEIQbjqgu1SLgtZ49P9apCzX8BhximWxI/clJEP3GS+renWeDDTV2re/grnLRmoz3FQS44AMt/9/MwGGcU/S1knIxMob2aulTFTUvrDi15OXp/rw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--rananta.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=L254X9hK; arc=none smtp.client-ip=209.85.161.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--rananta.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="L254X9hK" Received: by mail-oo1-f73.google.com with SMTP id 006d021491bc7-6574d3d44f9so121114eaf.3 for ; Wed, 10 Dec 2025 10:14:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1765390462; x=1765995262; 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=OADA+w36zyF2QwiRAwxFp/cNGe8R1v4XJPBiRDY9Wv0=; b=L254X9hKt5Mx1TcHuw9Ns03lmTl7p5PLTothqUBRx1xWrzXsO7jDTWRG2ZMAUYyjuZ kk6qzR1I46QA/wKqNciFt7/4/aewL+SN7jbZB9BW/Q5dlZJkPg8EuN3kNbCotTWipp3w 5I4xjz82DU8xZJt7Gb3Dn38jAJPBV+r4GBLl2DN7ElDLGsird12+AP/xvB209MTZ01i1 wi35XnUC3u6zRfzMB5TKysvk/E0ZKfnd4G0kZmyK1da1+c5hKAZ6q8HsacVfC8JJBmMi jFPeqUuzwp+/5lH5Y0kHVOcYe9xpThUxQ8bEiQ7ljJ50Id/qUXLaLSK+aj1GAmn4qKIx DlPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765390462; x=1765995262; 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=OADA+w36zyF2QwiRAwxFp/cNGe8R1v4XJPBiRDY9Wv0=; b=N1I0FQ4/z4u4xJ6BKWe/HN6QL+bBaFNe1E9vNHHscKuXSe7mmGatZkk7Dbf7Mls/wM czmDzFCZLV8KivC+JkV5HBj8ME7wO/I2v67Kgz3R0HHuDxwvDXiy10qZz8gEIvGROOOy TYJ/0r3EWOT0Z+pTxjBqmOpbNLMFLUzb187aSiL9421sqAED/lY9BB4iizAIz6FT9ruH pDPwgPG3eXlAM+nhIsG/u+b5bOqd9q6iBJUUd+G2OZiaoebRnAoZucIiMBNkEX4bE12/ l6LWbYIw+KjHnOB6UefLLGa1Mh8Qk2OG5kRdou3i/J/kxwGEjf5+OuK82uchzYxvmiD+ Q5MA== X-Forwarded-Encrypted: i=1; AJvYcCWfN0DYm/183hpPoM0IhtoogH7+3gkiNZVNC2/8ghn9YDvkQ6vUUAaoIWj5T0c4us8Gf4/xc8MCkmTqAa4=@vger.kernel.org X-Gm-Message-State: AOJu0YzsXNEJVdhTUXGF4+58TygvzNpHFU0qzLauCV3oq++LrUBSrYoi v8HcaCLhEuvxbW0E/KzBrxal3pTMaTAc4lvRxcPLwwCPYg6QenYWZvtz7ncSIGaWnrhKVC6DHh4 qmNuJImZhUw== X-Google-Smtp-Source: AGHT+IEuUilpfnFwrJTIh0iqV5NAI2XsS8nmu4AsQnCNm+ygdHl/IjoxgPSIRn1z8y5iHoKh8fA4kQBxFgRB X-Received: from ilbbz2.prod.google.com ([2002:a05:6e02:2682:b0:436:f324:45]) (user=rananta job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6820:2917:b0:659:9a49:9017 with SMTP id 006d021491bc7-65b2ad8f869mr2143102eaf.68.1765390462665; Wed, 10 Dec 2025 10:14:22 -0800 (PST) Date: Wed, 10 Dec 2025 18:14:13 +0000 In-Reply-To: <20251210181417.3677674-1-rananta@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251210181417.3677674-1-rananta@google.com> X-Mailer: git-send-email 2.52.0.239.gd5f0c6e74e-goog Message-ID: <20251210181417.3677674-3-rananta@google.com> Subject: [PATCH v2 2/6] vfio: selftests: Introduce a sysfs lib From: Raghavendra Rao Ananta To: David Matlack , Alex Williamson , Alex Williamson Cc: Josh Hilke , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Raghavendra Rao Ananta Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Introduce a sysfs liibrary to handle the common reads/writes to the PCI sysfs files, for example, getting the total number of VFs supported by the device via /sys/bus/pci/devices/$BDF/sriov_totalvfs. The library will be used in the upcoming test patch to configure the VFs for a given PF device. Opportunistically, move vfio_pci_get_group_from_dev() to this library as it falls under the same bucket. Rename it to sysfs_get_device_group() to align with other function names. Signed-off-by: Raghavendra Rao Ananta --- .../selftests/vfio/lib/include/libvfio.h | 1 + .../vfio/lib/include/libvfio/sysfs.h | 16 ++ tools/testing/selftests/vfio/lib/libvfio.mk | 1 + tools/testing/selftests/vfio/lib/sysfs.c | 151 ++++++++++++++++++ .../selftests/vfio/lib/vfio_pci_device.c | 22 +-- 5 files changed, 170 insertions(+), 21 deletions(-) create mode 100644 tools/testing/selftests/vfio/lib/include/libvfio/sysfs.h create mode 100644 tools/testing/selftests/vfio/lib/sysfs.c diff --git a/tools/testing/selftests/vfio/lib/include/libvfio.h b/tools/tes= ting/selftests/vfio/lib/include/libvfio.h index 279ddcd701944..bbe1d7616a648 100644 --- a/tools/testing/selftests/vfio/lib/include/libvfio.h +++ b/tools/testing/selftests/vfio/lib/include/libvfio.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include =20 diff --git a/tools/testing/selftests/vfio/lib/include/libvfio/sysfs.h b/too= ls/testing/selftests/vfio/lib/include/libvfio/sysfs.h new file mode 100644 index 0000000000000..1eca6b5cbcfcc --- /dev/null +++ b/tools/testing/selftests/vfio/lib/include/libvfio/sysfs.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_SYSFS_H +#define SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_SYSFS_H + +int sysfs_get_sriov_totalvfs(const char *bdf); +int sysfs_get_sriov_numvfs(const char *bdf); +void sysfs_set_sriov_numvfs(const char *bdfs, int numvfs); +void sysfs_get_sriov_vf_bdf(const char *pf_bdf, int i, char *out_vf_bdf); +bool sysfs_get_sriov_drivers_autoprobe(const char *bdf); +void sysfs_set_sriov_drivers_autoprobe(const char *bdf, bool val); +void sysfs_bind_driver(const char *bdf, const char *driver); +void sysfs_unbind_driver(const char *bdf, const char *driver); +int sysfs_get_driver(const char *bdf, char *out_driver); +unsigned int sysfs_get_device_group(const char *bdf); + +#endif /* SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_SYSFS_H */ diff --git a/tools/testing/selftests/vfio/lib/libvfio.mk b/tools/testing/se= lftests/vfio/lib/libvfio.mk index 9f47bceed16f4..b7857319c3f1f 100644 --- a/tools/testing/selftests/vfio/lib/libvfio.mk +++ b/tools/testing/selftests/vfio/lib/libvfio.mk @@ -6,6 +6,7 @@ LIBVFIO_SRCDIR :=3D $(selfdir)/vfio/lib LIBVFIO_C :=3D iommu.c LIBVFIO_C +=3D iova_allocator.c LIBVFIO_C +=3D libvfio.c +LIBVFIO_C +=3D sysfs.c LIBVFIO_C +=3D vfio_pci_device.c LIBVFIO_C +=3D vfio_pci_driver.c =20 diff --git a/tools/testing/selftests/vfio/lib/sysfs.c b/tools/testing/selft= ests/vfio/lib/sysfs.c new file mode 100644 index 0000000000000..5551e8b981075 --- /dev/null +++ b/tools/testing/selftests/vfio/lib/sysfs.c @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include +#include +#include + +#include + +static int sysfs_get_val(const char *component, const char *name, + const char *file) +{ + char path[PATH_MAX] =3D {0}; + char buf[32] =3D {0}; + int fd; + + snprintf(path, PATH_MAX, "/sys/bus/pci/%s/%s/%s", component, name, file); + fd =3D open(path, O_RDONLY); + if (fd < 0) + return fd; + + VFIO_ASSERT_GT(read(fd, buf, ARRAY_SIZE(buf)), 0); + VFIO_ASSERT_EQ(close(fd), 0); + + return strtol(buf, NULL, 0); +} + +static void sysfs_set_val(const char *component, const char *name, + const char *file, const char *val) +{ + char path[PATH_MAX] =3D {0}; + int fd; + + snprintf(path, PATH_MAX, "/sys/bus/pci/%s/%s/%s", component, name, file); + VFIO_ASSERT_GT(fd =3D open(path, O_WRONLY), 0); + + VFIO_ASSERT_EQ(write(fd, val, strlen(val)), strlen(val)); + VFIO_ASSERT_EQ(close(fd), 0); +} + +static int sysfs_get_device_val(const char *bdf, const char *file) +{ + sysfs_get_val("devices", bdf, file); +} + +static void sysfs_set_device_val(const char *bdf, const char *file, const = char *val) +{ + sysfs_set_val("devices", bdf, file, val); +} + +static void sysfs_set_driver_val(const char *driver, const char *file, con= st char *val) +{ + sysfs_set_val("drivers", driver, file, val); +} + +static void sysfs_set_device_val_int(const char *bdf, const char *file, in= t val) +{ + char val_str[32] =3D {0}; + + snprintf(val_str, sizeof(val_str), "%d", val); + sysfs_set_device_val(bdf, file, val_str); +} + +int sysfs_get_sriov_totalvfs(const char *bdf) +{ + return sysfs_get_device_val(bdf, "sriov_totalvfs"); +} + +int sysfs_get_sriov_numvfs(const char *bdf) +{ + return sysfs_get_device_val(bdf, "sriov_numvfs"); +} + +void sysfs_set_sriov_numvfs(const char *bdf, int numvfs) +{ + sysfs_set_device_val_int(bdf, "sriov_numvfs", numvfs); +} + +bool sysfs_get_sriov_drivers_autoprobe(const char *bdf) +{ + return (bool)sysfs_get_device_val(bdf, "sriov_drivers_autoprobe"); +} + +void sysfs_set_sriov_drivers_autoprobe(const char *bdf, bool val) +{ + sysfs_set_device_val_int(bdf, "sriov_drivers_autoprobe", val); +} + +void sysfs_bind_driver(const char *bdf, const char *driver) +{ + sysfs_set_driver_val(driver, "bind", bdf); +} + +void sysfs_unbind_driver(const char *bdf, const char *driver) +{ + sysfs_set_driver_val(driver, "unbind", bdf); +} + +void sysfs_get_sriov_vf_bdf(const char *pf_bdf, int i, char *out_vf_bdf) +{ + char vf_path[PATH_MAX] =3D {0}; + char path[PATH_MAX] =3D {0}; + int ret; + + snprintf(path, PATH_MAX, "/sys/bus/pci/devices/%s/virtfn%d", pf_bdf, i); + + ret =3D readlink(path, vf_path, PATH_MAX); + VFIO_ASSERT_NE(ret, -1); + + ret =3D sscanf(basename(vf_path), "%s", out_vf_bdf); + VFIO_ASSERT_EQ(ret, 1); +} + +unsigned int sysfs_get_device_group(const char *bdf) +{ + char dev_iommu_group_path[PATH_MAX] =3D {0}; + char path[PATH_MAX] =3D {0}; + unsigned int group; + int ret; + + snprintf(path, PATH_MAX, "/sys/bus/pci/devices/%s/iommu_group", bdf); + + ret =3D readlink(path, dev_iommu_group_path, sizeof(dev_iommu_group_path)= ); + VFIO_ASSERT_NE(ret, -1, "Failed to get the IOMMU group for device: %s\n",= bdf); + + ret =3D sscanf(basename(dev_iommu_group_path), "%u", &group); + VFIO_ASSERT_EQ(ret, 1, "Failed to get the IOMMU group for device: %s\n", = bdf); + + return group; +} + +int sysfs_get_driver(const char *bdf, char *out_driver) +{ + char driver_path[PATH_MAX] =3D {0}; + char path[PATH_MAX] =3D {0}; + int ret; + + snprintf(path, PATH_MAX, "/sys/bus/pci/devices/%s/driver", bdf); + ret =3D readlink(path, driver_path, PATH_MAX); + if (ret =3D=3D -1) { + if (errno =3D=3D ENOENT) + return -1; + + VFIO_FAIL("Failed to read %s\n", path); + } + + ret =3D sscanf(basename(driver_path), "%s", out_driver); + VFIO_ASSERT_EQ(ret, 1); + + return 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 64a19481b734f..9b2a123cee5fc 100644 --- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c +++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c @@ -22,8 +22,6 @@ #include "../../../kselftest.h" #include =20 -#define PCI_SYSFS_PATH "/sys/bus/pci/devices" - static void vfio_pci_irq_set(struct vfio_pci_device *device, u32 index, u32 vector, u32 count, int *fds) { @@ -181,24 +179,6 @@ void vfio_pci_device_reset(struct vfio_pci_device *dev= ice) ioctl_assert(device->fd, VFIO_DEVICE_RESET, NULL); } =20 -static unsigned int vfio_pci_get_group_from_dev(const char *bdf) -{ - char dev_iommu_group_path[PATH_MAX] =3D {0}; - char sysfs_path[PATH_MAX] =3D {0}; - unsigned int group; - int ret; - - snprintf_assert(sysfs_path, PATH_MAX, "%s/%s/iommu_group", PCI_SYSFS_PATH= , bdf); - - ret =3D readlink(sysfs_path, dev_iommu_group_path, sizeof(dev_iommu_group= _path)); - VFIO_ASSERT_NE(ret, -1, "Failed to get the IOMMU group for device: %s\n",= bdf); - - ret =3D sscanf(basename(dev_iommu_group_path), "%u", &group); - VFIO_ASSERT_EQ(ret, 1, "Failed to get the IOMMU group for device: %s\n", = bdf); - - return group; -} - static void vfio_pci_group_setup(struct vfio_pci_device *device, const cha= r *bdf) { struct vfio_group_status group_status =3D { @@ -207,7 +187,7 @@ static void vfio_pci_group_setup(struct vfio_pci_device= *device, const char *bdf char group_path[32]; int group; =20 - group =3D vfio_pci_get_group_from_dev(bdf); + group =3D sysfs_get_device_group(bdf); snprintf_assert(group_path, sizeof(group_path), "/dev/vfio/%d", group); =20 device->group_fd =3D open(group_path, O_RDWR); --=20 2.52.0.239.gd5f0c6e74e-goog