From owner-dev-commits-src-all@freebsd.org Mon Mar 15 05:14:36 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 341A05700F8; Mon, 15 Mar 2021 05:14:36 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4DzPjm10NFz3q3L; Mon, 15 Mar 2021 05:14:36 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 1529228E9; Mon, 15 Mar 2021 05:14:36 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 12F5EaYF074351; Mon, 15 Mar 2021 05:14:36 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 12F5EanN074350; Mon, 15 Mar 2021 05:14:36 GMT (envelope-from git) Date: Mon, 15 Mar 2021 05:14:36 GMT Message-Id: <202103150514.12F5EanN074350@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Wei Hu Subject: git: 279041093326 - stable/12 - Hyper-V: pcib: Check revoke status during device attach MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: whu X-Git-Repository: src X-Git-Refname: refs/heads/stable/12 X-Git-Reftype: branch X-Git-Commit: 279041093326704636531051ad188e81b8beb32c Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 15 Mar 2021 05:14:36 -0000 The branch stable/12 has been updated by whu: URL: https://cgit.FreeBSD.org/src/commit/?id=279041093326704636531051ad188e81b8beb32c commit 279041093326704636531051ad188e81b8beb32c Author: Wei Hu AuthorDate: 2020-10-15 05:57:20 +0000 Commit: Wei Hu CommitDate: 2021-03-15 05:11:50 +0000 Hyper-V: pcib: Check revoke status during device attach It is possible that the vmbus pcib channel is revoked during attach path. The attach path could be waiting for response from host and this response will never arrive since the channel has already been revoked from host point of view. Check this situation during wait complete and return failed if this happens. Reported by: Netapp MFC after: 2 weeks Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D26486 (cherry picked from commit 75c2786c25fef9a6f8239c9fc1631cd17756579b) --- sys/dev/hyperv/pcib/vmbus_pcib.c | 78 +++++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 12 deletions(-) diff --git a/sys/dev/hyperv/pcib/vmbus_pcib.c b/sys/dev/hyperv/pcib/vmbus_pcib.c index 0d49ae313ccd..72e430c946db 100644 --- a/sys/dev/hyperv/pcib/vmbus_pcib.c +++ b/sys/dev/hyperv/pcib/vmbus_pcib.c @@ -117,6 +117,31 @@ wait_for_completion(struct completion *c) mtx_unlock(&c->lock); } +/* + * Return: 0 if completed, a non-zero value if timed out. + */ +static int +wait_for_completion_timeout(struct completion *c, int timeout) +{ + int ret; + + mtx_lock(&c->lock); + + if (c->done == 0) + mtx_sleep(c, &c->lock, 0, "hvwfc", timeout); + + if (c->done > 0) { + c->done--; + ret = 0; + } else { + ret = 1; + } + + mtx_unlock(&c->lock); + + return (ret); +} + #define PCI_MAKE_VERSION(major, minor) ((uint32_t)(((major) << 16) | (major))) enum { @@ -438,6 +463,25 @@ struct compose_comp_ctxt { struct tran_int_desc int_desc; }; +/* + * It is possible the device is revoked during initialization. + * Check if this happens during wait. + * Return: 0 if response arrived, ENODEV if device revoked. + */ +static int +wait_for_response(struct hv_pcibus *hbus, struct completion *c) +{ + do { + if (vmbus_chan_is_revoked(hbus->sc->chan)) { + device_printf(hbus->pcib, + "The device is revoked.\n"); + return (ENODEV); + } + } while (wait_for_completion_timeout(c, hz /10) != 0); + + return 0; +} + static void hv_pci_generic_compl(void *context, struct pci_response *resp, int resp_packet_size) @@ -568,7 +612,9 @@ new_pcichild_device(struct hv_pcibus *hbus, struct pci_func_desc *desc) if (ret) goto err; - wait_for_completion(&comp_pkt.host_event); + if (wait_for_response(hbus, &comp_pkt.host_event)) + goto err; + free_completion(&comp_pkt.host_event); hpdev->desc = *desc; @@ -1011,10 +1057,15 @@ hv_pci_protocol_negotiation(struct hv_pcibus *hbus) ret = vmbus_chan_send(hbus->sc->chan, VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, version_req, sizeof(*version_req), (uint64_t)(uintptr_t)&ctxt.pkt); - if (ret) - goto out; + if (!ret) + ret = wait_for_response(hbus, &comp_pkt.host_event); - wait_for_completion(&comp_pkt.host_event); + if (ret) { + device_printf(hbus->pcib, + "vmbus_pcib failed to request version: %d\n", + ret); + goto out; + } if (comp_pkt.completion_status < 0) { device_printf(hbus->pcib, @@ -1072,11 +1123,12 @@ hv_pci_enter_d0(struct hv_pcibus *hbus) ret = vmbus_chan_send(hbus->sc->chan, VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, d0_entry, sizeof(*d0_entry), (uint64_t)(uintptr_t)&ctxt.pkt); + if (!ret) + ret = wait_for_response(hbus, &comp_pkt.host_event); + if (ret) goto out; - wait_for_completion(&comp_pkt.host_event); - if (comp_pkt.completion_status < 0) { device_printf(hbus->pcib, "vmbus_pcib failed to enable D0\n"); ret = EPROTO; @@ -1125,14 +1177,14 @@ hv_send_resources_allocated(struct hv_pcibus *hbus) VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, &pkt->message, sizeof(*res_assigned), (uint64_t)(uintptr_t)pkt); - if (ret) { - free_completion(&comp_pkt.host_event); - break; - } + if (!ret) + ret = wait_for_response(hbus, &comp_pkt.host_event); - wait_for_completion(&comp_pkt.host_event); free_completion(&comp_pkt.host_event); + if (ret) + break; + if (comp_pkt.completion_status < 0) { ret = EPROTO; device_printf(hbus->pcib, @@ -1413,9 +1465,11 @@ vmbus_pcib_attach(device_t dev) goto vmbus_close; ret = hv_pci_query_relations(hbus); + if (!ret) + ret = wait_for_response(hbus, hbus->query_comp); + if (ret) goto vmbus_close; - wait_for_completion(hbus->query_comp); ret = hv_pci_enter_d0(hbus); if (ret)