net/virtio: fix crash when dev is configured twice

Message ID 20220831085344.47995-1-achernavin@netgate.com (mailing list archive)
State Superseded, archived
Delegated to: Maxime Coquelin
Headers
Series net/virtio: fix crash when dev is configured twice |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/iol-mellanox-Performance success Performance Testing PASS
ci/iol-aarch64-unit-testing success Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/Intel-compilation success Compilation OK
ci/iol-x86_64-unit-testing success Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-aarch64-compile-testing success Testing PASS
ci/iol-x86_64-compile-testing success Testing PASS
ci/intel-Testing success Testing PASS
ci/github-robot: build success github build: passed

Commit Message

Alexander Chernavin Aug. 31, 2022, 8:53 a.m. UTC
  When first attempt to configure a device with RX interrupt enabled fails
for some reason (e.g. because "Multiple intr vector not supported"),
second attempt to configure the device with RX interrupt disabled and
feature set unchanged will succeed but will leave virtio queues not
allocated. Accessing the queues will cause a segfault.

First attempt:
  - virtio_dev_configure()
    - virtio_init_device() is called to reinit the device because
      "dev->data->dev_conf.intr_conf.rxq" is "1"
      - virtio_configure_intr() fails and returns an error
      - virtio_free_queues() frees previously allocated virtio queues
    - virtio_init_device() fails and returns an error
  - virtio_dev_configure() fails and returns an error

Second attempt:
  - virtio_dev_configure()
    - This time virtio_init_device() is not called, virtio queues
      are not allocated

With this fix, reinit the device during configuration if virtio queues
are not allocated.

Signed-off-by: Alexander Chernavin <achernavin@netgate.com>
---
 drivers/net/virtio/virtio_ethdev.c | 7 +++++++
 1 file changed, 7 insertions(+)
  

Comments

Chenbo Xia Sept. 26, 2022, 7:15 a.m. UTC | #1
> -----Original Message-----
> From: Alexander Chernavin <achernavin@netgate.com>
> Sent: Wednesday, August 31, 2022 4:54 PM
> To: maxime.coquelin@redhat.com; Xia, Chenbo <chenbo.xia@intel.com>
> Cc: dev@dpdk.org; Alexander Chernavin <achernavin@netgate.com>
> Subject: [PATCH] net/virtio: fix crash when dev is configured twice
> 
> When first attempt to configure a device with RX interrupt enabled fails
> for some reason (e.g. because "Multiple intr vector not supported"),
> second attempt to configure the device with RX interrupt disabled and
> feature set unchanged will succeed but will leave virtio queues not
> allocated. Accessing the queues will cause a segfault.
> 
> First attempt:
>   - virtio_dev_configure()
>     - virtio_init_device() is called to reinit the device because
>       "dev->data->dev_conf.intr_conf.rxq" is "1"
>       - virtio_configure_intr() fails and returns an error
>       - virtio_free_queues() frees previously allocated virtio queues
>     - virtio_init_device() fails and returns an error
>   - virtio_dev_configure() fails and returns an error
> 
> Second attempt:
>   - virtio_dev_configure()
>     - This time virtio_init_device() is not called, virtio queues
>       are not allocated
> 
> With this fix, reinit the device during configuration if virtio queues
> are not allocated.

Good catch. This is a fix, we should backport it, let's add fix and cc-stable
Tag.

Thanks,
Chenbo 

> 
> Signed-off-by: Alexander Chernavin <achernavin@netgate.com>
> ---
>  drivers/net/virtio/virtio_ethdev.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/net/virtio/virtio_ethdev.c
> b/drivers/net/virtio/virtio_ethdev.c
> index d180162abd..38bfe050b5 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -2616,6 +2616,13 @@ virtio_dev_configure(struct rte_eth_dev *dev)
>  			return ret;
>  	}
> 
> +	/* if queues are not allocated, reinit the device */
> +	if (hw->vqs == NULL) {
> +		ret = virtio_init_device(dev, hw->req_guest_features);
> +		if (ret < 0)
> +			return ret;
> +	}
> +
>  	if ((rxmode->mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) &&
>  			!virtio_with_feature(hw, VIRTIO_NET_F_RSS)) {
>  		PMD_DRV_LOG(ERR, "RSS support requested but not supported by
> the device");
> --
> 2.25.1
  

Patch

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index d180162abd..38bfe050b5 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -2616,6 +2616,13 @@  virtio_dev_configure(struct rte_eth_dev *dev)
 			return ret;
 	}
 
+	/* if queues are not allocated, reinit the device */
+	if (hw->vqs == NULL) {
+		ret = virtio_init_device(dev, hw->req_guest_features);
+		if (ret < 0)
+			return ret;
+	}
+
 	if ((rxmode->mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) &&
 			!virtio_with_feature(hw, VIRTIO_NET_F_RSS)) {
 		PMD_DRV_LOG(ERR, "RSS support requested but not supported by the device");