From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CDD0BC433F5 for ; Mon, 11 Oct 2021 13:54:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B7CDD60555 for ; Mon, 11 Oct 2021 13:54:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236670AbhJKN4E (ORCPT ); Mon, 11 Oct 2021 09:56:04 -0400 Received: from mail.kernel.org ([198.145.29.99]:41744 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235228AbhJKNyH (ORCPT ); Mon, 11 Oct 2021 09:54:07 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 6FE6960555; Mon, 11 Oct 2021 13:52:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1633960327; bh=2sxTtuvRTNg8nj8gTOBizQ3DzjYaIZI9y9Fch4FbnZo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=k2oGxgV4fyAMQ5gMr8eP6uG46J0xS2Y+8b1WN2Nem7pZxYl+qctc+aEX8ygK0kbkL KhkAKSD7HDU0VV3OoIICODLo/ZBy3ZNwjI+a35IMSpTVT3juIOkMgTs9I3wxsoYjWS PLHwmbpK3u60rvl+NPFooGTkpmYK4wY3PnsHyyqY= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, "K. Y. Srinivasan" , Haiyang Zhang , Stephen Hemminger , Wei Liu , Dexuan Cui , Lorenzo Pieralisi , Rob Herring , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , Bjorn Helgaas , Michael Kelley , Dan Carpenter , Long Li , Sasha Levin Subject: [PATCH 5.10 29/83] PCI: hv: Fix sleep while in non-sleep context when removing child devices from the bus Date: Mon, 11 Oct 2021 15:45:49 +0200 Message-Id: <20211011134509.375350818@linuxfoundation.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211011134508.362906295@linuxfoundation.org> References: <20211011134508.362906295@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Long Li [ Upstream commit 41608b64b10b80fe00dd253cd8326ec8ad85930f ] In hv_pci_bus_exit, the code is holding a spinlock while calling pci_destroy_slot(), which takes a mutex. This is not safe for spinlock. Fix this by moving the children to be deleted to a list on the stack, and removing them after spinlock is released. Fixes: 94d22763207a ("PCI: hv: Fix a race condition when removing the device") Cc: "K. Y. Srinivasan" Cc: Haiyang Zhang Cc: Stephen Hemminger Cc: Wei Liu Cc: Dexuan Cui Cc: Lorenzo Pieralisi Cc: Rob Herring Cc: "Krzysztof WilczyƄski" Cc: Bjorn Helgaas Cc: Michael Kelley Reported-by: Dan Carpenter Link: https://lore.kernel.org/linux-hyperv/20210823152130.GA21501@kili/ Signed-off-by: Long Li Reviewed-by: Wei Liu Link: https://lore.kernel.org/r/1630365207-20616-1-git-send-email-longli@linuxonhyperv.com Signed-off-by: Wei Liu Signed-off-by: Sasha Levin --- drivers/pci/controller/pci-hyperv.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c index 44e15f0e3a2e..ad3e3cde1c20 100644 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c @@ -3259,9 +3259,17 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs) return 0; if (!keep_devs) { - /* Delete any children which might still exist. */ + struct list_head removed; + + /* Move all present children to the list on stack */ + INIT_LIST_HEAD(&removed); spin_lock_irqsave(&hbus->device_list_lock, flags); - list_for_each_entry_safe(hpdev, tmp, &hbus->children, list_entry) { + list_for_each_entry_safe(hpdev, tmp, &hbus->children, list_entry) + list_move_tail(&hpdev->list_entry, &removed); + spin_unlock_irqrestore(&hbus->device_list_lock, flags); + + /* Remove all children in the list */ + list_for_each_entry_safe(hpdev, tmp, &removed, list_entry) { list_del(&hpdev->list_entry); if (hpdev->pci_slot) pci_destroy_slot(hpdev->pci_slot); @@ -3269,7 +3277,6 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs) put_pcichild(hpdev); put_pcichild(hpdev); } - spin_unlock_irqrestore(&hbus->device_list_lock, flags); } ret = hv_send_resources_released(hdev); -- 2.33.0