1
votes

I'm having an issue implementing EPT in a hypervisor I'm developing. I'm receiving error no. 48 (EPT violation. An attempt to access memory with a guest-physical address was disallowed by the configuration of the EPT paging structures) with an EXIT_QUALIFICATION of 0x81 upon doing a VMLAUNCH. I've checked the page allocation logic and made sure GUEST_CR3 = HOST_CR3. I'm not sure why is this happening. I'm running on VMWare on a Linux host.

This is the allocation logic:

EPTP alloc_ept(int initial_pages_count){
    int i;
    EPTP eptp;
    EPT_PML4E *ept_pml4;
    EPT_PDPTE *ept_pdpt;
    EPT_PDE *ept_pd;
    EPT_PTE *ept_pt;
    eptp.value = 0;

    ept_pml4 = kzalloc(4096, GFP_KERNEL | GFP_NOWAIT);
    if(!ept_pml4)
        goto pml4err;
    ept_pdpt = kzalloc(4096, GFP_KERNEL | GFP_NOWAIT);
    if(!ept_pdpt)
        goto pdpterr;
    ept_pd = kzalloc(4096, GFP_KERNEL | GFP_NOWAIT);
    if(!ept_pd)
        goto pderr;
    ept_pt = kzalloc(4096, GFP_KERNEL | GFP_NOWAIT);
    if(!ept_pt)
        goto pterr;

    for(i = 0; i < initial_pages_count; i++){
        ept_pt[i].fields.phys_addr = virt_to_phys(kzalloc(4096, GFP_KERNEL | GFP_NOWAIT)) >> 12;
        ept_pt[i].fields.read_access = 1;
        ept_pt[i].fields.write_access = 1;
        ept_pt[i].fields.execute_access = 1;
        // Read CR0.bit30(CD) to determine cache disable and check if memtype=6 is supported:
        ept_pt[i].fields.ept_memtype = 0;
    }

    ept_pd[0].fields.phys_addr = virt_to_phys(ept_pt) >> 12;
    ept_pd[0].fields.read_access = 1;
    ept_pd[0].fields.write_access = 1;
    ept_pd[0].fields.execute_access = 1;

    ept_pdpt[0].fields.phys_addr = virt_to_phys(ept_pd) >> 12;
    ept_pdpt[0].fields.read_access = 1;
    ept_pdpt[0].fields.write_access = 1;
    ept_pdpt[0].fields.execute_access = 1;

    ept_pml4[0].fields.phys_addr = virt_to_phys(ept_pdpt) >> 12;
    ept_pml4[0].fields.read_access = 1;
    ept_pml4[0].fields.write_access = 1;
    ept_pml4[0].fields.execute_access = 1;

    eptp.fields.pml4_phys_addr = virt_to_phys(ept_pml4) >> 12;
    // Read CR0.bit30(CD) to determine cache disable and check if memtype=6 is supported:
    eptp.fields.memtype = 0;
    eptp.fields.page_walk = 3;
    // TODO: Read IA32_VMX_EPT_VPID_CAP - bit 21 if this is supported:
    eptp.fields.accessed_and_dirty_flags_enabled = 0;
    printk("EPTP PML4 PHYS ADDR: %08llx", eptp.fields.pml4_phys_addr);

    return eptp;

    pterr:
    kfree(ept_pd);
    pderr:
    kfree(ept_pdpt);
    pdpterr:
    kfree(ept_pml4);
    pml4err:
    panic("EPT ALLOC ERROR!");
}

static inline void VMLAUNCH(void){
    uint8_t err;
    __asm__ __volatile__(
        "vmlaunch; setna %[err]"
        : [err]"=rm"(err) 
        : : "cc", "memory"
    );
    dump_vmcs();
    printk(KERN_ERR "VMLAUNCH failure (err %lx)", vmcs_read(VM_INSTRUCTION_ERROR));
    BUG_ON(err);
}

static void setup_vm_code(vmstate *vms){
    int i;
        EPT_PML4E *pml = phys_to_virt(vms->eptp.fields.pml4_phys_addr << 12);
        EPT_PDPTE *pdpt = phys_to_virt(pml->fields.phys_addr << 12);
        EPT_PDE *pd = phys_to_virt(pdpt->fields.phys_addr << 12);
        EPT_PTE *pt = phys_to_virt(pd->fields.phys_addr << 12);

    vms->initial_rip = (unsigned long)phys_to_virt(pt[0].fields.phys_addr << 12);
    for(i = 0; i < 4096; i++){
        // hlt
        *(char*)(vms->initial_rip+i) = 0xf4;
    }
    printk(KERN_INFO "INITIAL_RIP: %016lx", vms->initial_rip);
    printk(KERN_INFO "INITIAL_RIP_PHYS: %016llx", virt_to_phys((unsigned long*)vms->initial_rip));
    // Stack grows down
    vms->initial_rsp = (unsigned long)phys_to_virt(pt[9].fields.phys_addr << 12) + 4095;
}

static void prepare_vmx_cpu(void){
    uint32_t vmcs_revid = 0;
    uint32_t hi = 0;
    vmstate *vms = per_cpu(cpu_vms, smp_processor_id());

    // Populate VMCS revision id in vmxon region
    rdmsr_safe(MSR_IA32_VMX_BASIC, &vmcs_revid, &hi);
    memcpy(vms->vmxon_region, &vmcs_revid, 4);
    memcpy(vms->vmcs_region, &vmcs_revid, 4);

    vms->eptp = alloc_ept(10);
    setup_vm_code(vms);

    vmx_enable();   
}

static void handle_vmexit(void){
    int exit_reason = vmcs_read32(VM_EXIT_REASON);
    int basic_exit_code = exit_reason & 0xffff;
    int exit_qualification = vmcs_read32(EXIT_QUALIFICATION);
    int vm_entry_failure = exit_reason & 0x80000000;
    dump_vmcs();
    panic("VMEXIT WITH CODE %d, VM ENTRY FAILURE: %s, QUAL: %d", basic_exit_code, vm_entry_failure ? "true" : "false", exit_qualification);
    VMRESUME();
    //TODO: switch error reasons
}

static void vmx_setup_vm_controls(void){
    // VM Execution Controls
    vmcs_write(PIN_BASED_VM_EXEC_CONTROL, adjust_msr_control(MSR_IA32_VMX_PINBASED_CTLS, 0));
    vmcs_write(CPU_BASED_VM_EXEC_CONTROL, adjust_msr_control(
        MSR_IA32_VMX_PROCBASED_CTLS, CPU_BASED_HLT_EXITING | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS));
    vmcs_write(SECONDARY_VM_EXEC_CONTROL, adjust_msr_control(
        MSR_IA32_VMX_PROCBASED_CTLS2, CPU_BASED_CTL2_RDTSCP | CPU_BASED_CTL2_ENABLE_INVPCID | CPU_BASED_CTL2_ENABLE_VPID | CPU_BASED_CTL2_ENABLE_XSAVE_XRSTORS | CPU_BASED_CTL2_ENABLE_EPT
    ));

    //vmcs_write64(TSC_OFFSET, 0);  

    vmcs_write(CR0_READ_SHADOW, read_cr0());
    vmcs_write(CR4_READ_SHADOW, __read_cr4());
    vmcs_write(CR0_GUEST_HOST_MASK, ~0ul);
    vmcs_write(CR4_GUEST_HOST_MASK, ~0ul);

    // How many CR3_TARGET_VALUEs are considered without VM exit when MOV CR3, VAL
    vmcs_write(CR3_TARGET_COUNT, 0);

    // VM Entry & Exit Controls
    vmcs_write(VM_EXIT_CONTROLS, adjust_msr_control(MSR_IA32_VMX_EXIT_CTLS, VM_EXIT_IA32E_MODE | VM_EXIT_LOAD_IA32_EFER | VM_EXIT_HOST_ADDR_SPACE_SIZE));
    vmcs_write(VM_ENTRY_CONTROLS, adjust_msr_control(MSR_IA32_VMX_ENTRY_CTLS, VM_ENTRY_IA32E_MODE | VM_ENTRY_LOAD_IA32_EFER));
}

static void vmx_setup_initial_host_state(vmstate *vms){
    struct desc_ptr gdtptr, idt;

    vmcs_write(HOST_CR0, read_cr0());
    vmcs_write(HOST_CR3, __read_cr3());
    vmcs_write(HOST_CR4, __read_cr4());
    vmcs_write(HOST_RSP, (unsigned long)vms->vmm_handle_stack + vms->vmm_handle_stack_size - 1);
    vmcs_write(HOST_RIP, (unsigned long)handle_vmexit);

    /* An explanation of segment selectors: https://medium.com/hungys-blog/linux-kernel-memory-addressing-a0d304283af3 */
    // Segment Selectors
    vmcs_write(HOST_CS_SELECTOR, __KERNEL_CS);
    vmcs_write(HOST_DS_SELECTOR, __KERNEL_DS);
    vmcs_write(HOST_ES_SELECTOR, __KERNEL_DS);
    vmcs_write(HOST_SS_SELECTOR, __KERNEL_DS);
    vmcs_write(HOST_FS_SELECTOR, 0);
    vmcs_write(HOST_GS_SELECTOR, 0);
    vmcs_write(HOST_TR_SELECTOR, GDT_ENTRY_TSS*8);

    // Segment Base Adresses
    vmcs_write(HOST_FS_BASE, native_read_msr(MSR_FS_BASE));
    vmcs_write(HOST_GS_BASE, native_read_msr(MSR_GS_BASE));
    vmcs_write(HOST_TR_BASE, read_tr_base());
    native_store_gdt(&gdtptr);
    vmcs_write(HOST_GDTR_BASE, gdtptr.address);
    store_idt(&idt);
    vmcs_write(HOST_IDTR_BASE, idt.address);

    // MSRs
    vmcs_write(HOST_IA32_SYSENTER_CS, native_read_msr(MSR_IA32_SYSENTER_CS));
    vmcs_write(HOST_IA32_SYSENTER_ESP, native_read_msr(MSR_IA32_SYSENTER_ESP));
    vmcs_write(HOST_IA32_SYSENTER_EIP, native_read_msr(MSR_IA32_SYSENTER_EIP));
    vmcs_write64(HOST_IA32_EFER, native_read_msr(MSR_EFER));
}

static void RIPTEST(void) __attribute__((used));
static void RIPTEST(void){
    __asm__ __volatile__("hlt; hlt; hlt; hlt; hlt; hlt");
}

static void vmx_setup_initial_guest_state(vmstate *vms){
    vmcs_write(GUEST_CR0, read_cr0());
    vmcs_write(GUEST_CR3, __read_cr3());
    vmcs_write(GUEST_CR4, __read_cr4());
    vmcs_write(GUEST_DR7, 0);

    vmcs_write(GUEST_RIP, vms->initial_rip);
    //vmcs_write(GUEST_RIP, (unsigned long)RIPTEST);
    vmcs_write(GUEST_RSP, vms->initial_rsp);
    vmcs_write(GUEST_RFLAGS, 0x2); // Reserved flag

    // Setup selectors
    vmcs_write(GUEST_CS_SELECTOR, 0);
    vmcs_write(GUEST_SS_SELECTOR, 0);
    vmcs_write(GUEST_DS_SELECTOR, 0);
    vmcs_write(GUEST_ES_SELECTOR, 0);
    vmcs_write(GUEST_FS_SELECTOR, 0);
    vmcs_write(GUEST_GS_SELECTOR, 0);
    vmcs_write(GUEST_LDTR_SELECTOR, 0);
    vmcs_write(GUEST_TR_SELECTOR, 0);

    // Setup base addresses
    vmcs_write(GUEST_CS_BASE, 0);
    vmcs_write(GUEST_SS_BASE, 0);
    vmcs_write(GUEST_DS_BASE, 0);
    vmcs_write(GUEST_ES_BASE, 0);
    vmcs_write(GUEST_FS_BASE, native_read_msr(MSR_FS_BASE));
    vmcs_write(GUEST_GS_BASE, native_read_msr(MSR_GS_BASE));
    vmcs_write(GUEST_LDTR_BASE, 0);
    vmcs_write(GUEST_TR_BASE, 0);

    // Setup guest segment limits   
    vmcs_write(GUEST_CS_LIMIT, 0xFFFFFFFF);
    vmcs_write(GUEST_SS_LIMIT, 0xFFFFFFFF);
    vmcs_write(GUEST_DS_LIMIT, 0xFFFFFFFF);
    vmcs_write(GUEST_ES_LIMIT, 0xFFFFFFFF);
    vmcs_write(GUEST_FS_LIMIT, 0xFFFFFFFF);
    vmcs_write(GUEST_GS_LIMIT, 0xFFFFFFFF);
    vmcs_write(GUEST_LDTR_LIMIT, 0);
    vmcs_write(GUEST_TR_LIMIT, 0xFF);

    // Setup guest segment access rights
    // https://www.amd.com/system/files/TechDocs/24593.pdf#G10.910849
    vmcs_write(GUEST_CS_AR_BYTES, 0xA09B);
    vmcs_write(GUEST_SS_AR_BYTES, 0xA093);
    vmcs_write(GUEST_DS_AR_BYTES, 0xA093);
    vmcs_write(GUEST_ES_AR_BYTES, 0xA093);
    vmcs_write(GUEST_FS_AR_BYTES, 0xA093);
    vmcs_write(GUEST_GS_AR_BYTES, 0xA093);
    vmcs_write(GUEST_LDTR_AR_BYTES, 0x0082);
    vmcs_write(GUEST_TR_AR_BYTES, 0x008B);

    // Setup GDTR & IDTR
    vmcs_write(GUEST_GDTR_BASE, 0);
    vmcs_write(GUEST_IDTR_BASE, 0);
    vmcs_write(GUEST_GDTR_LIMIT, 0);
    vmcs_write(GUEST_IDTR_LIMIT, 0);

    vmcs_write(GUEST_IA32_EFER, native_read_msr(MSR_EFER));
    vmcs_write64(GUEST_IA32_DEBUGCTL, 0);

    // Setup sysenter primitives
    vmcs_write(GUEST_SYSENTER_CS, 0);
    vmcs_write(GUEST_SYSENTER_ESP, 0);
    vmcs_write(GUEST_SYSENTER_EIP, 0);
}

static void init_vmcs(vmstate *vms){
    VMPTRLD(vms->vmcs_physical);
    vmx_setup_vm_controls();
    vmx_setup_initial_guest_state(vms);
    vmx_setup_initial_host_state(vms);

    vmcs_write64(VMCS_LINK_POINTER, -1ull);

    //vmcs_write(EXCEPTION_BITMAP, 8192);

    vmcs_write64(EPT_POINTER, vms->eptp.value);
    //vmcs_write(VIRTUAL_PROCESSOR_ID, vms->vpid);
}

int vmx_launch(void){
    int cpu = smp_processor_id();
    vmstate *vms = per_cpu(cpu_vms, smp_processor_id());

    printk(KERN_INFO "Launching VM on CPU %d\n", cpu);
    init_vmcs(vms);
    VMLAUNCH();

    put_cpu();
    return 0;
}

int vmx_setup(void){
    int i = smp_processor_id();
    vmstate* vms;
    printk(KERN_INFO "NUM CPUS: %d\n", num_online_cpus());

    vms = create_vmstate();
    vms->vmxon_region = kmalloc(4096, GFP_KERNEL);
    vms->vmxon_physical = virt_to_phys(vms->vmxon_region);
    vms->vmcs_region = kzalloc(4096, GFP_KERNEL);
    vms->vmcs_physical = virt_to_phys(vms->vmcs_region);
    vms->vmm_handle_stack_size = 4096;
    vms->vmm_handle_stack = kmalloc(vms->vmm_handle_stack_size, GFP_KERNEL);
    vms->vpid = get_free_vpid();
    per_cpu(cpu_vms, i) = vms;


    prepare_vmx_cpu();
    printk(KERN_INFO "CPUS prepared!");

    vms = per_cpu(cpu_vms, i);
    if(vms->vmx_enabled == false) {
        printk(KERN_ALERT "Tearing down after VMXON failed!");
        vmx_teardown();
        return -1;
    }
    return 0;
}

static int __init hyper_init(void) {
    int err;

    get_cpu();
    printk(KERN_INFO "Hyper1 Init!\n");
    if(check_vmx_support()){
        device_cleanup();
        return -1;
    }
    if((err = setup_chrdev())){
        device_cleanup();
        return err;
    }
    if((err = vmx_setup())){
        device_cleanup();
        return err;
    }

    printk(KERN_INFO "Assigned major number %d\n", MAJOR(devt));
    vmx_launch();
    put_cpu();
    return 0;
}

VM log:

[  323.188232] Hyper1 Init!
[  323.189311] NUM CPUS: 2
[  323.192490] EPTP PML4 PHYS ADDR: 0007261e
[  323.192500] INITIAL_RIP: 18446615530478686208
[  323.194087] CPUS prepared!
[  323.195778] Assigned major number 240
[  323.198310] Launching VM on CPU 1
[  323.199330] vmwrite log: reg 4000 value 16
[  323.200639] vmwrite log: reg 4002 value ffffffff8401e1f2
[  323.202297] vmwrite log: reg 401e value a
[  323.203499] vmwrite log: reg 6004 value 80050033
[  323.204836] vmwrite log: reg 6006 value 626e0
[  323.206041] vmwrite log: reg 6000 value ffffffffffffffff
[  323.207529] vmwrite log: reg 6002 value ffffffffffffffff
[  323.209033] vmwrite log: reg 400a value 0
[  323.210121] vmwrite log: reg 400c value 236fff
[  323.211322] vmwrite log: reg 4012 value 93ff
[  323.212541] vmwrite log: reg 6800 value 80050033
[  323.213900] vmwrite log: reg 6802 value 7776e004
[  323.215150] vmwrite log: reg 6804 value 626e0
[  323.216457] vmwrite log: reg 681a value 0
[  323.217565] vmwrite log: reg 681e value ffff8b173262d000
[  323.219124] vmwrite log: reg 681c value ffff8b173260cfff
[  323.220656] vmwrite log: reg 6820 value 2
[  323.221746] vmwrite log: reg 802 value 0
[  323.222811] vmwrite log: reg 804 value 0
[  323.223938] vmwrite log: reg 806 value 0
[  323.225008] vmwrite log: reg 800 value 0
[  323.226082] vmwrite log: reg 808 value 0
[  323.227246] vmwrite log: reg 80a value 0
[  323.228437] vmwrite log: reg 80c value 0
[  323.229551] vmwrite log: reg 80e value 0
[  323.230626] vmwrite log: reg 6808 value 0
[  323.231753] vmwrite log: reg 680a value 0
[  323.232841] vmwrite log: reg 680c value 0
[  323.233925] vmwrite log: reg 6806 value 0
[  323.235037] vmwrite log: reg 680e value 7f624c519540
[  323.236473] vmwrite log: reg 6810 value ffff8b173bc40000
[  323.237903] vmwrite log: reg 6812 value 0
[  323.238988] vmwrite log: reg 6814 value 0
[  323.240129] vmwrite log: reg 4802 value ffffffff
[  323.241375] vmwrite log: reg 4804 value ffffffff
[  323.242619] vmwrite log: reg 4806 value ffffffff
[  323.243905] vmwrite log: reg 4800 value ffffffff
[  323.245150] vmwrite log: reg 4808 value ffffffff
[  323.246417] vmwrite log: reg 480a value ffffffff
[  323.247697] vmwrite log: reg 480c value 0
[  323.248784] vmwrite log: reg 480e value ff
[  323.249901] vmwrite log: reg 4816 value a09b
[  323.251053] vmwrite log: reg 4818 value a093
[  323.252243] vmwrite log: reg 481a value a093
[  323.253439] vmwrite log: reg 4814 value a093
[  323.254594] vmwrite log: reg 481c value a093
[  323.255822] vmwrite log: reg 481e value a093
[  323.256978] vmwrite log: reg 4820 value 82
[  323.258142] vmwrite log: reg 4822 value 8b
[  323.259238] vmwrite log: reg 6816 value 0
[  323.260350] vmwrite log: reg 6818 value 0
[  323.261421] vmwrite log: reg 4810 value 0
[  323.262489] vmwrite log: reg 4812 value 0
[  323.263762] vmwrite log: reg 2806 value d01
[  323.264960] vmwrite log: reg 2802 value 0
[  323.266068] vmwrite log: reg 482a value 0
[  323.267136] vmwrite log: reg 6824 value 0
[  323.268257] vmwrite log: reg 6826 value 0
[  323.269379] vmwrite log: reg 6c00 value 80050033
[  323.270601] vmwrite log: reg 6c02 value 7776e004
[  323.271879] vmwrite log: reg 6c04 value 626e0
[  323.273037] vmwrite log: reg 6c14 value ffff8b1732619fff
[  323.274435] vmwrite log: reg 6c16 value ffffffffc07154f0
[  323.275870] vmwrite log: reg c02 value 10
[  323.277134] vmwrite log: reg c06 value 18
[  323.278262] vmwrite log: reg c00 value 18
[  323.279443] vmwrite log: reg c04 value 18
[  323.280625] vmwrite log: reg c08 value 0
[  323.282006] vmwrite log: reg c0a value 0
[  323.283281] vmwrite log: reg c0c value 40
[  323.284409] vmwrite log: reg 6c06 value 7f624c519540
[  323.285794] vmwrite log: reg 6c08 value ffff8b173bc40000
[  323.287244] vmwrite log: reg 6c0a value 0
[  323.288367] vmwrite log: reg 6c0c value fffffe000002c000
[  323.289770] vmwrite log: reg 6c0e value fffffe0000000000
[  323.291169] vmwrite log: reg 4c00 value 10
[  323.292295] vmwrite log: reg 6c10 value fffffe000002d200
[  323.293696] vmwrite log: reg 6c12 value ffffffff860015f0
[  323.295124] vmwrite log: reg 2c02 value d01
[  323.296309] vmwrite log: reg 2800 value ffffffffffffffff
[  323.297711] vmwrite log: reg 201a value 7261e018
[  323.299105] *** Guest State ***
[  323.300022] CR0: actual=0x0000000080050033, shadow=0x0000000080050033, gh_mask=ffffffffffffffff
[  323.302373] CR4: actual=0x00000000000626e0, shadow=0x00000000000626e0, gh_mask=ffffffffffffffff
[  323.304697] CR3 = 0x000000007776e004
[  323.305687] PDPTR0 = 0x0000000000000000  PDPTR1 = 0x0000000000000000
[  323.307411] PDPTR2 = 0x0000000000000000  PDPTR3 = 0x0000000000000000
[  323.309117] RSP = 0xffff8b173260cfff  RIP = 0xffff8b173262d000
[  323.310683] RFLAGS=0x00010002         DR7 = 0x0000000000000400
[  323.312270] Sysenter RSP=0000000000000000 CS:RIP=0000:0000000000000000
[  323.314044] CS:   sel=0x0000, attr=0x0a09b, limit=0xffffffff, base=0x0000000000000000
[  323.316257] DS:   sel=0x0000, attr=0x0a093, limit=0xffffffff, base=0x0000000000000000
[  323.318371] SS:   sel=0x0000, attr=0x0a093, limit=0xffffffff, base=0x0000000000000000
[  323.320506] ES:   sel=0x0000, attr=0x0a093, limit=0xffffffff, base=0x0000000000000000
[  323.322580] FS:   sel=0x0000, attr=0x0a093, limit=0xffffffff, base=0x00007f624c519540
[  323.324678] GS:   sel=0x0000, attr=0x0a093, limit=0xffffffff, base=0xffff8b173bc40000
[  323.326774] GDTR:                           limit=0x00000000, base=0x0000000000000000
[  323.328880] LDTR: sel=0x0000, attr=0x00082, limit=0x00000000, base=0x0000000000000000
[  323.330982] IDTR:                           limit=0x00000000, base=0x0000000000000000
[  323.333073] TR:   sel=0x0000, attr=0x0008b, limit=0x000000ff, base=0x0000000000000000
[  323.335153] EFER =     0x0000000000000d01  PAT = 0x0000000000000000
[  323.337001] DebugCtl = 0x0000000000000000  DebugExceptions = 0x0000000000000000
[  323.338947] PerfGlobCtl = 0x0000000000000000
[  323.340114] vmread err: reg 2812 value 0
[  323.341171] BndCfgS = 0x0000000000000000
[  323.342235] Interruptibility = 00000000  ActivityState = 00000000
[  323.343874] vmread err: reg 810 value 0
[  323.344910] InterruptStatus = 0000
[  323.345840] *** Host State ***
[  323.346699] RIP = 0xffffffffc07154f0  RSP = 0xffff8b1732619fff
[  323.348287] CS=0010 SS=0018 DS=0018 ES=0018 FS=0000 GS=0000 TR=0040
[  323.349965] FSBase=00007f624c519540 GSBase=ffff8b173bc40000 TRBase=0000000000000000
[  323.352014] GDTBase=fffffe000002c000 IDTBase=fffffe0000000000
[  323.353586] CR0=0000000080050033 CR3=000000007776e004 CR4=00000000000626e0
[  323.355468] Sysenter RSP=fffffe000002d200 CS:RIP=0010:ffffffff860015f0
[  323.357231] EFER = 0x0000000000000d01  PAT = 0x0000000000000000
[  323.358815] PerfGlobCtl = 0x0000000000000000
[  323.359976] *** Control State ***
[  323.360877] PinBased=00000016 CPUBased=8401e1f2 SecondaryExec=0000000a
[  323.362632] EntryControls=000093ff ExitControls=00236fff
[  323.364073] ExceptionBitmap=00000000 PFECmask=00000000 PFECmatch=00000000
[  323.366003] VMEntry: intr_info=00000000 errcode=00000000 ilen=00000000
[  323.367768] VMExit: intr_info=00000000 errcode=00000000 ilen=00000003
[  323.369521]         reason=00000030 qualification=0000000000000081
[  323.371177] IDTVectoring: info=00000000 errcode=00000000
[  323.372614] TSC Offset = 0x0000000000000000
[  323.373742] vmread err: reg 810 value 810
[  323.374822] SVI|RVI = 08|10 TPR Threshold = 0x00
[  323.376079] vmread err: reg 2014 value 0
[  323.377276] APIC-access addr = 0x0000000000000000 virt-APIC addr = 0x0000000000000000
[  323.379498] vmread err: reg 2 value 0
[  323.380501] PostedIntrVec = 0x00
[  323.381383] EPT pointer = 0x000000007261e018
[  323.382534] Virtual processor ID = 0x0000
[  323.383629] Kernel panic - not syncing: VMEXIT WITH CODE 48, VM ENTRY FAILURE: false, QUAL: 129

Any help would be appreciated, thanks!

1

1 Answers

1
votes

It looks like it is only mapping 10 pages (40 KB) in the EPT, but GUEST CR3 is 7776e0000, which is not mapped.

If you want to only map a small amount of memory into the guest, then all the guest structures need to be located within that guest physical address range.