summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/acpi_lpss.c5
-rw-r--r--drivers/acpi/acpica/dsmethod.c5
-rw-r--r--drivers/acpi/acpica/uterror.c53
-rw-r--r--drivers/acpi/scan.c1
-rw-r--r--drivers/acpi/thermal.c23
-rw-r--r--drivers/acpi/utils.c5
-rw-r--r--drivers/platform/surface/surface_acpi_notify.c5
-rw-r--r--include/acpi/acpi_bus.h4
8 files changed, 86 insertions, 15 deletions
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index f08ffa75f4a7..d36dbb6564e2 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -576,10 +576,13 @@ static bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle)
 	}
 
 	for (i = 0; i < dep_devices.count; i++) {
-		if (dep_devices.handles[i] == handle)
+		if (dep_devices.handles[i] == handle) {
+			kfree(dep_devices.handles);
 			return true;
+		}
 	}
 
+	kfree(dep_devices.handles);
 	return false;
 }
 
diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c
index 9332bc688713..d97f8b843312 100644
--- a/drivers/acpi/acpica/dsmethod.c
+++ b/drivers/acpi/acpica/dsmethod.c
@@ -306,8 +306,9 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
 	/* Prevent wraparound of thread count */
 
 	if (obj_desc->method.thread_count == ACPI_UINT8_MAX) {
-		ACPI_ERROR((AE_INFO,
-			    "Method reached maximum reentrancy limit (255)"));
+		/* Suppressing this due to firmware bug flooding the logs */
+		/*ACPI_ERROR((AE_INFO,
+			    "Method reached maximum reentrancy limit (255)"));*/
 		return_ACPI_STATUS(AE_AML_METHOD_LIMIT);
 	}
 
diff --git a/drivers/acpi/acpica/uterror.c b/drivers/acpi/acpica/uterror.c
index 918aca7c4db4..4a482de2e55d 100644
--- a/drivers/acpi/acpica/uterror.c
+++ b/drivers/acpi/acpica/uterror.c
@@ -280,6 +280,56 @@ acpi_ut_namespace_error(const char *module_name,
 
 /*******************************************************************************
  *
+ * Limit the error message flood caused by a firmware bug:
+ *
+ * ACPI Error: Method reached maximum reentrancy limit (255) (20210331/dsmethod-309)
+ * ACPI Error: Aborting method \_SB.PCI0.LPC0.EC0.VFCD.PDVL due to previous error (AE_AML_METHOD_LIMIT) (20210331/psparse-529)
+ * [...]
+ * ACPI Error: Aborting method \_SB.PCI0.LPC0.EC0.VFCD.PDVL due to previous error (AE_AML_METHOD_LIMIT) (20210331/psparse-529)
+ *
+ ******************************************************************************/
+
+static bool acpi_disable_msg_flood_detect;
+
+static int __init acpi_no_msg_flood_detect_setup(char *s)
+{
+	acpi_disable_msg_flood_detect = true;
+	pr_info("ACPI error message flood detection disabled\n");
+
+	return 0;
+}
+
+early_param("acpi_no_msg_flood_detect", acpi_no_msg_flood_detect_setup);
+
+static bool acpi_skip_print_node(struct acpi_namespace_node *node)
+{
+	static bool skip_print = false;
+	struct acpi_buffer buffer;
+	acpi_status status;
+
+	if (acpi_disable_msg_flood_detect || !node)
+		return false;
+
+	if (!skip_print) {
+		/* Convert handle to full pathname */
+		buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
+		status = acpi_ns_handle_to_pathname(node, &buffer, TRUE);
+		if (ACPI_SUCCESS(status)) {
+			skip_print = !strcmp((const char *)buffer.pointer,
+					     "\\_SB.PCI0.LPC0.EC0.VFCD.PDVL");
+			ACPI_FREE(buffer.pointer);
+
+			if (skip_print)
+				return false; /* print once */
+		}
+	}
+
+	return skip_print;
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ut_method_error
  *
  * PARAMETERS:  module_name         - Caller's module name (for error output)
@@ -305,6 +355,9 @@ acpi_ut_method_error(const char *module_name,
 	acpi_status status;
 	struct acpi_namespace_node *node = prefix_node;
 
+	if (acpi_skip_print_node(node))
+		return;
+
 	ACPI_MSG_REDIRECT_BEGIN;
 	acpi_os_printf(ACPI_MSG_ERROR);
 
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index a0e347f6f97e..17c58bd14f34 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -2027,6 +2027,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep)
 		mutex_unlock(&acpi_dep_list_lock);
 	}
 
+	kfree(dep_devices.handles);
 	return count;
 }
 
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 40ecb55b52f8..dfd865c8ce97 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -375,8 +375,10 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
 			tz->trips.passive.flags.valid = 1;
 		}
 
-		if (memcmp(&tz->trips.passive.devices, &devices,
-			   sizeof(struct acpi_handle_list))) {
+		if (tz->trips.passive.devices.count != devices.count ||
+			   memcmp(tz->trips.passive.devices.handles,
+			   devices.handles, sizeof(acpi_handle) * devices.count)) {
+			kfree(tz->trips.passive.devices.handles);
 			memcpy(&tz->trips.passive.devices, &devices,
 			       sizeof(struct acpi_handle_list));
 			ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device");
@@ -440,8 +442,10 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
 				tz->trips.active[i].flags.valid = 1;
 			}
 
-			if (memcmp(&tz->trips.active[i].devices, &devices,
-				   sizeof(struct acpi_handle_list))) {
+			if (tz->trips.active[i].devices.count != devices.count ||
+				   memcmp(tz->trips.active[i].devices.handles,
+				   devices.handles, sizeof(acpi_handle) * devices.count)) {
+				kfree(tz->trips.active[i].devices.handles);
 				memcpy(&tz->trips.active[i].devices, &devices,
 				       sizeof(struct acpi_handle_list));
 				ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device");
@@ -459,8 +463,10 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
 		memset(&devices, 0, sizeof(devices));
 		status = acpi_evaluate_reference(tz->device->handle, "_TZD",
 						 NULL, &devices);
-		if (ACPI_SUCCESS(status) &&
-		    memcmp(&tz->devices, &devices, sizeof(devices))) {
+		if (ACPI_SUCCESS(status) && (tz->devices.count != devices.count ||
+		    memcmp(tz->devices.handles, devices.handles,
+		    sizeof(acpi_handle) * devices.count))) {
+			kfree(tz->devices.handles);
 			tz->devices = devices;
 			ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device");
 		}
@@ -1058,6 +1064,7 @@ end:
 static int acpi_thermal_remove(struct acpi_device *device)
 {
 	struct acpi_thermal *tz;
+	int i;
 
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
@@ -1066,6 +1073,10 @@ static int acpi_thermal_remove(struct acpi_device *device)
 	tz = acpi_driver_data(device);
 
 	acpi_thermal_unregister_thermal_zone(tz);
+	kfree(tz->trips.passive.devices.handles);
+	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
+		kfree(tz->trips.active[i].devices.handles);
+	kfree(tz->devices.handles);
 	kfree(tz);
 	return 0;
 }
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index 2ea14648a661..96f821c41756 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -370,7 +370,8 @@ acpi_evaluate_reference(acpi_handle handle,
 		goto end;
 	}
 
-	if (package->package.count > ACPI_MAX_HANDLES) {
+	list->handles = kcalloc(package->package.count, sizeof(*list->handles), GFP_KERNEL);
+	if (!list->handles) {
 		kfree(package);
 		return AE_NO_MEMORY;
 	}
@@ -402,7 +403,7 @@ acpi_evaluate_reference(acpi_handle handle,
       end:
 	if (ACPI_FAILURE(status)) {
 		list->count = 0;
-		//kfree(list->handles);
+		kfree(list->handles);
 	}
 
 	kfree(buffer.pointer);
diff --git a/drivers/platform/surface/surface_acpi_notify.c b/drivers/platform/surface/surface_acpi_notify.c
index 50500e562963..e3c7fe93100a 100644
--- a/drivers/platform/surface/surface_acpi_notify.c
+++ b/drivers/platform/surface/surface_acpi_notify.c
@@ -753,10 +753,13 @@ static bool is_san_consumer(struct platform_device *pdev, acpi_handle handle)
 	}
 
 	for (i = 0; i < dep_devices.count; i++) {
-		if (dep_devices.handles[i] == supplier)
+		if (dep_devices.handles[i] == supplier) {
+			kfree(dep_devices.handles);
 			return true;
+		}
 	}
 
+	kfree(dep_devices.handles);
 	return false;
 }
 
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 6badc50ec4e6..ae6b07d040f1 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -12,11 +12,9 @@
 #include <linux/device.h>
 #include <linux/property.h>
 
-/* TBD: Make dynamic */
-#define ACPI_MAX_HANDLES	10
 struct acpi_handle_list {
 	u32 count;
-	acpi_handle handles[ACPI_MAX_HANDLES];
+	acpi_handle* handles;
 };
 
 /* acpi_utils.h */