public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Romain Gantois <romain.gantois@bootlin.com>,
	Xu Yilun <yilun.xu@intel.com>,
	Xu Yilun <yilun.xu@linux.intel.com>,
	Sasha Levin <sashal@kernel.org>,
	mdf@kernel.org, linux-fpga@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH AUTOSEL 6.19-6.1] fpga: of-fpga-region: Fail if any bridge is missing
Date: Wed, 18 Feb 2026 21:03:44 -0500	[thread overview]
Message-ID: <20260219020422.1539798-8-sashal@kernel.org> (raw)
In-Reply-To: <20260219020422.1539798-1-sashal@kernel.org>

From: Romain Gantois <romain.gantois@bootlin.com>

[ Upstream commit c141c8221bc5089de915d9f26044df892c343c7e ]

When parsing the region bridge list from the "fpga-bridges" device tree
property, the of-fpga-region driver will silently ignore bridges which fail
to be obtained, for example due to a missing bridge driver or invalid
phandle.

This can lead to hardware issues if a region bridge stays coupled when
partial programming is performed.

Fail if any of the bridges specified in "fpga-bridges" cannot be obtained.

Signed-off-by: Romain Gantois <romain.gantois@bootlin.com>
Link: https://lore.kernel.org/r/20251127-of-fpga-region-fail-if-bridges-not-found-v1-1-ca674f8d07eb@bootlin.com
Reviewed-by: Xu Yilun <yilun.xu@intel.com>
Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This confirms the calling pattern: `fpga_region_program_fpga()` calls
`get_bridges()` which is `of_fpga_region_get_bridges()`. If bridges fail
to be obtained, the function proceeds to **disable bridges** (line 127)
and then **load FPGA image** (line 133). If a bridge was supposed to
decouple a region but was silently skipped, the FPGA programming
proceeds with the bridge still coupled - which can cause hardware
issues.

## Summary of Analysis

### What the bug is

The `of_fpga_region_get_bridges()` function iterates over bridges
specified in the device tree's "fpga-bridges" property. For each bridge,
it calls `of_fpga_bridge_get_to_list()` which can return:
- `0` = success
- `-EBUSY` = bridge in use
- `-ENODEV` = bridge not found (missing driver, invalid phandle)

The **old code** only checked for `-EBUSY` and silently ignored
`-ENODEV` and other errors. This means if a bridge driver is missing or
a phandle is invalid, the bridge is silently skipped and FPGA partial
reconfiguration proceeds without decoupling that bridge.

### Why it matters

FPGA bridges are isolation mechanisms. During partial reconfiguration,
bridges must be decoupled to prevent bus contention and hardware
corruption. If a bridge is silently skipped (not decoupled), partial
programming proceeds with the region still coupled, potentially causing
**hardware issues** - this is a data corruption / hardware damage
scenario.

### The fix

The change is minimal and surgical:
- `if (ret == -EBUSY)` → `if (ret)` (catches all errors, not just EBUSY)
- `return -EBUSY` → `return ret` (propagates the actual error code)
- Comment updates to match

This is a **2-line functional change** with comment updates. Very low
risk.

### Risk assessment

- **Scope**: Very small (2 functional lines changed)
- **Risk**: Low - the change makes the function stricter (fail on error
  instead of silently continue), which is the safe direction. The only
  risk is that some setups that previously "worked" (with silently
  missing bridges) would now fail to program the FPGA. But this is the
  correct behavior - programming without proper bridge decoupling is
  dangerous.
- **Dependencies**: None - this is a self-contained change
- **Code exists in stable**: The file has been present since v4.16
  (2017), so it exists in all active stable trees

### Stable criteria check

1. Obviously correct: Yes - checking all errors instead of just one
   specific error code
2. Fixes a real bug: Yes - silent bridge skip can lead to hardware
   issues during partial reconfiguration
3. Important issue: Yes - potential hardware damage/corruption
4. Small and contained: Yes - 2 functional lines changed in a single
   file
5. No new features: Correct - no new features added
6. Reviewed: Yes - "Reviewed-by: Xu Yilun <yilun.xu@intel.com>" (FPGA
   subsystem maintainer)

## Verification

- Read `of-fpga-region.c` (pre-patch version at lines 88-141): Confirmed
  old code only checks `ret == -EBUSY` at line 134
- Found `of_fpga_bridge_get_to_list` in `drivers/fpga/fpga-bridge.c`:
  Confirmed it can return `-ENODEV` (from `of_fpga_bridge_get`) or
  `-EBUSY`, not just `-EBUSY`
- Traced the call chain: `fpga_region_program_fpga()` →
  `region->get_bridges()` → `of_fpga_region_get_bridges()`. Confirmed at
  `fpga-region.c:119-120` that the callback is invoked before
  `fpga_bridges_disable()` at line 127 and `fpga_mgr_load()` at line 133
- Confirmed the file has existed since commit `ef3acdd820752` (v4.16,
  2017) - the bug has been present since file creation
- Confirmed the patch has `Reviewed-by: Xu Yilun` (FPGA subsystem
  maintainer)
- Confirmed the change is self-contained - no dependencies on other
  commits

**YES**

 drivers/fpga/of-fpga-region.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index 43db4bb77138a..caa091224dc54 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -83,7 +83,7 @@ static struct fpga_manager *of_fpga_region_get_mgr(struct device_node *np)
  * done with the bridges.
  *
  * Return: 0 for success (even if there are no bridges specified)
- * or -EBUSY if any of the bridges are in use.
+ * or an error code if any of the bridges are not available.
  */
 static int of_fpga_region_get_bridges(struct fpga_region *region)
 {
@@ -130,10 +130,10 @@ static int of_fpga_region_get_bridges(struct fpga_region *region)
 						 &region->bridge_list);
 		of_node_put(br);
 
-		/* If any of the bridges are in use, give up */
-		if (ret == -EBUSY) {
+		/* If any of the bridges are not available, give up */
+		if (ret) {
 			fpga_bridges_put(&region->bridge_list);
-			return -EBUSY;
+			return ret;
 		}
 	}
 
-- 
2.51.0


  parent reply	other threads:[~2026-02-19  2:04 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-19  2:03 [PATCH AUTOSEL 6.19] rust_binder: Fix build failure if !CONFIG_COMPAT Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.12] usb: chipidea: udc: fix DMA and SG cleanup in _ep_nuke() Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-5.15] staging: rtl8723bs: fix memory leak on failure path Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19] tty: vt/keyboard: Split apart vt_do_diacrit() Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-5.10] fix it87_wdt early reboot by reporting running timer Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-5.15] misc: eeprom: Fix EWEN/EWDS/ERAL commands for 93xx56 and 93xx66 Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-5.15] mmc: rtsx_pci: add quirk to disable MMC_CAP_AGGRESSIVE_PM for RTS525A Sasha Levin
2026-02-19 10:29   ` Ulf Hansson
2026-02-26 13:23     ` Sasha Levin
2026-02-19  2:03 ` Sasha Levin [this message]
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.12] soundwire: intel_auxdevice: add cs42l45 codec to wake_capable_list Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-5.10] iio: magnetometer: Remove IRQF_ONESHOT Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.1] watchdog: imx7ulp_wdt: handle the nowayout option Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-5.10] serial: 8250_dw: handle clock enable errors in runtime_resume Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.12] most: core: fix resource leak in most_register_interface error paths Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19] block: fix partial IOVA mapping cleanup in blk_rq_dma_map_iova Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.1] misc: bcm_vk: Fix possible null-pointer dereferences in bcm_vk_read() Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.1] dmaengine: sun6i: Choose appropriate burst length under maxburst Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.1] mmc: rtsx: reset power state on suspend Sasha Levin
2026-02-19 10:27   ` Ulf Hansson
2026-02-26 13:24     ` Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19] serial: rsci: Add set_rtrg() callback Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-5.10] Revert "mfd: da9052-spi: Change read-mask to write-mask" Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.18] pinctrl: mediatek: make devm allocations safer and clearer in mtk_eint_do_init() Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.12] serial: 8250: 8250_omap.c: Add support for handling UART error conditions Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.12] usb: gadget: f_fs: Fix ioctl error handling Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.12] phy: cadence-torrent: restore parent clock for refclk during resume Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-5.10] binder: don't use %pK through printk Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.18] iio: bmi270_i2c: Add MODULE_DEVICE_TABLE for BMI260/270 Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-5.15] iio: Use IRQF_NO_THREAD Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.12] mfd: intel-lpss: Add Intel Nova Lake-S PCI IDs Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.12] phy: ti: phy-j721e-wiz: restore mux selection during resume Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-5.10] MIPS: Loongson: Make cpumask_of_node() robust against NUMA_NO_NODE Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.12] usb: gadget: f_fs: fix DMA-BUF OUT queues Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-5.10] phy: fsl-imx8mq-usb: disable bind/unbind platform driver feature Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.18] watchdog: rzv2h_wdt: Discard pm_runtime_put() return value Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.1] soundwire: dmi-quirks: add mapping for Avell B.ON (OEM rebranded of NUC15) Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.18] pinctrl: renesas: rzt2h: Allow .get_direction() for IRQ function GPIOs Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.12] dmaengine: stm32-dma3: use module_platform_driver Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-5.15] staging: rtl8723bs: fix missing status update on sdio_alloc_irq() failure Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-5.15] phy: mvebu-cp110-utmi: fix dr_mode property read from dts Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.1] usb: typec: ucsi: psy: Fix voltage and current max for non-Fixed PDOs Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-5.10] serial: 8250: 8250_omap.c: Clear DMA RX running status only after DMA termination is done Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.1] dmaengine: stm32-mdma: initialize m2m_hw_period and ccr to fix warnings Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.18] misc: ti_fpc202: fix a potential memory leak in probe function Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260219020422.1539798-8-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=linux-fpga@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mdf@kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=romain.gantois@bootlin.com \
    --cc=stable@vger.kernel.org \
    --cc=yilun.xu@intel.com \
    --cc=yilun.xu@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox