Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ACPI / APEI: Switch NOTIFY_SEA to use the estatus queue

Now that the estatus queue can be used by more than one notification
method, we can move notifications that have NMI-like behaviour over.

Switch NOTIFY_SEA over to use the estatus queue. This makes it behave
in the same way as x86's NOTIFY_NMI.

Remove Kconfig's ability to turn ACPI_APEI_SEA off if ACPI_APEI_GHES
is selected. This roughly matches the x86 NOTIFY_NMI behaviour, and means
each architecture has at least one user of the estatus-queue, meaning it
doesn't need guarding with ifdef.

Signed-off-by: James Morse <james.morse@arm.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

James Morse and committed by
Rafael J. Wysocki
255097c8 9c9d0805

+6 -28
+1 -11
drivers/acpi/apei/Kconfig
··· 41 41 Turn on this option to enable the corresponding support. 42 42 43 43 config ACPI_APEI_SEA 44 - bool "APEI Synchronous External Abort logging/recovering support" 44 + bool 45 45 depends on ARM64 && ACPI_APEI_GHES 46 46 default y 47 - help 48 - This option should be enabled if the system supports 49 - firmware first handling of SEA (Synchronous External Abort). 50 - SEA happens with certain faults of data abort or instruction 51 - abort synchronous exceptions on ARMv8 systems. If a system 52 - supports firmware first handling of SEA, the platform analyzes 53 - and handles hardware error notifications from SEA, and it may then 54 - form a HW error record for the OS to parse and handle. This 55 - option allows the OS to look for such hardware error record, and 56 - take appropriate action. 57 47 58 48 config ACPI_APEI_MEMORY_FAILURE 59 49 bool "APEI memory error recovering support"
+5 -17
drivers/acpi/apei/ghes.c
··· 767 767 .notifier_call = ghes_notify_hed, 768 768 }; 769 769 770 - #ifdef CONFIG_HAVE_ACPI_APEI_NMI 771 770 /* 772 771 * Handlers for CPER records may not be NMI safe. For example, 773 772 * memory_failure_queue() takes spinlocks and calls schedule_work_on(). ··· 902 903 903 904 return ret; 904 905 } 905 - #endif /* CONFIG_HAVE_ACPI_APEI_NMI */ 906 906 907 907 #ifdef CONFIG_ACPI_APEI_SEA 908 908 static LIST_HEAD(ghes_sea); ··· 912 914 */ 913 915 int ghes_notify_sea(void) 914 916 { 915 - struct ghes *ghes; 916 - int ret = -ENOENT; 917 - 918 - rcu_read_lock(); 919 - list_for_each_entry_rcu(ghes, &ghes_sea, list) { 920 - if (!ghes_proc(ghes)) 921 - ret = 0; 922 - } 923 - rcu_read_unlock(); 924 - return ret; 917 + return ghes_in_nmi_spool_from_list(&ghes_sea); 925 918 } 926 919 927 920 static void ghes_sea_add(struct ghes *ghes) ··· 979 990 */ 980 991 synchronize_rcu(); 981 992 } 993 + #else /* CONFIG_HAVE_ACPI_APEI_NMI */ 994 + static inline void ghes_nmi_add(struct ghes *ghes) { } 995 + static inline void ghes_nmi_remove(struct ghes *ghes) { } 996 + #endif /* CONFIG_HAVE_ACPI_APEI_NMI */ 982 997 983 998 static void ghes_nmi_init_cxt(void) 984 999 { 985 1000 init_irq_work(&ghes_proc_irq_work, ghes_proc_in_irq); 986 1001 } 987 - #else /* CONFIG_HAVE_ACPI_APEI_NMI */ 988 - static inline void ghes_nmi_add(struct ghes *ghes) { } 989 - static inline void ghes_nmi_remove(struct ghes *ghes) { } 990 - static inline void ghes_nmi_init_cxt(void) { } 991 - #endif /* CONFIG_HAVE_ACPI_APEI_NMI */ 992 1002 993 1003 static int ghes_probe(struct platform_device *ghes_dev) 994 1004 {