实施 EPT 的问题
Issues implementing EPT
我在开发的管理程序中实施 EPT 时遇到问题。
我收到错误号。 48(EPT 违规。在执行 VMLAUNCH 时,EPT 分页结构 的配置不允许尝试使用访客物理地址访问内存EXIT_QUALIFICATION 0x81 .
我检查了页面分配逻辑并确保 GUEST_CR3 = HOST_CR3。我不确定为什么会这样。我 运行 在 Linux 主机上的 VMWare 上。
这是分配逻辑:
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;
}
虚拟机日志:
[ 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
任何帮助将不胜感激,谢谢!
EPT好像只映射了10页(40KB),但是GUEST CR3是7776e0000,没有映射。
如果只想将少量内存映射到来宾,则所有来宾结构都需要位于该来宾物理地址范围内。
我在开发的管理程序中实施 EPT 时遇到问题。 我收到错误号。 48(EPT 违规。在执行 VMLAUNCH 时,EPT 分页结构 的配置不允许尝试使用访客物理地址访问内存EXIT_QUALIFICATION 0x81 . 我检查了页面分配逻辑并确保 GUEST_CR3 = HOST_CR3。我不确定为什么会这样。我 运行 在 Linux 主机上的 VMWare 上。
这是分配逻辑:
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;
}
虚拟机日志:
[ 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
任何帮助将不胜感激,谢谢!
EPT好像只映射了10页(40KB),但是GUEST CR3是7776e0000,没有映射。
如果只想将少量内存映射到来宾,则所有来宾结构都需要位于该来宾物理地址范围内。