Skip to content

Commit c6875f3

Browse files
committed
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 <[email protected]> Signed-off-by: Boris Ostrovsky <[email protected]> Reviewed-by: Juergen Gross <[email protected]>
1 parent a8fabb3 commit c6875f3

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5267,6 +5267,10 @@
52675267
the unplug protocol
52685268
never -- do not unplug even if version check succeeds
52695269

5270+
xen_legacy_crash [X86,XEN]
5271+
Crash from Xen panic notifier, without executing late
5272+
panic() code such as dumping handler.
5273+
52705274
xen_nopvspin [X86,XEN]
52715275
Disables the ticketlock slowpath using Xen PV
52725276
optimizations.

arch/x86/xen/enlighten.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,19 +269,41 @@ void xen_reboot(int reason)
269269
BUG();
270270
}
271271

272+
static int reboot_reason = SHUTDOWN_reboot;
273+
static bool xen_legacy_crash;
272274
void xen_emergency_restart(void)
273275
{
274-
xen_reboot(SHUTDOWN_reboot);
276+
xen_reboot(reboot_reason);
275277
}
276278

277279
static int
278280
xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
279281
{
280-
if (!kexec_crash_loaded())
281-
xen_reboot(SHUTDOWN_crash);
282+
if (!kexec_crash_loaded()) {
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+
}
282297
return NOTIFY_DONE;
283298
}
284299

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+
285307
static struct notifier_block xen_panic_block = {
286308
.notifier_call = xen_panic_event,
287309
.priority = INT_MIN

0 commit comments

Comments
 (0)