我正在使用自制的VMM测试英特尔VMX,并在调用'vmlaunch'时点击“无效的访客状态”。
只有在向VM注入外部中断后重新运行VM时才会发生此错误
VMM启动VM如下,
1.拨打VMXON,
2.初始化VMXON / VMCS区域,
3.启动VM(从实模式到保护模式)
4. vm退出,
5.调用VMXOFF,并销毁VMXON / VMCS区域。
以下是外部中断处理程序
isr_common_stub:
## 1. Save CPU state
pusha ## Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
mov %ds, %eax ## Lower 16-bits of eax = ds.
push %eax ## save the data segment descriptor
mov $0x10, %eax ## kernel data segment descriptor
mov %eax, %ds
mov %eax, %es
mov %eax, %fs
mov %eax, %gs
## 2. Call C handler
call isr_handler
## 3. Restore state
pop %eax
mov %eax, %ds
mov %eax, %es
mov %eax, %fs
mov %eax, %gs
popa
add $8, %esp ## Cleans up the pushed error code and pushed ISR number
sti
iret ## pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
isr100:
cli
push $0
push $100
jmp isr_common_stub
isr_common_stub:
## 1. Save CPU state
pusha ## Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
mov %ds, %eax ## Lower 16-bits of eax = ds.
push %eax ## save the data segment descriptor
mov $0x10, %eax ## kernel data segment descriptor
mov %eax, %ds
mov %eax, %es
mov %eax, %fs
mov %eax, %gs
## 2. Call C handler
call isr_handler
## 3. Restore state
pop %eax
mov %eax, %ds
mov %eax, %es
mov %eax, %fs
mov %eax, %gs
popa
add $8, %esp ## Cleans up the pushed error code and pushed ISR number
sti
iret ## pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
isr100:
cli
push $0
push $100
jmp isr_common_stub
这是遇到无效访客状态错误时的VMCS转储。
[86429.875904] # GUEST_ES_SEL = 0x0
[86429.875905] # GUEST_CS_SEL = 0x0
[86429.875905] # GUEST_SS_SEL = 0x0
[86429.875906] # GUEST_DS_SEL = 0x0
[86429.875907] # GUEST_FS_SEL = 0x0
[86429.875907] # GUEST_GS_SEL = 0x0
[86429.875908] # GUEST_LDTR_SEL = 0x0
[86429.875908] # GUEST_TR_SEL = 0x0
[86429.875909] # GUEST_INTERRUPT_STATUS = 0x0
[86429.876003] # GUEST_PHYSICAL_ADDR_FULL = 0x0
[86429.876004] # GUEST_PHYSICAL_ADDR_HIGH = 0x0
[86429.876006] # VMCS_LINK_PTR_FULL = 0xffffffffffffffff
[86429.876007] # VMCS_LINK_PTR_HIGH = 0xffffffff
[86429.876009] # GUEST_IA32_DEBUGCTL_FULL = 0x0
[86429.876010] # GUEST_IA32_DEBUGCTL_HIGH = 0x0
[86429.876012] # GUEST_IA32_PAT_FULL = 0x0
[86429.876013] # GUEST_IA32_PAT_HIGH = 0x0
[86429.876015] # GUEST_IA32_EFER_FULL = 0x0
[86429.876017] # GUEST_IA32_EFER_HIGH = 0x0
[86429.876018] # GUEST_IA32_PERF_CTL_FULL = 0x0
[86429.876020] # GUEST_IA32_PERF_CTL_HIGH = 0x0
[86429.876020] # GUEST_PDPTE0_FULL = 0x0
[86429.876021] # GUEST_PDPTE0_HIGH = 0x0
[86429.876022] # GUEST_PDPTE1_FULL = 0x0
[86429.876022] # GUEST_PDPTE1_HIGH = 0x0
[86429.876023] # GUEST_PDPTE2_FULL = 0x0
[86429.876024] # GUEST_PDPTE2_HIGH = 0x0
[86429.876025] # GUEST_PDPTE3_FULL = 0x0
[86429.876025] # GUEST_PDPTE3_HIGH = 0x0
[86429.876067] # EXIT_INTERRUPT_INFO = 0x0
[86429.876067] # EXIT_INTERRUPT_ERRCODE = 0x0
[86429.876068] # IDT_VECTORING_INFO_FIELD = 0x0
[86429.876069] # IDT_VECTORING_ERRCODE = 0x0
[86429.876069] # EXIT_INSTR_LEN = 0x0
[86429.876070] # INSTR_INFO = 0x0
[86429.876070] # GUEST_ES_LIMIT = 0xffff
[86429.876071] # GUEST_CS_LIMIT = 0xffff
[86429.876072] # GUEST_SS_LIMIT = 0xffff
[86429.876072] # GUEST_DS_LIMIT = 0xffff
[86429.876073] # GUEST_FS_LIMIT = 0xffff
[86429.876074] # GUEST_GS_LIMIT = 0xffff
[86429.876075] # GUEST_LDTR_LIMIT = 0xffff
[86429.876075] # GUEST_TR_LIMIT = 0xffff
[86429.876076] # GUEST_GDTR_LIMIT = 0xffff
[86429.876077] # GUEST_IDTR_LIMIT = 0xffff
[86429.876077] # GUEST_ES_ATTR = 0x93
[86429.876078] # GUEST_CS_ATTR = 0x9b
[86429.876078] # GUEST_SS_ATTR = 0x93
[86429.876079] # GUEST_DS_ATTR = 0x93
[86429.876080] # GUEST_FS_ATTR = 0x93
[86429.876080] # GUEST_GS_ATTR = 0x93
[86429.876081] # GUEST_LDTR_ATTR = 0x82
[86429.876081] # GUEST_TR_ATTR = 0x8b
[86429.876082] # GUEST_INTERRUPTIBILITY_INFO = 0x0
[86429.876084] # GUEST_ACTIVITY_STATE = 0x0
[86429.876085] # GUEST_SMBASE = 0x0
[86429.876086] # GUEST_IA32_SYSENTER_CS = 0x0
[86429.876087] # vmread(0x482E) failed
[86429.876088] # RFLAGS: 0x242
[86429.876088] # GUEST_PREEMTION_TIMER INVALID_VALUE
[86429.876090] # HOST_IA32_SYSENTER_CS = 0x10
[86429.876092] # CR0_MASK = 0xfffffffffffffff0
[86429.876093] # CR4_MASK = 0xfffffffffffff871
[86429.876095] # CR0_READ_SHADOW = 0x60000010
[86429.876096] # CR4_READ_SHADOW = 0x10
[86429.876097] # CR3_TARGET_0 = 0x0
[86429.876099] # CR3_TARGET_1 = 0x23341e000
[86429.876101] # CR3_TARGET_2 = 0x0
[86429.876102] # CR3_TARGET_3 = 0x0
[86429.876103] # EXIT_QUALIFICATION = 0x0
[86429.876104] # IO_RCX = 0x0
[86429.876104] # IO_RSI = 0x0
[86429.876105] # IO_RDI = 0x0
[86429.876105] # IO_RIP = 0x0
[86429.876106] # GUEST_LINEAR_ADDR = 0x0
[86429.876108] # GUEST_CR0 = 0x50032
[86429.876108] # GUEST_CR3 = 0x0
[86429.876109] # GUEST_CR4 = 0x2050
[86429.876110] # GUEST_ES_BASE = 0x0
[86429.876110] # GUEST_CS_BASE = 0x0
[86429.876111] # GUEST_SS_BASE = 0x0
[86429.876111] # GUEST_DS_BASE = 0x0
[86429.876112] # GUEST_FS_BASE = 0x0
[86429.876112] # GUEST_GS_BASE = 0x0
[86429.876113] # GUEST_LDTR_BASE = 0x0
[86429.876114] # GUEST_TR_BASE = 0x0
[86429.876114] # GUEST_GDTR_BASE = 0x0
[86429.876115] # GUEST_IDTR_BASE = 0x0
[86429.876117] # GUEST_DR7 = 0x400
[86429.876118] # GUEST_RSP = 0x7bfa
[86429.876118] # GUEST_RIP = 0x7c00
[86429.876119] # GUEST_RFLAGS = 0x2
[86429.876120] # GUEST_PENDING_DEBUG_EXCEPT = 0x0
[86429.876120] # GUEST_IA32_SYSENTER_ESP = 0x0
[86429.876121] # GUEST_IA32_SYSENTER_EIP = 0x0
重新加载VMM后,VM可以正常运行 但是,如果我重新运行VM,则会遇到同样的错误。