diff mbox

[V2,1/9] ACPICA: Executer: Fix buffer allocation issue for generic_serial_bus region field accesses.

Message ID 1398695268-28645-2-git-send-email-tianyu.lan@intel.com
State Superseded
Headers show

Commit Message

Lan Tianyu April 28, 2014, 2:27 p.m. UTC
From: Lv Zheng <lv.zheng@intel.com>

The size of the buffer allocated for generic_serial_bus region access
is not correct.  This patch introduces acpi_ex_get_serial_access_length()
to be invoked to obtain correct data buffer length.  Reported by
Lan Tianyu, Fixed by Lv Zheng.

Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
---
 drivers/acpi/acpica/exfield.c | 104 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 97 insertions(+), 7 deletions(-)

Comments

Adam Williamson April 28, 2014, 5:52 p.m. UTC | #1
On Mon, 2014-04-28 at 22:27 +0800, Lan Tianyu wrote:
> From: Lv Zheng <lv.zheng@intel.com>
> 
> The size of the buffer allocated for generic_serial_bus region access
> is not correct.  This patch introduces acpi_ex_get_serial_access_length()
> to be invoked to obtain correct data buffer length.  Reported by
> Lan Tianyu, Fixed by Lv Zheng.
> 
> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>

Very superficial issue, and sorry I forgot to mention it for v1, but the
summary line for this patch (1/9) ends with a period - "...region field
accesses." - which I think is not the correct style?
Adam Williamson April 28, 2014, 6:08 p.m. UTC | #2
On Mon, 2014-04-28 at 10:52 -0700, Adam Williamson wrote:
> On Mon, 2014-04-28 at 22:27 +0800, Lan Tianyu wrote:
> > From: Lv Zheng <lv.zheng@intel.com>
> > 
> > The size of the buffer allocated for generic_serial_bus region access
> > is not correct.  This patch introduces acpi_ex_get_serial_access_length()
> > to be invoked to obtain correct data buffer length.  Reported by
> > Lan Tianyu, Fixed by Lv Zheng.
> > 
> > Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> > Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
> 
> Very superficial issue, and sorry I forgot to mention it for v1, but the
> summary line for this patch (1/9) ends with a period - "...region field
> accesses." - which I think is not the correct style?

In fact, it seems this patch already got merged into Linus' tree
somehow:

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/acpi/acpica/exfield.c?id=6273f00e6ecbd60494a979033b7e5271a29a0436

the others do not seem to have been merged yet.
Rafael J. Wysocki April 28, 2014, 10:50 p.m. UTC | #3
On Monday, April 28, 2014 11:08:25 AM Adam Williamson wrote:
> On Mon, 2014-04-28 at 10:52 -0700, Adam Williamson wrote:
> > On Mon, 2014-04-28 at 22:27 +0800, Lan Tianyu wrote:
> > > From: Lv Zheng <lv.zheng@intel.com>
> > > 
> > > The size of the buffer allocated for generic_serial_bus region access
> > > is not correct.  This patch introduces acpi_ex_get_serial_access_length()
> > > to be invoked to obtain correct data buffer length.  Reported by
> > > Lan Tianyu, Fixed by Lv Zheng.
> > > 
> > > Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > > Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> > > Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
> > 
> > Very superficial issue, and sorry I forgot to mention it for v1, but the
> > summary line for this patch (1/9) ends with a period - "...region field
> > accesses." - which I think is not the correct style?

Well, some people do that, but is it really a problem?

> In fact, it seems this patch already got merged into Linus' tree
> somehow:
> 
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/acpi/acpica/exfield.c?id=6273f00e6ecbd60494a979033b7e5271a29a0436

Yes, I wanted to have it in there now.

> the others do not seem to have been merged yet.

The rest has been queued up for 3.16.
Wolfram Sang April 29, 2014, 11:31 a.m. UTC | #4
> The rest has been queued up for 3.16.

I also aim for 3.16, yet it may take 1 or 2 weeks more until I'll be
able to review the I2C part of those patches.
Rafael J. Wysocki April 29, 2014, 9:37 p.m. UTC | #5
On Tuesday, April 29, 2014 01:31:28 PM Wolfram Sang wrote:
> 
> --3MwIy2ne0vdjdPXF
> Content-Type: text/plain; charset=us-ascii
> Content-Disposition: inline
> 
> 
> > The rest has been queued up for 3.16.
> 
> I also aim for 3.16, yet it may take 1 or 2 weeks more until I'll be
> able to review the I2C part of those patches.

That's fine, they can stay in my bleeding-edge branch till then.
diff mbox

Patch

diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c
index 68d9744..12878e1 100644
--- a/drivers/acpi/acpica/exfield.c
+++ b/drivers/acpi/acpica/exfield.c
@@ -45,10 +45,71 @@ 
 #include "accommon.h"
 #include "acdispat.h"
 #include "acinterp.h"
+#include "amlcode.h"
 
 #define _COMPONENT          ACPI_EXECUTER
 ACPI_MODULE_NAME("exfield")
 
+/* Local prototypes */
+static u32
+acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length);
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_serial_access_bytes
+ *
+ * PARAMETERS:  accessor_type   - The type of the protocol indicated by region
+ *                                field access attributes
+ *              access_length   - The access length of the region field
+ *
+ * RETURN:      Decoded access length
+ *
+ * DESCRIPTION: This routine returns the length of the generic_serial_bus
+ *              protocol bytes
+ *
+ ******************************************************************************/
+
+static u32
+acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length)
+{
+	u32 length;
+
+	switch (accessor_type) {
+	case AML_FIELD_ATTRIB_QUICK:
+
+		length = 0;
+		break;
+
+	case AML_FIELD_ATTRIB_SEND_RCV:
+	case AML_FIELD_ATTRIB_BYTE:
+
+		length = 1;
+		break;
+
+	case AML_FIELD_ATTRIB_WORD:
+	case AML_FIELD_ATTRIB_WORD_CALL:
+
+		length = 2;
+		break;
+
+	case AML_FIELD_ATTRIB_MULTIBYTE:
+	case AML_FIELD_ATTRIB_RAW_BYTES:
+	case AML_FIELD_ATTRIB_RAW_PROCESS:
+
+		length = access_length;
+		break;
+
+	case AML_FIELD_ATTRIB_BLOCK:
+	case AML_FIELD_ATTRIB_BLOCK_CALL:
+	default:
+
+		length = ACPI_GSBUS_BUFFER_SIZE;
+		break;
+	}
+
+	return (length);
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ex_read_data_from_field
@@ -63,8 +124,9 @@  ACPI_MODULE_NAME("exfield")
  *              Buffer, depending on the size of the field.
  *
  ******************************************************************************/
+
 acpi_status
-acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
+acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state,
 			     union acpi_operand_object *obj_desc,
 			     union acpi_operand_object **ret_buffer_desc)
 {
@@ -73,6 +135,7 @@  acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
 	acpi_size length;
 	void *buffer;
 	u32 function;
+	u16 accessor_type;
 
 	ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc);
 
@@ -116,9 +179,22 @@  acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
 			    ACPI_READ | (obj_desc->field.attribute << 16);
 		} else if (obj_desc->field.region_obj->region.space_id ==
 			   ACPI_ADR_SPACE_GSBUS) {
-			length = ACPI_GSBUS_BUFFER_SIZE;
-			function =
-			    ACPI_READ | (obj_desc->field.attribute << 16);
+			accessor_type = obj_desc->field.attribute;
+			length = acpi_ex_get_serial_access_length(accessor_type,
+								  obj_desc->
+								  field.
+								  access_length);
+
+			/*
+			 * Add additional 2 bytes for modeled generic_serial_bus data buffer:
+			 * typedef struct {
+			 *     BYTEStatus; // Byte 0 of the data buffer
+			 *     BYTELength; // Byte 1 of the data buffer
+			 *     BYTE[x-1]Data; // Bytes 2-x of the arbitrary length data buffer,
+			 * }
+			 */
+			length += 2;
+			function = ACPI_READ | (accessor_type << 16);
 		} else {	/* IPMI */
 
 			length = ACPI_IPMI_BUFFER_SIZE;
@@ -231,6 +307,7 @@  acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
 	void *buffer;
 	union acpi_operand_object *buffer_desc;
 	u32 function;
+	u16 accessor_type;
 
 	ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc);
 
@@ -284,9 +361,22 @@  acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
 			    ACPI_WRITE | (obj_desc->field.attribute << 16);
 		} else if (obj_desc->field.region_obj->region.space_id ==
 			   ACPI_ADR_SPACE_GSBUS) {
-			length = ACPI_GSBUS_BUFFER_SIZE;
-			function =
-			    ACPI_WRITE | (obj_desc->field.attribute << 16);
+			accessor_type = obj_desc->field.attribute;
+			length = acpi_ex_get_serial_access_length(accessor_type,
+								  obj_desc->
+								  field.
+								  access_length);
+
+			/*
+			 * Add additional 2 bytes for modeled generic_serial_bus data buffer:
+			 * typedef struct {
+			 *     BYTEStatus; // Byte 0 of the data buffer
+			 *     BYTELength; // Byte 1 of the data buffer
+			 *     BYTE[x-1]Data; // Bytes 2-x of the arbitrary length data buffer,
+			 * }
+			 */
+			length += 2;
+			function = ACPI_WRITE | (accessor_type << 16);
 		} else {	/* IPMI */
 
 			length = ACPI_IPMI_BUFFER_SIZE;