mbox series

[V3,0/5] virtio: Add virtio-device bindings

Message ID cover.1627273794.git.viresh.kumar@linaro.org
Headers show
Series virtio: Add virtio-device bindings | expand

Message

Viresh Kumar July 26, 2021, 4:51 a.m. UTC
Hi,

Currently the DT only provides support for following node types for virtio-mmio
nodes:

        virtio_mmio@a000000 {
                dma-coherent;
                interrupts = <0x00 0x10 0x01>;
                reg = <0x00 0xa000000 0x00 0x200>;
                compatible = "virtio,mmio";
        };

Here, each virtio-mmio corresponds to a virtio-device. But there is no way for
other users in the DT to show their dependency on virtio devices.

This patchset provides that support.

The first patch adds virtio-device bindings to allow for device sub-nodes to be
present and the second patch updates the virtio core to update the of_node.

Other patches add bindings for i2c and gpio devices.

Tested on x86 with qemu for arm64.

Pending:
- Arnd suggested that "virtio,deviceXX" may be a better compatible string, while
  I used "virtio,XX" to match what PCI and USB do currently. I didn't change it
  yet to hear Rob's view on the same before making the change, in case he has
  any preferences.

V2/2.1->V3:
- Added review-tags from Arnd and Wolfram.
- Only the 5th patch changed otherwise:
  - Use of_device_is_compatible() instead of keeping a list of devices.
  - Use snprintf (with BUG_ON on return value) to create the compatible string,
    whose length is fixed using "virtio,XXXXXXXX".
  - Use dev_of_node().

V1->V2:
- The changes (both binding and code) are made at virtio level, instead of
  virtio-mmio. This allows the same to be used by all device types, irrespective
  of the transport mechanism.

- Dropped the reg property and used compatible in the form "virtio,<DID>".

- Dropped dt-bindings/virtio/virtio_ids.h.

- Add a patch to sync virtio-ids from spec, required for the last patch.

--
Viresh

Viresh Kumar (5):
  dt-bindings: virtio: Add binding for virtio devices
  dt-bindings: i2c: Add bindings for i2c-virtio
  dt-bindings: gpio: Add bindings for gpio-virtio
  uapi: virtio_ids: Sync ids with specification
  virtio: Bind virtio device to device-tree node

 .../devicetree/bindings/gpio/gpio-virtio.yaml | 60 +++++++++++++++++++
 .../devicetree/bindings/i2c/i2c-virtio.yaml   | 51 ++++++++++++++++
 .../devicetree/bindings/virtio/mmio.yaml      |  2 +-
 .../bindings/virtio/virtio-device.yaml        | 47 +++++++++++++++
 drivers/virtio/virtio.c                       | 57 +++++++++++++++++-
 include/uapi/linux/virtio_ids.h               | 12 ++++
 6 files changed, 225 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-virtio.yaml
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-virtio.yaml
 create mode 100644 Documentation/devicetree/bindings/virtio/virtio-device.yaml

Comments

Alexey Kardashevskiy Sept. 13, 2021, 9:19 a.m. UTC | #1
On 26/07/2021 14:51, Viresh Kumar wrote:
> Bind the virtio devices with their of_node. This will help users of the
> virtio devices to mention their dependencies on the device in the DT
> itself. Like GPIO pin users can use the phandle of the device node, or
> the node may contain more subnodes to add i2c or spi eeproms and other
> users.
> 
> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
>  drivers/virtio/virtio.c | 57 ++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 54 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
> index 4b15c00c0a0a..d001e84a5b23 100644
> --- a/drivers/virtio/virtio.c
> +++ b/drivers/virtio/virtio.c
> @@ -4,6 +4,7 @@
>  #include <linux/virtio_config.h>
>  #include <linux/module.h>
>  #include <linux/idr.h>
> +#include <linux/of.h>
>  #include <uapi/linux/virtio_ids.h>
>  
>  /* Unique numbering for virtio devices. */
> @@ -292,6 +293,9 @@ static int virtio_dev_remove(struct device *_d)
>  
>  	/* Acknowledge the device's existence again. */
>  	virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
> +
> +	of_node_put(dev->dev.of_node);
> +
>  	return 0;
>  }
>  
> @@ -319,6 +323,43 @@ void unregister_virtio_driver(struct virtio_driver *driver)
>  }
>  EXPORT_SYMBOL_GPL(unregister_virtio_driver);
>  
> +static int virtio_device_of_init(struct virtio_device *dev)
> +{
> +	struct device_node *np, *pnode = dev_of_node(dev->dev.parent);
> +	char compat[] = "virtio,XXXXXXXX"; /* Reserve enough space 32-bit id */
> +	int ret, count;
> +
> +	if (!pnode)
> +		return 0;
> +
> +	count = of_get_available_child_count(pnode);
> +	if (!count)
> +		return 0;
> +
> +	/* There can be only 1 child node */
> +	if (WARN_ON(count > 1))
> +		return -EINVAL;
> +
> +	np = of_get_next_available_child(pnode, NULL);
> +	if (WARN_ON(!np))
> +		return -ENODEV;
> +
> +	BUG_ON(snprintf(compat, sizeof(compat), "virtio,%x", dev->id.device) >=
> +	       sizeof(compat));
> +
> +	if (!of_device_is_compatible(np, compat)) {


This broke powerpc/pseries as there these virtio devices are PCI so
there is no "compat" - PCI vendor id/device ids play role of "compat".
Thanks,




> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
> +	dev->dev.of_node = np;
> +	return 0;
> +
> +out:
> +	of_node_put(np);
> +	return ret;
> +}
> +
>  /**
>   * register_virtio_device - register virtio device
>   * @dev        : virtio device to be registered
> @@ -343,6 +384,10 @@ int register_virtio_device(struct virtio_device *dev)
>  	dev->index = err;
>  	dev_set_name(&dev->dev, "virtio%u", dev->index);
>  
> +	err = virtio_device_of_init(dev);
> +	if (err)
> +		goto out_ida_remove;
> +
>  	spin_lock_init(&dev->config_lock);
>  	dev->config_enabled = false;
>  	dev->config_change_pending = false;
> @@ -362,10 +407,16 @@ int register_virtio_device(struct virtio_device *dev)
>  	 */
>  	err = device_add(&dev->dev);
>  	if (err)
> -		ida_simple_remove(&virtio_index_ida, dev->index);
> +		goto out_of_node_put;
> +
> +	return 0;
> +
> +out_of_node_put:
> +	of_node_put(dev->dev.of_node);
> +out_ida_remove:
> +	ida_simple_remove(&virtio_index_ida, dev->index);
>  out:
> -	if (err)
> -		virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
> +	virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
>  	return err;
>  }
>  EXPORT_SYMBOL_GPL(register_virtio_device);
>
Michael S. Tsirkin Sept. 13, 2021, 9:45 a.m. UTC | #2
On Mon, Sep 13, 2021 at 07:19:17PM +1000, Alexey Kardashevskiy wrote:
> 
> 
> On 26/07/2021 14:51, Viresh Kumar wrote:
> > Bind the virtio devices with their of_node. This will help users of the
> > virtio devices to mention their dependencies on the device in the DT
> > itself. Like GPIO pin users can use the phandle of the device node, or
> > the node may contain more subnodes to add i2c or spi eeproms and other
> > users.
> > 
> > Reviewed-by: Arnd Bergmann <arnd@arndb.de>
> > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> > ---
> >  drivers/virtio/virtio.c | 57 ++++++++++++++++++++++++++++++++++++++---
> >  1 file changed, 54 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
> > index 4b15c00c0a0a..d001e84a5b23 100644
> > --- a/drivers/virtio/virtio.c
> > +++ b/drivers/virtio/virtio.c
> > @@ -4,6 +4,7 @@
> >  #include <linux/virtio_config.h>
> >  #include <linux/module.h>
> >  #include <linux/idr.h>
> > +#include <linux/of.h>
> >  #include <uapi/linux/virtio_ids.h>
> >  
> >  /* Unique numbering for virtio devices. */
> > @@ -292,6 +293,9 @@ static int virtio_dev_remove(struct device *_d)
> >  
> >  	/* Acknowledge the device's existence again. */
> >  	virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
> > +
> > +	of_node_put(dev->dev.of_node);
> > +
> >  	return 0;
> >  }
> >  
> > @@ -319,6 +323,43 @@ void unregister_virtio_driver(struct virtio_driver *driver)
> >  }
> >  EXPORT_SYMBOL_GPL(unregister_virtio_driver);
> >  
> > +static int virtio_device_of_init(struct virtio_device *dev)
> > +{
> > +	struct device_node *np, *pnode = dev_of_node(dev->dev.parent);
> > +	char compat[] = "virtio,XXXXXXXX"; /* Reserve enough space 32-bit id */
> > +	int ret, count;
> > +
> > +	if (!pnode)
> > +		return 0;
> > +
> > +	count = of_get_available_child_count(pnode);
> > +	if (!count)
> > +		return 0;
> > +
> > +	/* There can be only 1 child node */
> > +	if (WARN_ON(count > 1))
> > +		return -EINVAL;
> > +
> > +	np = of_get_next_available_child(pnode, NULL);
> > +	if (WARN_ON(!np))
> > +		return -ENODEV;
> > +
> > +	BUG_ON(snprintf(compat, sizeof(compat), "virtio,%x", dev->id.device) >=
> > +	       sizeof(compat));
> > +
> > +	if (!of_device_is_compatible(np, compat)) {
> 
> 
> This broke powerpc/pseries as there these virtio devices are PCI so
> there is no "compat" - PCI vendor id/device ids play role of "compat".
> Thanks,

Hmm now that you say this I wonder why do we bother
with this check, too. When can this be invoked for something
that is not a virtio device? And is it enough to just
skip of_node initialization then?


> 
> 
> 
> > +		ret = -EINVAL;


So basically ret = 0 above?


> > +		goto out;
> > +	}
> > +
> > +	dev->dev.of_node = np;
> > +	return 0;
> > +
> > +out:
> > +	of_node_put(np);
> > +	return ret;
> > +}
> > +
> >  /**
> >   * register_virtio_device - register virtio device
> >   * @dev        : virtio device to be registered
> > @@ -343,6 +384,10 @@ int register_virtio_device(struct virtio_device *dev)
> >  	dev->index = err;
> >  	dev_set_name(&dev->dev, "virtio%u", dev->index);
> >  
> > +	err = virtio_device_of_init(dev);
> > +	if (err)
> > +		goto out_ida_remove;
> > +
> >  	spin_lock_init(&dev->config_lock);
> >  	dev->config_enabled = false;
> >  	dev->config_change_pending = false;
> > @@ -362,10 +407,16 @@ int register_virtio_device(struct virtio_device *dev)
> >  	 */
> >  	err = device_add(&dev->dev);
> >  	if (err)
> > -		ida_simple_remove(&virtio_index_ida, dev->index);
> > +		goto out_of_node_put;
> > +
> > +	return 0;
> > +
> > +out_of_node_put:
> > +	of_node_put(dev->dev.of_node);
> > +out_ida_remove:
> > +	ida_simple_remove(&virtio_index_ida, dev->index);
> >  out:
> > -	if (err)
> > -		virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
> > +	virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
> >  	return err;
> >  }
> >  EXPORT_SYMBOL_GPL(register_virtio_device);
> > 
> 
> -- 
> Alexey
Alexey Kardashevskiy Sept. 13, 2021, 10:27 a.m. UTC | #3
On 13/09/2021 19:45, Michael S. Tsirkin wrote:
> On Mon, Sep 13, 2021 at 07:19:17PM +1000, Alexey Kardashevskiy wrote:
>>
>>
>> On 26/07/2021 14:51, Viresh Kumar wrote:
>>> Bind the virtio devices with their of_node. This will help users of the
>>> virtio devices to mention their dependencies on the device in the DT
>>> itself. Like GPIO pin users can use the phandle of the device node, or
>>> the node may contain more subnodes to add i2c or spi eeproms and other
>>> users.
>>>
>>> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
>>> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
>>> ---
>>>  drivers/virtio/virtio.c | 57 ++++++++++++++++++++++++++++++++++++++---
>>>  1 file changed, 54 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
>>> index 4b15c00c0a0a..d001e84a5b23 100644
>>> --- a/drivers/virtio/virtio.c
>>> +++ b/drivers/virtio/virtio.c
>>> @@ -4,6 +4,7 @@
>>>  #include <linux/virtio_config.h>
>>>  #include <linux/module.h>
>>>  #include <linux/idr.h>
>>> +#include <linux/of.h>
>>>  #include <uapi/linux/virtio_ids.h>
>>>  
>>>  /* Unique numbering for virtio devices. */
>>> @@ -292,6 +293,9 @@ static int virtio_dev_remove(struct device *_d)
>>>  
>>>  	/* Acknowledge the device's existence again. */
>>>  	virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
>>> +
>>> +	of_node_put(dev->dev.of_node);
>>> +
>>>  	return 0;
>>>  }
>>>  
>>> @@ -319,6 +323,43 @@ void unregister_virtio_driver(struct virtio_driver *driver)
>>>  }
>>>  EXPORT_SYMBOL_GPL(unregister_virtio_driver);
>>>  
>>> +static int virtio_device_of_init(struct virtio_device *dev)
>>> +{
>>> +	struct device_node *np, *pnode = dev_of_node(dev->dev.parent);
>>> +	char compat[] = "virtio,XXXXXXXX"; /* Reserve enough space 32-bit id */
>>> +	int ret, count;
>>> +
>>> +	if (!pnode)
>>> +		return 0;
>>> +
>>> +	count = of_get_available_child_count(pnode);
>>> +	if (!count)
>>> +		return 0;
>>> +
>>> +	/* There can be only 1 child node */
>>> +	if (WARN_ON(count > 1))
>>> +		return -EINVAL;
>>> +
>>> +	np = of_get_next_available_child(pnode, NULL);
>>> +	if (WARN_ON(!np))
>>> +		return -ENODEV;
>>> +
>>> +	BUG_ON(snprintf(compat, sizeof(compat), "virtio,%x", dev->id.device) >=
>>> +	       sizeof(compat));
>>> +
>>> +	if (!of_device_is_compatible(np, compat)) {
>>
>>
>> This broke powerpc/pseries as there these virtio devices are PCI so
>> there is no "compat" - PCI vendor id/device ids play role of "compat".
>> Thanks,
> 
> Hmm now that you say this I wonder why do we bother
> with this check, too. When can this be invoked for something
> that is not a virtio device? And is it enough to just
> skip of_node initialization then?


I am not following here, the problem device is virtio-scsi which is
virtio-derived, or you meant that virtio which hosts virtio-bus?

> 
>>
>>
>>
>>> +		ret = -EINVAL;
> 
> 
> So basically ret = 0 above?


Yup, this does fix it. Thanks,

> 
> 
>>> +		goto out;
>>> +	}
>>> +
>>> +	dev->dev.of_node = np;
>>> +	return 0;
>>> +
>>> +out:
>>> +	of_node_put(np);
>>> +	return ret;
>>> +}
>>> +
>>>  /**
>>>   * register_virtio_device - register virtio device
>>>   * @dev        : virtio device to be registered
>>> @@ -343,6 +384,10 @@ int register_virtio_device(struct virtio_device *dev)
>>>  	dev->index = err;
>>>  	dev_set_name(&dev->dev, "virtio%u", dev->index);
>>>  
>>> +	err = virtio_device_of_init(dev);
>>> +	if (err)
>>> +		goto out_ida_remove;
>>> +
>>>  	spin_lock_init(&dev->config_lock);
>>>  	dev->config_enabled = false;
>>>  	dev->config_change_pending = false;
>>> @@ -362,10 +407,16 @@ int register_virtio_device(struct virtio_device *dev)
>>>  	 */
>>>  	err = device_add(&dev->dev);
>>>  	if (err)
>>> -		ida_simple_remove(&virtio_index_ida, dev->index);
>>> +		goto out_of_node_put;
>>> +
>>> +	return 0;
>>> +
>>> +out_of_node_put:
>>> +	of_node_put(dev->dev.of_node);
>>> +out_ida_remove:
>>> +	ida_simple_remove(&virtio_index_ida, dev->index);
>>>  out:
>>> -	if (err)
>>> -		virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
>>> +	virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
>>>  	return err;
>>>  }
>>>  EXPORT_SYMBOL_GPL(register_virtio_device);
>>>
>>
>> -- 
>> Alexey
>
Guenter Roeck Sept. 13, 2021, 2:49 p.m. UTC | #4
On Mon, Jul 26, 2021 at 10:21:45AM +0530, Viresh Kumar wrote:
> Bind the virtio devices with their of_node. This will help users of the
> virtio devices to mention their dependencies on the device in the DT
> itself. Like GPIO pin users can use the phandle of the device node, or
> the node may contain more subnodes to add i2c or spi eeproms and other
> users.
> 
> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>

This patch causes a boot failure on sparc64: The virtio device no longer
instantiates. Reverting this patch fixes the problem. Bisect log attached.

Guenter

---
# bad: [6880fa6c56601bb8ed59df6c30fd390cc5f6dd8f] Linux 5.15-rc1
# good: [926de8c4326c14fcf35f1de142019043597a4fac] Merge tag 'acpi-5.15-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
git bisect start 'HEAD' '926de8c4326c'
# good: [8177a5c96229ff24da1e362789e359b68b4f34f5] Merge tag 'libata-5.15-2021-09-11' of git://git.kernel.dk/linux-block
git bisect good 8177a5c96229ff24da1e362789e359b68b4f34f5
# bad: [78e709522d2c012cb0daad2e668506637bffb7c2] Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
git bisect bad 78e709522d2c012cb0daad2e668506637bffb7c2
# bad: [7bc7f61897b66bef78bb5952e3d1e9f3aaf9ccca] Documentation: Add documentation for VDUSE
git bisect bad 7bc7f61897b66bef78bb5952e3d1e9f3aaf9ccca
# bad: [41116599a0731f4cd451e9d191d879ab45e31945] virtio/vsock: add 'VIRTIO_VSOCK_SEQ_EOR' bit.
git bisect bad 41116599a0731f4cd451e9d191d879ab45e31945
# good: [5262912ef3cfc5e518892c3d67fb36412cb813e2] vdpa/mlx5: Add support for control VQ and MAC setting
git bisect good 5262912ef3cfc5e518892c3d67fb36412cb813e2
# good: [7f815fce08d563006e43d1b7d2f9a0a4f3b832f3] dt-bindings: i2c: Add bindings for i2c-virtio
git bisect good 7f815fce08d563006e43d1b7d2f9a0a4f3b832f3
# good: [d5a8680dfab0547a4ecd708b1fe9de48598a6757] uapi: virtio_ids: Sync ids with specification
git bisect good d5a8680dfab0547a4ecd708b1fe9de48598a6757
# bad: [9af8f1061646e8e22b66413bedf7b3e2ab3d69e5] virtio/vsock: rename 'EOR' to 'EOM' bit.
git bisect bad 9af8f1061646e8e22b66413bedf7b3e2ab3d69e5
# bad: [694a1116b405d887c893525a6766b390989c8606] virtio: Bind virtio device to device-tree node
git bisect bad 694a1116b405d887c893525a6766b390989c8606
# first bad commit: [694a1116b405d887c893525a6766b390989c8606] virtio: Bind virtio device to device-tree node
Guenter Roeck Sept. 13, 2021, 4:19 p.m. UTC | #5
On Mon, Sep 13, 2021 at 07:49:07AM -0700, Guenter Roeck wrote:
> On Mon, Jul 26, 2021 at 10:21:45AM +0530, Viresh Kumar wrote:
> > Bind the virtio devices with their of_node. This will help users of the
> > virtio devices to mention their dependencies on the device in the DT
> > itself. Like GPIO pin users can use the phandle of the device node, or
> > the node may contain more subnodes to add i2c or spi eeproms and other
> > users.
> > 
> > Reviewed-by: Arnd Bergmann <arnd@arndb.de>
> > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> 
> This patch causes a boot failure on sparc64: The virtio device no longer
> instantiates. Reverting this patch fixes the problem. Bisect log attached.
> 

In case it matters: The problem is here:

+       if (!of_device_is_compatible(np, compat)) {
+               ret = -EINVAL;
+               goto out;
+       }

Guenter

> Guenter
> 
> ---
> # bad: [6880fa6c56601bb8ed59df6c30fd390cc5f6dd8f] Linux 5.15-rc1
> # good: [926de8c4326c14fcf35f1de142019043597a4fac] Merge tag 'acpi-5.15-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
> git bisect start 'HEAD' '926de8c4326c'
> # good: [8177a5c96229ff24da1e362789e359b68b4f34f5] Merge tag 'libata-5.15-2021-09-11' of git://git.kernel.dk/linux-block
> git bisect good 8177a5c96229ff24da1e362789e359b68b4f34f5
> # bad: [78e709522d2c012cb0daad2e668506637bffb7c2] Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
> git bisect bad 78e709522d2c012cb0daad2e668506637bffb7c2
> # bad: [7bc7f61897b66bef78bb5952e3d1e9f3aaf9ccca] Documentation: Add documentation for VDUSE
> git bisect bad 7bc7f61897b66bef78bb5952e3d1e9f3aaf9ccca
> # bad: [41116599a0731f4cd451e9d191d879ab45e31945] virtio/vsock: add 'VIRTIO_VSOCK_SEQ_EOR' bit.
> git bisect bad 41116599a0731f4cd451e9d191d879ab45e31945
> # good: [5262912ef3cfc5e518892c3d67fb36412cb813e2] vdpa/mlx5: Add support for control VQ and MAC setting
> git bisect good 5262912ef3cfc5e518892c3d67fb36412cb813e2
> # good: [7f815fce08d563006e43d1b7d2f9a0a4f3b832f3] dt-bindings: i2c: Add bindings for i2c-virtio
> git bisect good 7f815fce08d563006e43d1b7d2f9a0a4f3b832f3
> # good: [d5a8680dfab0547a4ecd708b1fe9de48598a6757] uapi: virtio_ids: Sync ids with specification
> git bisect good d5a8680dfab0547a4ecd708b1fe9de48598a6757
> # bad: [9af8f1061646e8e22b66413bedf7b3e2ab3d69e5] virtio/vsock: rename 'EOR' to 'EOM' bit.
> git bisect bad 9af8f1061646e8e22b66413bedf7b3e2ab3d69e5
> # bad: [694a1116b405d887c893525a6766b390989c8606] virtio: Bind virtio device to device-tree node
> git bisect bad 694a1116b405d887c893525a6766b390989c8606
> # first bad commit: [694a1116b405d887c893525a6766b390989c8606] virtio: Bind virtio device to device-tree node