]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
plat/kvm/shutdown.c: If on a `UEFI` system, rely on Runtime Services
authorSergiu Moga <sergiu.moga@protonmail.com>
Mon, 24 Apr 2023 17:53:52 +0000 (20:53 +0300)
committerUnikraft <monkey@unikraft.io>
Fri, 11 Aug 2023 10:47:30 +0000 (10:47 +0000)
Preferably, a UEFI system is also an ACPI system and thus these
functionalities should be implemented through ACPI methods. But for
now, make use of UEFI's Runtime Services for resetting the system,
since they are more reliable than what we have at the moment.

Signed-off-by: Sergiu Moga <sergiu.moga@protonmail.com>
Reviewed-by: Michalis Pappas <michalis@unikraft.io>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #909

plat/kvm/shutdown.c

index 605d2ff7d3414ad4d41b3b8344551fc9a235038e..1f677674c37a8b971432ef0594368f64c6f433c5 100644 (file)
 #include <uk/plat/common/irq.h>
 #include <uk/print.h>
 #include <uk/plat/bootstrap.h>
+#include <kvm/efi.h>
+#include <uk/plat/common/bootinfo.h>
 
 static void cpu_halt(void) __noreturn;
 
-/* TODO: implement CPU reset */
+#ifdef CONFIG_KVM_BOOT_EFI_STUB
+static void uk_efi_rs_reset_system(enum uk_efi_reset_type reset_type)
+{
+       const char reset_data[] = "UK EFI SYSTEM RESET";
+       struct uk_efi_runtime_services *rs;
+       struct ukplat_bootinfo *bi;
+
+       bi = ukplat_bootinfo_get();
+       if (unlikely(!bi || !bi->efi_st))
+               return;
+
+       rs = ((struct uk_efi_sys_tbl *)bi->efi_st)->runtime_services;
+       if (unlikely(!rs))
+               return;
+
+       rs->reset_system(reset_type, UK_EFI_SUCCESS,
+                        sizeof(reset_data), (void *)reset_data);
+}
+#else
+static void uk_efi_rs_reset_system(enum uk_efi_reset_type reset_type __unused)
+{ }
+#endif
+
 void ukplat_terminate(enum ukplat_gstate request)
 {
        uk_pr_info("Unikraft halted\n");
 
+       switch (request) {
+       case UKPLAT_HALT:
+               cpu_halt();
+
+               break;
+       case UKPLAT_RESTART:
+               uk_efi_rs_reset_system(UK_EFI_RESET_COLD);
+
+               break;
+       default:
+               uk_efi_rs_reset_system(UK_EFI_RESET_SHUTDOWN);
+       }
+
        /* Try to make system off */
        system_off(request);