diff --git a/hypervisor/arch/x86/guest/guest.c b/hypervisor/arch/x86/guest/guest.c index 438cd3967..864e1987a 100644 --- a/hypervisor/arch/x86/guest/guest.c +++ b/hypervisor/arch/x86/guest/guest.c @@ -552,6 +552,7 @@ int prepare_vm0_memmap_and_e820(struct vm *vm) return 0; } +#ifdef CONFIG_START_VM0_BSP_64BIT /******************************************************************* * GUEST initial page table * @@ -680,6 +681,7 @@ uint64_t create_guest_initial_paging(struct vm *vm) return GUEST_INIT_PAGE_TABLE_START; } +#endif /******************************************************************* * GUEST initial GDT table diff --git a/hypervisor/arch/x86/guest/vcpu.c b/hypervisor/arch/x86/guest/vcpu.c index e44e1e216..1f4b20a5f 100644 --- a/hypervisor/arch/x86/guest/vcpu.c +++ b/hypervisor/arch/x86/guest/vcpu.c @@ -7,6 +7,11 @@ #include #include +#ifdef CONFIG_EFI_STUB +#include +extern struct efi_ctx* efi_ctx; +#endif + vm_sw_loader_t vm_sw_loader; /*********************************************************************** @@ -67,14 +72,16 @@ int create_vcpu(int cpu_id, struct vm *vm, struct vcpu **rtn_vcpu_handle) vcpu->pcpu_id, vcpu->vm->attr.id, vcpu->vcpu_id, is_vcpu_bsp(vcpu) ? "PRIMARY" : "SECONDARY"); - /* Is this VCPU a VM BSP, create page hierarchy for this VM */ - if (is_vcpu_bsp(vcpu)) { +#ifdef CONFIG_START_VM0_BSP_64BIT + /* Is this VCPU a VM0 BSP, create page hierarchy for this VM */ + if (is_vcpu_bsp(vcpu) && is_vm0(vcpu->vm)) { /* Set up temporary guest page tables */ vm->arch_vm.guest_init_pml4 = create_guest_initial_paging(vm); pr_info("VM *d VCPU %d CR3: 0x%016llx ", vm->attr.id, vcpu->vcpu_id, vm->arch_vm.guest_init_pml4); } +#endif /* Allocate VMCS region for this VCPU */ vcpu->arch_vcpu.vmcs = alloc_page(); @@ -319,8 +326,24 @@ int prepare_vcpu(struct vm *vm, int pcpu_id) /* Load VM SW */ if (!vm_sw_loader) vm_sw_loader = general_sw_loader; + if (is_vm0(vcpu->vm)) { + vcpu->arch_vcpu.cpu_mode = CPU_MODE_PROTECTED; +#ifdef CONFIG_EFI_STUB + if ((efi_ctx->efer & MSR_IA32_EFER_LMA_BIT) && + (efi_ctx->cs_ar & 0x2000)) + vcpu->arch_vcpu.cpu_mode = CPU_MODE_64BIT; +#elif CONFIG_START_VM0_BSP_64BIT + vcpu->arch_vcpu.cpu_mode = CPU_MODE_64BIT; +#endif + } else { +#ifdef CONFIG_EFI_STUB + /* currently non-vm0 will boot kernel directly */ + vcpu->arch_vcpu.cpu_mode = CPU_MODE_PROTECTED; +#else + vcpu->arch_vcpu.cpu_mode = CPU_MODE_REAL; +#endif + } vm_sw_loader(vm, vcpu); - vcpu->arch_vcpu.cpu_mode = CPU_MODE_64BIT; } else { vcpu->arch_vcpu.cpu_mode = CPU_MODE_REAL; } diff --git a/hypervisor/arch/x86/vmx.c b/hypervisor/arch/x86/vmx.c index 8a01779d8..19ed01ea9 100644 --- a/hypervisor/arch/x86/vmx.c +++ b/hypervisor/arch/x86/vmx.c @@ -657,6 +657,7 @@ static void init_guest_state(struct vcpu *vcpu) limit = 0xffff; } else if (vcpu_mode == CPU_MODE_PROTECTED) { + /* Linear data segment in guest init gdt */ es = ss = ds = fs = gs = 0x18; limit = 0xffffffff; } else if (vcpu_mode == CPU_MODE_64BIT) { diff --git a/hypervisor/common/vm_load.c b/hypervisor/common/vm_load.c index dfa4804bc..c59df9010 100644 --- a/hypervisor/common/vm_load.c +++ b/hypervisor/common/vm_load.c @@ -122,8 +122,10 @@ int general_sw_loader(struct vm *vm, struct vcpu *vcpu) zeropage = (struct zero_page *) vm->sw.kernel_info.kernel_src_addr; kernel_entry_offset = (zeropage->hdr.setup_sects + 1) * 512; - /* 64bit entry is the 512bytes after the start */ - kernel_entry_offset += 512; + if (vcpu->arch_vcpu.cpu_mode == CPU_MODE_64BIT) + /* 64bit entry is the 512bytes after the start */ + kernel_entry_offset += 512; + vm->sw.kernel_info.kernel_entry_addr = (void *)((unsigned long)vm->sw.kernel_info.kernel_load_addr + kernel_entry_offset);