On Fri, Jan 05, 2024 at 03:20:16 -0500, Laine Stump wrote: > Rather than always binding to the vfio-pci driver, use the new > function virPCIDeviceFindBestVFIOVariant() to see if the running > kernel has a VFIO variant driver available that is a better match for > the device, and if one is found, use that instead. > > virPCIDeviceFindBestVFIOVariant() function reads the modalias file for > the given device from sysfs, then looks through > /lib/modules/${kernel_release}/modules.alias for the vfio_pci alias > that matches with the least number of wildcard ('*') fields. > > The appropriate "VFIO variant" driver for a device will be the PCI > driver implemented by the discovered module - these drivers are > compatible with (and provide the entire API of) the standard vfio-pci > driver, but have additional device-specific APIs that can be useful > for, e.g., saving/restoring state for migration. > > If a specific driver is named (using <driver model='blah'/> in the > device XML), that will still be used rather than searching > modules.alias; this makes it possible to force binding of vfio-pci if > there is an issue with the auto-selected variant driver. > > Signed-off-by: Laine Stump <laine@xxxxxxxxxx> > --- > > Changes from V2: > > * fail if device modalias file isn't found. This [1] ... > * use unsigned int instead of int for wildcardCt > * increase file memory buffer from 4MB to 8MB > * other minor nits pointed out by Peter [...] > +/* virPCIDeviceFindBestVFIOVariant: > + * > + * Find the "best" match of all vfio_pci aliases for @dev in the host > + * modules.alias file. This uses the algorithm of finding every > + * modules.alias line that begins with "vfio_pci:", then picking the > + * one that matches the device's own modalias value (from the file of > + * that name in the device's sysfs directory) with the fewest > + * "wildcards" (* character, meaning "match any value for this > + * attribute"). > + */ > +int > +virPCIDeviceFindBestVFIOVariant(virPCIDevice *dev, > + char **moduleName) > +{ > + g_autofree char *devModAliasPath = NULL; > + g_autofree char *devModAliasContent = NULL; > + const char *devModAlias; > + g_autoptr(virPCIDeviceAliasInfo) devModAliasInfo = NULL; > + struct utsname unameInfo; > + g_autofree char *modulesAliasPath = NULL; > + g_autofree char *modulesAliasContent = NULL; > + const char *line; > + unsigned int currentBestWildcardCt = INT_MAX; UINT_MAX > + > + *moduleName = NULL; > + > + /* get the modalias values for the device from sysfs */ > + devModAliasPath = virPCIFile(dev->name, "modalias"); > + if (virFileReadAll(devModAliasPath, 100, &devModAliasContent) < 0) ... [1] isn't true. > + return -1; > + > + VIR_DEBUG("modalias path: '%s' contents: '%s'", > + devModAliasPath, devModAliasContent); > + > + /* "pci:vNNNNNNNNdNNNNNNNNsvNNNNNNNNsdNNNNNNNNbcNNscNNiNN\n" */ > + if ((devModAlias = STRSKIP(devModAliasContent, "pci:")) == NULL || > + !(devModAliasInfo = virPCIDeviceAliasInfoNew(devModAlias))) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("device modalias file %1$s content has improper format"), > + devModAliasPath); > + return -1; > + } > + > + uname(&unameInfo); > + modulesAliasPath = g_strdup_printf("/lib/modules/%s/modules.alias", unameInfo.release); > + if (virFileReadAll(modulesAliasPath, 8 * 1024 * 1024, &modulesAliasContent) < 0) > + return -1; IIUC this is picking a driver which is 'better' than the default 'vfio_pci', but the device itself would still work if the default were used, right? In such case do we really want to treat any of the errors above as failures? I presueme a workaround for if any of the above breaks is to use an explicitly specified driver, right? > + > + /* Look for all lines that are aliases for vfio_pci drivers. > + * (The first line is always a comment, so we can be sure "alias" > + * is preceded by a newline) > + */ > + line = modulesAliasContent; > + _______________________________________________ Devel mailing list -- devel@xxxxxxxxxxxxxxxxx To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxx