Skip to content

Commit baacfdb

Browse files
fyin1NanlinXie
authored andcommitted
hv: Make bsp could start from real mode
S3 resume path for VM0 is put bsp of VM0 to real mode and jump to the wakeup vec of VM0. So we need to extend the init_guest_state to support start from real mode. We apply different CS:IP setting for BSP: - if entry_addr of BSP is larger than 0x100000, it's not wakeup from S3. We assume it's guest start and set CS:IP by hardcode. - if entry_addr of BSP is smaller than 0x100000, it's wakeup from S3. We setup CS:IP according to ACPI spec. Signed-off-by: Victor Sun <victor.sun@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent 0f9d964 commit baacfdb

File tree

1 file changed

+38
-13
lines changed

1 file changed

+38
-13
lines changed

hypervisor/arch/x86/vmx.c

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -525,13 +525,34 @@ static void init_guest_state(struct vcpu *vcpu)
525525
/***************************************************/
526526
if (vcpu_mode == CPU_MODE_REAL) {
527527
if (is_vcpu_bsp(vcpu)) {
528-
ASSERT(!is_vm0(vcpu->vm),
529-
"VM0 bsp should not be inited as realmode");
530-
/* BP is initialized with real mode */
531-
sel = REAL_MODE_BSP_INIT_CODE_SEL;
532-
/* For unrestricted guest, it is able to set a
533-
* high base address */
534-
base = (uint64_t)vcpu->entry_addr & 0xFFFF0000UL;
528+
/* There are two cases that we will start bsp in real
529+
* mode:
530+
* 1. UOS start
531+
* 2. SOS resume from S3
532+
*
533+
* For 1, DM will set correct entry_addr.
534+
* For 2, SOS resume caller will set entry_addr to
535+
* SOS wakeup vec. According to ACPI FACS spec,
536+
* wakeup vec should be < 1MB. So we use < 1MB
537+
* to detect whether it's resume from S3 and we
538+
* setup CS:IP to
539+
* (wakeup_vec >> 4):(wakeup_vec & 0x000F)
540+
* if it's resume from S3.
541+
*
542+
*/
543+
if ((uint64_t)vcpu->entry_addr < 0x100000) {
544+
sel =((uint64_t)vcpu->entry_addr & 0xFFFF0)
545+
>> 4;
546+
base = sel << 4;
547+
} else {
548+
/* BSP is initialized with real mode */
549+
sel = REAL_MODE_BSP_INIT_CODE_SEL;
550+
/* For unrestricted guest, it is able
551+
* to set a high base address
552+
*/
553+
base = (uint64_t)vcpu->entry_addr &
554+
0xFFFF0000UL;
555+
}
535556
} else {
536557
/* AP is initialized with real mode
537558
* and CS value is left shift 8 bits from sipi vector;
@@ -578,12 +599,16 @@ static void init_guest_state(struct vcpu *vcpu)
578599
/***************************************************/
579600
/* Set up guest instruction pointer */
580601
field = VMX_GUEST_RIP;
581-
if (vcpu_mode == CPU_MODE_REAL)
582-
if (is_vcpu_bsp(vcpu))
583-
value32 = 0x0000FFF0;
584-
else
585-
value32 = 0;
586-
else
602+
value32 = 0;
603+
if (vcpu_mode == CPU_MODE_REAL) {
604+
/* RIP is set here */
605+
if (is_vcpu_bsp(vcpu)) {
606+
if ((uint64_t)vcpu->entry_addr < 0x100000)
607+
value32 = (uint64_t)vcpu->entry_addr & 0x0F;
608+
else
609+
value32 = 0x0000FFF0;
610+
}
611+
} else
587612
value32 = (uint32_t)((uint64_t)vcpu->entry_addr);
588613

589614
pr_dbg("GUEST RIP on VMEntry %x ", value32);

0 commit comments

Comments
 (0)