All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: "Longpeng(Mike)" <longpeng2@huawei.com>
Cc: linux-kernel@vger.kernel.org, yechuan@huawei.com,
	huangzhichao@huawei.com,
	virtualization@lists.linux-foundation.org
Subject: Re: [PATCH v3] vp_vdpa: harden the logic of set status
Date: Wed, 4 Jan 2023 01:50:03 -0500	[thread overview]
Message-ID: <20230104014642-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <20230104042519.170-1-longpeng2@huawei.com>

On Wed, Jan 04, 2023 at 12:25:19PM +0800, Longpeng(Mike) wrote:
> From: Longpeng <longpeng2@huawei.com>
> 
> 1. We should not set status to 0 when invoking vp_vdpa_set_status(),
>    trigger a warning in that case.
> 
> 2. The driver MUST wait for a read of device_status to return 0 before
>    reinitializing the device. But we also don't want to keep us in an
>    infinite loop forever, so wait for 5s if we try to reset the device.
> 
> Signed-off-by: Longpeng <longpeng2@huawei.com>
> ---
> Changes v3->v2:
>  - move VP_VDPA_RESET_TIMEOUT_US near the other macros. [Stefano]
>  - refer v1.2 in comments. [Stefano]
>  - s/keep/keeping/  [Jason]
>  - use readx_poll_timeout. [Jason]
> 
> Changes v1->v2:
>  - use WARN_ON instead of BUG_ON. [Stefano]
>  - use "warning + failed" instead of "infinite loop". [Jason, Stefano]
>  - use usleep_range instead of msleep (checkpatch). [Longpeng]
> 
> ---
>  drivers/vdpa/virtio_pci/vp_vdpa.c | 22 +++++++++++++++++++++-
>  1 file changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/vdpa/virtio_pci/vp_vdpa.c b/drivers/vdpa/virtio_pci/vp_vdpa.c
> index d448db0c4de3..3fc496aea456 100644
> --- a/drivers/vdpa/virtio_pci/vp_vdpa.c
> +++ b/drivers/vdpa/virtio_pci/vp_vdpa.c
> @@ -10,6 +10,7 @@
>  
>  #include <linux/interrupt.h>
>  #include <linux/module.h>
> +#include <linux/iopoll.h>
>  #include <linux/pci.h>
>  #include <linux/vdpa.h>
>  #include <linux/virtio.h>
> @@ -22,6 +23,7 @@
>  #define VP_VDPA_QUEUE_MAX 256
>  #define VP_VDPA_DRIVER_NAME "vp_vdpa"
>  #define VP_VDPA_NAME_SIZE 256
> +#define VP_VDPA_RESET_TIMEOUT_US 5000000 /* 5s */
>  
>  struct vp_vring {
>  	void __iomem *notify;
> @@ -214,6 +216,9 @@ static void vp_vdpa_set_status(struct vdpa_device *vdpa, u8 status)
>  	struct virtio_pci_modern_device *mdev = vp_vdpa_to_mdev(vp_vdpa);
>  	u8 s = vp_vdpa_get_status(vdpa);
>  
> +	/* We should never be setting status to 0. */
> +	WARN_ON(status == 0);
> +
>  	if (status & VIRTIO_CONFIG_S_DRIVER_OK &&
>  	    !(s & VIRTIO_CONFIG_S_DRIVER_OK)) {
>  		vp_vdpa_request_irq(vp_vdpa);

Isn't this user-triggerable? What prevents that?

> @@ -226,10 +231,25 @@ static int vp_vdpa_reset(struct vdpa_device *vdpa)
>  {
>  	struct vp_vdpa *vp_vdpa = vdpa_to_vp(vdpa);
>  	struct virtio_pci_modern_device *mdev = vp_vdpa_to_mdev(vp_vdpa);
> -	u8 s = vp_vdpa_get_status(vdpa);
> +	u8 tmp, s = vp_vdpa_get_status(vdpa);
> +	int ret;
>  
>  	vp_modern_set_status(mdev, 0);
>  
> +	/*
> +	 * As the virtio v1.1/v1.2 spec (4.1.4.3.2) says: After writing 0 to
> +	 * device_status, the driver MUST wait for a read of device_status
> +	 * to return 0 before reinitializing the device.
> +	 * To avoid keeping us here forever, we only wait for 5 seconds.
> +	 */
> +	ret = readx_poll_timeout(vp_ioread8, &mdev->common->device_status, tmp,
> +				 tmp == 0, 1000, VP_VDPA_RESET_TIMEOUT_US);
> +	if (ret) {
> +		dev_err(&mdev->pci_dev->dev,
> +			"vp_vdpa: fail to reset device, %d\n", ret);
> +		return ret;
> +	}
> +
>  	if (s & VIRTIO_CONFIG_S_DRIVER_OK)
>  		vp_vdpa_free_irq(vp_vdpa);

Do all callers actually check return status of reset?
If not they will happily reinitialize the device and violate the spec.



> -- 
> 2.23.0

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

WARNING: multiple messages have this Message-ID (diff)
From: "Michael S. Tsirkin" <mst@redhat.com>
To: "Longpeng(Mike)" <longpeng2@huawei.com>
Cc: jasowang@redhat.com, sgarzare@redhat.com,
	arei.gonglei@huawei.com, yechuan@huawei.com,
	huangzhichao@huawei.com,
	virtualization@lists.linux-foundation.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3] vp_vdpa: harden the logic of set status
Date: Wed, 4 Jan 2023 01:50:03 -0500	[thread overview]
Message-ID: <20230104014642-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <20230104042519.170-1-longpeng2@huawei.com>

On Wed, Jan 04, 2023 at 12:25:19PM +0800, Longpeng(Mike) wrote:
> From: Longpeng <longpeng2@huawei.com>
> 
> 1. We should not set status to 0 when invoking vp_vdpa_set_status(),
>    trigger a warning in that case.
> 
> 2. The driver MUST wait for a read of device_status to return 0 before
>    reinitializing the device. But we also don't want to keep us in an
>    infinite loop forever, so wait for 5s if we try to reset the device.
> 
> Signed-off-by: Longpeng <longpeng2@huawei.com>
> ---
> Changes v3->v2:
>  - move VP_VDPA_RESET_TIMEOUT_US near the other macros. [Stefano]
>  - refer v1.2 in comments. [Stefano]
>  - s/keep/keeping/  [Jason]
>  - use readx_poll_timeout. [Jason]
> 
> Changes v1->v2:
>  - use WARN_ON instead of BUG_ON. [Stefano]
>  - use "warning + failed" instead of "infinite loop". [Jason, Stefano]
>  - use usleep_range instead of msleep (checkpatch). [Longpeng]
> 
> ---
>  drivers/vdpa/virtio_pci/vp_vdpa.c | 22 +++++++++++++++++++++-
>  1 file changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/vdpa/virtio_pci/vp_vdpa.c b/drivers/vdpa/virtio_pci/vp_vdpa.c
> index d448db0c4de3..3fc496aea456 100644
> --- a/drivers/vdpa/virtio_pci/vp_vdpa.c
> +++ b/drivers/vdpa/virtio_pci/vp_vdpa.c
> @@ -10,6 +10,7 @@
>  
>  #include <linux/interrupt.h>
>  #include <linux/module.h>
> +#include <linux/iopoll.h>
>  #include <linux/pci.h>
>  #include <linux/vdpa.h>
>  #include <linux/virtio.h>
> @@ -22,6 +23,7 @@
>  #define VP_VDPA_QUEUE_MAX 256
>  #define VP_VDPA_DRIVER_NAME "vp_vdpa"
>  #define VP_VDPA_NAME_SIZE 256
> +#define VP_VDPA_RESET_TIMEOUT_US 5000000 /* 5s */
>  
>  struct vp_vring {
>  	void __iomem *notify;
> @@ -214,6 +216,9 @@ static void vp_vdpa_set_status(struct vdpa_device *vdpa, u8 status)
>  	struct virtio_pci_modern_device *mdev = vp_vdpa_to_mdev(vp_vdpa);
>  	u8 s = vp_vdpa_get_status(vdpa);
>  
> +	/* We should never be setting status to 0. */
> +	WARN_ON(status == 0);
> +
>  	if (status & VIRTIO_CONFIG_S_DRIVER_OK &&
>  	    !(s & VIRTIO_CONFIG_S_DRIVER_OK)) {
>  		vp_vdpa_request_irq(vp_vdpa);

Isn't this user-triggerable? What prevents that?

> @@ -226,10 +231,25 @@ static int vp_vdpa_reset(struct vdpa_device *vdpa)
>  {
>  	struct vp_vdpa *vp_vdpa = vdpa_to_vp(vdpa);
>  	struct virtio_pci_modern_device *mdev = vp_vdpa_to_mdev(vp_vdpa);
> -	u8 s = vp_vdpa_get_status(vdpa);
> +	u8 tmp, s = vp_vdpa_get_status(vdpa);
> +	int ret;
>  
>  	vp_modern_set_status(mdev, 0);
>  
> +	/*
> +	 * As the virtio v1.1/v1.2 spec (4.1.4.3.2) says: After writing 0 to
> +	 * device_status, the driver MUST wait for a read of device_status
> +	 * to return 0 before reinitializing the device.
> +	 * To avoid keeping us here forever, we only wait for 5 seconds.
> +	 */
> +	ret = readx_poll_timeout(vp_ioread8, &mdev->common->device_status, tmp,
> +				 tmp == 0, 1000, VP_VDPA_RESET_TIMEOUT_US);
> +	if (ret) {
> +		dev_err(&mdev->pci_dev->dev,
> +			"vp_vdpa: fail to reset device, %d\n", ret);
> +		return ret;
> +	}
> +
>  	if (s & VIRTIO_CONFIG_S_DRIVER_OK)
>  		vp_vdpa_free_irq(vp_vdpa);

Do all callers actually check return status of reset?
If not they will happily reinitialize the device and violate the spec.



> -- 
> 2.23.0


  reply	other threads:[~2023-01-04  6:50 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-04  4:25 [PATCH v3] vp_vdpa: harden the logic of set status Longpeng(Mike)
2023-01-04  6:50 ` Michael S. Tsirkin [this message]
2023-01-04  6:50   ` Michael S. Tsirkin
2023-01-09  9:17   ` Jason Wang
2023-01-09  9:17     ` Jason Wang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230104014642-mutt-send-email-mst@kernel.org \
    --to=mst@redhat.com \
    --cc=huangzhichao@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=longpeng2@huawei.com \
    --cc=virtualization@lists.linux-foundation.org \
    --cc=yechuan@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.