dm: pm: add s3 support for an ovmf-booted User VM
For ovmf-booted User VM, we should set CMOS shutdown status register (index 0xF) as S3_resume(0xFE). So ovmf will read it and start S3 resume at POST entry. And ovmf will read waking vector from FACS table and transfer control to guest. Tracked-On: #8624 Signed-off-by: Haiwei Li <haiwei.li@intel.com>
This commit is contained in:
parent
c42b45e9a3
commit
374ad1c9ed
|
@ -102,6 +102,7 @@ bool vtpm2;
|
||||||
bool is_winvm;
|
bool is_winvm;
|
||||||
bool skip_pci_mem64bar_workaround = false;
|
bool skip_pci_mem64bar_workaround = false;
|
||||||
bool gfx_ui = false;
|
bool gfx_ui = false;
|
||||||
|
bool ovmf_loaded = false;
|
||||||
|
|
||||||
static int guest_ncpus;
|
static int guest_ncpus;
|
||||||
static int virtio_msix = 1;
|
static int virtio_msix = 1;
|
||||||
|
@ -752,6 +753,8 @@ vm_suspend_resume(struct vmctx *ctx)
|
||||||
* 6. hypercall restart vm
|
* 6. hypercall restart vm
|
||||||
*/
|
*/
|
||||||
vm_pause(ctx);
|
vm_pause(ctx);
|
||||||
|
if (ovmf_loaded)
|
||||||
|
vrtc_suspend(ctx);
|
||||||
|
|
||||||
vm_clear_ioreq(ctx);
|
vm_clear_ioreq(ctx);
|
||||||
vm_stop_watchdog(ctx);
|
vm_stop_watchdog(ctx);
|
||||||
|
@ -1016,6 +1019,7 @@ main(int argc, char *argv[])
|
||||||
case CMD_OPT_OVMF:
|
case CMD_OPT_OVMF:
|
||||||
if (!vsbl_file_name && acrn_parse_ovmf(optarg) != 0)
|
if (!vsbl_file_name && acrn_parse_ovmf(optarg) != 0)
|
||||||
errx(EX_USAGE, "invalid ovmf param %s", optarg);
|
errx(EX_USAGE, "invalid ovmf param %s", optarg);
|
||||||
|
ovmf_loaded = true;
|
||||||
skip_pci_mem64bar_workaround = true;
|
skip_pci_mem64bar_workaround = true;
|
||||||
break;
|
break;
|
||||||
case CMD_OPT_IASL:
|
case CMD_OPT_IASL:
|
||||||
|
|
|
@ -297,7 +297,7 @@ acrn_sw_load(struct vmctx *ctx)
|
||||||
{
|
{
|
||||||
if (vsbl_file_name)
|
if (vsbl_file_name)
|
||||||
return acrn_sw_load_vsbl(ctx);
|
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);
|
return acrn_sw_load_ovmf(ctx);
|
||||||
else if (kernel_file_name)
|
else if (kernel_file_name)
|
||||||
return acrn_sw_load_bzimage(ctx);
|
return acrn_sw_load_bzimage(ctx);
|
||||||
|
|
|
@ -1040,6 +1040,17 @@ vrtc_set_time(struct vrtc *vrtc, time_t secs)
|
||||||
return error;
|
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
|
int
|
||||||
vrtc_init(struct vmctx *ctx)
|
vrtc_init(struct vmctx *ctx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,6 +53,7 @@ extern bool pt_tpm2;
|
||||||
extern bool ssram;
|
extern bool ssram;
|
||||||
extern bool vtpm2;
|
extern bool vtpm2;
|
||||||
extern bool is_winvm;
|
extern bool is_winvm;
|
||||||
|
extern bool ovmf_loaded;
|
||||||
|
|
||||||
enum acrn_thread_prio {
|
enum acrn_thread_prio {
|
||||||
PRIO_VCPU = PRIO_MIN,
|
PRIO_VCPU = PRIO_MIN,
|
||||||
|
|
|
@ -43,6 +43,7 @@ struct vrtc;
|
||||||
struct vmctx;
|
struct vmctx;
|
||||||
|
|
||||||
int vrtc_init(struct vmctx *ctx);
|
int vrtc_init(struct vmctx *ctx);
|
||||||
|
void vrtc_suspend(struct vmctx *ctx);
|
||||||
void vrtc_enable_localtime(int l_time);
|
void vrtc_enable_localtime(int l_time);
|
||||||
void vrtc_deinit(struct vmctx *ctx);
|
void vrtc_deinit(struct vmctx *ctx);
|
||||||
int vrtc_set_time(struct vrtc *vrtc, time_t secs);
|
int vrtc_set_time(struct vrtc *vrtc, time_t secs);
|
||||||
|
|
Loading…
Reference in New Issue