Skip to content

Commit

Permalink
plat/*: Signal shutdown cause on QEMU
Browse files Browse the repository at this point in the history
This uses the `isa-debug-exit` device to pass an exit code to QEMU. By
default this device is not available but can be enabled using the
`-device isa-debug-exit` switch on the QEMU command-line.

Github-Fixes: unikraft#1018
Signed-off-by: Marco Schlumpp <marco@unikraft.io>
  • Loading branch information
mschlumpp committed Aug 3, 2023
1 parent d21fb22 commit 7594d1a
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 10 deletions.
2 changes: 1 addition & 1 deletion plat/common/arm/cpu_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ void reset(void)
}

/* Systems support PSCI >= 0.2 can do system off from PSCI */
void system_off(void)
void system_off(enum ukplat_gstate request __unused)
{
struct smccc_args smccc_arguments = {0};

Expand Down
3 changes: 2 additions & 1 deletion plat/common/include/arm/arm64/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#include <inttypes.h>
#include <uk/essentials.h>
#include <uk/plat/bootstrap.h>
#include <uk/alloc.h>
#include <uk/assert.h>
#include <arm/smccc.h>
Expand All @@ -57,7 +58,7 @@ extern smccc_conduit_fn_t smccc_psci_call;
/* CPU native APIs */
void halt(void);
void reset(void);
void system_off(void);
void system_off(enum ukplat_gstate request);
#ifdef CONFIG_HAVE_SMP
int cpu_on(__lcpuid id, __paddr_t entry, void *arg);
#endif /* CONFIG_HAVE_SMP */
Expand Down
2 changes: 1 addition & 1 deletion plat/common/include/x86/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
#include <string.h>

void halt(void);
void system_off(void);
void system_off(enum ukplat_gstate request);

static inline void cpuid(__u32 fn, __u32 subfn,
__u32 *eax, __u32 *ebx,
Expand Down
32 changes: 27 additions & 5 deletions plat/common/x86/cpu_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,18 @@ unsigned long read_cr2(void)
return cr2;
}

void system_off(void)
#ifdef CONFIG_KVM_VMM_QEMU
/**
* Trigger an exit() in QEMU with the code `value << 1 | 1`.
* @param value the value used in the calculation of the exit code
*/
static void qemu_debug_exit(int value)
{
outw(0x501, value);
}
#endif /* CONFIG_KVM_VMM_QEMU */

void system_off(enum ukplat_gstate request __maybe_unused)
{
#ifdef CONFIG_KVM_VMM_FIRECRACKER
/* Trigger the reset line via the PS/2 controller. On firecracker
Expand All @@ -55,6 +66,17 @@ void system_off(void)
outb(0x64, 0xFE);
#endif /* CONFIG_KVM_VMM_FIRECRACKER */

#ifdef CONFIG_KVM_VMM_QEMU
/* If we are crashing then try to exit QEMU with the isa-debug-exit
* device.
* Should be harmless if it is not present. This is used to enable
* automated tests on virtio. Note that the actual QEMU exit() status
* will be 85 ('S', 42 << 1 | 1).
*/
if (request == UKPLAT_CRASH)
qemu_debug_exit(42);
#endif /* CONFIG_KVM_VMM_QEMU */

/*
* Perform an ACPI shutdown by writing (SLP_TYPa | SLP_EN) to PM1a_CNT.
* Generally speaking, we'd have to jump through a lot of hoops to
Expand All @@ -64,11 +86,11 @@ void system_off(void)
*/
outw(0x604, 0x2000);

#ifdef CONFIG_KVM_VMM_QEMU
/*
* If that didn't work for whatever reason, try poking the QEMU
* "isa-debug-exit" device to "shutdown". Should be harmless if it is
* not present. This is used to enable automated tests on virtio. Note
* that the actual QEMU exit() status will be 83 ('S', 41 << 1 | 1).
* "isa-debug-exit" device to "shutdown".
*/
outw(0x501, 41);
qemu_debug_exit(41);
#endif /* CONFIG_KVM_VMM_QEMU */
}
4 changes: 2 additions & 2 deletions plat/kvm/shutdown.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@
static void cpu_halt(void) __noreturn;

/* TODO: implement CPU reset */
void ukplat_terminate(enum ukplat_gstate request __unused)
void ukplat_terminate(enum ukplat_gstate request)
{
uk_pr_info("Unikraft halted\n");

/* Try to make system off */
system_off();
system_off(request);

/*
* If we got here, there is no way to initiate "shutdown" on virtio
Expand Down

0 comments on commit 7594d1a

Please sign in to comment.