All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kurt Borja <kuurtb@gmail.com>
To: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
	"Armin Wolf" <W_Armin@gmx.de>
Cc: platform-driver-x86@vger.kernel.org,
	"Hans de Goede" <hdegoede@redhat.com>,
	Dell.Client.Kernel@dell.com, linux-kernel@vger.kernel.org,
	Kurt Borja <kuurtb@gmail.com>
Subject: [PATCH v2 05/10] platform/x86: alienware-wmi-wmax: Improve platform profile probe
Date: Tue, 25 Feb 2025 17:24:55 -0500	[thread overview]
Message-ID: <20250225222500.23535-6-kuurtb@gmail.com> (raw)
In-Reply-To: <20250225222500.23535-1-kuurtb@gmail.com>

Get and store the AWCC system description in alienware_awcc_setup()
instead of awcc_platform_profile_probe() and add a check for integer
overflows to avoid misbehaviors.

While at it, replace set_bit() with it's non-atomic version __set_bit()
because `choices` belong to this thread only.

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
Reviewed-by: Armin Wolf <W_Armin@gmx.de>
---
 .../platform/x86/dell/alienware-wmi-wmax.c    | 61 ++++++++++++++-----
 1 file changed, 46 insertions(+), 15 deletions(-)

diff --git a/drivers/platform/x86/dell/alienware-wmi-wmax.c b/drivers/platform/x86/dell/alienware-wmi-wmax.c
index 4a8335d90b5d..965b427f8f0a 100644
--- a/drivers/platform/x86/dell/alienware-wmi-wmax.c
+++ b/drivers/platform/x86/dell/alienware-wmi-wmax.c
@@ -37,6 +37,9 @@
 #define AWCC_THERMAL_MODE_MASK			GENMASK(3, 0)
 #define AWCC_RESOURCE_ID_MASK			GENMASK(7, 0)
 
+/* Arbitrary limit based on supported models */
+#define AWCC_MAX_RES_COUNT			16
+
 static bool force_platform_profile;
 module_param_unsafe(force_platform_profile, bool, 0);
 MODULE_PARM_DESC(force_platform_profile, "Forces auto-detecting thermal profiles without checking if WMI thermal backend is available");
@@ -211,6 +214,17 @@ struct wmax_u32_args {
 
 struct awcc_priv {
 	struct wmi_device *wdev;
+	union {
+		u32 system_description;
+		struct {
+			u8 fan_count;
+			u8 temp_count;
+			u8 unknown_count;
+			u8 profile_count;
+		} __packed;
+		u8 res_count[4];
+	} __packed;
+
 	struct device *ppdev;
 	u8 supported_profiles[PLATFORM_PROFILE_LAST];
 };
@@ -614,38 +628,41 @@ static int awcc_platform_profile_probe(void *drvdata, unsigned long *choices)
 	enum platform_profile_option profile;
 	struct awcc_priv *priv = drvdata;
 	enum awcc_thermal_profile mode;
-	u8 sys_desc[4];
-	u32 first_mode;
+	u8 id, offset = 0;
 	u32 out_data;
 	int ret;
-	u8 id;
 
-	ret = awcc_thermal_information(priv->wdev, AWCC_OP_GET_SYSTEM_DESCRIPTION,
-				       0, (u32 *) &sys_desc);
-	if (ret < 0)
-		return ret;
-
-	first_mode = sys_desc[0] + sys_desc[1];
-
-	for (u32 i = 0; i < sys_desc[3]; i++) {
-		ret = awcc_op_get_resource_id(priv->wdev, i + first_mode, &out_data);
+	/*
+	 * Thermal profile IDs are listed last at offset
+	 *	fan_count + temp_count + unknown_count
+	 */
+	for (unsigned int i = 0; i < ARRAY_SIZE(priv->res_count) - 1; i++)
+		offset += priv->res_count[i];
 
+	for (unsigned int i = 0; i < priv->profile_count; i++) {
+		ret = awcc_op_get_resource_id(priv->wdev, i + offset, &out_data);
 		if (ret == -EIO)
 			return ret;
 
+		/*
+		 * Some devices report an incorrect number of thermal profiles
+		 * so the resource ID list may end prematurely
+		 */
 		if (ret == -EBADRQC)
 			break;
 
 		/* Some IDs have a BIT(8) flag that should be ignored */
 		id = FIELD_GET(AWCC_RESOURCE_ID_MASK, out_data);
-		if (!is_awcc_thermal_profile_id(id))
+		if (!is_awcc_thermal_profile_id(id)) {
+			dev_dbg(&priv->wdev->dev, "Unmapped thermal profile ID 0x%02x\n", id);
 			continue;
+		}
 
 		mode = FIELD_GET(AWCC_THERMAL_MODE_MASK, id);
 		profile = awcc_mode_to_platform_profile[mode];
 		priv->supported_profiles[profile] = id;
 
-		set_bit(profile, choices);
+		__set_bit(profile, choices);
 	}
 
 	if (bitmap_empty(choices, PLATFORM_PROFILE_LAST))
@@ -655,7 +672,7 @@ static int awcc_platform_profile_probe(void *drvdata, unsigned long *choices)
 		priv->supported_profiles[PLATFORM_PROFILE_PERFORMANCE] =
 			AWCC_THERMAL_MODE_GMODE;
 
-		set_bit(PLATFORM_PROFILE_PERFORMANCE, choices);
+		__set_bit(PLATFORM_PROFILE_PERFORMANCE, choices);
 	}
 
 	return 0;
@@ -686,6 +703,20 @@ static int alienware_awcc_setup(struct wmi_device *wdev)
 	if (!priv)
 		return -ENOMEM;
 
+	ret = awcc_thermal_information(wdev, AWCC_OP_GET_SYSTEM_DESCRIPTION,
+				       0, &priv->system_description);
+	if (ret < 0)
+		return ret;
+
+	/* Sanity check */
+	for (unsigned int i = 0; i < ARRAY_SIZE(priv->res_count); i++) {
+		if (priv->res_count[i] > AWCC_MAX_RES_COUNT) {
+			dev_err(&wdev->dev, "Malformed system description: 0x%08x\n",
+				priv->system_description);
+			return -ENXIO;
+		}
+	}
+
 	priv->wdev = wdev;
 	dev_set_drvdata(&wdev->dev, priv);
 
-- 
2.48.1


  parent reply	other threads:[~2025-02-25 22:25 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-25 22:24 [PATCH v2 00/10] platform/x86: alienware-wmi-wmax: HWMON support + DebugFS + Improvements Kurt Borja
2025-02-25 22:24 ` [PATCH v2 01/10] platform/x86: alienware-wmi-wmax: Rename thermal related symbols Kurt Borja
2025-02-25 22:24 ` [PATCH v2 02/10] platform/x86: alienware-wmi-wmax: Refactor is_awcc_thermal_mode() Kurt Borja
2025-03-04 15:02   ` Ilpo Järvinen
2025-03-04 16:18     ` Kurt Borja
2025-02-25 22:24 ` [PATCH v2 03/10] platform/x86: alienware-wmi-wmax: Improve internal AWCC API Kurt Borja
2025-02-25 22:24 ` [PATCH v2 04/10] platform/x86: alienware-wmi-wmax: Modify supported_thermal_profiles[] Kurt Borja
2025-03-04 15:33   ` Ilpo Järvinen
2025-02-25 22:24 ` Kurt Borja [this message]
2025-03-04 15:40   ` [PATCH v2 05/10] platform/x86: alienware-wmi-wmax: Improve platform profile probe Ilpo Järvinen
2025-03-04 16:22     ` Kurt Borja
2025-02-25 22:24 ` [PATCH v2 06/10] platform/x86: alienware-wmi-wmax: Add support for the "custom" thermal profile Kurt Borja
2025-02-25 22:24 ` [PATCH v2 07/10] platform/x86: alienware-wmi-wmax: Add HWMON support Kurt Borja
2025-03-04 15:53   ` Ilpo Järvinen
2025-03-04 16:27     ` Kurt Borja
2025-03-04 16:31       ` Ilpo Järvinen
2025-03-05 11:10   ` kernel test robot
2025-02-25 22:24 ` [PATCH v2 08/10] platform/x86: alienware-wmi-wmax: Add support for manual fan control Kurt Borja
2025-02-25 22:24 ` [PATCH v2 09/10] platform/x86: alienware-wmi-wmax: Add a DebugFS interface Kurt Borja
2025-02-25 22:25 ` [PATCH v2 10/10] platform/x86: alienware-wmi: Improve and update documentation Kurt Borja

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=20250225222500.23535-6-kuurtb@gmail.com \
    --to=kuurtb@gmail.com \
    --cc=Dell.Client.Kernel@dell.com \
    --cc=W_Armin@gmx.de \
    --cc=hdegoede@redhat.com \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=platform-driver-x86@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.