All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Revert "platform/x86: hp-wmi: Changing bios_args.data to be dynamically allocated"
@ 2022-06-06 20:54 Jorge Lopez
  2022-06-07  9:54 ` Andy Shevchenko
  0 siblings, 1 reply; 3+ messages in thread
From: Jorge Lopez @ 2022-06-06 20:54 UTC (permalink / raw)
  To: platform-driver-x86

This reverts commit 4b4967cbd2685f313411e6facf915fb2ae01d796.

Changes to bios_args.data to be allocated dynamically causes
several WMI calls for OMEN laptops to fail.  The problem
is resolved by reverting commit 4b4967cbd26.

All changes were validated on a HP ZBook Workstation notebook,
HP EliteBook x360, HP EliteBook 850 G8, and Omen 15 notebooks.
Additional validation was included in the test process to
ensure no other	commands were incorrectly handled.

Signed-off-by: Jorge Lopez <jorge.lopez2@hp.com>

---
Based on the latest platform-drivers-x86.git/for-next
---
 drivers/platform/x86/hp-wmi.c | 62 ++++++++++++++++-------------------
 1 file changed, 29 insertions(+), 33 deletions(-)

diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index 0e9a25b56e0e..b917571a1e47 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -90,17 +90,12 @@ enum hp_wmi_event_ids {
 	HPWMI_BATTERY_CHARGE_PERIOD	= 0x10,
 };
 
-/*
- * struct bios_args buffer is dynamically allocated.  New WMI command types
- * were introduced that exceeds 128-byte data size.  Changes to handle
- * the data size allocation scheme were kept in hp_wmi_perform_qurey function.
- */
 struct bios_args {
 	u32 signature;
 	u32 command;
 	u32 commandtype;
 	u32 datasize;
-	u8 data[];
+	u8 data[128];
 };
 
 enum hp_wmi_commandtype {
@@ -286,43 +281,37 @@ static inline int encode_outsize_for_pvsz(int outsize)
 static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
 				void *buffer, int insize, int outsize)
 {
-	struct acpi_buffer input, output = { ACPI_ALLOCATE_BUFFER, NULL };
+	int mid;
 	struct bios_return *bios_return;
-	union acpi_object *obj = NULL;
-	struct bios_args *args = NULL;
-	int mid, actual_outsize, ret;
-	size_t bios_args_size;
+	int actual_outsize;
+	union acpi_object *obj;
+	struct bios_args args = {
+		.signature = 0x55434553,
+		.command = command,
+		.commandtype = query,
+		.datasize = insize,
+		.data = { 0 },
+	};
+	struct acpi_buffer input = { sizeof(struct bios_args), &args };
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	int ret = 0;
 
 	mid = encode_outsize_for_pvsz(outsize);
 	if (WARN_ON(mid < 0))
 		return mid;
 
-	bios_args_size = struct_size(args, data, insize);
-	args = kmalloc(bios_args_size, GFP_KERNEL);
-	if (!args)
-		return -ENOMEM;
-
-	input.length = bios_args_size;
-	input.pointer = args;
-
-	args->signature = 0x55434553;
-	args->command = command;
-	args->commandtype = query;
-	args->datasize = insize;
-	memcpy(args->data, buffer, flex_array_size(args, data, insize));
+	if (WARN_ON(insize > sizeof(args.data)))
+		return -EINVAL;
+	memcpy(&args.data[0], buffer, insize);
 
-	ret = wmi_evaluate_method(HPWMI_BIOS_GUID, 0, mid, &input, &output);
-	if (ret)
-		goto out_free;
+	wmi_evaluate_method(HPWMI_BIOS_GUID, 0, mid, &input, &output);
 
 	obj = output.pointer;
-	if (!obj) {
-		ret = -EINVAL;
-		goto out_free;
-	}
+
+	if (!obj)
+		return -EINVAL;
 
 	if (obj->type != ACPI_TYPE_BUFFER) {
-		pr_warn("query 0x%x returned an invalid object 0x%x\n", query, ret);
 		ret = -EINVAL;
 		goto out_free;
 	}
@@ -347,7 +336,6 @@ static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
 
 out_free:
 	kfree(obj);
-	kfree(args);
 	return ret;
 }
 
@@ -605,6 +593,7 @@ static int hp_wmi_rfkill2_refresh(void)
 	for (i = 0; i < rfkill2_count; i++) {
 		int num = rfkill2[i].num;
 		struct bios_rfkill2_device_state *devstate;
+
 		devstate = &state.device[num];
 
 		if (num >= state.count ||
@@ -625,6 +614,7 @@ static ssize_t display_show(struct device *dev, struct device_attribute *attr,
 			    char *buf)
 {
 	int value = hp_wmi_read_int(HPWMI_DISPLAY_QUERY);
+
 	if (value < 0)
 		return value;
 	return sprintf(buf, "%d\n", value);
@@ -634,6 +624,7 @@ static ssize_t hddtemp_show(struct device *dev, struct device_attribute *attr,
 			    char *buf)
 {
 	int value = hp_wmi_read_int(HPWMI_HDDTEMP_QUERY);
+
 	if (value < 0)
 		return value;
 	return sprintf(buf, "%d\n", value);
@@ -643,6 +634,7 @@ static ssize_t als_show(struct device *dev, struct device_attribute *attr,
 			char *buf)
 {
 	int value = hp_wmi_read_int(HPWMI_ALS_QUERY);
+
 	if (value < 0)
 		return value;
 	return sprintf(buf, "%d\n", value);
@@ -652,6 +644,7 @@ static ssize_t dock_show(struct device *dev, struct device_attribute *attr,
 			 char *buf)
 {
 	int value = hp_wmi_get_dock_state();
+
 	if (value < 0)
 		return value;
 	return sprintf(buf, "%d\n", value);
@@ -661,6 +654,7 @@ static ssize_t tablet_show(struct device *dev, struct device_attribute *attr,
 			   char *buf)
 {
 	int value = hp_wmi_get_tablet_mode();
+
 	if (value < 0)
 		return value;
 	return sprintf(buf, "%d\n", value);
@@ -671,6 +665,7 @@ static ssize_t postcode_show(struct device *dev, struct device_attribute *attr,
 {
 	/* Get the POST error code of previous boot failure. */
 	int value = hp_wmi_read_int(HPWMI_POSTCODEERROR_QUERY);
+
 	if (value < 0)
 		return value;
 	return sprintf(buf, "0x%x\n", value);
@@ -1013,6 +1008,7 @@ static int __init hp_wmi_rfkill2_setup(struct platform_device *device)
 		struct rfkill *rfkill;
 		enum rfkill_type type;
 		char *name;
+
 		switch (state.device[i].radio_type) {
 		case HPWMI_WIFI:
 			type = RFKILL_TYPE_WLAN;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] Revert "platform/x86: hp-wmi: Changing bios_args.data to be dynamically allocated"
  2022-06-06 20:54 [PATCH] Revert "platform/x86: hp-wmi: Changing bios_args.data to be dynamically allocated" Jorge Lopez
@ 2022-06-07  9:54 ` Andy Shevchenko
  2022-06-07 20:01   ` Jorge Lopez
  0 siblings, 1 reply; 3+ messages in thread
From: Andy Shevchenko @ 2022-06-07  9:54 UTC (permalink / raw)
  To: Jorge Lopez; +Cc: Platform Driver

On Tue, Jun 7, 2022 at 7:59 AM Jorge Lopez <jorgealtxwork@gmail.com> wrote:
>
> This reverts commit 4b4967cbd2685f313411e6facf915fb2ae01d796.
>
> Changes to bios_args.data to be allocated dynamically causes
> several WMI calls for OMEN laptops to fail.  The problem
> is resolved by reverting commit 4b4967cbd26.

As a quick fix it's good, but have you had a chance to understand why
this failure happened in the first place?

Can you check my theory that is expressed in the code below?

...

> -       bios_args_size = struct_size(args, data, insize);

Try to replace insize here with

max(insize, 128)

> -       args = kmalloc(bios_args_size, GFP_KERNEL);
> -       if (!args)
> -               return -ENOMEM;
> -
> -       input.length = bios_args_size;
> -       input.pointer = args;

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Revert "platform/x86: hp-wmi: Changing bios_args.data to be dynamically allocated"
  2022-06-07  9:54 ` Andy Shevchenko
@ 2022-06-07 20:01   ` Jorge Lopez
  0 siblings, 0 replies; 3+ messages in thread
From: Jorge Lopez @ 2022-06-07 20:01 UTC (permalink / raw)
  To: Andy Shevchenko; +Cc: Platform Driver

Hi Andy,

I will ask to remove review request title is  "[PATCH] Revert "platform/x86:
hp-wmi: Changing bios_args.data to be dynamically allocated"

I am testing a cleaner solution to submit instead of  reverting the
changes to hp_wmi_perform_query method.  The changes were made and
tested on business notebooks without any issues.  I will submit a new
patch as soon as I get the test results from a  community member who
owns an Omen 15 system.

The proposed patch which I am pending test results, it is as follows

diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index 0e9a25b56e0e..7bcfa07cc6ab 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -292,12 +292,14 @@ static int hp_wmi_perform_query(int query, enum
hp_wmi_command command,
  struct bios_args *args = NULL;
  int mid, actual_outsize, ret;
  size_t bios_args_size;
+ int actual_insize;

  mid = encode_outsize_for_pvsz(outsize);
  if (WARN_ON(mid < 0))
  return mid;

- bios_args_size = struct_size(args, data, insize);
+ actual_insize = max(insize, 128);
+ bios_args_size = struct_size(args, data, actual_insize);
  args = kmalloc(bios_args_size, GFP_KERNEL);
  if (!args)
  return -ENOMEM;
-----

I received confirmation from another community member and confirmed
the patch resolves HPWMI_FAN GET/SET calls in an OMEN Laptop
15-ek0xxx.   No problems were reported when testing on several Elite
and Zbooks.

Regards,

Jorge

On Tue, Jun 7, 2022 at 4:55 AM Andy Shevchenko
<andy.shevchenko@gmail.com> wrote:
>
> On Tue, Jun 7, 2022 at 7:59 AM Jorge Lopez <jorgealtxwork@gmail.com> wrote:
> >
> > This reverts commit 4b4967cbd2685f313411e6facf915fb2ae01d796.
> >
> > Changes to bios_args.data to be allocated dynamically causes
> > several WMI calls for OMEN laptops to fail.  The problem
> > is resolved by reverting commit 4b4967cbd26.
>
> As a quick fix it's good, but have you had a chance to understand why
> this failure happened in the first place?
>
> Can you check my theory that is expressed in the code below?
>
> ...
>
> > -       bios_args_size = struct_size(args, data, insize);
>
> Try to replace insize here with
>
> max(insize, 128)
>
> > -       args = kmalloc(bios_args_size, GFP_KERNEL);
> > -       if (!args)
> > -               return -ENOMEM;
> > -
> > -       input.length = bios_args_size;
> > -       input.pointer = args;
>
> --
> With Best Regards,
> Andy Shevchenko

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-06-08  0:38 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-06 20:54 [PATCH] Revert "platform/x86: hp-wmi: Changing bios_args.data to be dynamically allocated" Jorge Lopez
2022-06-07  9:54 ` Andy Shevchenko
2022-06-07 20:01   ` Jorge Lopez

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.