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 <[email protected]>
> ---
>
> 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 -- [email protected]
To unsubscribe send an email to [email protected]