From nobody Fri Jun 19 18:20:18 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B4E5C433EF for ; Thu, 31 Mar 2022 07:11:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231859AbiCaHNV (ORCPT ); Thu, 31 Mar 2022 03:13:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43340 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231945AbiCaHM4 (ORCPT ); Thu, 31 Mar 2022 03:12:56 -0400 Received: from angie.orcam.me.uk (angie.orcam.me.uk [78.133.224.34]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 4F4CEC624F; Thu, 31 Mar 2022 00:10:56 -0700 (PDT) Received: by angie.orcam.me.uk (Postfix, from userid 500) id 091BD92009D; Thu, 31 Mar 2022 09:10:56 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by angie.orcam.me.uk (Postfix) with ESMTP id 01B0B92009B; Thu, 31 Mar 2022 08:10:55 +0100 (BST) Date: Thu, 31 Mar 2022 08:10:55 +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 1/5] x86/PCI: Add PIRQ routing table range checks In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Verify that the PCI IRQ Routing Table header as well as individual slot=20 entries are all wholly contained within the BIOS memory area. Do not=20 even call the checksum calculator if the header would overrun the area=20 and then bail out early if any slot would. Signed-off-by: Maciej W. Rozycki --- New change in v4. --- arch/x86/pci/irq.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) linux-x86-pirq-range-check.diff Index: linux-macro/arch/x86/pci/irq.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- linux-macro.orig/arch/x86/pci/irq.c +++ linux-macro/arch/x86/pci/irq.c @@ -68,7 +68,8 @@ void (*pcibios_disable_irq)(struct pci_d * and perform checksum verification. */ =20 -static inline struct irq_routing_table *pirq_check_routing_table(u8 *addr) +static inline struct irq_routing_table *pirq_check_routing_table(u8 *addr, + u8 *limit) { struct irq_routing_table *rt; int i; @@ -78,7 +79,8 @@ static inline struct irq_routing_table * if (rt->signature !=3D PIRQ_SIGNATURE || rt->version !=3D PIRQ_VERSION || rt->size % 16 || - rt->size < sizeof(struct irq_routing_table)) + rt->size < sizeof(struct irq_routing_table) || + (limit && rt->size > limit - addr)) return NULL; sum =3D 0; for (i =3D 0; i < rt->size; i++) @@ -99,17 +101,22 @@ static inline struct irq_routing_table * =20 static struct irq_routing_table * __init pirq_find_routing_table(void) { + u8 * const bios_start =3D (u8 *)__va(0xf0000); + u8 * const bios_end =3D (u8 *)__va(0x100000); u8 *addr; struct irq_routing_table *rt; =20 if (pirq_table_addr) { - rt =3D pirq_check_routing_table((u8 *) __va(pirq_table_addr)); + rt =3D pirq_check_routing_table((u8 *)__va(pirq_table_addr), + NULL); if (rt) return rt; printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n"); } - for (addr =3D (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += =3D 16) { - rt =3D pirq_check_routing_table(addr); + for (addr =3D bios_start; + addr < bios_end - sizeof(struct irq_routing_table); + addr +=3D 16) { + rt =3D pirq_check_routing_table(addr, bios_end); if (rt) return rt; } From nobody Fri Jun 19 18:20:18 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5F7A4C433EF for ; Thu, 31 Mar 2022 07:11:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231872AbiCaHN3 (ORCPT ); Thu, 31 Mar 2022 03:13:29 -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 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" PIRQ routing tables provided by the PCI BIOS usually specify the PCI=20 vendor:device ID as well as the bus address of the device implementing=20 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=20 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=20 literally, even if they are all zeros. Handle this case then and iterate over all PCI devices until we find a=20 matching router handler if the vendor ID given by the routing table is=20 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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" ? */ =20 +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 =3D pirq_routers; h->vendor; h++) { + /* First look for a router match */ + if (rt->rtr_vendor =3D=3D h->vendor && + h->probe(r, dev, rt->rtr_device)) + return true; + /* Fall back to a device match */ + if (dev->vendor =3D=3D 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 =3D pirq_table; - struct irq_router_handler *h; + struct pci_dev *dev; =20 #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); =20 - pirq_router_dev =3D 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 =3D pci_get_domain_bus_and_slot(0, rt->rtr_bus, + rt->rtr_devfn); + if (dev && pirq_try_router(r, rt, dev)) + pirq_router_dev =3D dev; + } else { + dev =3D NULL; + for_each_pci_dev(dev) { + if (pirq_try_router(r, rt, dev)) { + pirq_router_dev =3D dev; + break; + } + } } =20 - for (h =3D pirq_routers; h->vendor; h++) { - /* First look for a router match */ - if (rt->rtr_vendor =3D=3D h->vendor && - h->probe(r, pirq_router_dev, rt->rtr_device)) - break; - /* Fall back to a device match */ - if (pirq_router_dev->vendor =3D=3D 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); =20 /* The device remains referenced for the kernel lifetime */ } From nobody Fri Jun 19 18:20:18 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 055DDC4332F for ; Thu, 31 Mar 2022 07:11:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231807AbiCaHNm (ORCPT ); Thu, 31 Mar 2022 03:13:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40496 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231960AbiCaHNE (ORCPT ); Thu, 31 Mar 2022 03:13:04 -0400 Received: from angie.orcam.me.uk (angie.orcam.me.uk [78.133.224.34]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 9DA30C6808; Thu, 31 Mar 2022 00:11:06 -0700 (PDT) Received: by angie.orcam.me.uk (Postfix, from userid 500) id 007DF92009C; Thu, 31 Mar 2022 09:11:05 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by angie.orcam.me.uk (Postfix) with ESMTP id F125F92009B; Thu, 31 Mar 2022 08:11:05 +0100 (BST) Date: Thu, 31 Mar 2022 08:11:05 +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 3/5] x86/PCI: Add $IRT PIRQ routing table support In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Handle the $IRT PCI IRQ Routing Table format used by AMI for its BCP=20 (BIOS Configuration Program) external tool meant for tweaking BIOS=20 structures without the need to rebuild it from sources[1]. The $IRT format has been invented by AMI before Microsoft has come up=20 with its $PIR format and a $IRT table is therefore there in some systems=20 that lack a $PIR table, such as the DataExpert EXP8449 mainboard based=20 on the ALi FinALi 486 chipset (M1489/M1487), which predates DMI 2.0 and=20 cannot therefore be easily identified at run time. Unlike with the $PIR format there is no alignment guarantee as to the=20 placement of the $IRT table, so scan the whole BIOS area bytewise. Credit to Michal Necasek for helping me chase documentation for the=20 format. References: [1] "What is BCP? - AMI", Signed-off-by: Maciej W. Rozycki Cc: Michal Necasek Tested-by: Dmitry Osipenko # crosvm --- Changes from v3: - Correct the BIOS memory scan such as to verify that the PCI IRQ Routing Table header as well as individual slot entries are all wholly contained=20 within the BIOS memory area. - Following commit 5224f7909617 ("treewide: Replace zero-length arrays=20 with flexible-array members") also make `slots' in `irt_routing_table' a=20 flexible-array member. New change in v3. --- arch/x86/include/asm/pci_x86.h | 9 ++++ arch/x86/pci/irq.c | 76 ++++++++++++++++++++++++++++++++++++= +++++ 2 files changed, 85 insertions(+) linux-x86-pirq-irt.diff Index: linux-macro/arch/x86/include/asm/pci_x86.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- linux-macro.orig/arch/x86/include/asm/pci_x86.h +++ linux-macro/arch/x86/include/asm/pci_x86.h @@ -93,6 +93,15 @@ struct irq_routing_table { struct irq_info slots[]; } __attribute__((packed)); =20 +struct irt_routing_table { + u32 signature; /* IRT_SIGNATURE should be here */ + u8 size; /* Number of entries provided */ + u8 used; /* Number of entries actually used */ + u16 exclusive_irqs; /* IRQs devoted exclusively to + PCI usage */ + struct irq_info slots[]; +} __attribute__((packed)); + extern unsigned int pcibios_irq_mask; =20 extern raw_spinlock_t pci_config_lock; Index: linux-macro/arch/x86/pci/irq.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- linux-macro.orig/arch/x86/pci/irq.c +++ linux-macro/arch/x86/pci/irq.c @@ -25,6 +25,8 @@ #define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24= )) #define PIRQ_VERSION 0x0100 =20 +#define IRT_SIGNATURE (('$' << 0) + ('I' << 8) + ('R' << 16) + ('T' << 24)) + static int broken_hp_bios_irq9; static int acer_tm360_irqrouting; =20 @@ -93,7 +95,74 @@ static inline struct irq_routing_table * return NULL; } =20 +/* + * Handle the $IRT PCI IRQ Routing Table format used by AMI for its BCP + * (BIOS Configuration Program) external tool meant for tweaking BIOS + * structures without the need to rebuild it from sources. The $IRT + * format has been invented by AMI before Microsoft has come up with its + * $PIR format and a $IRT table is therefore there in some systems that + * lack a $PIR table. + * + * It uses the same PCI BIOS 2.1 format for interrupt routing entries + * themselves but has a different simpler header prepended instead, + * occupying 8 bytes, where a `$IRT' signature is followed by one byte + * specifying the total number of interrupt routing entries allocated in + * the table, then one byte specifying the actual number of entries used + * (which the BCP tool can take advantage of when modifying the table), + * and finally a 16-bit word giving the IRQs devoted exclusively to PCI. + * Unlike with the $PIR table there is no alignment guarantee. + * + * Given the similarity of the two formats the $IRT one is trivial to + * convert to the $PIR one, which we do here, except that obviously we + * have no information as to the router device to use, but we can handle + * it by matching PCI device IDs actually seen on the bus against ones + * that our individual routers recognise. + * + * Reportedly there is another $IRT table format where a 16-bit word + * follows the header instead that points to interrupt routing entries + * in a $PIR table provided elsewhere. In that case this code will not + * be reached though as the $PIR table will have been chosen instead. + */ +static inline struct irq_routing_table *pirq_convert_irt_table(u8 *addr, + u8 *limit) +{ + struct irt_routing_table *ir; + struct irq_routing_table *rt; + u16 size; + u8 sum; + int i; + + ir =3D (struct irt_routing_table *)addr; + if (ir->signature !=3D IRT_SIGNATURE || !ir->used || ir->size < ir->used) + return NULL; + + size =3D sizeof(*ir) + ir->used * sizeof(ir->slots[0]); + if (size > limit - addr) + return NULL; + + DBG(KERN_DEBUG "PCI: $IRT Interrupt Routing Table found at 0x%lx\n", + __pa(ir)); + + size =3D sizeof(*rt) + ir->used * sizeof(rt->slots[0]); + rt =3D kzalloc(size, GFP_KERNEL); + if (!rt) + return NULL; + + rt->signature =3D PIRQ_SIGNATURE; + rt->version =3D PIRQ_VERSION; + rt->size =3D size; + rt->exclusive_irqs =3D ir->exclusive_irqs; + for (i =3D 0; i < ir->used; i++) + rt->slots[i] =3D ir->slots[i]; + + addr =3D (u8 *)rt; + sum =3D 0; + for (i =3D 0; i < size; i++) + sum +=3D addr[i]; + rt->checksum =3D -sum; =20 + return rt; +} =20 /* * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. @@ -120,6 +189,13 @@ static struct irq_routing_table * __init if (rt) return rt; } + for (addr =3D bios_start; + addr < bios_end - sizeof(struct irt_routing_table); + addr++) { + rt =3D pirq_convert_irt_table(addr, bios_end); + if (rt) + return rt; + } return NULL; } From nobody Fri Jun 19 18:20:18 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BBF31C433F5 for ; Thu, 31 Mar 2022 07:12:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231701AbiCaHNq (ORCPT ); Thu, 31 Mar 2022 03:13:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40620 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231985AbiCaHNF (ORCPT ); Thu, 31 Mar 2022 03:13:05 -0400 Received: from angie.orcam.me.uk (angie.orcam.me.uk [78.133.224.34]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 7B1717EB28; Thu, 31 Mar 2022 00:11:11 -0700 (PDT) Received: by angie.orcam.me.uk (Postfix, from userid 500) id D8F3992009C; Thu, 31 Mar 2022 09:11:10 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by angie.orcam.me.uk (Postfix) with ESMTP id D79EB92009B; Thu, 31 Mar 2022 08:11:10 +0100 (BST) Date: Thu, 31 Mar 2022 08:11:10 +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 4/5] x86/PCI: Fix ALi M1487 (IBC) PIRQ router link value interpretation In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Fix an issue with commit 1ce849c75534 ("x86/PCI: Add support for the ALi=20 M1487 (IBC) PIRQ router") and correct ALi M1487 (IBC) PIRQ router link=20 value (`pirq' cookie) interpretation according to findings in the BIOS. Credit to Nikolai Zhubr for the detective work as to the bit layout. Signed-off-by: Maciej W. Rozycki Cc: Nikolai Zhubr Fixes: 1ce849c75534 ("x86/PCI: Add support for the ALi M1487 (IBC) PIRQ rou= ter") Cc: stable@vger.kernel.org # v5.15+ --- No change from v3. New change in v3. --- arch/x86/pci/irq.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) linux-x86-pirq-router-finali-link.diff Index: linux-macro/arch/x86/pci/irq.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- linux-macro.orig/arch/x86/pci/irq.c +++ linux-macro/arch/x86/pci/irq.c @@ -337,6 +337,15 @@ static void write_pc_conf_nybble(u8 base pc_conf_set(reg, x); } =20 +/* + * FinALi pirq rules are as follows: + * + * - bit 0 selects between INTx Routing Table Mapping Registers, + * + * - bit 3 selects the nibble within the INTx Routing Table Mapping Regist= er, + * + * - bits 7:4 map to bits 3:0 of the PCI INTx Sensitivity Register. + */ static int pirq_finali_get(struct pci_dev *router, struct pci_dev *dev, int pirq) { @@ -344,11 +353,13 @@ static int pirq_finali_get(struct pci_de 0, 9, 3, 10, 4, 5, 7, 6, 0, 11, 0, 12, 0, 14, 0, 15 }; unsigned long flags; + u8 index; u8 x; =20 + index =3D (pirq & 1) << 1 | (pirq & 8) >> 3; raw_spin_lock_irqsave(&pc_conf_lock, flags); pc_conf_set(PC_CONF_FINALI_LOCK, PC_CONF_FINALI_LOCK_KEY); - x =3D irqmap[read_pc_conf_nybble(PC_CONF_FINALI_PCI_INTX_RT1, pirq - 1)]; + x =3D irqmap[read_pc_conf_nybble(PC_CONF_FINALI_PCI_INTX_RT1, index)]; pc_conf_set(PC_CONF_FINALI_LOCK, 0); raw_spin_unlock_irqrestore(&pc_conf_lock, flags); return x; @@ -362,13 +373,15 @@ static int pirq_finali_set(struct pci_de }; u8 val =3D irqmap[irq]; unsigned long flags; + u8 index; =20 if (!val) return 0; =20 + index =3D (pirq & 1) << 1 | (pirq & 8) >> 3; raw_spin_lock_irqsave(&pc_conf_lock, flags); pc_conf_set(PC_CONF_FINALI_LOCK, PC_CONF_FINALI_LOCK_KEY); - write_pc_conf_nybble(PC_CONF_FINALI_PCI_INTX_RT1, pirq - 1, val); + write_pc_conf_nybble(PC_CONF_FINALI_PCI_INTX_RT1, index, val); pc_conf_set(PC_CONF_FINALI_LOCK, 0); raw_spin_unlock_irqrestore(&pc_conf_lock, flags); return 1; @@ -377,7 +390,7 @@ static int pirq_finali_set(struct pci_de static int pirq_finali_lvl(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) { - u8 mask =3D ~(1u << (pirq - 1)); + u8 mask =3D ~((pirq & 0xf0u) >> 4); unsigned long flags; u8 trig; From nobody Fri Jun 19 18:20:18 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BC8ADC433EF for ; Thu, 31 Mar 2022 07:12:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231926AbiCaHNu (ORCPT ); Thu, 31 Mar 2022 03:13:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43164 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231784AbiCaHNJ (ORCPT ); Thu, 31 Mar 2022 03:13:09 -0400 Received: from angie.orcam.me.uk (angie.orcam.me.uk [IPv6:2001:4190:8020::34]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 96E9CA0BF6; Thu, 31 Mar 2022 00:11:15 -0700 (PDT) Received: by angie.orcam.me.uk (Postfix, from userid 500) id D0E099200B3; Thu, 31 Mar 2022 09:11:14 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by angie.orcam.me.uk (Postfix) with ESMTP id CBA1D92009E; Thu, 31 Mar 2022 08:11:14 +0100 (BST) Date: Thu, 31 Mar 2022 08:11:14 +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 5/5] x86/PCI: Fix coding style in PIRQ table verification In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Remove an extraneous space with a cast in `pirq_check_routing_table'. Signed-off-by: Maciej W. Rozycki --- Changes from v3: - Remove parts obsoleted by 1/5. New change in v3. --- arch/x86/pci/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Index: linux-macro/arch/x86/pci/irq.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- linux-macro.orig/arch/x86/pci/irq.c +++ linux-macro/arch/x86/pci/irq.c @@ -77,7 +77,7 @@ static inline struct irq_routing_table * int i; u8 sum; =20 - rt =3D (struct irq_routing_table *) addr; + rt =3D (struct irq_routing_table *)addr; if (rt->signature !=3D PIRQ_SIGNATURE || rt->version !=3D PIRQ_VERSION || rt->size % 16 ||