Received: by 2002:a05:6a10:2726:0:0:0:0 with SMTP id ib38csp182498pxb; Thu, 31 Mar 2022 02:50:49 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy+ddAt3khnepKDkrTluCXefHak//mWe1rM91PSyfwwdMgaEyxUzodIWFdp8XDdRSfHmGFb X-Received: by 2002:a05:6a00:4198:b0:4fa:8591:5456 with SMTP id ca24-20020a056a00419800b004fa85915456mr38396573pfb.81.1648720249700; Thu, 31 Mar 2022 02:50:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648720249; cv=none; d=google.com; s=arc-20160816; b=LHjKcJClvEZhwFbt44IDZOQtp7NK14BD0gN6ofIThHMel0uz4LhNq1IzI8K77J9cDS bKlIqhgk3MLJwxnRh1w711OlZpzDrTmSuUYJT51QJFjtpUZt6cAyFGv3zt7911cmoG5F HWumf6807cbo9aHFOOYVswywClDBtj5mL8MpFTKEAtV0BsYlNRroyO1p0eS7HNQDtxlD MD6WnEMaEnAzJ68Jh3D9eoK0g1WoO6KFP3vE3BP1qRcrsynMUyUr2CNbiugp9YbsY2yB Dx/T64RJMt8jdcmPjZ8L3o9S0B6Mh8fDqurzXo4MotL24+fI22+GONkCwK3YpTFHDya4 DIeg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:user-agent:references:message-id :in-reply-to:subject:cc:to:from:date; bh=XWz+D3EgUO963UEbJ74lkHYtB55aRIcssPdBZR0NUoc=; b=CLReGut2pS/sQXUpWbgekXv1HtPN2s+c8SypDhIVAhKA99Xg8aKIFbT9LIbd5WISzT z3WpuT9t7IzoxwhBXvVyxLLSQiIU9qLDxss9p0Cdqsx/PJFaQoaY2NFVSEc5Tl/2Tqbi szCCyfJgkNPfWOcy20XqflahaWlsc26XAyeHhmQvS0HMHcLcAFNQH9ZYomi1ZaWV954n kjg8rwPX6hpgk4ELSBRhe/731rbfBdKb8fRmNh77vzKpTCChQg+cHuqzl0xKFHuAkg9G soW0n07f3D02oanXIbuE6itm8cBJlbdmEtXXjxz/sDVJPF16R0IKWZbVmcIKG/5eUzvt n88g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id mw1-20020a17090b4d0100b001bf6715212dsi3076587pjb.104.2022.03.31.02.50.36; Thu, 31 Mar 2022 02:50:49 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231230AbiCaHN1 (ORCPT + 99 others); Thu, 31 Mar 2022 03:13:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42606 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231847AbiCaHM6 (ORCPT ); Thu, 31 Mar 2022 03:12:58 -0400 Received: from angie.orcam.me.uk (angie.orcam.me.uk [78.133.224.34]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id D7B92C627D; Thu, 31 Mar 2022 00:11:01 -0700 (PDT) Received: by angie.orcam.me.uk (Postfix, from userid 500) id 35C7F92009C; Thu, 31 Mar 2022 09:11:01 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by angie.orcam.me.uk (Postfix) with ESMTP id 3080892009B; Thu, 31 Mar 2022 08:11:01 +0100 (BST) Date: Thu, 31 Mar 2022 08:11:01 +0100 (BST) From: "Maciej W. Rozycki" To: Bjorn Helgaas , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" cc: Arnd Bergmann , Nikolai Zhubr , Michal Necasek , Dmitry Osipenko , Linus Torvalds , x86@kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 2/5] x86/PCI: Handle PIRQ routing tables with no router device given In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org PIRQ routing tables provided by the PCI BIOS usually specify the PCI vendor:device ID as well as the bus address of the device implementing the PIRQ router, e.g.: PCI: Interrupt Routing Table found at 0xc00fde10 [...] PCI: Attempting to find IRQ router for [8086:7000] pci 0000:00:07.0: PIIX/ICH IRQ router [8086:7000] however in some cases they do not, in which case we fail to match the router handler, e.g.: PCI: Interrupt Routing Table found at 0xc00fdae0 [...] PCI: Attempting to find IRQ router for [0000:0000] PCI: Interrupt router not found at 00:00 This is because we always match the vendor:device ID and the bus address literally, even if they are all zeros. Handle this case then and iterate over all PCI devices until we find a matching router handler if the vendor ID given by the routing table is the invalid value of zero: PCI: Attempting to find IRQ router for [0000:0000] PCI: Trying IRQ router for [1039:0496] pci 0000:00:05.0: SiS85C497 IRQ router [1039:0496] Signed-off-by: Maciej W. Rozycki Tested-by: Nikolai Zhubr --- No change from v3. Changes from v2: - Document new output in the change description. - Add Nikolai's Tested-by annotation. Changes from v1: - Preinitialise `dev' in `pirq_find_router' for `for_each_pci_dev'. - Avoid calling `pirq_try_router' with null `dev'. --- arch/x86/pci/irq.c | 64 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 20 deletions(-) linux-x86-pirq-router-nodev.diff Index: linux-macro/arch/x86/pci/irq.c =================================================================== --- linux-macro.orig/arch/x86/pci/irq.c +++ linux-macro/arch/x86/pci/irq.c @@ -1182,10 +1182,32 @@ static struct pci_dev *pirq_router_dev; * chipset" ? */ +static bool __init pirq_try_router(struct irq_router *r, + struct irq_routing_table *rt, + struct pci_dev *dev) +{ + struct irq_router_handler *h; + + DBG(KERN_DEBUG "PCI: Trying IRQ router for [%04x:%04x]\n", + dev->vendor, dev->device); + + for (h = pirq_routers; h->vendor; h++) { + /* First look for a router match */ + if (rt->rtr_vendor == h->vendor && + h->probe(r, dev, rt->rtr_device)) + return true; + /* Fall back to a device match */ + if (dev->vendor == h->vendor && + h->probe(r, dev, dev->device)) + return true; + } + return false; +} + static void __init pirq_find_router(struct irq_router *r) { struct irq_routing_table *rt = pirq_table; - struct irq_router_handler *h; + struct pci_dev *dev; #ifdef CONFIG_PCI_BIOS if (!rt->signature) { @@ -1204,27 +1226,29 @@ static void __init pirq_find_router(stru DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for [%04x:%04x]\n", rt->rtr_vendor, rt->rtr_device); - pirq_router_dev = pci_get_domain_bus_and_slot(0, rt->rtr_bus, - rt->rtr_devfn); - if (!pirq_router_dev) { - DBG(KERN_DEBUG "PCI: Interrupt router not found at " - "%02x:%02x\n", rt->rtr_bus, rt->rtr_devfn); - return; + /* Use any vendor:device provided by the routing table or try all. */ + if (rt->rtr_vendor) { + dev = pci_get_domain_bus_and_slot(0, rt->rtr_bus, + rt->rtr_devfn); + if (dev && pirq_try_router(r, rt, dev)) + pirq_router_dev = dev; + } else { + dev = NULL; + for_each_pci_dev(dev) { + if (pirq_try_router(r, rt, dev)) { + pirq_router_dev = dev; + break; + } + } } - for (h = pirq_routers; h->vendor; h++) { - /* First look for a router match */ - if (rt->rtr_vendor == h->vendor && - h->probe(r, pirq_router_dev, rt->rtr_device)) - break; - /* Fall back to a device match */ - if (pirq_router_dev->vendor == h->vendor && - h->probe(r, pirq_router_dev, pirq_router_dev->device)) - break; - } - dev_info(&pirq_router_dev->dev, "%s IRQ router [%04x:%04x]\n", - pirq_router.name, - pirq_router_dev->vendor, pirq_router_dev->device); + if (pirq_router_dev) + dev_info(&pirq_router_dev->dev, "%s IRQ router [%04x:%04x]\n", + pirq_router.name, + pirq_router_dev->vendor, pirq_router_dev->device); + else + DBG(KERN_DEBUG "PCI: Interrupt router not found at " + "%02x:%02x\n", rt->rtr_bus, rt->rtr_devfn); /* The device remains referenced for the kernel lifetime */ }