.. | .. |
---|
1140 | 1140 | return true; |
---|
1141 | 1141 | } |
---|
1142 | 1142 | |
---|
1143 | | -static int __init sdei_init(void) |
---|
| 1143 | +void __init sdei_init(void) |
---|
1144 | 1144 | { |
---|
1145 | 1145 | struct platform_device *pdev; |
---|
1146 | 1146 | int ret; |
---|
1147 | 1147 | |
---|
1148 | 1148 | ret = platform_driver_register(&sdei_driver); |
---|
1149 | 1149 | if (ret || !sdei_present_acpi()) |
---|
1150 | | - return ret; |
---|
| 1150 | + return; |
---|
1151 | 1151 | |
---|
1152 | 1152 | pdev = platform_device_register_simple(sdei_driver.driver.name, |
---|
1153 | 1153 | 0, NULL, 0); |
---|
.. | .. |
---|
1157 | 1157 | pr_info("Failed to register ACPI:SDEI platform device %d\n", |
---|
1158 | 1158 | ret); |
---|
1159 | 1159 | } |
---|
1160 | | - |
---|
1161 | | - return ret; |
---|
1162 | 1160 | } |
---|
1163 | | - |
---|
1164 | | -/* |
---|
1165 | | - * On an ACPI system SDEI needs to be ready before HEST:GHES tries to register |
---|
1166 | | - * its events. ACPI is initialised from a subsys_initcall(), GHES is initialised |
---|
1167 | | - * by device_initcall(). We want to be called in the middle. |
---|
1168 | | - */ |
---|
1169 | | -subsys_initcall_sync(sdei_init); |
---|
1170 | 1161 | |
---|
1171 | 1162 | int sdei_event_handler(struct pt_regs *regs, |
---|
1172 | 1163 | struct sdei_registered_event *arg) |
---|
.. | .. |
---|
1195 | 1186 | return err; |
---|
1196 | 1187 | } |
---|
1197 | 1188 | NOKPROBE_SYMBOL(sdei_event_handler); |
---|
| 1189 | + |
---|
| 1190 | +void sdei_handler_abort(void) |
---|
| 1191 | +{ |
---|
| 1192 | + /* |
---|
| 1193 | + * If the crash happened in an SDEI event handler then we need to |
---|
| 1194 | + * finish the handler with the firmware so that we can have working |
---|
| 1195 | + * interrupts in the crash kernel. |
---|
| 1196 | + */ |
---|
| 1197 | + if (__this_cpu_read(sdei_active_critical_event)) { |
---|
| 1198 | + pr_warn("still in SDEI critical event context, attempting to finish handler.\n"); |
---|
| 1199 | + __sdei_handler_abort(); |
---|
| 1200 | + __this_cpu_write(sdei_active_critical_event, NULL); |
---|
| 1201 | + } |
---|
| 1202 | + if (__this_cpu_read(sdei_active_normal_event)) { |
---|
| 1203 | + pr_warn("still in SDEI normal event context, attempting to finish handler.\n"); |
---|
| 1204 | + __sdei_handler_abort(); |
---|
| 1205 | + __this_cpu_write(sdei_active_normal_event, NULL); |
---|
| 1206 | + } |
---|
| 1207 | +} |
---|