aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLv Zheng <lv.zheng@intel.com>2016-12-15 23:07:57 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-12-26 17:16:39 -0500
commit9c4aa1eecb48cfac18ed5e3aca9d9ae58fbafc11 (patch)
tree09090669e6210c5cacb16bc8af2048ba94ec8793
parent7ce7d89f48834cefece7804d38fc5d85382edf77 (diff)
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 <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt10
-rw-r--r--drivers/acpi/internal.h1
-rw-r--r--drivers/acpi/scan.c1
-rw-r--r--drivers/acpi/sysfs.c56
4 files changed, 68 insertions, 0 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 21e2d8863705..d1eec5ed1134 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -106,6 +106,16 @@
106 use by PCI 106 use by PCI
107 Format: <irq>,<irq>... 107 Format: <irq>,<irq>...
108 108
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
109 acpi_no_auto_serialize [HW,ACPI] 119 acpi_no_auto_serialize [HW,ACPI]
110 Disable auto-serialization of AML methods 120 Disable auto-serialization of AML methods
111 AML control methods that contain the opcodes to create 121 AML control methods that contain the opcodes to create
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 1b41a2739dac..0c452265c111 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -37,6 +37,7 @@ void acpi_amba_init(void);
37static inline void acpi_amba_init(void) {} 37static inline void acpi_amba_init(void) {}
38#endif 38#endif
39int acpi_sysfs_init(void); 39int acpi_sysfs_init(void);
40void acpi_gpe_apply_masked_gpes(void);
40void acpi_container_init(void); 41void acpi_container_init(void);
41void acpi_memory_hotplug_init(void); 42void acpi_memory_hotplug_init(void);
42#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC 43#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 45dec874ea55..192691880d55 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -2074,6 +2074,7 @@ int __init acpi_scan_init(void)
2074 } 2074 }
2075 } 2075 }
2076 2076
2077 acpi_gpe_apply_masked_gpes();
2077 acpi_update_all_gpes(); 2078 acpi_update_all_gpes();
2078 acpi_ec_ecdt_start(); 2079 acpi_ec_ecdt_start();
2079 2080
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index 703c26e7022c..cf05ae973381 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -708,6 +708,62 @@ end:
708 return result ? result : size; 708 return result ? result : size;
709} 709}
710 710
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
734static u64 __initdata acpi_masked_gpes;
735
736static 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
748void __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
711void acpi_irq_stats_init(void) 767void acpi_irq_stats_init(void)
712{ 768{
713 acpi_status status; 769 acpi_status status;