From patchwork Tue Jun 9 22:30:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian May X-Patchwork-Id: 1306335 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49hPvm11l1z9sSJ; Wed, 10 Jun 2020 08:30:27 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1jimlE-00059g-VE; Tue, 09 Jun 2020 22:30:24 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1jimlD-000593-DN for kernel-team@lists.ubuntu.com; Tue, 09 Jun 2020 22:30:23 +0000 Received: from mail-wr1-f72.google.com ([209.85.221.72]) by youngberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1jimlD-00011g-44 for kernel-team@lists.ubuntu.com; Tue, 09 Jun 2020 22:30:23 +0000 Received: by mail-wr1-f72.google.com with SMTP id p10so146513wrn.19 for ; Tue, 09 Jun 2020 15:30:23 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gpdSakdjMg1+SryXNgFIi+4sF15Un78xaauvYPZw44I=; b=uErssP4wuOi1UEXFNe5XS4otxflu57G4vUG7tyESZPGMW9+qcHTFko+Lgf1B1lQGSQ xNh7TG1rwDXn8xevEztJJuxOYuOsapCGzL0k8VKkW0KBCAaFlFPj6LapQk1jGu5kP+Ot yfab+1UchhI2jSUm3LMXH3vBb5xLLV6X8BoBBJekhOJAIjxT3ccd+0JveoGjSa+oXIRW 3aBHmSTU7EKFdXVcXJtN3/ZIx+dyooJiN3ySl1sx5hhgTJmiA12oA/qk5o7ywfQOQ1Fh Gw7OjKiBzAHE8jGX7st3arcm8cdPQlm/Bs3N+wlDJ0W7pD3+nsMs1Y4Cm8d6+QJsewyu koNg== X-Gm-Message-State: AOAM532ZUxbVz2NAXWkKsxu10IWlw/gEtkbA3OyVMfJu1bLoc6rLH5II 3AGmokkBdIpOAFtAqO2TW+wFdvfraKkXzhyADif3yesMOr3a+lgRxwRNADcJbJ9ghZp4uiJ8XrX 2dfp7MoaPjVLEPczDr9P/toYkUx68RVfPzyc3l/awSA== X-Received: by 2002:a7b:cbce:: with SMTP id n14mr221053wmi.66.1591741822504; Tue, 09 Jun 2020 15:30:22 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwh6ycOFwgfBNz/rrX86e270+SvgXq+6qxQJfW8wfD/DoQPUTMTl4bA6omBSEXGATo1kdQ35w== X-Received: by 2002:a7b:cbce:: with SMTP id n14mr220994wmi.66.1591741821474; Tue, 09 Jun 2020 15:30:21 -0700 (PDT) Received: from localhost.localdomain ([2001:67c:1562:8007::aac:44bb]) by smtp.gmail.com with ESMTPSA id w15sm4332546wmk.30.2020.06.09.15.30.20 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jun 2020 15:30:21 -0700 (PDT) From: Ian May To: kernel-team@lists.ubuntu.com Subject: [bionic:linux-azure-4.15][PATCH 1/2] PCI: hv: Decouple the func definition in hv_dr_state from VSP message Date: Tue, 9 Jun 2020 17:30:14 -0500 Message-Id: <20200609223015.43751-2-ian.may@canonical.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200609223015.43751-1-ian.may@canonical.com> References: <20200609223015.43751-1-ian.may@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Long Li BugLink: https://bugs.launchpad.net/bugs/1880975 hv_dr_state is used to find present PCI devices on the bus. The structure reuses struct pci_function_description from VSP message to describe a device. To prepare support for pci_function_description v2, decouple this dependence in hv_dr_state so it can work with both v1 and v2 VSP messages. There is no functionality change. Signed-off-by: Long Li Signed-off-by: Lorenzo Pieralisi Reviewed-by: Michael Kelley (backported from f9ad0f361cf3b58fd26d409c6150126547259772) [since hibernate patches are not in tree, needed to manually apply part of patch] Signed-off-by: Ian May --- drivers/pci/host/pci-hyperv.c | 98 ++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 29 deletions(-) diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c index 81da709aa757..4c9fdf151474 100644 --- a/drivers/pci/host/pci-hyperv.c +++ b/drivers/pci/host/pci-hyperv.c @@ -488,10 +488,24 @@ struct hv_dr_work { struct hv_pcibus_device *bus; }; +struct hv_pcidev_description { + u16 v_id; /* vendor ID */ + u16 d_id; /* device ID */ + u8 rev; + u8 prog_intf; + u8 subclass; + u8 base_class; + u32 subsystem_id; + union win_slot_encoding win_slot; + u32 ser; /* serial number */ + u32 flags; + u16 virtual_numa_node; +}; + struct hv_dr_state { struct list_head list_entry; u32 device_count; - struct pci_function_description func[0]; + struct hv_pcidev_description func[0]; }; enum hv_pcichild_state { @@ -519,7 +533,7 @@ struct hv_pci_dev { refcount_t refs; enum hv_pcichild_state state; struct pci_slot *pci_slot; - struct pci_function_description desc; + struct hv_pcidev_description desc; bool reported_missing; struct hv_pcibus_device *hbus; struct work_struct wrk; @@ -1614,7 +1628,7 @@ static void put_pcichild(struct hv_pci_dev *hpdev, * Return: Pointer to the new tracking struct */ static struct hv_pci_dev *new_pcichild_device(struct hv_pcibus_device *hbus, - struct pci_function_description *desc) + struct hv_pcidev_description *desc) { struct hv_pci_dev *hpdev; struct pci_child_message *res_req; @@ -1726,7 +1740,7 @@ static void pci_devices_present_work(struct work_struct *work) u32 child_no; bool found; struct list_head *iter; - struct pci_function_description *new_desc; + struct hv_pcidev_description *new_desc; struct hv_pci_dev *hpdev; struct hv_pcibus_device *hbus; struct list_head removed; @@ -1852,41 +1866,25 @@ static void pci_devices_present_work(struct work_struct *work) } /** - * hv_pci_devices_present() - Handles list of new children + * hv_pci_start_relations_work() - Queue work to start device discovery * @hbus: Root PCI bus, as understood by this driver - * @relations: Packet from host listing children + * @dr: The list of children returned from host * - * This function is invoked whenever a new list of devices for - * this bus appears. + * Return: 0 on success, -errno on failure */ -static void hv_pci_devices_present(struct hv_pcibus_device *hbus, - struct pci_bus_relations *relations) +static int hv_pci_start_relations_work(struct hv_pcibus_device *hbus, + struct hv_dr_state *dr) { - struct hv_dr_state *dr; struct hv_dr_work *dr_wrk; unsigned long flags; bool pending_dr; dr_wrk = kzalloc(sizeof(*dr_wrk), GFP_NOWAIT); if (!dr_wrk) - return; - - dr = kzalloc(offsetof(struct hv_dr_state, func) + - (sizeof(struct pci_function_description) * - (relations->device_count)), GFP_NOWAIT); - if (!dr) { - kfree(dr_wrk); - return; - } + return -ENOMEM; INIT_WORK(&dr_wrk->wrk, pci_devices_present_work); dr_wrk->bus = hbus; - dr->device_count = relations->device_count; - if (dr->device_count != 0) { - memcpy(dr->func, relations->func, - sizeof(struct pci_function_description) * - dr->device_count); - } spin_lock_irqsave(&hbus->device_list_lock, flags); /* @@ -1904,6 +1902,47 @@ static void hv_pci_devices_present(struct hv_pcibus_device *hbus, get_hvpcibus(hbus); queue_work(hbus->wq, &dr_wrk->wrk); } + + return 0; +} + +/** + * hv_pci_devices_present() - Handle list of new children + * @hbus: Root PCI bus, as understood by this driver + * @relations: Packet from host listing children + * + * Process a new list of devices on the bus. The list of devices is + * discovered by VSP and sent to us via VSP message PCI_BUS_RELATIONS, + * whenever a new list of devices for this bus appears. + */ +static void hv_pci_devices_present(struct hv_pcibus_device *hbus, + struct pci_bus_relations *relations) +{ + struct hv_dr_state *dr; + int i; + + dr = kzalloc(offsetof(struct hv_dr_state, func) + + (sizeof(struct hv_pcidev_description) * + (relations->device_count)), GFP_NOWAIT); + + if (!dr) + return; + + dr->device_count = relations->device_count; + for (i = 0; i < dr->device_count; i++) { + dr->func[i].v_id = relations->func[i].v_id; + dr->func[i].d_id = relations->func[i].d_id; + dr->func[i].rev = relations->func[i].rev; + dr->func[i].prog_intf = relations->func[i].prog_intf; + dr->func[i].subclass = relations->func[i].subclass; + dr->func[i].base_class = relations->func[i].base_class; + dr->func[i].subsystem_id = relations->func[i].subsystem_id; + dr->func[i].win_slot = relations->func[i].win_slot; + dr->func[i].ser = relations->func[i].ser; + } + + if (hv_pci_start_relations_work(hbus, dr)) + kfree(dr); } /** @@ -2753,7 +2792,7 @@ static void hv_pci_bus_exit(struct hv_device *hdev) struct pci_packet teardown_packet; u8 buffer[sizeof(struct pci_message)]; } pkt; - struct pci_bus_relations relations; + struct hv_dr_state *dr; struct hv_pci_compl comp_pkt; int ret; @@ -2765,8 +2804,9 @@ static void hv_pci_bus_exit(struct hv_device *hdev) return; /* Delete any children which might still exist. */ - memset(&relations, 0, sizeof(relations)); - hv_pci_devices_present(hbus, &relations); + dr = kzalloc(sizeof(*dr), GFP_KERNEL); + if (dr && hv_pci_start_relations_work(hbus, dr)) + kfree(dr); ret = hv_send_resources_released(hdev); if (ret) From patchwork Tue Jun 9 22:30:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian May X-Patchwork-Id: 1306336 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49hPvn1btFz9sRR; Wed, 10 Jun 2020 08:30:29 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1jimlG-0005AM-3j; Tue, 09 Jun 2020 22:30:26 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1jimlE-00059T-FV for kernel-team@lists.ubuntu.com; Tue, 09 Jun 2020 22:30:24 +0000 Received: from mail-wr1-f70.google.com ([209.85.221.70]) by youngberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1jimlE-00011n-7X for kernel-team@lists.ubuntu.com; Tue, 09 Jun 2020 22:30:24 +0000 Received: by mail-wr1-f70.google.com with SMTP id d6so165056wrn.1 for ; Tue, 09 Jun 2020 15:30:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=C5f4p9zdzIMWqiOJ7SwYtIFGzRunD3ALhdKu94BayS8=; b=lJWevOnQrN3BsLHVS+CVDj7dlMbhRdLd0Isqldk+eKMzsGFXjQKHVEkrmaSEj28wRu jNytrl2idn4JrvIGEbcmOBuRhKPX/zvY8+zzTbewA+pWTD3mJdR9LD8iXSPYK3kvYTlC PCNzp1QGMkJCSlqGm0NB/73e6MiWQS4Fp1g2yqaB8ilxVJ2FjNig5bUav4/MahGPshEB 81MYUBn4E2XV/N3UeO5w3f5K1MOR1ijK1F0khXLsYoiWPWLqM/PCCJnjycHR5+Lme5Y0 PbMQjWSxDGBmLjYzQQ2zh44NafmCMPXA6mfosZKGqFILelnz3MQ7PNyrW+Lz2sR7tOSu 3L3w== X-Gm-Message-State: AOAM532OLAGYXgO+lxKClq6fkGd5QRE0yKw5lnOwWCq1yy5oVsPB+tdV Ueu2+kCKIUcntbO0jDweYTHQWQ/Nz1nbzflbDFyUsbit014HPOyRBhoSUrzjsJVEAvPyyLWNQG0 KUIEKG2On3C7Te7m1vBL6KtoV0+71mdbgrvm7BSfxUg== X-Received: by 2002:a5d:42cd:: with SMTP id t13mr37598wrr.355.1591741823661; Tue, 09 Jun 2020 15:30:23 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzXZ9PPrvpDSOgBHJsdpr2bz95Ykl3CzQS5/5EruFNnsCvCuLZblyJ7lD3DAY6l1Ha5w0ZVoA== X-Received: by 2002:a5d:42cd:: with SMTP id t13mr37582wrr.355.1591741823424; Tue, 09 Jun 2020 15:30:23 -0700 (PDT) Received: from localhost.localdomain ([2001:67c:1562:8007::aac:44bb]) by smtp.gmail.com with ESMTPSA id w15sm4332546wmk.30.2020.06.09.15.30.22 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jun 2020 15:30:23 -0700 (PDT) From: Ian May To: kernel-team@lists.ubuntu.com Subject: [bionic:linux-azure-4.15][PATCH 2/2] PCI: hv: Add support for protocol 1.3 and support PCI_BUS_RELATIONS2 Date: Tue, 9 Jun 2020 17:30:15 -0500 Message-Id: <20200609223015.43751-3-ian.may@canonical.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200609223015.43751-1-ian.may@canonical.com> References: <20200609223015.43751-1-ian.may@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Long Li BugLink: https://bugs.launchpad.net/bugs/1880975 Starting with Hyper-V PCI protocol version 1.3, the host VSP can send PCI_BUS_RELATIONS2 and pass the vNUMA node information for devices on the bus. The vNUMA node tells which guest NUMA node this device is on based on guest VM configuration topology and physical device information. Add code to negotiate v1.3 and process PCI_BUS_RELATIONS2. Signed-off-by: Long Li Signed-off-by: Lorenzo Pieralisi Reviewed-by: Michael Kelley (backported from 999dd956d8389f3a512808f36fac97e1c8e87c7f) [since hibernate patches are not in tree, needed to manually apply part of patch] Signed-off-by: Ian May --- drivers/pci/host/pci-hyperv.c | 109 ++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c index 4c9fdf151474..f5cb6b5f5515 100644 --- a/drivers/pci/host/pci-hyperv.c +++ b/drivers/pci/host/pci-hyperv.c @@ -73,6 +73,7 @@ enum pci_protocol_version_t { PCI_PROTOCOL_VERSION_1_1 = PCI_MAKE_VERSION(1, 1), /* Win10 */ PCI_PROTOCOL_VERSION_1_2 = PCI_MAKE_VERSION(1, 2), /* RS1 */ + PCI_PROTOCOL_VERSION_1_3 = PCI_MAKE_VERSION(1, 3), /* Vibranium */ }; #define CPU_AFFINITY_ALL -1ULL @@ -82,6 +83,7 @@ enum pci_protocol_version_t { * first. */ static enum pci_protocol_version_t pci_protocol_versions[] = { + PCI_PROTOCOL_VERSION_1_3, PCI_PROTOCOL_VERSION_1_2, PCI_PROTOCOL_VERSION_1_1, }; @@ -134,6 +136,7 @@ enum pci_message_type { PCI_RESOURCES_ASSIGNED2 = PCI_MESSAGE_BASE + 0x16, PCI_CREATE_INTERRUPT_MESSAGE2 = PCI_MESSAGE_BASE + 0x17, PCI_DELETE_INTERRUPT_MESSAGE2 = PCI_MESSAGE_BASE + 0x18, /* unused */ + PCI_BUS_RELATIONS2 = PCI_MESSAGE_BASE + 0x19, PCI_MESSAGE_MAXIMUM }; @@ -179,6 +182,26 @@ struct pci_function_description { u32 ser; /* serial number */ } __packed; +enum pci_device_description_flags { + HV_PCI_DEVICE_FLAG_NONE = 0x0, + HV_PCI_DEVICE_FLAG_NUMA_AFFINITY = 0x1, +}; + +struct pci_function_description2 { + u16 v_id; /* vendor ID */ + u16 d_id; /* device ID */ + u8 rev; + u8 prog_intf; + u8 subclass; + u8 base_class; + u32 subsystem_id; + union win_slot_encoding win_slot; + u32 ser; /* serial number */ + u32 flags; + u16 virtual_numa_node; + u16 reserved; +} __packed; + /** * struct hv_msi_desc * @vector: IDT entry @@ -314,6 +337,12 @@ struct pci_bus_relations { struct pci_function_description func[0]; } __packed; +struct pci_bus_relations2 { + struct pci_incoming_message incoming; + u32 device_count; + struct pci_function_description2 func[0]; +} __packed; + struct pci_q_res_req_response { struct vmpacket_descriptor hdr; s32 status; /* negative values are failures */ @@ -1153,6 +1182,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) break; case PCI_PROTOCOL_VERSION_1_2: + case PCI_PROTOCOL_VERSION_1_3: size = hv_compose_msi_req_v2(&ctxt.int_pkts.v2, dest, hpdev->desc.win_slot.slot, @@ -1537,6 +1567,27 @@ static void hv_pci_remove_slots(struct hv_pcibus_device *hbus) } } +/* + * Set NUMA node for the devices on the bus + */ +static void hv_pci_assign_numa_node(struct hv_pcibus_device *hbus) +{ + struct pci_dev *dev; + struct pci_bus *bus = hbus->pci_bus; + struct hv_pci_dev *hv_dev; + + list_for_each_entry(dev, &bus->devices, bus_list) { + hv_dev = get_pcichild_wslot(hbus, devfn_to_wslot(dev->devfn)); + if (!hv_dev) + continue; + + if (hv_dev->desc.flags & HV_PCI_DEVICE_FLAG_NUMA_AFFINITY) + set_dev_node(&dev->dev, hv_dev->desc.virtual_numa_node); + + put_pcichild(hv_dev, hv_pcidev_ref_by_slot); + } +} + /** * create_root_hv_pci_bus() - Expose a new root PCI bus * @hbus: Root PCI bus, as understood by this driver @@ -1559,6 +1610,7 @@ static int create_root_hv_pci_bus(struct hv_pcibus_device *hbus) pci_lock_rescan_remove(); pci_scan_child_bus(hbus->pci_bus); + hv_pci_assign_numa_node(hbus); pci_bus_assign_resources(hbus->pci_bus); hv_pci_assign_slots(hbus); pci_bus_add_devices(hbus->pci_bus); @@ -1848,6 +1900,7 @@ static void pci_devices_present_work(struct work_struct *work) */ pci_lock_rescan_remove(); pci_scan_child_bus(hbus->pci_bus); + hv_pci_assign_numa_node(hbus); hv_pci_assign_slots(hbus); pci_unlock_rescan_remove(); break; @@ -1945,6 +1998,46 @@ static void hv_pci_devices_present(struct hv_pcibus_device *hbus, kfree(dr); } +/** + * hv_pci_devices_present2() - Handle list of new children + * @hbus: Root PCI bus, as understood by this driver + * @relations: Packet from host listing children + * + * This function is the v2 version of hv_pci_devices_present() + */ +static void hv_pci_devices_present2(struct hv_pcibus_device *hbus, + struct pci_bus_relations2 *relations) +{ + struct hv_dr_state *dr; + int i; + + dr = kzalloc(offsetof(struct hv_dr_state, func) + + (sizeof(struct hv_pcidev_description) * + (relations->device_count)), GFP_NOWAIT); + + if (!dr) + return; + + dr->device_count = relations->device_count; + for (i = 0; i < dr->device_count; i++) { + dr->func[i].v_id = relations->func[i].v_id; + dr->func[i].d_id = relations->func[i].d_id; + dr->func[i].rev = relations->func[i].rev; + dr->func[i].prog_intf = relations->func[i].prog_intf; + dr->func[i].subclass = relations->func[i].subclass; + dr->func[i].base_class = relations->func[i].base_class; + dr->func[i].subsystem_id = relations->func[i].subsystem_id; + dr->func[i].win_slot = relations->func[i].win_slot; + dr->func[i].ser = relations->func[i].ser; + dr->func[i].flags = relations->func[i].flags; + dr->func[i].virtual_numa_node = + relations->func[i].virtual_numa_node; + } + + if (hv_pci_start_relations_work(hbus, dr)) + kfree(dr); +} + /** * hv_eject_device_work() - Asynchronously handles ejection * @work: Work struct embedded in internal device struct @@ -2048,6 +2141,7 @@ static void hv_pci_onchannelcallback(void *context) struct pci_response *response; struct pci_incoming_message *new_message; struct pci_bus_relations *bus_rel; + struct pci_bus_relations2 *bus_rel2; struct pci_dev_incoming *dev_message; struct hv_pci_dev *hpdev; @@ -2114,6 +2208,21 @@ static void hv_pci_onchannelcallback(void *context) hv_pci_devices_present(hbus, bus_rel); break; + case PCI_BUS_RELATIONS2: + + bus_rel2 = (struct pci_bus_relations2 *)buffer; + if (bytes_recvd < + offsetof(struct pci_bus_relations2, func) + + (sizeof(struct pci_function_description2) * + (bus_rel2->device_count))) { + dev_err(&hbus->hdev->device, + "bus relations v2 too small\n"); + break; + } + + hv_pci_devices_present2(hbus, bus_rel2); + break; + case PCI_EJECT: dev_message = (struct pci_dev_incoming *)buffer;