diff --git a/devicemodel/core/main.c b/devicemodel/core/main.c index f52a057c9c..ff650485b8 100644 --- a/devicemodel/core/main.c +++ b/devicemodel/core/main.c @@ -102,6 +102,7 @@ bool vtpm2; bool is_winvm; bool skip_pci_mem64bar_workaround = false; bool gfx_ui = false; +bool ovmf_loaded = false; static int guest_ncpus; static int virtio_msix = 1; @@ -752,6 +753,8 @@ vm_suspend_resume(struct vmctx *ctx) * 6. hypercall restart vm */ vm_pause(ctx); + if (ovmf_loaded) + vrtc_suspend(ctx); vm_clear_ioreq(ctx); vm_stop_watchdog(ctx); @@ -1016,6 +1019,7 @@ main(int argc, char *argv[]) case CMD_OPT_OVMF: if (!vsbl_file_name && acrn_parse_ovmf(optarg) != 0) errx(EX_USAGE, "invalid ovmf param %s", optarg); + ovmf_loaded = true; skip_pci_mem64bar_workaround = true; break; case CMD_OPT_IASL: diff --git a/devicemodel/core/sw_load_common.c b/devicemodel/core/sw_load_common.c index 10c841ac7e..a13a269015 100644 --- a/devicemodel/core/sw_load_common.c +++ b/devicemodel/core/sw_load_common.c @@ -297,7 +297,7 @@ acrn_sw_load(struct vmctx *ctx) { if (vsbl_file_name) return acrn_sw_load_vsbl(ctx); - else if ((ovmf_file_name != NULL) ^ (ovmf_code_file_name && ovmf_vars_file_name)) + else if (ovmf_loaded) return acrn_sw_load_ovmf(ctx); else if (kernel_file_name) return acrn_sw_load_bzimage(ctx); diff --git a/devicemodel/hw/platform/rtc.c b/devicemodel/hw/platform/rtc.c index 3ca75a7e58..d6b5133a33 100644 --- a/devicemodel/hw/platform/rtc.c +++ b/devicemodel/hw/platform/rtc.c @@ -1040,6 +1040,17 @@ vrtc_set_time(struct vrtc *vrtc, time_t secs) return error; } +/* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE) + * BIOS will read it and start S3 resume at POST Entry + */ +void vrtc_suspend(struct vmctx *ctx) +{ + struct vrtc *vrtc = ctx->vrtc; + struct rtcdev *rtc = &vrtc->rtcdev; + + *((uint8_t *)rtc + 0xF) = 0xFE; +} + int vrtc_init(struct vmctx *ctx) { diff --git a/devicemodel/include/dm.h b/devicemodel/include/dm.h index e839e3b76d..a67099c15c 100644 --- a/devicemodel/include/dm.h +++ b/devicemodel/include/dm.h @@ -53,6 +53,7 @@ extern bool pt_tpm2; extern bool ssram; extern bool vtpm2; extern bool is_winvm; +extern bool ovmf_loaded; enum acrn_thread_prio { PRIO_VCPU = PRIO_MIN, diff --git a/devicemodel/include/rtc.h b/devicemodel/include/rtc.h index 2186505171..de56fce6f9 100644 --- a/devicemodel/include/rtc.h +++ b/devicemodel/include/rtc.h @@ -43,6 +43,7 @@ struct vrtc; struct vmctx; int vrtc_init(struct vmctx *ctx); +void vrtc_suspend(struct vmctx *ctx); void vrtc_enable_localtime(int l_time); void vrtc_deinit(struct vmctx *ctx); int vrtc_set_time(struct vrtc *vrtc, time_t secs);