Commit ec6badfb authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'acpi-5.14-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull ACPI fixes from Rafael Wysocki:
 "These fix a recently broken Kconfig dependency and ACPI device
  reference counting in an iterator macro.

  Specifics:

   - Fix recently broken Kconfig dependency for the ACPI table override
     via built-in initrd (Robert Richter)

   - Fix ACPI device reference counting in the for_each_acpi_dev_match()
     helper macro to avoid use-after-free (Andy Shevchenko)"

* tag 'acpi-5.14-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI: utils: Fix reference counting in for_each_acpi_dev_match()
  ACPI: Kconfig: Fix table override from built-in initrd
parents 1d597682 0b8a53a8
...@@ -370,7 +370,7 @@ config ACPI_TABLE_UPGRADE ...@@ -370,7 +370,7 @@ config ACPI_TABLE_UPGRADE
config ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD config ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD
bool "Override ACPI tables from built-in initrd" bool "Override ACPI tables from built-in initrd"
depends on ACPI_TABLE_UPGRADE depends on ACPI_TABLE_UPGRADE
depends on INITRAMFS_SOURCE!="" && INITRAMFS_COMPRESSION="" depends on INITRAMFS_SOURCE!="" && INITRAMFS_COMPRESSION_NONE
help help
This option provides functionality to override arbitrary ACPI tables This option provides functionality to override arbitrary ACPI tables
from built-in uncompressed initrd. from built-in uncompressed initrd.
......
...@@ -860,11 +860,9 @@ EXPORT_SYMBOL(acpi_dev_present); ...@@ -860,11 +860,9 @@ EXPORT_SYMBOL(acpi_dev_present);
* Return the next match of ACPI device if another matching device was present * Return the next match of ACPI device if another matching device was present
* at the moment of invocation, or NULL otherwise. * at the moment of invocation, or NULL otherwise.
* *
* FIXME: The function does not tolerate the sudden disappearance of @adev, e.g.
* in the case of a hotplug event. That said, the caller should ensure that
* this will never happen.
*
* The caller is responsible for invoking acpi_dev_put() on the returned device. * The caller is responsible for invoking acpi_dev_put() on the returned device.
* On the other hand the function invokes acpi_dev_put() on the given @adev
* assuming that its reference counter had been increased beforehand.
* *
* See additional information in acpi_dev_present() as well. * See additional information in acpi_dev_present() as well.
*/ */
...@@ -880,6 +878,7 @@ acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const cha ...@@ -880,6 +878,7 @@ acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const cha
match.hrv = hrv; match.hrv = hrv;
dev = bus_find_device(&acpi_bus_type, start, &match, acpi_dev_match_cb); dev = bus_find_device(&acpi_bus_type, start, &match, acpi_dev_match_cb);
acpi_dev_put(adev);
return dev ? to_acpi_device(dev) : NULL; return dev ? to_acpi_device(dev) : NULL;
} }
EXPORT_SYMBOL(acpi_dev_get_next_match_dev); EXPORT_SYMBOL(acpi_dev_get_next_match_dev);
......
...@@ -34,7 +34,6 @@ static long __init parse_acpi_path(const struct efi_dev_path *node, ...@@ -34,7 +34,6 @@ static long __init parse_acpi_path(const struct efi_dev_path *node,
break; break;
if (!adev->pnp.unique_id && node->acpi.uid == 0) if (!adev->pnp.unique_id && node->acpi.uid == 0)
break; break;
acpi_dev_put(adev);
} }
if (!adev) if (!adev)
return -ENODEV; return -ENODEV;
......
...@@ -173,10 +173,8 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg, ...@@ -173,10 +173,8 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
int ret; int ret;
for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) { for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) {
if (!adev->status.enabled) { if (!adev->status.enabled)
acpi_dev_put(adev);
continue; continue;
}
if (bridge->n_sensors >= CIO2_NUM_PORTS) { if (bridge->n_sensors >= CIO2_NUM_PORTS) {
acpi_dev_put(adev); acpi_dev_put(adev);
...@@ -185,7 +183,6 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg, ...@@ -185,7 +183,6 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
} }
sensor = &bridge->sensors[bridge->n_sensors]; sensor = &bridge->sensors[bridge->n_sensors];
sensor->adev = adev;
strscpy(sensor->name, cfg->hid, sizeof(sensor->name)); strscpy(sensor->name, cfg->hid, sizeof(sensor->name));
ret = cio2_bridge_read_acpi_buffer(adev, "SSDB", ret = cio2_bridge_read_acpi_buffer(adev, "SSDB",
...@@ -215,6 +212,7 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg, ...@@ -215,6 +212,7 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
goto err_free_swnodes; goto err_free_swnodes;
} }
sensor->adev = acpi_dev_get(adev);
adev->fwnode.secondary = fwnode; adev->fwnode.secondary = fwnode;
dev_info(&cio2->dev, "Found supported sensor %s\n", dev_info(&cio2->dev, "Found supported sensor %s\n",
......
...@@ -707,11 +707,6 @@ acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv); ...@@ -707,11 +707,6 @@ acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv);
* @hrv: Hardware Revision of the device, pass -1 to not check _HRV * @hrv: Hardware Revision of the device, pass -1 to not check _HRV
* *
* The caller is responsible for invoking acpi_dev_put() on the returned device. * The caller is responsible for invoking acpi_dev_put() on the returned device.
*
* FIXME: Due to above requirement there is a window that may invalidate @adev
* and next iteration will use a dangling pointer, e.g. in the case of a
* hotplug event. That said, the caller should ensure that this will never
* happen.
*/ */
#define for_each_acpi_dev_match(adev, hid, uid, hrv) \ #define for_each_acpi_dev_match(adev, hid, uid, hrv) \
for (adev = acpi_dev_get_first_match_dev(hid, uid, hrv); \ for (adev = acpi_dev_get_first_match_dev(hid, uid, hrv); \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment