From: Greg Kroah-Hartman Date: Sat, 9 Jun 2018 14:47:47 +0000 (+0200) Subject: 4.17-stable patches X-Git-Tag: v4.17.1~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7888f079c622fe4759d42c48e4605dbbd47bf9a5;p=thirdparty%2Fkernel%2Fstable-queue.git 4.17-stable patches added patches: pci-hv-do-not-wait-forever-on-a-device-that-has-disappeared.patch --- diff --git a/queue-4.17/pci-hv-do-not-wait-forever-on-a-device-that-has-disappeared.patch b/queue-4.17/pci-hv-do-not-wait-forever-on-a-device-that-has-disappeared.patch new file mode 100644 index 00000000000..1cc6ff75a08 --- /dev/null +++ b/queue-4.17/pci-hv-do-not-wait-forever-on-a-device-that-has-disappeared.patch @@ -0,0 +1,131 @@ +From c3635da2a336441253c33298b87b3042db100725 Mon Sep 17 00:00:00 2001 +From: Dexuan Cui +Date: Wed, 23 May 2018 21:12:01 +0000 +Subject: PCI: hv: Do not wait forever on a device that has disappeared + +From: Dexuan Cui + +commit c3635da2a336441253c33298b87b3042db100725 upstream. + +Before the guest finishes the device initialization, the device can be +removed anytime by the host, and after that the host won't respond to +the guest's request, so the guest should be prepared to handle this +case. + +Add a polling mechanism to detect device presence. + +Signed-off-by: Dexuan Cui +[lorenzo.pieralisi@arm.com: edited commit log] +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Haiyang Zhang +Cc: Stephen Hemminger +Cc: K. Y. Srinivasan +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/host/pci-hyperv.c | 46 +++++++++++++++++++++++++++++++----------- + 1 file changed, 34 insertions(+), 12 deletions(-) + +--- a/drivers/pci/host/pci-hyperv.c ++++ b/drivers/pci/host/pci-hyperv.c +@@ -556,6 +556,26 @@ static void put_pcichild(struct hv_pci_d + static void get_hvpcibus(struct hv_pcibus_device *hv_pcibus); + static void put_hvpcibus(struct hv_pcibus_device *hv_pcibus); + ++/* ++ * There is no good way to get notified from vmbus_onoffer_rescind(), ++ * so let's use polling here, since this is not a hot path. ++ */ ++static int wait_for_response(struct hv_device *hdev, ++ struct completion *comp) ++{ ++ while (true) { ++ if (hdev->channel->rescind) { ++ dev_warn_once(&hdev->device, "The device is gone.\n"); ++ return -ENODEV; ++ } ++ ++ if (wait_for_completion_timeout(comp, HZ / 10)) ++ break; ++ } ++ ++ return 0; ++} ++ + /** + * devfn_to_wslot() - Convert from Linux PCI slot to Windows + * @devfn: The Linux representation of PCI slot +@@ -1568,7 +1588,8 @@ static struct hv_pci_dev *new_pcichild_d + if (ret) + goto error; + +- wait_for_completion(&comp_pkt.host_event); ++ if (wait_for_response(hbus->hdev, &comp_pkt.host_event)) ++ goto error; + + hpdev->desc = *desc; + refcount_set(&hpdev->refs, 1); +@@ -2069,15 +2090,16 @@ static int hv_pci_protocol_negotiation(s + sizeof(struct pci_version_request), + (unsigned long)pkt, VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); ++ if (!ret) ++ ret = wait_for_response(hdev, &comp_pkt.host_event); ++ + if (ret) { + dev_err(&hdev->device, +- "PCI Pass-through VSP failed sending version reqquest: %#x", ++ "PCI Pass-through VSP failed to request version: %d", + ret); + goto exit; + } + +- wait_for_completion(&comp_pkt.host_event); +- + if (comp_pkt.completion_status >= 0) { + pci_protocol_version = pci_protocol_versions[i]; + dev_info(&hdev->device, +@@ -2286,11 +2308,12 @@ static int hv_pci_enter_d0(struct hv_dev + ret = vmbus_sendpacket(hdev->channel, d0_entry, sizeof(*d0_entry), + (unsigned long)pkt, VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); ++ if (!ret) ++ ret = wait_for_response(hdev, &comp_pkt.host_event); ++ + if (ret) + goto exit; + +- wait_for_completion(&comp_pkt.host_event); +- + if (comp_pkt.completion_status < 0) { + dev_err(&hdev->device, + "PCI Pass-through VSP failed D0 Entry with status %x\n", +@@ -2330,11 +2353,10 @@ static int hv_pci_query_relations(struct + + ret = vmbus_sendpacket(hdev->channel, &message, sizeof(message), + 0, VM_PKT_DATA_INBAND, 0); +- if (ret) +- return ret; ++ if (!ret) ++ ret = wait_for_response(hdev, &comp); + +- wait_for_completion(&comp); +- return 0; ++ return ret; + } + + /** +@@ -2404,11 +2426,11 @@ static int hv_send_resources_allocated(s + size_res, (unsigned long)pkt, + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); ++ if (!ret) ++ ret = wait_for_response(hdev, &comp_pkt.host_event); + if (ret) + break; + +- wait_for_completion(&comp_pkt.host_event); +- + if (comp_pkt.completion_status < 0) { + ret = -EPROTO; + dev_err(&hdev->device, diff --git a/queue-4.17/series b/queue-4.17/series index dbeaffca7ac..684aee1ad0c 100644 --- a/queue-4.17/series +++ b/queue-4.17/series @@ -12,3 +12,4 @@ team-use-netdev_features_t-instead-of-u32.patch vrf-check-the-original-netdevice-for-generating-redirect.patch net-dsa-b53-fix-for-brcm-tag-issue-in-cygnus-soc.patch ipmr-fix-error-path-when-ipmr_new_table-fails.patch +pci-hv-do-not-wait-forever-on-a-device-that-has-disappeared.patch