linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC Patch v1 03/13] PCI, pci-label: release allocated ACPI object on error recovery path
       [not found] <1387349901-3391-1-git-send-email-jiang.liu@linux.intel.com>
@ 2013-12-18  6:58 ` Jiang Liu
  2013-12-18  6:58 ` [RFC Patch v1 04/13] ACPI, PCI: replace open-coded _DSM specific code with helper functions Jiang Liu
  2013-12-18  6:58 ` [RFC Patch v1 05/13] PCI, pci-label: treat PCI label with index 0 as valid label Jiang Liu
  2 siblings, 0 replies; 3+ messages in thread
From: Jiang Liu @ 2013-12-18  6:58 UTC (permalink / raw)
  To: Rafael J . Wysocki, Bjorn Helgaas, Lv Zheng, Len Brown,
	Leonidas Da Silva Barbosa, Ashley Lai, Peter Huewe, Rajiv Andrade,
	Marcel Selhorst, Sirrix AG, Daniel Vetter, David Airlie,
	Jiri Kosina, linux-pci, linux-kernel
  Cc: Jiang Liu, Tony Luck

Function dsm_get_label() leaks the returned ACPI object if
obj->package.count is not 2, so fix the possible memory leak.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 drivers/pci/pci-label.c |   12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c
index d51f45a..f6e01a5 100644
--- a/drivers/pci/pci-label.c
+++ b/drivers/pci/pci-label.c
@@ -233,11 +233,7 @@ dsm_get_label(acpi_handle handle, int func,
 		return -1;
 
 	obj = (union acpi_object *)output->pointer;
-
-	switch (obj->type) {
-	case ACPI_TYPE_PACKAGE:
-		if (obj->package.count != 2)
-			break;
+	if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 2) {
 		len = obj->package.elements[0].integer.value;
 		if (buf) {
 			if (attribute == ACPI_ATTR_INDEX_SHOW)
@@ -250,10 +246,10 @@ dsm_get_label(acpi_handle handle, int func,
 		}
 		kfree(output->pointer);
 		return len;
-	break;
-	default:
-		kfree(output->pointer);
 	}
+
+	kfree(output->pointer);
+
 	return -1;
 }
 
-- 
1.7.10.4


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

* [RFC Patch v1 04/13] ACPI, PCI: replace open-coded _DSM specific code with helper functions
       [not found] <1387349901-3391-1-git-send-email-jiang.liu@linux.intel.com>
  2013-12-18  6:58 ` [RFC Patch v1 03/13] PCI, pci-label: release allocated ACPI object on error recovery path Jiang Liu
@ 2013-12-18  6:58 ` Jiang Liu
  2013-12-18  6:58 ` [RFC Patch v1 05/13] PCI, pci-label: treat PCI label with index 0 as valid label Jiang Liu
  2 siblings, 0 replies; 3+ messages in thread
From: Jiang Liu @ 2013-12-18  6:58 UTC (permalink / raw)
  To: Rafael J . Wysocki, Bjorn Helgaas, Lv Zheng, Len Brown,
	Leonidas Da Silva Barbosa, Ashley Lai, Peter Huewe, Rajiv Andrade,
	Marcel Selhorst, Sirrix AG, Daniel Vetter, David Airlie,
	Jiri Kosina, linux-pci, linux-kernel
  Cc: Jiang Liu, Tony Luck

Use helper functions to simplify _DSM related code in pci-label driver.
Also enforce more strict checks on objects returned by _DSM method.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 drivers/pci/pci-label.c |  121 +++++++++++++----------------------------------
 1 file changed, 34 insertions(+), 87 deletions(-)

diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c
index f6e01a5..f12dcd1 100644
--- a/drivers/pci/pci-label.c
+++ b/drivers/pci/pci-label.c
@@ -195,80 +195,58 @@ enum acpi_attr_enum {
 static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf)
 {
 	int len;
-	len = utf16s_to_utf8s((const wchar_t *)obj->
-			      package.elements[1].string.pointer,
-			      obj->package.elements[1].string.length,
+	len = utf16s_to_utf8s((const wchar_t *)obj->string.pointer,
+			      obj->string.length,
 			      UTF16_LITTLE_ENDIAN,
 			      buf, PAGE_SIZE);
 	buf[len] = '\n';
 }
 
 static int
-dsm_get_label(acpi_handle handle, int func,
-	      struct acpi_buffer *output,
-	      char *buf, enum acpi_attr_enum attribute)
+dsm_get_label(struct device *dev, char *buf, enum acpi_attr_enum attr)
 {
-	struct acpi_object_list input;
-	union acpi_object params[4];
-	union acpi_object *obj;
-	int len = 0;
-
-	int err;
-
-	input.count = 4;
-	input.pointer = params;
-	params[0].type = ACPI_TYPE_BUFFER;
-	params[0].buffer.length = sizeof(device_label_dsm_uuid);
-	params[0].buffer.pointer = (char *)device_label_dsm_uuid;
-	params[1].type = ACPI_TYPE_INTEGER;
-	params[1].integer.value = 0x02;
-	params[2].type = ACPI_TYPE_INTEGER;
-	params[2].integer.value = func;
-	params[3].type = ACPI_TYPE_PACKAGE;
-	params[3].package.count = 0;
-	params[3].package.elements = NULL;
-
-	err = acpi_evaluate_object(handle, "_DSM", &input, output);
-	if (err)
+	acpi_handle handle;
+	union acpi_object *obj, *tmp;
+	int len = -1;
+
+	handle = ACPI_HANDLE(dev);
+	if (!handle)
 		return -1;
 
-	obj = (union acpi_object *)output->pointer;
-	if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 2) {
-		len = obj->package.elements[0].integer.value;
+	obj = acpi_evaluate_dsm(handle, device_label_dsm_uuid, 0x2,
+				DEVICE_LABEL_DSM, NULL);
+	if (!obj)
+		return -1;
+
+	tmp = obj->package.elements;
+	if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 2 &&
+	    tmp[0].type == ACPI_TYPE_INTEGER &&
+	    tmp[1].type == ACPI_TYPE_STRING) {
+		len = tmp[0].integer.value;
 		if (buf) {
-			if (attribute == ACPI_ATTR_INDEX_SHOW)
+			/*
+			 * This second string element is optional even when
+			 * this _DSM is implemented; when not implemented,
+			 * this entry must return a null string.
+			 */
+			if (attr == ACPI_ATTR_INDEX_SHOW)
 				scnprintf(buf, PAGE_SIZE, "%llu\n",
-				obj->package.elements[0].integer.value);
-			else if (attribute == ACPI_ATTR_LABEL_SHOW)
-				dsm_label_utf16s_to_utf8s(obj, buf);
-			kfree(output->pointer);
-			return strlen(buf);
+				tmp->integer.value);
+			else if (attr == ACPI_ATTR_LABEL_SHOW)
+				dsm_label_utf16s_to_utf8s(tmp + 1, buf);
+			len = strlen(buf) > 0 ? strlen(buf) : -1;
 		}
-		kfree(output->pointer);
-		return len;
 	}
 
-	kfree(output->pointer);
+	ACPI_FREE(obj);
 
-	return -1;
+	return len;
 }
 
 static bool
 device_has_dsm(struct device *dev)
 {
-	acpi_handle handle;
-	struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
-
-	handle = ACPI_HANDLE(dev);
-
-	if (!handle)
-		return FALSE;
-
-	if (dsm_get_label(handle, DEVICE_LABEL_DSM, &output, NULL,
-			  ACPI_ATTR_NONE) > 0)
-		return TRUE;
-
-	return FALSE;
+	return dsm_get_label(dev, NULL, ACPI_ATTR_NONE) > 0;
 }
 
 static umode_t
@@ -287,44 +265,13 @@ acpi_index_string_exist(struct kobject *kobj, struct attribute *attr, int n)
 static ssize_t
 acpilabel_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
-	struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
-	acpi_handle handle;
-	int length;
-
-	handle = ACPI_HANDLE(dev);
-
-	if (!handle)
-		return -1;
-
-	length = dsm_get_label(handle, DEVICE_LABEL_DSM,
-			       &output, buf, ACPI_ATTR_LABEL_SHOW);
-
-	if (length < 1)
-		return -1;
-
-	return length;
+	return dsm_get_label(dev, buf, ACPI_ATTR_LABEL_SHOW);
 }
 
 static ssize_t
 acpiindex_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
-	struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
-	acpi_handle handle;
-	int length;
-
-	handle = ACPI_HANDLE(dev);
-
-	if (!handle)
-		return -1;
-
-	length = dsm_get_label(handle, DEVICE_LABEL_DSM,
-			       &output, buf, ACPI_ATTR_INDEX_SHOW);
-
-	if (length < 0)
-		return -1;
-
-	return length;
-
+	return dsm_get_label(dev, buf, ACPI_ATTR_INDEX_SHOW);
 }
 
 static struct device_attribute acpi_attr_label = {
-- 
1.7.10.4


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

* [RFC Patch v1 05/13] PCI, pci-label: treat PCI label with index 0 as valid label
       [not found] <1387349901-3391-1-git-send-email-jiang.liu@linux.intel.com>
  2013-12-18  6:58 ` [RFC Patch v1 03/13] PCI, pci-label: release allocated ACPI object on error recovery path Jiang Liu
  2013-12-18  6:58 ` [RFC Patch v1 04/13] ACPI, PCI: replace open-coded _DSM specific code with helper functions Jiang Liu
@ 2013-12-18  6:58 ` Jiang Liu
  2 siblings, 0 replies; 3+ messages in thread
From: Jiang Liu @ 2013-12-18  6:58 UTC (permalink / raw)
  To: Rafael J . Wysocki, Bjorn Helgaas, Lv Zheng, Len Brown,
	Leonidas Da Silva Barbosa, Ashley Lai, Peter Huewe, Rajiv Andrade,
	Marcel Selhorst, Sirrix AG, Daniel Vetter, David Airlie,
	Jiri Kosina, linux-pci, linux-kernel
  Cc: Jiang Liu, Tony Luck

Current pci-label driver detects ACPI label by checking label index
returned by ACPI _DSM method, and treat it as valid if label index
is positive. According to ACPI Firmware specification 3.1, zero is
also an valid label index. So change code to detect availability of
ACPI slot label by checking availaiblity of ACPI _DSM function for
PCI label.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 drivers/pci/pci-label.c |   34 ++++++++++++++++++----------------
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c
index f12dcd1..0260b14 100644
--- a/drivers/pci/pci-label.c
+++ b/drivers/pci/pci-label.c
@@ -187,7 +187,6 @@ static const char device_label_dsm_uuid[] = {
 };
 
 enum acpi_attr_enum {
-	ACPI_ATTR_NONE = 0,
 	ACPI_ATTR_LABEL_SHOW,
 	ACPI_ATTR_INDEX_SHOW,
 };
@@ -222,20 +221,16 @@ dsm_get_label(struct device *dev, char *buf, enum acpi_attr_enum attr)
 	if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 2 &&
 	    tmp[0].type == ACPI_TYPE_INTEGER &&
 	    tmp[1].type == ACPI_TYPE_STRING) {
-		len = tmp[0].integer.value;
-		if (buf) {
-			/*
-			 * This second string element is optional even when
-			 * this _DSM is implemented; when not implemented,
-			 * this entry must return a null string.
-			 */
-			if (attr == ACPI_ATTR_INDEX_SHOW)
-				scnprintf(buf, PAGE_SIZE, "%llu\n",
-				tmp->integer.value);
-			else if (attr == ACPI_ATTR_LABEL_SHOW)
-				dsm_label_utf16s_to_utf8s(tmp + 1, buf);
-			len = strlen(buf) > 0 ? strlen(buf) : -1;
-		}
+		/*
+		 * The second string element is optional even when
+		 * this _DSM is implemented; when not implemented,
+		 * this entry must return a null string.
+		 */
+		if (attr == ACPI_ATTR_INDEX_SHOW)
+			scnprintf(buf, PAGE_SIZE, "%llu\n", tmp->integer.value);
+		else if (attr == ACPI_ATTR_LABEL_SHOW)
+			dsm_label_utf16s_to_utf8s(tmp + 1, buf);
+		len = strlen(buf) > 0 ? strlen(buf) : -1;
 	}
 
 	ACPI_FREE(obj);
@@ -246,7 +241,14 @@ dsm_get_label(struct device *dev, char *buf, enum acpi_attr_enum attr)
 static bool
 device_has_dsm(struct device *dev)
 {
-	return dsm_get_label(dev, NULL, ACPI_ATTR_NONE) > 0;
+	acpi_handle handle;
+
+	handle = ACPI_HANDLE(dev);
+	if (!handle)
+		return false;
+
+	return !!acpi_check_dsm(handle, device_label_dsm_uuid, 0x2,
+				1 << DEVICE_LABEL_DSM);
 }
 
 static umode_t
-- 
1.7.10.4


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

end of thread, other threads:[~2013-12-18  6:58 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1387349901-3391-1-git-send-email-jiang.liu@linux.intel.com>
2013-12-18  6:58 ` [RFC Patch v1 03/13] PCI, pci-label: release allocated ACPI object on error recovery path Jiang Liu
2013-12-18  6:58 ` [RFC Patch v1 04/13] ACPI, PCI: replace open-coded _DSM specific code with helper functions Jiang Liu
2013-12-18  6:58 ` [RFC Patch v1 05/13] PCI, pci-label: treat PCI label with index 0 as valid label Jiang Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).