Message ID | 20221111145505.1232-1-longpeng2@huawei.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp789060wru; Fri, 11 Nov 2022 07:01:23 -0800 (PST) X-Google-Smtp-Source: AA0mqf6LYc+YhNep9LGlDEXAjAcFV5kHfQ5Evm60feGdKV+lCLSNtU48NpjwAFAziCBq9o1qI49Z X-Received: by 2002:a17:907:1b89:b0:7ad:b51d:39d0 with SMTP id mz9-20020a1709071b8900b007adb51d39d0mr2049368ejc.571.1668178883464; Fri, 11 Nov 2022 07:01:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668178883; cv=none; d=google.com; s=arc-20160816; b=QrDpRa/Ma/iVRByptHa9bc9p8HGCP31zooX79AHfYvkw62EFHcyzGqFZSXPeQuRnaI RCotigQbP0FaWLNrP7Jk5ZefoBmEcjeI9k8YLVB73hOsjFuOdPZnY/bPzmGxapxGSySB 8MrhpVIiiwqA+te0wsKSH3wOoOYUkfLJxKIdfqzVLJqUjMYkYAq0ko6PW0qdu9grW5mK MmzyB3VeWO8t0aSnbswcKNLxTHQjW0a/aF9Feq9KIT1e4cphlEIHkCnGmAoVMYQTAulU 5Jz+TlbbOwoCiBnsXmva7duzDQ0mwiJyBga0JhS/dH4ADCrq7DeAJCENtnZeiFCyhT5x hu2A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=48BSwluPyChUVkVnKaSteUp42J2apwptQpDrEZfnRrk=; b=dqTBGJEL1y7cBXnOPEJVs5Fhb40iOdryzqZAgEe3lO0Q5u40xO/UuhF8mFEqwq+ZpM Dqv2USNp4TfVHjd1ZvjyZ+zSZjQrOAAkY7KBdlDu2RPKm0DZ+QypeWwJ6cQP4hfrE0E9 4CdC3JU/6T6Eyiga5IcQmE4Xi1ZM3q0su7JOCwyzCBv82CApY0s7qZoOh9otZg2xDgVd 29rNRSdcym8E+IHFWz78U/ZYhXnEFXeA0+y+mfR+JjOCp3OJYVyvKklsUd/eARXkfwCE CNwm194Ozn/vWD2bX7SNbCWMiBs6yWSots0ECcnjRJMSV0ouTRFbcSnaQUWgdsf3IMSo abFA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id g4-20020aa7c584000000b0045bd677b3d5si2014188edq.342.2022.11.11.07.00.23; Fri, 11 Nov 2022 07:01:23 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234679AbiKKOzR (ORCPT <rfc822;winker.wchi@gmail.com> + 99 others); Fri, 11 Nov 2022 09:55:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58096 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234610AbiKKOzO (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Fri, 11 Nov 2022 09:55:14 -0500 Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 04377DEB6 for <linux-kernel@vger.kernel.org>; Fri, 11 Nov 2022 06:55:13 -0800 (PST) Received: from kwepemi100025.china.huawei.com (unknown [172.30.72.57]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4N81vf1g5LzmVpN; Fri, 11 Nov 2022 22:54:54 +0800 (CST) Received: from DESKTOP-27KDQMV.china.huawei.com (10.174.148.223) by kwepemi100025.china.huawei.com (7.221.188.158) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Fri, 11 Nov 2022 22:55:09 +0800 From: "Longpeng(Mike)" <longpeng2@huawei.com> To: <stefanha@redhat.com>, <mst@redhat.com>, <jasowang@redhat.com>, <sgarzare@redhat.com> CC: <virtualization@lists.linux-foundation.org>, <arei.gonglei@huawei.com>, <yechuan@huawei.com>, <huangzhichao@huawei.com>, <linux-kernel@vger.kernel.org>, <xiehong@huawei.com>, Longpeng <longpeng2@huawei.com> Subject: [PATCH] vp_vdpa: harden the logic of set status Date: Fri, 11 Nov 2022 22:55:05 +0800 Message-ID: <20221111145505.1232-1-longpeng2@huawei.com> X-Mailer: git-send-email 2.25.0.windows.1 MIME-Version: 1.0 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII X-Originating-IP: [10.174.148.223] X-ClientProxiedBy: dggems703-chm.china.huawei.com (10.3.19.180) To kwepemi100025.china.huawei.com (7.221.188.158) X-CFilter-Loop: Reflected X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749212341001391471?= X-GMAIL-MSGID: =?utf-8?q?1749212341001391471?= |
Series |
vp_vdpa: harden the logic of set status
|
|
Commit Message
Longpeng(Mike)
Nov. 11, 2022, 2:55 p.m. UTC
From: Longpeng <longpeng2@huawei.com> 1. We should not set status to 0 when invoking vp_vdpa_set_status(). 2. The driver MUST wait for a read of device_status to return 0 before reinitializing the device. Signed-off-by: Longpeng <longpeng2@huawei.com> --- drivers/vdpa/virtio_pci/vp_vdpa.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
Comments
On Fri, Nov 11, 2022 at 10:55:05PM +0800, Longpeng(Mike) wrote: >From: Longpeng <longpeng2@huawei.com> > >1. We should not set status to 0 when invoking vp_vdpa_set_status(). > >2. The driver MUST wait for a read of device_status to return 0 before > reinitializing the device. > >Signed-off-by: Longpeng <longpeng2@huawei.com> >--- > drivers/vdpa/virtio_pci/vp_vdpa.c | 11 ++++++++++- > 1 file changed, 10 insertions(+), 1 deletion(-) > >diff --git a/drivers/vdpa/virtio_pci/vp_vdpa.c b/drivers/vdpa/virtio_pci/vp_vdpa.c >index d448db0c4de3..d35fac5cde11 100644 >--- a/drivers/vdpa/virtio_pci/vp_vdpa.c >+++ b/drivers/vdpa/virtio_pci/vp_vdpa.c >@@ -212,8 +212,12 @@ static void vp_vdpa_set_status(struct vdpa_device *vdpa, u8 status) > { > 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); Is this change really needed? >+ u8 s; >+ >+ /* We should never be setting status to 0. */ >+ BUG_ON(status == 0); IMHO panicking the kernel seems excessive in this case, please use WARN_ON and maybe return earlier. > >+ s = vp_vdpa_get_status(vdpa); > if (status & VIRTIO_CONFIG_S_DRIVER_OK && > !(s & VIRTIO_CONFIG_S_DRIVER_OK)) { > vp_vdpa_request_irq(vp_vdpa); >@@ -229,6 +233,11 @@ static int vp_vdpa_reset(struct vdpa_device *vdpa) > u8 s = vp_vdpa_get_status(vdpa); > > vp_modern_set_status(mdev, 0); >+ /* After writing 0 to device_status, the driver MUST wait for a read of >+ * device_status to return 0 before reinitializing the device. >+ */ >+ while (vp_modern_get_status(mdev)) >+ msleep(1); Should we set a limit after which we give up? A malfunctioning device could keep us here forever. Thanks, Stefano > > if (s & VIRTIO_CONFIG_S_DRIVER_OK) > vp_vdpa_free_irq(vp_vdpa); >-- >2.23.0 >
在 2022/11/11 23:14, Stefano Garzarella 写道: > On Fri, Nov 11, 2022 at 10:55:05PM +0800, Longpeng(Mike) wrote: >> From: Longpeng <longpeng2@huawei.com> >> >> 1. We should not set status to 0 when invoking vp_vdpa_set_status(). >> >> 2. The driver MUST wait for a read of device_status to return 0 before >> reinitializing the device. >> >> Signed-off-by: Longpeng <longpeng2@huawei.com> >> --- >> drivers/vdpa/virtio_pci/vp_vdpa.c | 11 ++++++++++- >> 1 file changed, 10 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/vdpa/virtio_pci/vp_vdpa.c >> b/drivers/vdpa/virtio_pci/vp_vdpa.c >> index d448db0c4de3..d35fac5cde11 100644 >> --- a/drivers/vdpa/virtio_pci/vp_vdpa.c >> +++ b/drivers/vdpa/virtio_pci/vp_vdpa.c >> @@ -212,8 +212,12 @@ static void vp_vdpa_set_status(struct vdpa_device >> *vdpa, u8 status) >> { >> 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); > > Is this change really needed? > No need to get the status if we try to set status to 0 (trigger BUG). >> + u8 s; >> + >> + /* We should never be setting status to 0. */ >> + BUG_ON(status == 0); > > IMHO panicking the kernel seems excessive in this case, please use > WARN_ON and maybe return earlier. > Um...I referenced the vp_reset/vp_set_status, >> >> + s = vp_vdpa_get_status(vdpa); >> if (status & VIRTIO_CONFIG_S_DRIVER_OK && >> !(s & VIRTIO_CONFIG_S_DRIVER_OK)) { >> vp_vdpa_request_irq(vp_vdpa); >> @@ -229,6 +233,11 @@ static int vp_vdpa_reset(struct vdpa_device *vdpa) >> u8 s = vp_vdpa_get_status(vdpa); >> >> vp_modern_set_status(mdev, 0); >> + /* After writing 0 to device_status, the driver MUST wait for a >> read of >> + * device_status to return 0 before reinitializing the device. >> + */ >> + while (vp_modern_get_status(mdev)) >> + msleep(1); > > Should we set a limit after which we give up? A malfunctioning device > could keep us here forever. > Yes, but the malfunctioning device maybe can not work anymore, how to handle it? > Thanks, > Stefano > >> >> if (s & VIRTIO_CONFIG_S_DRIVER_OK) >> vp_vdpa_free_irq(vp_vdpa); >> -- >> 2.23.0 >> > > .
On Fri, Nov 11, 2022 at 11:49:10PM +0800, Longpeng (Mike, Cloud Infrastructure Service Product Dept.) wrote: > > >在 2022/11/11 23:14, Stefano Garzarella 写道: >>On Fri, Nov 11, 2022 at 10:55:05PM +0800, Longpeng(Mike) wrote: >>>From: Longpeng <longpeng2@huawei.com> >>> >>>1. We should not set status to 0 when invoking vp_vdpa_set_status(). >>> >>>2. The driver MUST wait for a read of device_status to return 0 before >>> reinitializing the device. >>> >>>Signed-off-by: Longpeng <longpeng2@huawei.com> >>>--- >>>drivers/vdpa/virtio_pci/vp_vdpa.c | 11 ++++++++++- >>>1 file changed, 10 insertions(+), 1 deletion(-) >>> >>>diff --git a/drivers/vdpa/virtio_pci/vp_vdpa.c >>>b/drivers/vdpa/virtio_pci/vp_vdpa.c >>>index d448db0c4de3..d35fac5cde11 100644 >>>--- a/drivers/vdpa/virtio_pci/vp_vdpa.c >>>+++ b/drivers/vdpa/virtio_pci/vp_vdpa.c >>>@@ -212,8 +212,12 @@ static void vp_vdpa_set_status(struct >>>vdpa_device *vdpa, u8 status) >>>{ >>> 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); >> >>Is this change really needed? >> >No need to get the status if we try to set status to 0 (trigger BUG). > Okay, but that's the case that should never happen, so IMHO we can leave it as it is. >>>+ u8 s; >>>+ >>>+ /* We should never be setting status to 0. */ >>>+ BUG_ON(status == 0); >> >>IMHO panicking the kernel seems excessive in this case, please use >>WARN_ON and maybe return earlier. >> >Um...I referenced the vp_reset/vp_set_status, Ah I see, maybe it's an old code, because recently we always try to avoid BUG_ON(). > >>> >>>+ s = vp_vdpa_get_status(vdpa); >>> if (status & VIRTIO_CONFIG_S_DRIVER_OK && >>> !(s & VIRTIO_CONFIG_S_DRIVER_OK)) { >>> vp_vdpa_request_irq(vp_vdpa); >>>@@ -229,6 +233,11 @@ static int vp_vdpa_reset(struct vdpa_device *vdpa) >>> u8 s = vp_vdpa_get_status(vdpa); >>> >>> vp_modern_set_status(mdev, 0); >>>+ /* After writing 0 to device_status, the driver MUST wait for >>>a read of >>>+ * device_status to return 0 before reinitializing the device. >>>+ */ >>>+ while (vp_modern_get_status(mdev)) >>>+ msleep(1); >> >>Should we set a limit after which we give up? A malfunctioning >>device could keep us here forever. >> >Yes, but the malfunctioning device maybe can not work anymore, how to >handle it? Maybe we should set the status to broken, but in this case we could just return an error if we couldn't reset it, how about that? Thanks, Stefano
在 2022/11/12 0:35, Stefano Garzarella 写道: > On Fri, Nov 11, 2022 at 11:49:10PM +0800, Longpeng (Mike, Cloud > Infrastructure Service Product Dept.) wrote: >> >> >> 在 2022/11/11 23:14, Stefano Garzarella 写道: >>> On Fri, Nov 11, 2022 at 10:55:05PM +0800, Longpeng(Mike) wrote: >>>> From: Longpeng <longpeng2@huawei.com> >>>> >>>> 1. We should not set status to 0 when invoking vp_vdpa_set_status(). >>>> >>>> 2. The driver MUST wait for a read of device_status to return 0 before >>>> reinitializing the device. >>>> >>>> Signed-off-by: Longpeng <longpeng2@huawei.com> >>>> --- >>>> drivers/vdpa/virtio_pci/vp_vdpa.c | 11 ++++++++++- >>>> 1 file changed, 10 insertions(+), 1 deletion(-) >>>> >>>> diff --git a/drivers/vdpa/virtio_pci/vp_vdpa.c >>>> b/drivers/vdpa/virtio_pci/vp_vdpa.c >>>> index d448db0c4de3..d35fac5cde11 100644 >>>> --- a/drivers/vdpa/virtio_pci/vp_vdpa.c >>>> +++ b/drivers/vdpa/virtio_pci/vp_vdpa.c >>>> @@ -212,8 +212,12 @@ static void vp_vdpa_set_status(struct >>>> vdpa_device *vdpa, u8 status) >>>> { >>>> 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); >>> >>> Is this change really needed? >>> >> No need to get the status if we try to set status to 0 (trigger BUG). >> > > Okay, but that's the case that should never happen, so IMHO we can leave > it as it is. > OK. >>>> + u8 s; >>>> + >>>> + /* We should never be setting status to 0. */ >>>> + BUG_ON(status == 0); >>> >>> IMHO panicking the kernel seems excessive in this case, please use >>> WARN_ON and maybe return earlier. >>> >> Um...I referenced the vp_reset/vp_set_status, > > Ah I see, maybe it's an old code, because recently we always try to > avoid BUG_ON(). > OK. The checkpatch.pl script also triggered a waring about it. I'll use WARN_ON in next version. >> >>>> >>>> + s = vp_vdpa_get_status(vdpa); >>>> if (status & VIRTIO_CONFIG_S_DRIVER_OK && >>>> !(s & VIRTIO_CONFIG_S_DRIVER_OK)) { >>>> vp_vdpa_request_irq(vp_vdpa); >>>> @@ -229,6 +233,11 @@ static int vp_vdpa_reset(struct vdpa_device *vdpa) >>>> u8 s = vp_vdpa_get_status(vdpa); >>>> >>>> vp_modern_set_status(mdev, 0); >>>> + /* After writing 0 to device_status, the driver MUST wait for a >>>> read of >>>> + * device_status to return 0 before reinitializing the device. >>>> + */ >>>> + while (vp_modern_get_status(mdev)) >>>> + msleep(1); >>> >>> Should we set a limit after which we give up? A malfunctioning device >>> could keep us here forever. >>> >> Yes, but the malfunctioning device maybe can not work anymore, how to >> handle it? > > Maybe we should set the status to broken, but in this case we could just > return an error if we couldn't reset it, how about that? > It can work, but it seems to violate the specification. Maybe we can also wait for other guys' suggestions and then decide how to handle the exception. > Thanks, > Stefano > > .
在 2022/11/12 15:33, Longpeng (Mike, Cloud Infrastructure Service Product Dept.) 写道: > > > 在 2022/11/12 0:35, Stefano Garzarella 写道: >> On Fri, Nov 11, 2022 at 11:49:10PM +0800, Longpeng (Mike, Cloud >> Infrastructure Service Product Dept.) wrote: >>> >>> >>> 在 2022/11/11 23:14, Stefano Garzarella 写道: >>>> On Fri, Nov 11, 2022 at 10:55:05PM +0800, Longpeng(Mike) wrote: >>>>> From: Longpeng <longpeng2@huawei.com> >>>>> >>>>> 1. We should not set status to 0 when invoking vp_vdpa_set_status(). >>>>> >>>>> 2. The driver MUST wait for a read of device_status to return 0 >>>>> before >>>>> reinitializing the device. >>>>> >>>>> Signed-off-by: Longpeng <longpeng2@huawei.com> >>>>> --- >>>>> drivers/vdpa/virtio_pci/vp_vdpa.c | 11 ++++++++++- >>>>> 1 file changed, 10 insertions(+), 1 deletion(-) >>>>> >>>>> diff --git a/drivers/vdpa/virtio_pci/vp_vdpa.c >>>>> b/drivers/vdpa/virtio_pci/vp_vdpa.c >>>>> index d448db0c4de3..d35fac5cde11 100644 >>>>> --- a/drivers/vdpa/virtio_pci/vp_vdpa.c >>>>> +++ b/drivers/vdpa/virtio_pci/vp_vdpa.c >>>>> @@ -212,8 +212,12 @@ static void vp_vdpa_set_status(struct >>>>> vdpa_device *vdpa, u8 status) >>>>> { >>>>> 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); >>>> >>>> Is this change really needed? >>>> >>> No need to get the status if we try to set status to 0 (trigger BUG). >>> >> >> Okay, but that's the case that should never happen, so IMHO we can >> leave it as it is. >> > OK. > >>>>> + u8 s; >>>>> + >>>>> + /* We should never be setting status to 0. */ >>>>> + BUG_ON(status == 0); >>>> >>>> IMHO panicking the kernel seems excessive in this case, please use >>>> WARN_ON and maybe return earlier. >>>> >>> Um...I referenced the vp_reset/vp_set_status, >> >> Ah I see, maybe it's an old code, because recently we always try to >> avoid BUG_ON(). >> > OK. The checkpatch.pl script also triggered a waring about it. > I'll use WARN_ON in next version. > >>> >>>>> >>>>> + s = vp_vdpa_get_status(vdpa); >>>>> if (status & VIRTIO_CONFIG_S_DRIVER_OK && >>>>> !(s & VIRTIO_CONFIG_S_DRIVER_OK)) { >>>>> vp_vdpa_request_irq(vp_vdpa); >>>>> @@ -229,6 +233,11 @@ static int vp_vdpa_reset(struct vdpa_device >>>>> *vdpa) >>>>> u8 s = vp_vdpa_get_status(vdpa); >>>>> >>>>> vp_modern_set_status(mdev, 0); >>>>> + /* After writing 0 to device_status, the driver MUST wait for >>>>> a read of >>>>> + * device_status to return 0 before reinitializing the device. >>>>> + */ >>>>> + while (vp_modern_get_status(mdev)) >>>>> + msleep(1); >>>> >>>> Should we set a limit after which we give up? A malfunctioning >>>> device could keep us here forever. >>>> >>> Yes, but the malfunctioning device maybe can not work anymore, how >>> to handle it? >> >> Maybe we should set the status to broken, but in this case we could >> just return an error if we couldn't reset it, how about that? >> > It can work, but it seems to violate the specification. Maybe we can > also wait for other guys' suggestions and then decide how to handle > the exception. Need more thought but it's not an issue that is introduced in this patch, we can do optimization on top. Probably a warning plus FAILED. Then at least the device can DOS the driver which is good for hardening as well. Thanks > >> Thanks, >> Stefano >> >> . >
diff --git a/drivers/vdpa/virtio_pci/vp_vdpa.c b/drivers/vdpa/virtio_pci/vp_vdpa.c index d448db0c4de3..d35fac5cde11 100644 --- a/drivers/vdpa/virtio_pci/vp_vdpa.c +++ b/drivers/vdpa/virtio_pci/vp_vdpa.c @@ -212,8 +212,12 @@ static void vp_vdpa_set_status(struct vdpa_device *vdpa, u8 status) { 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 s; + + /* We should never be setting status to 0. */ + BUG_ON(status == 0); + s = vp_vdpa_get_status(vdpa); if (status & VIRTIO_CONFIG_S_DRIVER_OK && !(s & VIRTIO_CONFIG_S_DRIVER_OK)) { vp_vdpa_request_irq(vp_vdpa); @@ -229,6 +233,11 @@ static int vp_vdpa_reset(struct vdpa_device *vdpa) u8 s = vp_vdpa_get_status(vdpa); vp_modern_set_status(mdev, 0); + /* After writing 0 to device_status, the driver MUST wait for a read of + * device_status to return 0 before reinitializing the device. + */ + while (vp_modern_get_status(mdev)) + msleep(1); if (s & VIRTIO_CONFIG_S_DRIVER_OK) vp_vdpa_free_irq(vp_vdpa);