From b030905bf5a6423d3000827a9d1cb973161cd2bb Mon Sep 17 00:00:00 2001 From: Nirmal Patel Date: Mon, 29 Jun 2026 16:50:25 +0000 Subject: PCI: vmd: Add feature to scan BIOS-enumerated devices Newer VMD with device ID 0x28C1 has unique settings compared to its predecessor where BIOS enumerates the entire VMD device tree and assigns respective configurations. VMD configuration BAR0 carries over from GNR legacy VMD as the mechanism to access the configuration space of the devices owned by VMD. The size of this window is fixed at 256 MB, where each function consumes 4 KB and every bus consumes 1 MB. The shadow and scratchpad registers have been relocated from the VMD configuration space to the VMD MMIO space in VMD BAR4/BAR5, otherwise refers to as MEMBAR2 or MSI-X bar. VMD MSI-X remapping enable/disable is no longer supported. On this new device, simply obtain the bus hide range and shadow register values set by BIOS and perform a bus scan. Also refactor vmd_enable_domain(). Signed-off-by: Nirmal Patel Signed-off-by: Manivannan Sadhasivam Signed-off-by: Bjorn Helgaas Link: https://patch.msgid.link/20260629165025.268836-1-nirmal.patel@linux.intel.com --- include/linux/pci_ids.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 1c9d40e09107..5026012269ad 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2892,6 +2892,7 @@ #define PCI_DEVICE_ID_INTEL_HDA_ICH8 0x284b #define PCI_DEVICE_ID_INTEL_ICH8_6 0x2850 #define PCI_DEVICE_ID_INTEL_VMD_28C0 0x28c0 +#define PCI_DEVICE_ID_INTEL_VMD_28C1 0x28c1 #define PCI_DEVICE_ID_INTEL_ICH9_0 0x2910 #define PCI_DEVICE_ID_INTEL_ICH9_2 0x2912 #define PCI_DEVICE_ID_INTEL_ICH9_3 0x2913 -- cgit v1.2.3 From 008cb88edb41f3c7c8e0ed763ff9f26719830984 Mon Sep 17 00:00:00 2001 From: Steffen Persvold Date: Thu, 9 Jul 2026 14:24:46 +0200 Subject: PCI: host-generic: Fix NULL pointer dereference on 32-bit CAM systems On 32-bit systems the config space is too large to ioremap in one go, so pci_ecam_create() maps each bus segment separately and relies on the ->add_bus callback (pci_ecam_add_bus) to populate the per-bus mapping in cfg->winp[]. pci_ecam_map_bus() then uses that mapping as the base for every config access. The generic ECAM ops (pci_generic_ecam_ops) already provide the ->add_bus and ->remove_bus callbacks, but the CAM (legacy) ops in pci-host-generic.c do not. As a result, on a 32-bit host using "pci-host-cam-generic" the per-bus mapping is never set up and the first config read dereferences a NULL base, crashing during bus enumeration: Unable to handle kernel NULL pointer dereference at virtual address 00000800 Oops [#1] CPU: 0 PID: 1 Comm: swapper Not tainted 6.9.7+ #43 Hardware name: Digilent Nexys-Video-A7 RV32 (DT) epc : pci_generic_config_read+0x40/0xb0 ra : pci_generic_config_read+0x2c/0xb0 [] pci_generic_config_read+0x40/0xb0 [] pci_bus_read_config_dword+0x50/0xb0 [] pci_bus_generic_read_dev_vendor_id+0x3c/0x1ec [] pci_scan_single_device+0xa4/0x11c [] pci_scan_slot+0x9c/0x23c [] pci_scan_child_bus_extend+0x58/0x2f4 [] pci_scan_root_bus_bridge+0x64/0xe8 [] pci_host_probe+0x20/0xc8 [] pci_host_common_probe+0x144/0x1e4 Fix this by giving the CAM ops the same ->add_bus/->remove_bus callbacks. Since pci_ecam_add_bus() and pci_ecam_remove_bus() are static to ecam.c, move the CAM ops definition there as pci_generic_cam_ops (mirroring pci_generic_ecam_ops) and export it for pci-host-generic.c to reference. Fixes: 8fe55ef23387 ("PCI: Dynamically map ECAM regions") Signed-off-by: Steffen Persvold [mani: removed timestamp from log] Signed-off-by: Manivannan Sadhasivam Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260709122446.3151899-1-spersvold@gmail.com --- include/linux/pci-ecam.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h index d930651473b4..044f67ced6ff 100644 --- a/include/linux/pci-ecam.h +++ b/include/linux/pci-ecam.h @@ -81,6 +81,9 @@ void __iomem *pci_ecam_map_bus(struct pci_bus *bus, unsigned int devfn, /* default ECAM ops */ extern const struct pci_ecam_ops pci_generic_ecam_ops; +/* default CAM ops */ +extern const struct pci_ecam_ops pci_generic_cam_ops; + #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) extern const struct pci_ecam_ops pci_32b_ops; /* 32-bit accesses only */ extern const struct pci_ecam_ops pci_32b_read_ops; /* 32-bit read only */ -- cgit v1.2.3 From 3ffc4c9690c33ee28cdb3d0182b12f9c623e3acc Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Thu, 23 Jul 2026 23:00:48 +0100 Subject: PCI: Fix UAF when probe runs concurrent to dyn ID removal Dynamic IDs are only guaranteed to be valid when dynids.lock is held, as remove_id_store() can free the node. Thus, make a copy in pci_match_device(). Also, clarify that the id parameter is only valid during probe. Fixes: 0994375e9614 ("PCI: add remove_id sysfs entry") Reported-by: Sashiko Link: https://lore.kernel.org/all/20260619170503.518F61F00A3A@smtp.kernel.org/ Signed-off-by: Gary Guo Signed-off-by: Bjorn Helgaas Reviewed-by: Danilo Krummrich Link: https://patch.msgid.link/20260723-pci_id_fix-v4-9-3580726844e1@garyguo.net --- include/linux/pci.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index ebb5b9d76360..f128d8c0cbb6 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -979,6 +979,7 @@ struct module; * function returns zero when the driver chooses to * take "ownership" of the device or an error code * (negative number) otherwise. + * The pci_device_id parameter is only valid during probe. * The probe function always gets called from process * context, so it can sleep. * @remove: The remove() function gets called whenever a device -- cgit v1.2.3 From 3fc686d550f6dba3f4fd53aec173b6dee15e7f98 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Wed, 29 Jul 2026 10:22:28 +0530 Subject: PCI/ERR: Add support for resetting the Root Ports in a platform-specific way Some host bridge devices require resetting the Root Ports in a platform specific way to recover them from error conditions such as Fatal AER errors, Link Down, etc. Introduce pci_host_bridge::reset_root_port() callback and call it from pcibios_reset_secondary_bus() if available. Also, save the Root Port config space before reset and restore it afterwards. The .reset_root_port() callback is responsible for resetting the given Root Port referenced by the 'pci_dev' pointer in a platform-specific way and bring it back to the working state if possible. If any error occurs during the reset operation, relevant errno should be returned. Signed-off-by: Manivannan Sadhasivam Signed-off-by: Manivannan Sadhasivam Signed-off-by: Bjorn Helgaas Tested-by: Brian Norris Tested-by: Krishna Chaitanya Chundru Tested-by: Richard Zhu Reviewed-by: Frank Li Link: https://patch.msgid.link/20260729-pci-port-reset-v9-2-53570b92064d@oss.qualcomm.com --- include/linux/pci.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index ebb5b9d76360..be82cc0a3371 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -646,6 +646,7 @@ struct pci_host_bridge { void (*release_fn)(struct pci_host_bridge *); int (*enable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev); void (*disable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev); + int (*reset_root_port)(struct pci_host_bridge *bridge, struct pci_dev *dev); void *release_data; unsigned int ignore_reset_delay:1; /* For entire hierarchy */ unsigned int no_ext_tags:1; /* No Extended Tags */ -- cgit v1.2.3 From 071e245ab749c52338ec4eb7fe0a9bb2cee97492 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Tue, 7 Jul 2026 17:01:43 +0530 Subject: PCI: Add support for PCIe WAKE# interrupt According to PCIe r7.0, sec 5.3.3.2, two link wakeup mechanisms are defined: Beacon and WAKE#. Beacon is a hardware-only mechanism and is invisible to software (sec 4.2.7.8.1). This change adds support for the WAKE# mechanism in the PCI core. According to the PCIe specification, multiple WAKE# signals can exist in a system or several components in the hierarchy may share a single WAKE# signal. In configurations involving a PCIe switch, each downstream port (DSP) of the switch may be connected to a separate WAKE# line, allowing each endpoint to signal WAKE# independently. From figure 5.4 in sec 5.3.3.2, WAKE# can also be terminated at the switch itself. Such topologies are typically not described in Device Tree, therefore it is out of scope for this series. To support this, the WAKE# should be described in the device tree node of the endpoint/bridge. If all endpoints share a single WAKE# line, then each endpoint node shall describe the same WAKE# signal or a single WAKE# in the Root Port node. In pci_device_add(), PCI framework will search for the WAKE# in device node. Once found, register for the wake IRQ through dev_pm_set_dedicated_wake_irq() associates a wakeup IRQ with a device and requests it, but the PM core keeps the IRQ disabled by default. The IRQ is enabled by the PM core, only when the device is permitted to wake the system, i.e. during system suspend and after runtime suspend, and only when device wakeup is enabled. If the same WAKE# GPIO is described in multiple device tree nodes, only the first device that successfully registers the wake IRQ will succeed, while subsequent registrations may fail. This limitation does not affect functional correctness, since WAKE# is only used to bring the link to D0, and endpoint-specific wakeup handling is resolved later through PME detection (PME_EN is set in suspend path by PCI core by default). When the wake IRQ fires, the wakeirq handler invokes pm_runtime_resume() to bring the device back to an active power state, such as transitioning from D3cold to D0. Once the device is active and the link is usable, the endpoint may generate a PME, which is then handled by the PCI core through PME polling or the PCIe PME service driver to complete the wakeup of the endpoint. WAKE# is added in dts schema and merged based on below links. Link: https://lore.kernel.org/all/20250515090517.3506772-1-krishna.chundru@oss.qualcomm.com/ Link: https://github.com/devicetree-org/dt-schema/pull/170 Signed-off-by: Krishna Chaitanya Chundru Signed-off-by: Bjorn Helgaas Reviewed-by: Linus Walleij Reviewed-by: Bartosz Golaszewski Acked-by: Manivannan Sadhasivam Link: https://patch.msgid.link/20260707-wakeirq_support-v12-1-b4453f5bcc97@oss.qualcomm.com --- include/linux/of_pci.h | 6 ++++++ include/linux/pci.h | 2 ++ 2 files changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h index 29658c0ee71f..649fe8eafcfa 100644 --- a/include/linux/of_pci.h +++ b/include/linux/of_pci.h @@ -30,12 +30,18 @@ static inline void of_pci_check_probe_only(void) { } #if IS_ENABLED(CONFIG_OF_IRQ) int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin); +void pci_configure_of_wake_gpio(struct pci_dev *dev); +void pci_remove_of_wake_gpio(struct pci_dev *dev); #else static inline int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin) { return 0; } + +static inline void pci_configure_of_wake_gpio(struct pci_dev *dev) { } + +static inline void pci_remove_of_wake_gpio(struct pci_dev *dev) { } #endif #endif diff --git a/include/linux/pci.h b/include/linux/pci.h index ebb5b9d76360..75c1613cc91f 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -587,6 +587,8 @@ struct pci_dev { /* These methods index pci_reset_fn_methods[] */ u8 reset_methods[PCI_NUM_RESET_METHODS]; /* In priority order */ + struct gpio_desc *wake; /* WAKE# GPIO */ + #ifdef CONFIG_PCIE_TPH u16 tph_cap; /* TPH capability offset */ u8 tph_mode; /* TPH mode */ -- cgit v1.2.3 From 6d99b198629dde79aa098214e82f2a99ea44f330 Mon Sep 17 00:00:00 2001 From: Brett Zhou Date: Tue, 21 Jul 2026 16:28:47 +0800 Subject: PCI: dwc: Add PCI ID for LECARC PCIe PMU Add support for the PCIe PMU found on LECARC SoCs. LECARC platforms use the standard DesignWare PCIe Controller, and the existing DWC driver already handles the enumeration and basic functionality through the generic PCIe core. Hence, add the PCI vendor ID to the vendor-specific capability (VSEC) list, which enables the standard DWC RAS/DES feature detection. Signed-off-by: Brett Zhou Signed-off-by: Braden Zhang [mani: commit log] Signed-off-by: Manivannan Sadhasivam Link: https://patch.msgid.link/20260721-pcie-pmu-v5-1-570e44af7cde@lecomputing.com --- include/linux/pcie-dwc.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pcie-dwc.h b/include/linux/pcie-dwc.h index 8ff778e7aec0..0df5fa81b561 100644 --- a/include/linux/pcie-dwc.h +++ b/include/linux/pcie-dwc.h @@ -11,6 +11,8 @@ #include +#define PCI_VENDOR_ID_LECARC 0x0720 + struct dwc_pcie_vsec_id { u16 vendor_id; u16 vsec_id; @@ -32,6 +34,8 @@ static const struct dwc_pcie_vsec_id dwc_pcie_rasdes_vsec_ids[] = { .vsec_id = 0x02, .vsec_rev = 0x4 }, { .vendor_id = PCI_VENDOR_ID_SAMSUNG, .vsec_id = 0x02, .vsec_rev = 0x4 }, + { .vendor_id = PCI_VENDOR_ID_LECARC, + .vsec_id = 0x02, .vsec_rev = 0x4 }, {} }; -- cgit v1.2.3