virtualization.lists.linux-foundation.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/1] virtio: add driver_override support
@ 2025-12-08 22:09 Max Gurtovoy
  2025-12-09 15:48 ` Stefan Hajnoczi
  2025-12-09 16:34 ` Michael S. Tsirkin
  0 siblings, 2 replies; 7+ messages in thread
From: Max Gurtovoy @ 2025-12-08 22:09 UTC (permalink / raw)
  To: mst, stefanha, sgarzare, virtualization, kvm
  Cc: oren, aevdaev, aaptel, Max Gurtovoy

Add support for the 'driver_override' attribute to Virtio devices. This
allows users to control which Virtio bus driver binds to a given Virtio
device.

If 'driver_override' is not set, the existing behavior is preserved and
devices will continue to auto-bind to the first matching Virtio bus
driver.

Tested with virtio blk device (virtio core and pci drivers are loaded):

  $ modprobe my_virtio_blk

  # automatically unbind from virtio_blk driver and override + bind to
  # my_virtio_blk driver.
  $ driverctl -v -b virtio set-override virtio0 my_virtio_blk

In addition, driverctl saves the configuration persistently under
/etc/driverctl.d/.

Signed-off-by: Avraham Evdaev <aevdaev@nvidia.com>
Signed-off-by: Max Gurtovoy <mgurtovoy@nvidia.com>
---

changes from v1:
 - use !strcmp() to compare strings (MST)
 - extend commit msg with example (MST)

---
 drivers/virtio/virtio.c | 34 ++++++++++++++++++++++++++++++++++
 include/linux/virtio.h  |  4 ++++
 2 files changed, 38 insertions(+)

diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index a09eb4d62f82..993dc928be49 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -61,12 +61,41 @@ static ssize_t features_show(struct device *_d,
 }
 static DEVICE_ATTR_RO(features);
 
+static ssize_t driver_override_store(struct device *_d,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct virtio_device *dev = dev_to_virtio(_d);
+	int ret;
+
+	ret = driver_set_override(_d, &dev->driver_override, buf, count);
+	if (ret)
+		return ret;
+
+	return count;
+}
+
+static ssize_t driver_override_show(struct device *_d,
+				    struct device_attribute *attr, char *buf)
+{
+	struct virtio_device *dev = dev_to_virtio(_d);
+	ssize_t len;
+
+	device_lock(_d);
+	len = sysfs_emit(buf, "%s\n", dev->driver_override);
+	device_unlock(_d);
+
+	return len;
+}
+static DEVICE_ATTR_RW(driver_override);
+
 static struct attribute *virtio_dev_attrs[] = {
 	&dev_attr_device.attr,
 	&dev_attr_vendor.attr,
 	&dev_attr_status.attr,
 	&dev_attr_modalias.attr,
 	&dev_attr_features.attr,
+	&dev_attr_driver_override.attr,
 	NULL,
 };
 ATTRIBUTE_GROUPS(virtio_dev);
@@ -88,6 +117,10 @@ static int virtio_dev_match(struct device *_dv, const struct device_driver *_dr)
 	struct virtio_device *dev = dev_to_virtio(_dv);
 	const struct virtio_device_id *ids;
 
+	/* Check override first, and if set, only use the named driver */
+	if (dev->driver_override)
+		return !strcmp(dev->driver_override, _dr->name);
+
 	ids = drv_to_virtio(_dr)->id_table;
 	for (i = 0; ids[i].device; i++)
 		if (virtio_id_match(dev, &ids[i]))
@@ -582,6 +615,7 @@ void unregister_virtio_device(struct virtio_device *dev)
 {
 	int index = dev->index; /* save for after device release */
 
+	kfree(dev->driver_override);
 	device_unregister(&dev->dev);
 	virtio_debug_device_exit(dev);
 	ida_free(&virtio_index_ida, index);
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index db31fc6f4f1f..418bb490bdc6 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -138,6 +138,9 @@ struct virtio_admin_cmd {
  * @config_lock: protects configuration change reporting
  * @vqs_list_lock: protects @vqs.
  * @dev: underlying device.
+ * @driver_override: driver name to force a match; do not set directly,
+ *                   because core frees it; use driver_set_override() to
+ *                   set or clear it.
  * @id: the device type identification (used to match it with a driver).
  * @config: the configuration ops for this device.
  * @vringh_config: configuration ops for host vrings.
@@ -158,6 +161,7 @@ struct virtio_device {
 	spinlock_t config_lock;
 	spinlock_t vqs_list_lock;
 	struct device dev;
+	const char *driver_override;
 	struct virtio_device_id id;
 	const struct virtio_config_ops *config;
 	const struct vringh_config_ops *vringh_config;
-- 
2.18.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/1] virtio: add driver_override support
  2025-12-08 22:09 [PATCH v2 1/1] virtio: add driver_override support Max Gurtovoy
@ 2025-12-09 15:48 ` Stefan Hajnoczi
  2025-12-09 16:34 ` Michael S. Tsirkin
  1 sibling, 0 replies; 7+ messages in thread
From: Stefan Hajnoczi @ 2025-12-09 15:48 UTC (permalink / raw)
  To: Max Gurtovoy; +Cc: mst, sgarzare, virtualization, kvm, oren, aevdaev, aaptel

[-- Attachment #1: Type: text/plain, Size: 4406 bytes --]

On Tue, Dec 09, 2025 at 12:09:08AM +0200, Max Gurtovoy wrote:
> Add support for the 'driver_override' attribute to Virtio devices. This
> allows users to control which Virtio bus driver binds to a given Virtio
> device.
> 
> If 'driver_override' is not set, the existing behavior is preserved and
> devices will continue to auto-bind to the first matching Virtio bus
> driver.
> 
> Tested with virtio blk device (virtio core and pci drivers are loaded):
> 
>   $ modprobe my_virtio_blk
> 
>   # automatically unbind from virtio_blk driver and override + bind to
>   # my_virtio_blk driver.
>   $ driverctl -v -b virtio set-override virtio0 my_virtio_blk

Why a second virtio-blk driver implementation? Please explain the use
case.

Thanks,
Stefan

> In addition, driverctl saves the configuration persistently under
> /etc/driverctl.d/.
> 
> Signed-off-by: Avraham Evdaev <aevdaev@nvidia.com>
> Signed-off-by: Max Gurtovoy <mgurtovoy@nvidia.com>
> ---
> 
> changes from v1:
>  - use !strcmp() to compare strings (MST)
>  - extend commit msg with example (MST)
> 
> ---
>  drivers/virtio/virtio.c | 34 ++++++++++++++++++++++++++++++++++
>  include/linux/virtio.h  |  4 ++++
>  2 files changed, 38 insertions(+)
> 
> diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
> index a09eb4d62f82..993dc928be49 100644
> --- a/drivers/virtio/virtio.c
> +++ b/drivers/virtio/virtio.c
> @@ -61,12 +61,41 @@ static ssize_t features_show(struct device *_d,
>  }
>  static DEVICE_ATTR_RO(features);
>  
> +static ssize_t driver_override_store(struct device *_d,
> +				     struct device_attribute *attr,
> +				     const char *buf, size_t count)
> +{
> +	struct virtio_device *dev = dev_to_virtio(_d);
> +	int ret;
> +
> +	ret = driver_set_override(_d, &dev->driver_override, buf, count);
> +	if (ret)
> +		return ret;
> +
> +	return count;
> +}
> +
> +static ssize_t driver_override_show(struct device *_d,
> +				    struct device_attribute *attr, char *buf)
> +{
> +	struct virtio_device *dev = dev_to_virtio(_d);
> +	ssize_t len;
> +
> +	device_lock(_d);
> +	len = sysfs_emit(buf, "%s\n", dev->driver_override);
> +	device_unlock(_d);
> +
> +	return len;
> +}
> +static DEVICE_ATTR_RW(driver_override);
> +
>  static struct attribute *virtio_dev_attrs[] = {
>  	&dev_attr_device.attr,
>  	&dev_attr_vendor.attr,
>  	&dev_attr_status.attr,
>  	&dev_attr_modalias.attr,
>  	&dev_attr_features.attr,
> +	&dev_attr_driver_override.attr,
>  	NULL,
>  };
>  ATTRIBUTE_GROUPS(virtio_dev);
> @@ -88,6 +117,10 @@ static int virtio_dev_match(struct device *_dv, const struct device_driver *_dr)
>  	struct virtio_device *dev = dev_to_virtio(_dv);
>  	const struct virtio_device_id *ids;
>  
> +	/* Check override first, and if set, only use the named driver */
> +	if (dev->driver_override)
> +		return !strcmp(dev->driver_override, _dr->name);
> +
>  	ids = drv_to_virtio(_dr)->id_table;
>  	for (i = 0; ids[i].device; i++)
>  		if (virtio_id_match(dev, &ids[i]))
> @@ -582,6 +615,7 @@ void unregister_virtio_device(struct virtio_device *dev)
>  {
>  	int index = dev->index; /* save for after device release */
>  
> +	kfree(dev->driver_override);
>  	device_unregister(&dev->dev);
>  	virtio_debug_device_exit(dev);
>  	ida_free(&virtio_index_ida, index);
> diff --git a/include/linux/virtio.h b/include/linux/virtio.h
> index db31fc6f4f1f..418bb490bdc6 100644
> --- a/include/linux/virtio.h
> +++ b/include/linux/virtio.h
> @@ -138,6 +138,9 @@ struct virtio_admin_cmd {
>   * @config_lock: protects configuration change reporting
>   * @vqs_list_lock: protects @vqs.
>   * @dev: underlying device.
> + * @driver_override: driver name to force a match; do not set directly,
> + *                   because core frees it; use driver_set_override() to
> + *                   set or clear it.
>   * @id: the device type identification (used to match it with a driver).
>   * @config: the configuration ops for this device.
>   * @vringh_config: configuration ops for host vrings.
> @@ -158,6 +161,7 @@ struct virtio_device {
>  	spinlock_t config_lock;
>  	spinlock_t vqs_list_lock;
>  	struct device dev;
> +	const char *driver_override;
>  	struct virtio_device_id id;
>  	const struct virtio_config_ops *config;
>  	const struct vringh_config_ops *vringh_config;
> -- 
> 2.18.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/1] virtio: add driver_override support
  2025-12-08 22:09 [PATCH v2 1/1] virtio: add driver_override support Max Gurtovoy
  2025-12-09 15:48 ` Stefan Hajnoczi
@ 2025-12-09 16:34 ` Michael S. Tsirkin
  2025-12-09 17:45   ` Max Gurtovoy
  1 sibling, 1 reply; 7+ messages in thread
From: Michael S. Tsirkin @ 2025-12-09 16:34 UTC (permalink / raw)
  To: Max Gurtovoy
  Cc: stefanha, sgarzare, virtualization, kvm, oren, aevdaev, aaptel

On Tue, Dec 09, 2025 at 12:09:08AM +0200, Max Gurtovoy wrote:
> Add support for the 'driver_override' attribute to Virtio devices. This
> allows users to control which Virtio bus driver binds to a given Virtio
> device.
> 
> If 'driver_override' is not set, the existing behavior is preserved and
> devices will continue to auto-bind to the first matching Virtio bus
> driver.

oh, it's a device driver not the bus driver, actually.

> Tested with virtio blk device (virtio core and pci drivers are loaded):
> 
>   $ modprobe my_virtio_blk
> 
>   # automatically unbind from virtio_blk driver and override + bind to
>   # my_virtio_blk driver.
>   $ driverctl -v -b virtio set-override virtio0 my_virtio_blk
> 
> In addition, driverctl saves the configuration persistently under
> /etc/driverctl.d/.

what is this "mydriver" though? what are valid examples that
we want to support? 

> 
> Signed-off-by: Avraham Evdaev <aevdaev@nvidia.com>
> Signed-off-by: Max Gurtovoy <mgurtovoy@nvidia.com>
> ---
> 
> changes from v1:
>  - use !strcmp() to compare strings (MST)
>  - extend commit msg with example (MST)
> 
> ---
>  drivers/virtio/virtio.c | 34 ++++++++++++++++++++++++++++++++++
>  include/linux/virtio.h  |  4 ++++
>  2 files changed, 38 insertions(+)
> 
> diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
> index a09eb4d62f82..993dc928be49 100644
> --- a/drivers/virtio/virtio.c
> +++ b/drivers/virtio/virtio.c
> @@ -61,12 +61,41 @@ static ssize_t features_show(struct device *_d,
>  }
>  static DEVICE_ATTR_RO(features);
>  
> +static ssize_t driver_override_store(struct device *_d,
> +				     struct device_attribute *attr,
> +				     const char *buf, size_t count)
> +{
> +	struct virtio_device *dev = dev_to_virtio(_d);
> +	int ret;
> +
> +	ret = driver_set_override(_d, &dev->driver_override, buf, count);
> +	if (ret)
> +		return ret;
> +
> +	return count;
> +}
> +
> +static ssize_t driver_override_show(struct device *_d,
> +				    struct device_attribute *attr, char *buf)
> +{
> +	struct virtio_device *dev = dev_to_virtio(_d);
> +	ssize_t len;
> +
> +	device_lock(_d);
> +	len = sysfs_emit(buf, "%s\n", dev->driver_override);
> +	device_unlock(_d);
> +
> +	return len;
> +}
> +static DEVICE_ATTR_RW(driver_override);
> +
>  static struct attribute *virtio_dev_attrs[] = {
>  	&dev_attr_device.attr,
>  	&dev_attr_vendor.attr,
>  	&dev_attr_status.attr,
>  	&dev_attr_modalias.attr,
>  	&dev_attr_features.attr,
> +	&dev_attr_driver_override.attr,
>  	NULL,
>  };
>  ATTRIBUTE_GROUPS(virtio_dev);
> @@ -88,6 +117,10 @@ static int virtio_dev_match(struct device *_dv, const struct device_driver *_dr)
>  	struct virtio_device *dev = dev_to_virtio(_dv);
>  	const struct virtio_device_id *ids;
>  
> +	/* Check override first, and if set, only use the named driver */
> +	if (dev->driver_override)
> +		return !strcmp(dev->driver_override, _dr->name);
> +
>  	ids = drv_to_virtio(_dr)->id_table;
>  	for (i = 0; ids[i].device; i++)
>  		if (virtio_id_match(dev, &ids[i]))
> @@ -582,6 +615,7 @@ void unregister_virtio_device(struct virtio_device *dev)
>  {
>  	int index = dev->index; /* save for after device release */
>  
> +	kfree(dev->driver_override);
>  	device_unregister(&dev->dev);
>  	virtio_debug_device_exit(dev);
>  	ida_free(&virtio_index_ida, index);
> diff --git a/include/linux/virtio.h b/include/linux/virtio.h
> index db31fc6f4f1f..418bb490bdc6 100644
> --- a/include/linux/virtio.h
> +++ b/include/linux/virtio.h
> @@ -138,6 +138,9 @@ struct virtio_admin_cmd {
>   * @config_lock: protects configuration change reporting
>   * @vqs_list_lock: protects @vqs.
>   * @dev: underlying device.
> + * @driver_override: driver name to force a match; do not set directly,
> + *                   because core frees it; use driver_set_override() to
> + *                   set or clear it.
>   * @id: the device type identification (used to match it with a driver).
>   * @config: the configuration ops for this device.
>   * @vringh_config: configuration ops for host vrings.
> @@ -158,6 +161,7 @@ struct virtio_device {
>  	spinlock_t config_lock;
>  	spinlock_t vqs_list_lock;
>  	struct device dev;
> +	const char *driver_override;
>  	struct virtio_device_id id;
>  	const struct virtio_config_ops *config;
>  	const struct vringh_config_ops *vringh_config;
> -- 
> 2.18.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/1] virtio: add driver_override support
  2025-12-09 16:34 ` Michael S. Tsirkin
@ 2025-12-09 17:45   ` Max Gurtovoy
  2025-12-09 17:48     ` Michael S. Tsirkin
  0 siblings, 1 reply; 7+ messages in thread
From: Max Gurtovoy @ 2025-12-09 17:45 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: stefanha, sgarzare, virtualization, kvm, oren, aevdaev, aaptel


On 09/12/2025 18:34, Michael S. Tsirkin wrote:
> On Tue, Dec 09, 2025 at 12:09:08AM +0200, Max Gurtovoy wrote:
>> Add support for the 'driver_override' attribute to Virtio devices. This
>> allows users to control which Virtio bus driver binds to a given Virtio
>> device.
>>
>> If 'driver_override' is not set, the existing behavior is preserved and
>> devices will continue to auto-bind to the first matching Virtio bus
>> driver.
> oh, it's a device driver not the bus driver, actually.

Yes. I'll fix the commit message.


>
>> Tested with virtio blk device (virtio core and pci drivers are loaded):
>>
>>    $ modprobe my_virtio_blk
>>
>>    # automatically unbind from virtio_blk driver and override + bind to
>>    # my_virtio_blk driver.
>>    $ driverctl -v -b virtio set-override virtio0 my_virtio_blk
>>
>> In addition, driverctl saves the configuration persistently under
>> /etc/driverctl.d/.
> what is this "mydriver" though? what are valid examples that
> we want to support?

This is an example for a custom virtio block driver.

It can be any custom virtio-XX driver (XX=FS/NET/..).

>> Signed-off-by: Avraham Evdaev <aevdaev@nvidia.com>
>> Signed-off-by: Max Gurtovoy <mgurtovoy@nvidia.com>
>> ---
>>
>> changes from v1:
>>   - use !strcmp() to compare strings (MST)
>>   - extend commit msg with example (MST)
>>
>> ---
>>   drivers/virtio/virtio.c | 34 ++++++++++++++++++++++++++++++++++
>>   include/linux/virtio.h  |  4 ++++
>>   2 files changed, 38 insertions(+)
>>
>> diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
>> index a09eb4d62f82..993dc928be49 100644
>> --- a/drivers/virtio/virtio.c
>> +++ b/drivers/virtio/virtio.c
>> @@ -61,12 +61,41 @@ static ssize_t features_show(struct device *_d,
>>   }
>>   static DEVICE_ATTR_RO(features);
>>   
>> +static ssize_t driver_override_store(struct device *_d,
>> +				     struct device_attribute *attr,
>> +				     const char *buf, size_t count)
>> +{
>> +	struct virtio_device *dev = dev_to_virtio(_d);
>> +	int ret;
>> +
>> +	ret = driver_set_override(_d, &dev->driver_override, buf, count);
>> +	if (ret)
>> +		return ret;
>> +
>> +	return count;
>> +}
>> +
>> +static ssize_t driver_override_show(struct device *_d,
>> +				    struct device_attribute *attr, char *buf)
>> +{
>> +	struct virtio_device *dev = dev_to_virtio(_d);
>> +	ssize_t len;
>> +
>> +	device_lock(_d);
>> +	len = sysfs_emit(buf, "%s\n", dev->driver_override);
>> +	device_unlock(_d);
>> +
>> +	return len;
>> +}
>> +static DEVICE_ATTR_RW(driver_override);
>> +
>>   static struct attribute *virtio_dev_attrs[] = {
>>   	&dev_attr_device.attr,
>>   	&dev_attr_vendor.attr,
>>   	&dev_attr_status.attr,
>>   	&dev_attr_modalias.attr,
>>   	&dev_attr_features.attr,
>> +	&dev_attr_driver_override.attr,
>>   	NULL,
>>   };
>>   ATTRIBUTE_GROUPS(virtio_dev);
>> @@ -88,6 +117,10 @@ static int virtio_dev_match(struct device *_dv, const struct device_driver *_dr)
>>   	struct virtio_device *dev = dev_to_virtio(_dv);
>>   	const struct virtio_device_id *ids;
>>   
>> +	/* Check override first, and if set, only use the named driver */
>> +	if (dev->driver_override)
>> +		return !strcmp(dev->driver_override, _dr->name);
>> +
>>   	ids = drv_to_virtio(_dr)->id_table;
>>   	for (i = 0; ids[i].device; i++)
>>   		if (virtio_id_match(dev, &ids[i]))
>> @@ -582,6 +615,7 @@ void unregister_virtio_device(struct virtio_device *dev)
>>   {
>>   	int index = dev->index; /* save for after device release */
>>   
>> +	kfree(dev->driver_override);
>>   	device_unregister(&dev->dev);
>>   	virtio_debug_device_exit(dev);
>>   	ida_free(&virtio_index_ida, index);
>> diff --git a/include/linux/virtio.h b/include/linux/virtio.h
>> index db31fc6f4f1f..418bb490bdc6 100644
>> --- a/include/linux/virtio.h
>> +++ b/include/linux/virtio.h
>> @@ -138,6 +138,9 @@ struct virtio_admin_cmd {
>>    * @config_lock: protects configuration change reporting
>>    * @vqs_list_lock: protects @vqs.
>>    * @dev: underlying device.
>> + * @driver_override: driver name to force a match; do not set directly,
>> + *                   because core frees it; use driver_set_override() to
>> + *                   set or clear it.
>>    * @id: the device type identification (used to match it with a driver).
>>    * @config: the configuration ops for this device.
>>    * @vringh_config: configuration ops for host vrings.
>> @@ -158,6 +161,7 @@ struct virtio_device {
>>   	spinlock_t config_lock;
>>   	spinlock_t vqs_list_lock;
>>   	struct device dev;
>> +	const char *driver_override;
>>   	struct virtio_device_id id;
>>   	const struct virtio_config_ops *config;
>>   	const struct vringh_config_ops *vringh_config;
>> -- 
>> 2.18.1

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/1] virtio: add driver_override support
  2025-12-09 17:45   ` Max Gurtovoy
@ 2025-12-09 17:48     ` Michael S. Tsirkin
  2025-12-09 18:20       ` Max Gurtovoy
  0 siblings, 1 reply; 7+ messages in thread
From: Michael S. Tsirkin @ 2025-12-09 17:48 UTC (permalink / raw)
  To: Max Gurtovoy
  Cc: stefanha, sgarzare, virtualization, kvm, oren, aevdaev, aaptel

On Tue, Dec 09, 2025 at 07:45:19PM +0200, Max Gurtovoy wrote:
> 
> On 09/12/2025 18:34, Michael S. Tsirkin wrote:
> > On Tue, Dec 09, 2025 at 12:09:08AM +0200, Max Gurtovoy wrote:
> > > Add support for the 'driver_override' attribute to Virtio devices. This
> > > allows users to control which Virtio bus driver binds to a given Virtio
> > > device.
> > > 
> > > If 'driver_override' is not set, the existing behavior is preserved and
> > > devices will continue to auto-bind to the first matching Virtio bus
> > > driver.
> > oh, it's a device driver not the bus driver, actually.
> 
> Yes. I'll fix the commit message.
> 
> 
> > 
> > > Tested with virtio blk device (virtio core and pci drivers are loaded):
> > > 
> > >    $ modprobe my_virtio_blk
> > > 
> > >    # automatically unbind from virtio_blk driver and override + bind to
> > >    # my_virtio_blk driver.
> > >    $ driverctl -v -b virtio set-override virtio0 my_virtio_blk
> > > 
> > > In addition, driverctl saves the configuration persistently under
> > > /etc/driverctl.d/.
> > what is this "mydriver" though? what are valid examples that
> > we want to support?
> 
> This is an example for a custom virtio block driver.
> 
> It can be any custom virtio-XX driver (XX=FS/NET/..).

Is "custom" a way to say "out of tree"?

> > > Signed-off-by: Avraham Evdaev <aevdaev@nvidia.com>
> > > Signed-off-by: Max Gurtovoy <mgurtovoy@nvidia.com>
> > > ---
> > > 
> > > changes from v1:
> > >   - use !strcmp() to compare strings (MST)
> > >   - extend commit msg with example (MST)
> > > 
> > > ---
> > >   drivers/virtio/virtio.c | 34 ++++++++++++++++++++++++++++++++++
> > >   include/linux/virtio.h  |  4 ++++
> > >   2 files changed, 38 insertions(+)
> > > 
> > > diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
> > > index a09eb4d62f82..993dc928be49 100644
> > > --- a/drivers/virtio/virtio.c
> > > +++ b/drivers/virtio/virtio.c
> > > @@ -61,12 +61,41 @@ static ssize_t features_show(struct device *_d,
> > >   }
> > >   static DEVICE_ATTR_RO(features);
> > > +static ssize_t driver_override_store(struct device *_d,
> > > +				     struct device_attribute *attr,
> > > +				     const char *buf, size_t count)
> > > +{
> > > +	struct virtio_device *dev = dev_to_virtio(_d);
> > > +	int ret;
> > > +
> > > +	ret = driver_set_override(_d, &dev->driver_override, buf, count);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	return count;
> > > +}
> > > +
> > > +static ssize_t driver_override_show(struct device *_d,
> > > +				    struct device_attribute *attr, char *buf)
> > > +{
> > > +	struct virtio_device *dev = dev_to_virtio(_d);
> > > +	ssize_t len;
> > > +
> > > +	device_lock(_d);
> > > +	len = sysfs_emit(buf, "%s\n", dev->driver_override);
> > > +	device_unlock(_d);
> > > +
> > > +	return len;
> > > +}
> > > +static DEVICE_ATTR_RW(driver_override);
> > > +
> > >   static struct attribute *virtio_dev_attrs[] = {
> > >   	&dev_attr_device.attr,
> > >   	&dev_attr_vendor.attr,
> > >   	&dev_attr_status.attr,
> > >   	&dev_attr_modalias.attr,
> > >   	&dev_attr_features.attr,
> > > +	&dev_attr_driver_override.attr,
> > >   	NULL,
> > >   };
> > >   ATTRIBUTE_GROUPS(virtio_dev);
> > > @@ -88,6 +117,10 @@ static int virtio_dev_match(struct device *_dv, const struct device_driver *_dr)
> > >   	struct virtio_device *dev = dev_to_virtio(_dv);
> > >   	const struct virtio_device_id *ids;
> > > +	/* Check override first, and if set, only use the named driver */
> > > +	if (dev->driver_override)
> > > +		return !strcmp(dev->driver_override, _dr->name);
> > > +
> > >   	ids = drv_to_virtio(_dr)->id_table;
> > >   	for (i = 0; ids[i].device; i++)
> > >   		if (virtio_id_match(dev, &ids[i]))
> > > @@ -582,6 +615,7 @@ void unregister_virtio_device(struct virtio_device *dev)
> > >   {
> > >   	int index = dev->index; /* save for after device release */
> > > +	kfree(dev->driver_override);
> > >   	device_unregister(&dev->dev);
> > >   	virtio_debug_device_exit(dev);
> > >   	ida_free(&virtio_index_ida, index);
> > > diff --git a/include/linux/virtio.h b/include/linux/virtio.h
> > > index db31fc6f4f1f..418bb490bdc6 100644
> > > --- a/include/linux/virtio.h
> > > +++ b/include/linux/virtio.h
> > > @@ -138,6 +138,9 @@ struct virtio_admin_cmd {
> > >    * @config_lock: protects configuration change reporting
> > >    * @vqs_list_lock: protects @vqs.
> > >    * @dev: underlying device.
> > > + * @driver_override: driver name to force a match; do not set directly,
> > > + *                   because core frees it; use driver_set_override() to
> > > + *                   set or clear it.
> > >    * @id: the device type identification (used to match it with a driver).
> > >    * @config: the configuration ops for this device.
> > >    * @vringh_config: configuration ops for host vrings.
> > > @@ -158,6 +161,7 @@ struct virtio_device {
> > >   	spinlock_t config_lock;
> > >   	spinlock_t vqs_list_lock;
> > >   	struct device dev;
> > > +	const char *driver_override;
> > >   	struct virtio_device_id id;
> > >   	const struct virtio_config_ops *config;
> > >   	const struct vringh_config_ops *vringh_config;
> > > -- 
> > > 2.18.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/1] virtio: add driver_override support
  2025-12-09 17:48     ` Michael S. Tsirkin
@ 2025-12-09 18:20       ` Max Gurtovoy
  2025-12-09 18:24         ` Michael S. Tsirkin
  0 siblings, 1 reply; 7+ messages in thread
From: Max Gurtovoy @ 2025-12-09 18:20 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: stefanha, sgarzare, virtualization, kvm, oren, aevdaev, aaptel


On 09/12/2025 19:48, Michael S. Tsirkin wrote:
> On Tue, Dec 09, 2025 at 07:45:19PM +0200, Max Gurtovoy wrote:
>> On 09/12/2025 18:34, Michael S. Tsirkin wrote:
>>> On Tue, Dec 09, 2025 at 12:09:08AM +0200, Max Gurtovoy wrote:
>>>> Add support for the 'driver_override' attribute to Virtio devices. This
>>>> allows users to control which Virtio bus driver binds to a given Virtio
>>>> device.
>>>>
>>>> If 'driver_override' is not set, the existing behavior is preserved and
>>>> devices will continue to auto-bind to the first matching Virtio bus
>>>> driver.
>>> oh, it's a device driver not the bus driver, actually.
>> Yes. I'll fix the commit message.
>>
>>
>>>> Tested with virtio blk device (virtio core and pci drivers are loaded):
>>>>
>>>>     $ modprobe my_virtio_blk
>>>>
>>>>     # automatically unbind from virtio_blk driver and override + bind to
>>>>     # my_virtio_blk driver.
>>>>     $ driverctl -v -b virtio set-override virtio0 my_virtio_blk
>>>>
>>>> In addition, driverctl saves the configuration persistently under
>>>> /etc/driverctl.d/.
>>> what is this "mydriver" though? what are valid examples that
>>> we want to support?
>> This is an example for a custom virtio block driver.
>>
>> It can be any custom virtio-XX driver (XX=FS/NET/..).
> Is "custom" a way to say "out of tree"?

The driver_override mechanism fits both in-tree/out-of-tree drivers.

>
>>>> Signed-off-by: Avraham Evdaev <aevdaev@nvidia.com>
>>>> Signed-off-by: Max Gurtovoy <mgurtovoy@nvidia.com>
>>>> ---
>>>>
>>>> changes from v1:
>>>>    - use !strcmp() to compare strings (MST)
>>>>    - extend commit msg with example (MST)
>>>>
>>>> ---
>>>>    drivers/virtio/virtio.c | 34 ++++++++++++++++++++++++++++++++++
>>>>    include/linux/virtio.h  |  4 ++++
>>>>    2 files changed, 38 insertions(+)
>>>>
>>>> diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
>>>> index a09eb4d62f82..993dc928be49 100644
>>>> --- a/drivers/virtio/virtio.c
>>>> +++ b/drivers/virtio/virtio.c
>>>> @@ -61,12 +61,41 @@ static ssize_t features_show(struct device *_d,
>>>>    }
>>>>    static DEVICE_ATTR_RO(features);
>>>> +static ssize_t driver_override_store(struct device *_d,
>>>> +				     struct device_attribute *attr,
>>>> +				     const char *buf, size_t count)
>>>> +{
>>>> +	struct virtio_device *dev = dev_to_virtio(_d);
>>>> +	int ret;
>>>> +
>>>> +	ret = driver_set_override(_d, &dev->driver_override, buf, count);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	return count;
>>>> +}
>>>> +
>>>> +static ssize_t driver_override_show(struct device *_d,
>>>> +				    struct device_attribute *attr, char *buf)
>>>> +{
>>>> +	struct virtio_device *dev = dev_to_virtio(_d);
>>>> +	ssize_t len;
>>>> +
>>>> +	device_lock(_d);
>>>> +	len = sysfs_emit(buf, "%s\n", dev->driver_override);
>>>> +	device_unlock(_d);
>>>> +
>>>> +	return len;
>>>> +}
>>>> +static DEVICE_ATTR_RW(driver_override);
>>>> +
>>>>    static struct attribute *virtio_dev_attrs[] = {
>>>>    	&dev_attr_device.attr,
>>>>    	&dev_attr_vendor.attr,
>>>>    	&dev_attr_status.attr,
>>>>    	&dev_attr_modalias.attr,
>>>>    	&dev_attr_features.attr,
>>>> +	&dev_attr_driver_override.attr,
>>>>    	NULL,
>>>>    };
>>>>    ATTRIBUTE_GROUPS(virtio_dev);
>>>> @@ -88,6 +117,10 @@ static int virtio_dev_match(struct device *_dv, const struct device_driver *_dr)
>>>>    	struct virtio_device *dev = dev_to_virtio(_dv);
>>>>    	const struct virtio_device_id *ids;
>>>> +	/* Check override first, and if set, only use the named driver */
>>>> +	if (dev->driver_override)
>>>> +		return !strcmp(dev->driver_override, _dr->name);
>>>> +
>>>>    	ids = drv_to_virtio(_dr)->id_table;
>>>>    	for (i = 0; ids[i].device; i++)
>>>>    		if (virtio_id_match(dev, &ids[i]))
>>>> @@ -582,6 +615,7 @@ void unregister_virtio_device(struct virtio_device *dev)
>>>>    {
>>>>    	int index = dev->index; /* save for after device release */
>>>> +	kfree(dev->driver_override);
>>>>    	device_unregister(&dev->dev);
>>>>    	virtio_debug_device_exit(dev);
>>>>    	ida_free(&virtio_index_ida, index);
>>>> diff --git a/include/linux/virtio.h b/include/linux/virtio.h
>>>> index db31fc6f4f1f..418bb490bdc6 100644
>>>> --- a/include/linux/virtio.h
>>>> +++ b/include/linux/virtio.h
>>>> @@ -138,6 +138,9 @@ struct virtio_admin_cmd {
>>>>     * @config_lock: protects configuration change reporting
>>>>     * @vqs_list_lock: protects @vqs.
>>>>     * @dev: underlying device.
>>>> + * @driver_override: driver name to force a match; do not set directly,
>>>> + *                   because core frees it; use driver_set_override() to
>>>> + *                   set or clear it.
>>>>     * @id: the device type identification (used to match it with a driver).
>>>>     * @config: the configuration ops for this device.
>>>>     * @vringh_config: configuration ops for host vrings.
>>>> @@ -158,6 +161,7 @@ struct virtio_device {
>>>>    	spinlock_t config_lock;
>>>>    	spinlock_t vqs_list_lock;
>>>>    	struct device dev;
>>>> +	const char *driver_override;
>>>>    	struct virtio_device_id id;
>>>>    	const struct virtio_config_ops *config;
>>>>    	const struct vringh_config_ops *vringh_config;
>>>> -- 
>>>> 2.18.1

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/1] virtio: add driver_override support
  2025-12-09 18:20       ` Max Gurtovoy
@ 2025-12-09 18:24         ` Michael S. Tsirkin
  0 siblings, 0 replies; 7+ messages in thread
From: Michael S. Tsirkin @ 2025-12-09 18:24 UTC (permalink / raw)
  To: Max Gurtovoy
  Cc: stefanha, sgarzare, virtualization, kvm, oren, aevdaev, aaptel

On Tue, Dec 09, 2025 at 08:20:45PM +0200, Max Gurtovoy wrote:
> 
> On 09/12/2025 19:48, Michael S. Tsirkin wrote:
> > On Tue, Dec 09, 2025 at 07:45:19PM +0200, Max Gurtovoy wrote:
> > > On 09/12/2025 18:34, Michael S. Tsirkin wrote:
> > > > On Tue, Dec 09, 2025 at 12:09:08AM +0200, Max Gurtovoy wrote:
> > > > > Add support for the 'driver_override' attribute to Virtio devices. This
> > > > > allows users to control which Virtio bus driver binds to a given Virtio
> > > > > device.
> > > > > 
> > > > > If 'driver_override' is not set, the existing behavior is preserved and
> > > > > devices will continue to auto-bind to the first matching Virtio bus
> > > > > driver.
> > > > oh, it's a device driver not the bus driver, actually.
> > > Yes. I'll fix the commit message.
> > > 
> > > 
> > > > > Tested with virtio blk device (virtio core and pci drivers are loaded):
> > > > > 
> > > > >     $ modprobe my_virtio_blk
> > > > > 
> > > > >     # automatically unbind from virtio_blk driver and override + bind to
> > > > >     # my_virtio_blk driver.
> > > > >     $ driverctl -v -b virtio set-override virtio0 my_virtio_blk
> > > > > 
> > > > > In addition, driverctl saves the configuration persistently under
> > > > > /etc/driverctl.d/.
> > > > what is this "mydriver" though? what are valid examples that
> > > > we want to support?
> > > This is an example for a custom virtio block driver.
> > > 
> > > It can be any custom virtio-XX driver (XX=FS/NET/..).
> > Is "custom" a way to say "out of tree"?
> 
> The driver_override mechanism fits both in-tree/out-of-tree drivers.

good to know.  which in tree drivers can use it?
this is the part that's missing in the commit log.

thanks


> > 
> > > > > Signed-off-by: Avraham Evdaev <aevdaev@nvidia.com>
> > > > > Signed-off-by: Max Gurtovoy <mgurtovoy@nvidia.com>
> > > > > ---
> > > > > 
> > > > > changes from v1:
> > > > >    - use !strcmp() to compare strings (MST)
> > > > >    - extend commit msg with example (MST)
> > > > > 
> > > > > ---
> > > > >    drivers/virtio/virtio.c | 34 ++++++++++++++++++++++++++++++++++
> > > > >    include/linux/virtio.h  |  4 ++++
> > > > >    2 files changed, 38 insertions(+)
> > > > > 
> > > > > diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
> > > > > index a09eb4d62f82..993dc928be49 100644
> > > > > --- a/drivers/virtio/virtio.c
> > > > > +++ b/drivers/virtio/virtio.c
> > > > > @@ -61,12 +61,41 @@ static ssize_t features_show(struct device *_d,
> > > > >    }
> > > > >    static DEVICE_ATTR_RO(features);
> > > > > +static ssize_t driver_override_store(struct device *_d,
> > > > > +				     struct device_attribute *attr,
> > > > > +				     const char *buf, size_t count)
> > > > > +{
> > > > > +	struct virtio_device *dev = dev_to_virtio(_d);
> > > > > +	int ret;
> > > > > +
> > > > > +	ret = driver_set_override(_d, &dev->driver_override, buf, count);
> > > > > +	if (ret)
> > > > > +		return ret;
> > > > > +
> > > > > +	return count;
> > > > > +}
> > > > > +
> > > > > +static ssize_t driver_override_show(struct device *_d,
> > > > > +				    struct device_attribute *attr, char *buf)
> > > > > +{
> > > > > +	struct virtio_device *dev = dev_to_virtio(_d);
> > > > > +	ssize_t len;
> > > > > +
> > > > > +	device_lock(_d);
> > > > > +	len = sysfs_emit(buf, "%s\n", dev->driver_override);
> > > > > +	device_unlock(_d);
> > > > > +
> > > > > +	return len;
> > > > > +}
> > > > > +static DEVICE_ATTR_RW(driver_override);
> > > > > +
> > > > >    static struct attribute *virtio_dev_attrs[] = {
> > > > >    	&dev_attr_device.attr,
> > > > >    	&dev_attr_vendor.attr,
> > > > >    	&dev_attr_status.attr,
> > > > >    	&dev_attr_modalias.attr,
> > > > >    	&dev_attr_features.attr,
> > > > > +	&dev_attr_driver_override.attr,
> > > > >    	NULL,
> > > > >    };
> > > > >    ATTRIBUTE_GROUPS(virtio_dev);
> > > > > @@ -88,6 +117,10 @@ static int virtio_dev_match(struct device *_dv, const struct device_driver *_dr)
> > > > >    	struct virtio_device *dev = dev_to_virtio(_dv);
> > > > >    	const struct virtio_device_id *ids;
> > > > > +	/* Check override first, and if set, only use the named driver */
> > > > > +	if (dev->driver_override)
> > > > > +		return !strcmp(dev->driver_override, _dr->name);
> > > > > +
> > > > >    	ids = drv_to_virtio(_dr)->id_table;
> > > > >    	for (i = 0; ids[i].device; i++)
> > > > >    		if (virtio_id_match(dev, &ids[i]))
> > > > > @@ -582,6 +615,7 @@ void unregister_virtio_device(struct virtio_device *dev)
> > > > >    {
> > > > >    	int index = dev->index; /* save for after device release */
> > > > > +	kfree(dev->driver_override);
> > > > >    	device_unregister(&dev->dev);
> > > > >    	virtio_debug_device_exit(dev);
> > > > >    	ida_free(&virtio_index_ida, index);
> > > > > diff --git a/include/linux/virtio.h b/include/linux/virtio.h
> > > > > index db31fc6f4f1f..418bb490bdc6 100644
> > > > > --- a/include/linux/virtio.h
> > > > > +++ b/include/linux/virtio.h
> > > > > @@ -138,6 +138,9 @@ struct virtio_admin_cmd {
> > > > >     * @config_lock: protects configuration change reporting
> > > > >     * @vqs_list_lock: protects @vqs.
> > > > >     * @dev: underlying device.
> > > > > + * @driver_override: driver name to force a match; do not set directly,
> > > > > + *                   because core frees it; use driver_set_override() to
> > > > > + *                   set or clear it.
> > > > >     * @id: the device type identification (used to match it with a driver).
> > > > >     * @config: the configuration ops for this device.
> > > > >     * @vringh_config: configuration ops for host vrings.
> > > > > @@ -158,6 +161,7 @@ struct virtio_device {
> > > > >    	spinlock_t config_lock;
> > > > >    	spinlock_t vqs_list_lock;
> > > > >    	struct device dev;
> > > > > +	const char *driver_override;
> > > > >    	struct virtio_device_id id;
> > > > >    	const struct virtio_config_ops *config;
> > > > >    	const struct vringh_config_ops *vringh_config;
> > > > > -- 
> > > > > 2.18.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-12-09 18:24 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-08 22:09 [PATCH v2 1/1] virtio: add driver_override support Max Gurtovoy
2025-12-09 15:48 ` Stefan Hajnoczi
2025-12-09 16:34 ` Michael S. Tsirkin
2025-12-09 17:45   ` Max Gurtovoy
2025-12-09 17:48     ` Michael S. Tsirkin
2025-12-09 18:20       ` Max Gurtovoy
2025-12-09 18:24         ` Michael S. Tsirkin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).