Unverified Commit f0f7a3f5 authored by Qiu Wenbo's avatar Qiu Wenbo Committed by Ilpo Järvinen
Browse files

platform/x86: int3472: Fix double free of GPIO device during unregister



regulator_unregister() already frees the associated GPIO device. On
ThinkPad X9 (Lunar Lake), this causes a double free issue that leads to
random failures when other drivers (typically Intel THC) attempt to
allocate interrupts. The root cause is that the reference count of the
pinctrl_intel_platform module unexpectedly drops to zero when this
driver defers its probe.

This behavior can also be reproduced by unloading the module directly.

Fix the issue by removing the redundant release of the GPIO device
during regulator unregistration.

Cc: stable@vger.kernel.org
Fixes: 1e5d088a ("platform/x86: int3472: Stop using devm_gpiod_get()")
Signed-off-by: default avatarQiu Wenbo <qiuwenbo@kylinsec.com.cn>
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@intel.com>
Reviewed-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: default avatarHans de Goede <hansg@kernel.org>
Reviewed-by: default avatarDaniel Scally <dan.scally@ideasonboard.com>
Link: https://patch.msgid.link/20251028063009.289414-1-qiuwenbo@gnome.org


Signed-off-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
parent 34cbd6e0
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -245,15 +245,12 @@ int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
	if (IS_ERR(regulator->rdev))
		return PTR_ERR(regulator->rdev);

	int3472->regulators[int3472->n_regulator_gpios].ena_gpio = gpio;
	int3472->n_regulator_gpios++;
	return 0;
}

void skl_int3472_unregister_regulator(struct int3472_discrete_device *int3472)
{
	for (int i = 0; i < int3472->n_regulator_gpios; i++) {
	for (int i = 0; i < int3472->n_regulator_gpios; i++)
		regulator_unregister(int3472->regulators[i].rdev);
		gpiod_put(int3472->regulators[i].ena_gpio);
	}
}
+0 −1
Original line number Diff line number Diff line
@@ -100,7 +100,6 @@ struct int3472_gpio_regulator {
	struct regulator_consumer_supply supply_map[GPIO_REGULATOR_SUPPLY_MAP_COUNT * 2];
	char supply_name_upper[GPIO_SUPPLY_NAME_LENGTH];
	char regulator_name[GPIO_REGULATOR_NAME_LENGTH];
	struct gpio_desc *ena_gpio;
	struct regulator_dev *rdev;
	struct regulator_desc rdesc;
};