Skip to content

Commit 9c4aa1e

Browse files
Lv Zhengrafaeljw
authored andcommitted
ACPI / sysfs: Provide quirk mechanism to prevent GPE flooding
Sometimes, the users may require a quirk to be provided from ACPI subsystem core to prevent a GPE from flooding. Normally, if a GPE cannot be dispatched, ACPICA core automatically prevents the GPE from firing. But there are cases the GPE is dispatched by _Lxx/_Exx provided via AML table, and OSPM is lacking of the knowledge to get _Lxx/_Exx correctly executed to handle the GPE, thus the GPE flooding may still occur. The existing quirk mechanism can be enabled/disabled using the following commands to prevent such kind of GPE flooding during runtime: # echo mask > /sys/firmware/acpi/interrupts/gpe00 # echo unmask > /sys/firmware/acpi/interrupts/gpe00 To avoid GPE flooding during boot, we need a boot stage mechanism. This patch provides such a boot stage quirk mechanism to stop this kind of GPE flooding. This patch doesn't fix any feature gap but since the new feature gaps could be found in the future endlessly, and can disappear if the feature gaps are filled, providing a boot parameter rather than a DMI table should suffice. Link: https://bugzilla.kernel.org/show_bug.cgi?id=53071 Link: https://bugzilla.kernel.org/show_bug.cgi?id=117481 Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/887793 Signed-off-by: Lv Zheng <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 7ce7d89 commit 9c4aa1e

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,16 @@
106106
use by PCI
107107
Format: <irq>,<irq>...
108108

109+
acpi_mask_gpe= [HW,ACPI]
110+
Due to the existence of _Lxx/_Exx, some GPEs triggered
111+
by unsupported hardware/firmware features can result in
112+
GPE floodings that cannot be automatically disabled by
113+
the GPE dispatcher.
114+
This facility can be used to prevent such uncontrolled
115+
GPE floodings.
116+
Format: <int>
117+
Support masking of GPEs numbered from 0x00 to 0x7f.
118+
109119
acpi_no_auto_serialize [HW,ACPI]
110120
Disable auto-serialization of AML methods
111121
AML control methods that contain the opcodes to create

drivers/acpi/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ void acpi_amba_init(void);
3737
static inline void acpi_amba_init(void) {}
3838
#endif
3939
int acpi_sysfs_init(void);
40+
void acpi_gpe_apply_masked_gpes(void);
4041
void acpi_container_init(void);
4142
void acpi_memory_hotplug_init(void);
4243
#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC

drivers/acpi/scan.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2074,6 +2074,7 @@ int __init acpi_scan_init(void)
20742074
}
20752075
}
20762076

2077+
acpi_gpe_apply_masked_gpes();
20772078
acpi_update_all_gpes();
20782079
acpi_ec_ecdt_start();
20792080

drivers/acpi/sysfs.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,62 @@ static ssize_t counter_set(struct kobject *kobj,
708708
return result ? result : size;
709709
}
710710

711+
/*
712+
* A Quirk Mechanism for GPE Flooding Prevention:
713+
*
714+
* Quirks may be needed to prevent GPE flooding on a specific GPE. The
715+
* flooding typically cannot be detected and automatically prevented by
716+
* ACPI_GPE_DISPATCH_NONE check because there is a _Lxx/_Exx prepared in
717+
* the AML tables. This normally indicates a feature gap in Linux, thus
718+
* instead of providing endless quirk tables, we provide a boot parameter
719+
* for those who want this quirk. For example, if the users want to prevent
720+
* the GPE flooding for GPE 00, they need to specify the following boot
721+
* parameter:
722+
* acpi_mask_gpe=0x00
723+
* The masking status can be modified by the following runtime controlling
724+
* interface:
725+
* echo unmask > /sys/firmware/acpi/interrupts/gpe00
726+
*/
727+
728+
/*
729+
* Currently, the GPE flooding prevention only supports to mask the GPEs
730+
* numbered from 00 to 7f.
731+
*/
732+
#define ACPI_MASKABLE_GPE_MAX 0x80
733+
734+
static u64 __initdata acpi_masked_gpes;
735+
736+
static int __init acpi_gpe_set_masked_gpes(char *val)
737+
{
738+
u8 gpe;
739+
740+
if (kstrtou8(val, 0, &gpe) || gpe > ACPI_MASKABLE_GPE_MAX)
741+
return -EINVAL;
742+
acpi_masked_gpes |= ((u64)1<<gpe);
743+
744+
return 1;
745+
}
746+
__setup("acpi_mask_gpe=", acpi_gpe_set_masked_gpes);
747+
748+
void __init acpi_gpe_apply_masked_gpes(void)
749+
{
750+
acpi_handle handle;
751+
acpi_status status;
752+
u8 gpe;
753+
754+
for (gpe = 0;
755+
gpe < min_t(u8, ACPI_MASKABLE_GPE_MAX, acpi_current_gpe_count);
756+
gpe++) {
757+
if (acpi_masked_gpes & ((u64)1<<gpe)) {
758+
status = acpi_get_gpe_device(gpe, &handle);
759+
if (ACPI_SUCCESS(status)) {
760+
pr_info("Masking GPE 0x%x.\n", gpe);
761+
(void)acpi_mask_gpe(handle, gpe, TRUE);
762+
}
763+
}
764+
}
765+
}
766+
711767
void acpi_irq_stats_init(void)
712768
{
713769
acpi_status status;

0 commit comments

Comments
 (0)