dm: pm: add s3 support for an User VM with elf/bzImage

For an elf-loaded or beImage-loaded User VM, acrn-dm is responsible for
handling s3 related matters.

After resume from S3, acrn-dm should read waking_vector and set related
registers to make guest to resume.

Tracked-On: #8536
Signed-off-by: Haiwei Li <haiwei.li@intel.com>
This commit is contained in:
Haiwei Li 2024-06-21 12:50:17 +08:00 committed by acrnsi-robot
parent 374ad1c9ed
commit fbe30d4001
3 changed files with 44 additions and 1 deletions

View File

@ -742,6 +742,7 @@ vm_system_reset(struct vmctx *ctx)
static void static void
vm_suspend_resume(struct vmctx *ctx) vm_suspend_resume(struct vmctx *ctx)
{ {
struct acrn_vcpu_regs bsp_regs;
/* /*
* If we get warm reboot request, we don't want to exit the * If we get warm reboot request, we don't want to exit the
* vcpu_loop/vm_loop/mevent_loop. So we do: * vcpu_loop/vm_loop/mevent_loop. So we do:
@ -764,8 +765,32 @@ vm_suspend_resume(struct vmctx *ctx)
vm_reset_watchdog(ctx); vm_reset_watchdog(ctx);
vm_reset(ctx); vm_reset(ctx);
bsp_regs = ctx->bsp_regs;
/* for bzImage or elf */
if (!ovmf_loaded) {
uint32_t *guest_wakeup_vec32;
/* 64BIT_WAKE_SUPPORTED_F is not set */
guest_wakeup_vec32 = paddr_guest2host(ctx,
get_acpi_wakingvector_offset(),
get_acpi_wakingvector_length());
/* set the BSP waking vector */
bsp_regs.vcpu_regs.cs_sel = (uint16_t)((*guest_wakeup_vec32 >> 4U) & 0xFFFFU);
bsp_regs.vcpu_regs.cs_base = bsp_regs.vcpu_regs.cs_sel << 4U;
/* real mode code segment */
bsp_regs.vcpu_regs.cs_ar = 0x009FU;
bsp_regs.vcpu_regs.cs_limit = 0xFFFFU;
bsp_regs.vcpu_regs.rip = 0x0U;
/* CR0_ET | CR0_NE */
bsp_regs.vcpu_regs.cr0 = 0x30;
/* real mode gdt */
bsp_regs.vcpu_regs.gdt.limit = 0xFFFFU;
bsp_regs.vcpu_regs.gdt.base = 0UL;
/* real mode idt */
bsp_regs.vcpu_regs.idt.limit = 0xFFFFU;
bsp_regs.vcpu_regs.idt.base = 0UL;
}
/* set the BSP init state */ /* set the BSP init state */
vm_set_vcpu_regs(ctx, &ctx->bsp_regs); vm_set_vcpu_regs(ctx, &bsp_regs);
vm_run(ctx); vm_run(ctx);
} }

View File

@ -93,6 +93,10 @@
#define RTCT_OFFSET 0xF00 #define RTCT_OFFSET 0xF00
#define DSDT_OFFSET 0x1100 #define DSDT_OFFSET 0x1100
/* Define the byte offset and byte length in FACS table */
#define WAKING_VECTOR_OFFSET 12
#define WAKING_VECTOR_LEN 4
#define ASL_TEMPLATE "dm.XXXXXXX" #define ASL_TEMPLATE "dm.XXXXXXX"
#define ASL_SUFFIX ".aml" #define ASL_SUFFIX ".aml"
@ -1112,6 +1116,18 @@ get_acpi_table_length(void)
return ACPI_LENGTH; return ACPI_LENGTH;
} }
uint32_t
get_acpi_wakingvector_offset(void)
{
return basl_acpi_base + FACS_OFFSET + WAKING_VECTOR_OFFSET;
}
uint32_t
get_acpi_wakingvector_length(void)
{
return WAKING_VECTOR_LEN;
}
int int
get_default_iasl_compiler(void) get_default_iasl_compiler(void)
{ {

View File

@ -99,6 +99,8 @@ struct acpi_madt_local_apic {
void acpi_table_enable(int num); void acpi_table_enable(int num);
uint32_t get_acpi_base(void); uint32_t get_acpi_base(void);
uint32_t get_acpi_table_length(void); uint32_t get_acpi_table_length(void);
uint32_t get_acpi_wakingvector_offset(void);
uint32_t get_acpi_wakingvector_length(void);
struct vmctx; struct vmctx;