diff options
author | Boris Ostrovsky <boris.ostrovsky@oracle.com> | 2019-09-30 16:44:41 -0400 |
---|---|---|
committer | Boris Ostrovsky <boris.ostrovsky@oracle.com> | 2019-10-07 17:53:30 -0400 |
commit | c6875f3aacf2a5a913205accddabf0bfb75cac76 (patch) | |
tree | ab2ad24560746f3b179b5c3d48ee8461a1eee0d9 | |
parent | a8fabb38525c51a094607768bac3ba46b3f4a9d5 (diff) |
x86/xen: Return from panic notifier
Currently execution of panic() continues until Xen's panic notifier
(xen_panic_event()) is called at which point we make a hypercall that
never returns.
This means that any notifier that is supposed to be called later as
well as significant part of panic() code (such as pstore writes from
kmsg_dump()) is never executed.
There is no reason for xen_panic_event() to be this last point in
execution since panic()'s emergency_restart() will call into
xen_emergency_restart() from where we can perform our hypercall.
Nevertheless, we will provide xen_legacy_crash boot option that will
preserve original behavior during crash. This option could be used,
for example, if running kernel dumper (which happens after panic
notifiers) is undesirable.
Reported-by: James Dingwall <james@dingwall.me.uk>
Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
-rw-r--r-- | Documentation/admin-guide/kernel-parameters.txt | 4 | ||||
-rw-r--r-- | arch/x86/xen/enlighten.c | 28 |
2 files changed, 29 insertions, 3 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 4c1971960afa..5ea005c9e2d6 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt | |||
@@ -5267,6 +5267,10 @@ | |||
5267 | the unplug protocol | 5267 | the unplug protocol |
5268 | never -- do not unplug even if version check succeeds | 5268 | never -- do not unplug even if version check succeeds |
5269 | 5269 | ||
5270 | xen_legacy_crash [X86,XEN] | ||
5271 | Crash from Xen panic notifier, without executing late | ||
5272 | panic() code such as dumping handler. | ||
5273 | |||
5270 | xen_nopvspin [X86,XEN] | 5274 | xen_nopvspin [X86,XEN] |
5271 | Disables the ticketlock slowpath using Xen PV | 5275 | Disables the ticketlock slowpath using Xen PV |
5272 | optimizations. | 5276 | optimizations. |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 750f46ad018a..205b1176084f 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -269,19 +269,41 @@ void xen_reboot(int reason) | |||
269 | BUG(); | 269 | BUG(); |
270 | } | 270 | } |
271 | 271 | ||
272 | static int reboot_reason = SHUTDOWN_reboot; | ||
273 | static bool xen_legacy_crash; | ||
272 | void xen_emergency_restart(void) | 274 | void xen_emergency_restart(void) |
273 | { | 275 | { |
274 | xen_reboot(SHUTDOWN_reboot); | 276 | xen_reboot(reboot_reason); |
275 | } | 277 | } |
276 | 278 | ||
277 | static int | 279 | static int |
278 | xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr) | 280 | xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr) |
279 | { | 281 | { |
280 | if (!kexec_crash_loaded()) | 282 | if (!kexec_crash_loaded()) { |
281 | xen_reboot(SHUTDOWN_crash); | 283 | if (xen_legacy_crash) |
284 | xen_reboot(SHUTDOWN_crash); | ||
285 | |||
286 | reboot_reason = SHUTDOWN_crash; | ||
287 | |||
288 | /* | ||
289 | * If panic_timeout==0 then we are supposed to wait forever. | ||
290 | * However, to preserve original dom0 behavior we have to drop | ||
291 | * into hypervisor. (domU behavior is controlled by its | ||
292 | * config file) | ||
293 | */ | ||
294 | if (panic_timeout == 0) | ||
295 | panic_timeout = -1; | ||
296 | } | ||
282 | return NOTIFY_DONE; | 297 | return NOTIFY_DONE; |
283 | } | 298 | } |
284 | 299 | ||
300 | static int __init parse_xen_legacy_crash(char *arg) | ||
301 | { | ||
302 | xen_legacy_crash = true; | ||
303 | return 0; | ||
304 | } | ||
305 | early_param("xen_legacy_crash", parse_xen_legacy_crash); | ||
306 | |||
285 | static struct notifier_block xen_panic_block = { | 307 | static struct notifier_block xen_panic_block = { |
286 | .notifier_call = xen_panic_event, | 308 | .notifier_call = xen_panic_event, |
287 | .priority = INT_MIN | 309 | .priority = INT_MIN |