From nobody Mon Feb 9 01:06:27 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1565783878; cv=none; d=zoho.com; s=zohoarc; b=c59yTSsb6C+zefqIb3pdS1Z6J8aofOvcsvwfHndWZGvQkLvifi+uvkMu4sRdXhKGXbmgu3X2zK1s3NXjHtCpfEb6ZGGREDekXBkcSWnUe9HoJjZhHkFGs3ld88H2lnsG5aBocyJ8md9rd3Gey3rvMuTbsdMyqfq4pStYCzb46J4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1565783878; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=2fWL4lnkJU+TIKRZ1SQG5JZsJ1K5wxT+92Okrjcr3eI=; b=Eup2l9vQtVbYakFQyBDsaIGZMwpsWLCT3sk0jZqMP48eBvuAENyYSoVFdM05LgeSMldgtm7lmo6rVvgZi8kg7vaH4n6yyUJCSMejnuGOTOTwD2Snjexn57kfRkgtp1ZJkvfPgXKaNOWx/PaNVgTgL7V1Aonm125gVD39jURhSEE= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1565783878963245.71641561339015; Wed, 14 Aug 2019 04:57:58 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5057B3001467; Wed, 14 Aug 2019 11:57:57 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id F3CC07AB72; Wed, 14 Aug 2019 11:57:56 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 792E71C89; Wed, 14 Aug 2019 11:57:55 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x7EBvsaT015485 for ; Wed, 14 Aug 2019 07:57:54 -0400 Received: by smtp.corp.redhat.com (Postfix) id 3FD3B348C3; Wed, 14 Aug 2019 11:57:54 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.30]) by smtp.corp.redhat.com (Postfix) with ESMTP id BF06D34940 for ; Wed, 14 Aug 2019 11:57:53 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 14 Aug 2019 13:57:32 +0200 Message-Id: <3a54dd800f660c24922ad83a77c634b2bd4b1866.1565777704.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 03/18] virpcimock: Create driver_override file in device dirs X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Wed, 14 Aug 2019 11:57:57 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Newer kernels (v3.16-rc1~29^2~6^4) have 'driver_override' file which simplifies way of binding a PCI device to desired driver. Libvirt has support for this for some time too (v2.3.0-rc1~236), but not our virpcimock. So far we did not care because our code is designed to deal with this situation. Except for one. hypothetical case: binding a device to the vfio-pci driver can be successful only via driver_override. Any attempt to bind a PCI device to vfio-pci driver using old method (new_id + unbind + bind) will fail because of b803b29c1a5. While on vanilla kernel I'm able to use the old method successfully, it's failing on RHEL kernels (not sure why). Signed-off-by: Michal Privoznik Reviewed-by: Daniel Henrique Barboza --- tests/virpcimock.c | 52 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/tests/virpcimock.c b/tests/virpcimock.c index 6865f992dc..1c21e4e045 100644 --- a/tests/virpcimock.c +++ b/tests/virpcimock.c @@ -87,6 +87,11 @@ char *fakesysfspcidir; * Probe for a driver that handles the specified device. * Data in format "DDDD:BB:DD.F" (Domain:Bus:Device.Function). * + * /sys/bus/pci/devices//driver_override + * Name of a driver that overrides preferred driver can be written + * here. The device will be attached to it on drivers_probe event. + * Writing an empty string (or "\n") clears the override. + * * As a little hack, we are not mocking write to these files, but close() * instead. The advantage is we don't need any self growing array to hold = the * partial writes and construct them back. We can let all the writes finis= h, @@ -147,6 +152,7 @@ static struct pciDevice *pci_device_find_by_content(con= st char *path); static void pci_driver_new(const char *name, int fail, ...); static struct pciDriver *pci_driver_find_by_dev(struct pciDevice *dev); static struct pciDriver *pci_driver_find_by_path(const char *path); +static struct pciDriver *pci_driver_find_by_driver_override(struct pciDevi= ce *dev); static int pci_driver_bind(struct pciDriver *driver, struct pciDevice *dev= ); static int pci_driver_unbind(struct pciDriver *driver, struct pciDevice *d= ev); static int pci_driver_handle_change(int fd, const char *path); @@ -202,7 +208,8 @@ make_symlink(const char *path, static int pci_read_file(const char *path, char *buf, - size_t buf_size) + size_t buf_size, + bool truncate) { int ret =3D -1; int fd =3D -1; @@ -224,7 +231,8 @@ pci_read_file(const char *path, goto cleanup; } =20 - if (ftruncate(fd, 0) < 0) + if (truncate && + ftruncate(fd, 0) < 0) goto cleanup; =20 ret =3D 0; @@ -398,6 +406,8 @@ pci_device_new_from_stub(const struct pciDevice *data) ABORT("@tmp overflow"); make_file(devpath, "class", tmp, -1); =20 + make_file(devpath, "driver_override", NULL, -1); + if (snprintf(tmp, sizeof(tmp), "%s/../../../kernel/iommu_groups/%d", devpath, dev->iommuGroup) < 0) { @@ -441,7 +451,7 @@ pci_device_find_by_content(const char *path) { char tmp[32]; =20 - if (pci_read_file(path, tmp, sizeof(tmp)) < 0) + if (pci_read_file(path, tmp, sizeof(tmp), true) < 0) return NULL; =20 return pci_device_find_by_id(tmp); @@ -450,7 +460,10 @@ pci_device_find_by_content(const char *path) static int pci_device_autobind(struct pciDevice *dev) { - struct pciDriver *driver =3D pci_driver_find_by_dev(dev); + struct pciDriver *driver =3D pci_driver_find_by_driver_override(dev); + + if (!driver) + driver =3D pci_driver_find_by_dev(dev); =20 if (!driver) { /* No driver found. Nothing to do */ @@ -544,6 +557,31 @@ pci_driver_find_by_path(const char *path) return NULL; } =20 +static struct pciDriver * +pci_driver_find_by_driver_override(struct pciDevice *dev) +{ + VIR_AUTOFREE(char *) path =3D NULL; + char tmp[32]; + size_t i; + + if (virAsprintfQuiet(&path, + SYSFS_PCI_PREFIX "devices/%s/driver_override", + dev->id) < 0) + return NULL; + + if (pci_read_file(path, tmp, sizeof(tmp), false) < 0) + return NULL; + + for (i =3D 0; i < nPCIDrivers; i++) { + struct pciDriver *driver =3D pciDrivers[i]; + + if (STREQ(tmp, driver->name)) + return driver; + } + + return NULL; +} + static int pci_driver_bind(struct pciDriver *driver, struct pciDevice *dev) @@ -657,6 +695,8 @@ pci_driver_handle_change(int fd ATTRIBUTE_UNUSED, const= char *path) ret =3D pci_driver_handle_remove_id(path); else if (STREQ(file, "drivers_probe")) ret =3D pci_driver_handle_drivers_probe(path); + else if (STREQ(file, "driver_override")) + ret =3D 0; /* nada */ else ABORT("Not handled write to: %s", path); return ret; @@ -711,7 +751,7 @@ pci_driver_handle_new_id(const char *path) goto cleanup; } =20 - if (pci_read_file(path, buf, sizeof(buf)) < 0) + if (pci_read_file(path, buf, sizeof(buf), true) < 0) goto cleanup; =20 if (sscanf(buf, "%x %x", &vendor, &device) < 2) { @@ -766,7 +806,7 @@ pci_driver_handle_remove_id(const char *path) goto cleanup; } =20 - if (pci_read_file(path, buf, sizeof(buf)) < 0) + if (pci_read_file(path, buf, sizeof(buf), true) < 0) goto cleanup; =20 if (sscanf(buf, "%x %x", &vendor, &device) < 2) { --=20 2.21.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list