From patchwork Mon May 3 14:46:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boqun Feng X-Patchwork-Id: 12236061 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id ACDD3C433B4 for ; Mon, 3 May 2021 14:49:57 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E1903611C0 for ; Mon, 3 May 2021 14:49:56 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E1903611C0 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=o308nsq/hNUvS/O9KXnoBbxeyOjD7W0Rt6nEGw8TzaM=; b=NIOg1/TBUCTp5n4uLPbModOWR nRZxklHq7hR5MmhUdTKBh5vl4BFMt7jNFLODQDuvF5GW0Qb3JrsdFZr80UrFpy2bVXPBFy86+HTaW GoSy/5Gt0b8kHmHmrD3FdLPepQFAJtEHThOW18yw16xzkCZ2WcUsJWurcLmQ86v8vc0vepQy7Qkay bPfn1ghO4RiPIcnLo7cXjLcgMjJZMR6wnNqillhBWKXGQ+XzvIFu0HKL1bqH2lSDUTY3c7JiZ5Eba IgrBtHIhSFzK4pYkqm4xRzxoXPboynif0JPm2Z9jDqPeoiFLzgwB8s1HWWfi5D/rp6Xu/0DymWnoK 6HYNWIcbw==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1ldZry-00E6hM-6U; Mon, 03 May 2021 14:48:22 +0000 Received: from bombadil.infradead.org ([2607:7c80:54:e::133]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1ldZrQ-00E6Xz-S2 for linux-arm-kernel@desiato.infradead.org; Mon, 03 May 2021 14:47:51 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=K7WNcv9gpl7Pc9Bs4CClcYzbGI8iLKijx7i4GjrAumE=; b=CgdHW48Vh3XyZm5BCUALltVIoF NQtqSmSNJ/SeTHAKQ6/SA39yoOJj9UfqEyweTKD37HiHq/PtRMnrdgvxZmCuyx/XyJob3wXGNXFae I3zp93HIRlLUUBNmucaQzyuIXBviY2OFRKgbE0eabV+fRJ7pLgT6dlfe4Z+AqbujaYPA0lfy/kopu YRSJgUlTF/dEm7WS226FU6KDzO2t7Ki7+sn5S8hTRA0yUnjTnF6uaOY3HHeVCbSJbaPbARRjoOpGs C4q03MhL3/TF84Xe6Q0OExBQZQcmda7O+hIQNoW+aIvx/eMmOQOs0AyfRhMY0YWxVE/ouidy8GzvK WuMUzl/Q==; Received: from mail-qv1-xf34.google.com ([2607:f8b0:4864:20::f34]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1ldZrN-0038c4-VK for linux-arm-kernel@lists.infradead.org; Mon, 03 May 2021 14:47:47 +0000 Received: by mail-qv1-xf34.google.com with SMTP id h1so1869736qvv.10 for ; Mon, 03 May 2021 07:47:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=K7WNcv9gpl7Pc9Bs4CClcYzbGI8iLKijx7i4GjrAumE=; b=hDTXkLgdcBg/8iActEuVZQsBNINluBlGBSf7I7odEakWa+wbqfIS8ru5mGYOIN3W9a Z8u+zqGdzHrqgNzvNLnG2YTpfUBkO9Pm69m3IWELrOgpm07CycymYoSV0E7Tlh5a12GP N8CSKMpNXgp2AGXk4Id6oTZoCkc0gd1FWZJyKTEf42SJBXZo7FdHE+6ELCXM9YKMX2ua HLOgS1hcP12qpAIdthqyAUltnITk3NcCCVGNaMnj9wjeIq9+MPZNM9ApVf8SFVAMs/7m 0kdHTcxfFvXHezgVH14WCzSV8H+wu03fGHprIRg5AChgBT9MZqNHQyp+zB9vhKkQtV+X xY0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=K7WNcv9gpl7Pc9Bs4CClcYzbGI8iLKijx7i4GjrAumE=; b=BU4LtkUzrrnOhqZ+b9OlqZRSTRlsa8kPxKndkVs6Uo4Ya+WCj8XgdBIXTf7XwNZm4g Xm8gel7abA7vyzuuBr3yREAHc/7jkeNcafQYfFLggqJ/pRk2JCz/u+UBgl81rFlpLJ7i 2ZoLdmazpM6krpfWgaFwWGgzzGXfOSp6IvdVPvfq4ja5H+alG+y8TyZQ/DSlItxbqaVq KNPAZmD04sjCUIed1fUlmeYaO6ruTz9zpQl3cNp8caF0K6hFTSSyPJDeZ0CsC2ZhFBwC avDHPfXgVNAm02KJ7EHEjxhiOoQmPrXYTeJbLhJ2YBT6plcIlfP3VQYWF0s7plCSJPWQ JPHg== X-Gm-Message-State: AOAM533/y3d72QFMDmS2P3m/T/EO9fYWGD2UGfVmXXpFvwEqfrYmp3sG rsVY14qSnIYFaCmSXdEIK8g= X-Google-Smtp-Source: ABdhPJwhFORps0pBFTvoj1SZER6t9pF8hcj2oPdiHng2UNuDKEAEABMrq6X2quoa/uEV0cg+fxBuVA== X-Received: by 2002:ad4:4f11:: with SMTP id fb17mr20178028qvb.18.1620053264946; Mon, 03 May 2021 07:47:44 -0700 (PDT) Received: from auth1-smtp.messagingengine.com (auth1-smtp.messagingengine.com. [66.111.4.227]) by smtp.gmail.com with ESMTPSA id n15sm8qti.51.2021.05.03.07.47.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 May 2021 07:47:44 -0700 (PDT) Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailauth.nyi.internal (Postfix) with ESMTP id 8439927C005A; Mon, 3 May 2021 10:47:43 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute2.internal (MEProxy); Mon, 03 May 2021 10:47:43 -0400 X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrvdefgedgkedvucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpeeuohhquhhn ucfhvghnghcuoegsohhquhhnrdhfvghnghesghhmrghilhdrtghomheqnecuggftrfgrth htvghrnhephedvveetfefgiedutedtfeevvddvleekjeeuffffleeguefhhfejteekieeu ueelnecukfhppedufedurddutdejrddurddvheegnecuvehluhhsthgvrhfuihiivgeptd enucfrrghrrghmpehmrghilhhfrhhomhepsghoqhhunhdomhgvshhmthhprghuthhhphgv rhhsohhnrghlihhthidqieelvdeghedtieegqddujeejkeehheehvddqsghoqhhunhdrfh gvnhhgpeepghhmrghilhdrtghomhesfhhigihmvgdrnhgrmhgv X-ME-Proxy: Received: from localhost (unknown [131.107.1.254]) by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 3 May 2021 10:47:42 -0400 (EDT) From: Boqun Feng To: Bjorn Helgaas , Arnd Bergmann , Marc Zyngier Cc: Russell King , Andrew Lunn , Sebastian Hesselbarth , Gregory Clement , Catalin Marinas , Will Deacon , Thomas Bogendoerfer , Lorenzo Pieralisi , Rob Herring , "K. Y. Srinivasan" , Haiyang Zhang , Stephen Hemminger , Wei Liu , Thomas Petazzoni , Boqun Feng , Mike Rapoport , Robin Murphy , Thomas Gleixner , Jon Derrick , Sunil Muthuswamy , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-mips@vger.kernel.org, linux-pci@vger.kernel.org, linux-hyperv@vger.kernel.org Subject: [RFC v2 3/7] PCI: hv: Generify PCI probing Date: Mon, 3 May 2021 22:46:31 +0800 Message-Id: <20210503144635.2297386-4-boqun.feng@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210503144635.2297386-1-boqun.feng@gmail.com> References: <20210503144635.2297386-1-boqun.feng@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210503_074746_038607_DD0F73F7 X-CRM114-Status: GOOD ( 25.98 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Arnd Bergmann In order to support ARM64 Hyper-V PCI, we need to set up the bridge at probing time because ARM64 is a PCI_DOMAIN_GENERIC arch and we don't have pci_config_window (ARM64 sysdata) for a PCI root bus on Hyper-V, so it's impossible to retrieve the information (e.g. PCI domains, irq domains) from bus sysdata on ARM64 after creation. Originally in create_root_hv_pci_bus(), pci_create_root_bus() is used to create the root bus and the corresponding bridge based on x86 sysdata. Now we create a bridge first and then call pci_scan_root_bus_bridge(), which allows us to do the necessary set-ups for the bridge. Signed-off-by: Arnd Bergmann Signed-off-by: Boqun Feng --- drivers/pci/controller/pci-hyperv.c | 61 +++++++++++++++-------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c index 27a17a1e4a7c..27b922b4bb7b 100644 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c @@ -450,6 +450,7 @@ enum hv_pcibus_state { struct hv_pcibus_device { struct pci_sysdata sysdata; + struct pci_host_bridge *bridge; /* Protocol version negotiated with the host */ enum pci_protocol_version_t protocol_version; enum hv_pcibus_state state; @@ -462,13 +463,10 @@ struct hv_pcibus_device { struct resource *high_mmio_res; struct completion *survey_event; struct completion remove_event; - struct pci_bus *pci_bus; spinlock_t config_lock; /* Avoid two threads writing index page */ spinlock_t device_list_lock; /* Protect lists below */ void __iomem *cfg_addr; - struct list_head resources_for_children; - struct list_head children; struct list_head dr_list; @@ -1804,7 +1802,7 @@ static void hv_pci_assign_slots(struct hv_pcibus_device *hbus) slot_nr = PCI_SLOT(wslot_to_devfn(hpdev->desc.win_slot.slot)); snprintf(name, SLOT_NAME_SIZE, "%u", hpdev->desc.ser); - hpdev->pci_slot = pci_create_slot(hbus->pci_bus, slot_nr, + hpdev->pci_slot = pci_create_slot(hbus->bridge->bus, slot_nr, name, NULL); if (IS_ERR(hpdev->pci_slot)) { pr_warn("pci_create slot %s failed\n", name); @@ -1834,7 +1832,7 @@ static void hv_pci_remove_slots(struct hv_pcibus_device *hbus) static void hv_pci_assign_numa_node(struct hv_pcibus_device *hbus) { struct pci_dev *dev; - struct pci_bus *bus = hbus->pci_bus; + struct pci_bus *bus = hbus->bridge->bus; struct hv_pci_dev *hv_dev; list_for_each_entry(dev, &bus->devices, bus_list) { @@ -1857,24 +1855,24 @@ static void hv_pci_assign_numa_node(struct hv_pcibus_device *hbus) */ static int create_root_hv_pci_bus(struct hv_pcibus_device *hbus) { - /* Register the device */ - hbus->pci_bus = pci_create_root_bus(&hbus->hdev->device, - 0, /* bus number is always zero */ - &hv_pcifront_ops, - &hbus->sysdata, - &hbus->resources_for_children); - if (!hbus->pci_bus) - return -ENODEV; + int error; + struct pci_host_bridge *bridge = hbus->bridge; + + bridge->dev.parent = &hbus->hdev->device; + bridge->sysdata = &hbus->sysdata; + bridge->ops = &hv_pcifront_ops; + bridge->msi = &hbus->msi_chip; + bridge->msi->dev = &hbus->hdev->device; - hbus->pci_bus->msi = &hbus->msi_chip; - hbus->pci_bus->msi->dev = &hbus->hdev->device; + error = pci_scan_root_bus_bridge(bridge); + if (error) + return error; pci_lock_rescan_remove(); - pci_scan_child_bus(hbus->pci_bus); hv_pci_assign_numa_node(hbus); - pci_bus_assign_resources(hbus->pci_bus); + pci_bus_assign_resources(bridge->bus); hv_pci_assign_slots(hbus); - pci_bus_add_devices(hbus->pci_bus); + pci_bus_add_devices(bridge->bus); pci_unlock_rescan_remove(); hbus->state = hv_pcibus_installed; return 0; @@ -2139,7 +2137,7 @@ static void pci_devices_present_work(struct work_struct *work) * because there may have been changes. */ pci_lock_rescan_remove(); - pci_scan_child_bus(hbus->pci_bus); + pci_scan_child_bus(hbus->bridge->bus); hv_pci_assign_numa_node(hbus); hv_pci_assign_slots(hbus); pci_unlock_rescan_remove(); @@ -2310,8 +2308,8 @@ static void hv_eject_device_work(struct work_struct *work) /* * Ejection can come before or after the PCI bus has been set up, so * attempt to find it and tear down the bus state, if it exists. This - * must be done without constructs like pci_domain_nr(hbus->pci_bus) - * because hbus->pci_bus may not exist yet. + * must be done without constructs like pci_domain_nr(hbus->bridge->bus) + * because hbus->bridge->bus may not exist yet. */ wslot = wslot_to_devfn(hpdev->desc.win_slot.slot); pdev = pci_get_domain_bus_and_slot(hbus->sysdata.domain, 0, wslot); @@ -2680,8 +2678,7 @@ static int hv_pci_allocate_bridge_windows(struct hv_pcibus_device *hbus) /* Modify this resource to become a bridge window. */ hbus->low_mmio_res->flags |= IORESOURCE_WINDOW; hbus->low_mmio_res->flags &= ~IORESOURCE_BUSY; - pci_add_resource(&hbus->resources_for_children, - hbus->low_mmio_res); + pci_add_resource(&hbus->bridge->windows, hbus->low_mmio_res); } if (hbus->high_mmio_space) { @@ -2700,8 +2697,7 @@ static int hv_pci_allocate_bridge_windows(struct hv_pcibus_device *hbus) /* Modify this resource to become a bridge window. */ hbus->high_mmio_res->flags |= IORESOURCE_WINDOW; hbus->high_mmio_res->flags &= ~IORESOURCE_BUSY; - pci_add_resource(&hbus->resources_for_children, - hbus->high_mmio_res); + pci_add_resource(&hbus->bridge->windows, hbus->high_mmio_res); } return 0; @@ -3031,6 +3027,7 @@ static void hv_put_dom_num(u16 dom) static int hv_pci_probe(struct hv_device *hdev, const struct hv_vmbus_device_id *dev_id) { + struct pci_host_bridge *bridge; struct hv_pcibus_device *hbus; u16 dom_req, dom; char *name; @@ -3043,6 +3040,10 @@ static int hv_pci_probe(struct hv_device *hdev, */ BUILD_BUG_ON(sizeof(*hbus) > HV_HYP_PAGE_SIZE); + bridge = devm_pci_alloc_host_bridge(&hdev->device, 0); + if (!bridge) + return -ENOMEM; + /* * With the recent 59bb47985c1d ("mm, sl[aou]b: guarantee natural * alignment for kmalloc(power-of-two)"), kzalloc() is able to allocate @@ -3064,6 +3065,8 @@ static int hv_pci_probe(struct hv_device *hdev, hbus = kzalloc(HV_HYP_PAGE_SIZE, GFP_KERNEL); if (!hbus) return -ENOMEM; + + hbus->bridge = bridge; hbus->state = hv_pcibus_init; hbus->wslot_res_allocated = -1; @@ -3101,7 +3104,6 @@ static int hv_pci_probe(struct hv_device *hdev, refcount_set(&hbus->remove_lock, 1); INIT_LIST_HEAD(&hbus->children); INIT_LIST_HEAD(&hbus->dr_list); - INIT_LIST_HEAD(&hbus->resources_for_children); spin_lock_init(&hbus->config_lock); spin_lock_init(&hbus->device_list_lock); spin_lock_init(&hbus->retarget_msi_interrupt_lock); @@ -3307,9 +3309,9 @@ static int hv_pci_remove(struct hv_device *hdev) if (hbus->state == hv_pcibus_installed) { /* Remove the bus from PCI's point of view. */ pci_lock_rescan_remove(); - pci_stop_root_bus(hbus->pci_bus); + pci_stop_root_bus(hbus->bridge->bus); hv_pci_remove_slots(hbus); - pci_remove_root_bus(hbus->pci_bus); + pci_remove_root_bus(hbus->bridge->bus); pci_unlock_rescan_remove(); hbus->state = hv_pcibus_removed; } @@ -3320,7 +3322,6 @@ static int hv_pci_remove(struct hv_device *hdev) iounmap(hbus->cfg_addr); hv_free_config_window(hbus); - pci_free_resource_list(&hbus->resources_for_children); hv_pci_free_bridge_windows(hbus); irq_domain_remove(hbus->irq_domain); irq_domain_free_fwnode(hbus->sysdata.fwnode); @@ -3406,7 +3407,7 @@ static int hv_pci_restore_msi_msg(struct pci_dev *pdev, void *arg) */ static void hv_pci_restore_msi_state(struct hv_pcibus_device *hbus) { - pci_walk_bus(hbus->pci_bus, hv_pci_restore_msi_msg, NULL); + pci_walk_bus(hbus->bridge->bus, hv_pci_restore_msi_msg, NULL); } static int hv_pci_resume(struct hv_device *hdev)