Skip to content

Commit

Permalink
platform/x86: dell-ddv: Fix cache invalidation on resume
Browse files Browse the repository at this point in the history
If one or both sensor buffers could not be initialized, either
due to missing hardware support or due to some error during probing,
the resume handler will encounter undefined behaviour when
attempting to lock buffers then protected by an uninitialized or
destroyed mutex.
Fix this by introducing a "active" flag which is set during probe,
and only invalidate buffers which where flaged as "active".

Tested on a Dell Inspiron 3505.

Fixes: 3b7eeff ("platform/x86: dell-ddv: Add hwmon support")
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
Link: https://lore.kernel.org/r/20230218115318.20662-1-W_Armin@gmx.de
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
  • Loading branch information
Armin Wolf authored and Hans de Goede committed Mar 7, 2023
1 parent 24efcdf commit 001f61c
Showing 1 changed file with 7 additions and 1 deletion.
8 changes: 7 additions & 1 deletion drivers/platform/x86/dell/dell-wmi-ddv.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ struct combined_chip_info {
};

struct dell_wmi_ddv_sensors {
bool active;
struct mutex lock; /* protect caching */
unsigned long timestamp;
union acpi_object *obj;
Expand Down Expand Up @@ -520,6 +521,9 @@ static struct hwmon_channel_info *dell_wmi_ddv_channel_create(struct device *dev

static void dell_wmi_ddv_hwmon_cache_invalidate(struct dell_wmi_ddv_sensors *sensors)
{
if (!sensors->active)
return;

mutex_lock(&sensors->lock);
kfree(sensors->obj);
sensors->obj = NULL;
Expand All @@ -530,6 +534,7 @@ static void dell_wmi_ddv_hwmon_cache_destroy(void *data)
{
struct dell_wmi_ddv_sensors *sensors = data;

sensors->active = false;
mutex_destroy(&sensors->lock);
kfree(sensors->obj);
}
Expand All @@ -549,6 +554,7 @@ static struct hwmon_channel_info *dell_wmi_ddv_channel_init(struct wmi_device *w
return ERR_PTR(ret);

mutex_init(&sensors->lock);
sensors->active = true;

ret = devm_add_action_or_reset(&wdev->dev, dell_wmi_ddv_hwmon_cache_destroy, sensors);
if (ret < 0)
Expand Down Expand Up @@ -852,7 +858,7 @@ static int dell_wmi_ddv_resume(struct device *dev)
{
struct dell_wmi_ddv_data *data = dev_get_drvdata(dev);

/* Force re-reading of all sensors */
/* Force re-reading of all active sensors */
dell_wmi_ddv_hwmon_cache_invalidate(&data->fans);
dell_wmi_ddv_hwmon_cache_invalidate(&data->temps);

Expand Down

0 comments on commit 001f61c

Please sign in to comment.