FUCK
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
#include <utsm/vmx.h>
|
||||
#include <utsm/ept.h>
|
||||
#include <utsm/vmm.h>
|
||||
#include <utsm/hypercall.h>
|
||||
#include <utsm/ipc_shm.h>
|
||||
#include <utsm/log.h>
|
||||
#include <utsm/types.h>
|
||||
|
||||
/* VM-Exit 处理器:从 VMCS 读取 exit reason 与 guest 状态,分发处理。
|
||||
*
|
||||
* Phase 1.1:处理 HLT(终止 guest)、EPT violation(动态映射)、异常。
|
||||
* Phase 1.3:增加 VMCALL hypercall 处理(读 guest GPR、分发、写返回值)。
|
||||
*/
|
||||
|
||||
extern void vmx_vmresume_wrapper(void);
|
||||
|
||||
static u64 g_vmexit_count;
|
||||
|
||||
static void log_exit_diagnostics(u64 reason, u64 qualification, u64 rip, u64 len) {
|
||||
log_hex64("[VMEXIT] reason=", reason);
|
||||
log_hex64("[VMEXIT] qual=", qualification);
|
||||
log_hex64("[VMEXIT] rip=", rip);
|
||||
log_hex64("[VMEXIT] ilen=", len);
|
||||
}
|
||||
|
||||
/* 处理 HLT:Phase 1.1 自检场景下表示 guest 完成测试,停止 guest。 */
|
||||
static int handle_hlt(u64 rip, u64 instr_len, int *out_resume) {
|
||||
*out_resume = 0; /* 不 resume,guest 终止 */
|
||||
log_info("[VMEXIT] HLT - guest halted");
|
||||
(void)rip; (void)instr_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 处理 EPT violation:动态映射缺失的 GPA。
|
||||
* Phase 1.1:1:1 映射缺失的页面,权限 RWX。 */
|
||||
static int handle_ept_violation(u64 qualification, int *out_resume) {
|
||||
u64 gpa = vmx_vmcs_read(VMCS_GUEST_PHYSICAL_ADDR);
|
||||
u64 page = gpa & ~(EPT_PAGE_SIZE - 1);
|
||||
log_hex64("[VMEXIT] EPT violation gpa=", gpa);
|
||||
(void)qualification;
|
||||
/* 1:1 映射该页(假设 HPA=GPA) */
|
||||
if (ept_identity_map(page, EPT_PAGE_SIZE, EPT_RWX) != 0) {
|
||||
log_error("[VMEXIT] failed to map EPT page");
|
||||
*out_resume = 0;
|
||||
return -1;
|
||||
}
|
||||
*out_resume = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 处理通用异常:打印诊断信息,终止 guest。 */
|
||||
static int handle_exception(u64 qualification, u64 rip, int *out_resume) {
|
||||
u64 intr_info = vmx_vmcs_read(0x4404); /* VM_EXIT_INTR_INFO */
|
||||
log_hex64("[VMEXIT] exception intr_info=", intr_info);
|
||||
log_hex64("[VMEXIT] exception qual=", qualification);
|
||||
log_hex64("[VMEXIT] exception rip=", rip);
|
||||
*out_resume = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* VM-Exit 主分发器。从 vmx_vm_exit_handler(汇编入口)调用。
|
||||
* 返回 1 表示 vmresume;0 表示终止 guest。 */
|
||||
int vmexit_dispatch(void) {
|
||||
u64 reason = vmx_vmcs_read(VMCS_EXIT_REASON) & 0xFFFF;
|
||||
u64 qualification = vmx_vmcs_read(VMCS_EXIT_QUALIFICATION);
|
||||
u64 rip = vmx_vmcs_read(VMCS_GUEST_RIP);
|
||||
u64 instr_len = vmx_vmcs_read(VMCS_INSTRUCTION_LENGTH);
|
||||
int resume = 0;
|
||||
|
||||
g_vmexit_count++;
|
||||
|
||||
switch (reason) {
|
||||
case EXIT_HLT:
|
||||
handle_hlt(rip, instr_len, &resume);
|
||||
break;
|
||||
case EXIT_EPT_VIOLATION:
|
||||
handle_ept_violation(qualification, &resume);
|
||||
break;
|
||||
case EXIT_EXCEPTION_NMI:
|
||||
handle_exception(qualification, rip, &resume);
|
||||
break;
|
||||
case EXIT_TRIPLE_FAULT:
|
||||
log_error("[VMEXIT] triple fault");
|
||||
resume = 0;
|
||||
break;
|
||||
case EXIT_CPUID:
|
||||
/* 简化:让 guest 通过 CPUID,前进 RIP。Phase 1.2+ 完整模拟。 */
|
||||
log_info("[VMEXIT] CPUID - skip");
|
||||
vmx_vmcs_write(VMCS_GUEST_RIP, rip + instr_len);
|
||||
resume = 1;
|
||||
break;
|
||||
case EXIT_IO_INSTRUCTION:
|
||||
/* 简化:跳过 IO 指令。Phase 1.4 virtio-console 完整处理。 */
|
||||
vmx_vmcs_write(VMCS_GUEST_RIP, rip + instr_len);
|
||||
resume = 1;
|
||||
break;
|
||||
case EXIT_RDMSR:
|
||||
case EXIT_WRMSR:
|
||||
vmx_vmcs_write(VMCS_GUEST_RIP, rip + instr_len);
|
||||
resume = 1;
|
||||
break;
|
||||
case EXIT_VMCALL:
|
||||
/* VMCALL hypercall: read guest GPRs from g_guest_regs (saved by
|
||||
* vmexit_asm.S), dispatch to the hypercall handler, and write
|
||||
* the return value into g_guest_regs.rax. The handler also
|
||||
* advances GUEST_RIP past the VMCALL instruction. */
|
||||
{
|
||||
int hcall_resume = hypercall_handle(
|
||||
g_guest_regs.rax, g_guest_regs.rdi,
|
||||
g_guest_regs.rsi, g_guest_regs.rdx,
|
||||
rip, instr_len);
|
||||
resume = hcall_resume;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
log_exit_diagnostics(reason, qualification, rip, instr_len);
|
||||
resume = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
(void)qualification;
|
||||
return resume;
|
||||
}
|
||||
|
||||
u64 vmexit_get_count(void) { return g_vmexit_count; }
|
||||
Reference in New Issue
Block a user