struct
page *vmcs_page, *msr_bitmap_page;
void
*vmcs, *vmcs_phys, *host_stack, *msr_bitmap_phys, *msr_bitmap;
unsigned
short
cs, ds, es, fs, gs, ss, tr, ldtr;
unsigned
int
cr0, cr3, cr4;
VmxPinBasedControls pin_base;
VmxProcessorBasedControls process_base;
VmxSecondaryProcessorBasedControls secondary_process_base;
VmxVmEntryControls entry;
VmxVmExitControls
exit
;
VmxExceptionBitmap exception_bitmap = {0};
vmcs_page = alloc_pages(GFP_KERNEL, 0);
vmcs_phys = (
void
*)page_to_phys(vmcs_page);
vmcs = page_address(vmcs_page);
memset
(vmcs, 0, 0x1000);
*(
char
*)vmcs = 1;
vmx_config.vmcs_region_page = vmcs_page;
asm_vmptrld(vmcs_phys);
cr0 = asm_read_cr0();
cr3 = asm_read_cr3();
cr4 = asm_read_cr4();
asm_vmwrite(GUEST_CR0, cr0);
asm_vmwrite(GUEST_CR3, cr3);
asm_vmwrite(GUEST_CR4, cr4);
asm_vmwrite(CR0_READ_SHADOW, cr0);
asm_vmwrite(CR4_READ_SHADOW, cr4);
asm_vmwrite(GUEST_DR7, 0x400);
es = asm_read_es();
cs = asm_read_cs();
ds = asm_read_ds();
fs = asm_read_fs();
gs = asm_read_gs();
ss = asm_read_ss();
tr = asm_read_tr();
ldtr = asm_read_ldtr();
asm_vmwrite(GUEST_ES_SELECTOR, es);
asm_vmwrite(GUEST_ES_BASE, get_segment_base(es));
asm_vmwrite(GUEST_ES_LIMIT, get_segment_limit(es));
asm_vmwrite(GUEST_ES_AR_BYTES, get_segment_access_rights(es));
printk(KERN_INFO
"[*] es: %#llx %#llx %#llx %#llx\n"
, (__u64)es, (__u64)get_segment_base(es), (__u64)get_segment_limit(es), (__u64)(get_segment_access_rights(es) & 0xffffffff));
asm_vmwrite(GUEST_CS_SELECTOR, cs);
asm_vmwrite(GUEST_CS_BASE, get_segment_base(cs));
asm_vmwrite(GUEST_CS_LIMIT, get_segment_limit(cs));
asm_vmwrite(GUEST_CS_AR_BYTES, get_segment_access_rights(cs));
printk(KERN_INFO
"[*] cs: %#llx %#llx %#llx %#llx\n"
, (__u64)cs, (__u64)get_segment_base(cs), (__u64)get_segment_limit(cs), (__u64)(get_segment_access_rights(cs) & 0xffffffff));
asm_vmwrite(GUEST_DS_SELECTOR, ds);
asm_vmwrite(GUEST_DS_BASE, get_segment_base(ds));
asm_vmwrite(GUEST_DS_LIMIT, get_segment_limit(ds));
asm_vmwrite(GUEST_DS_AR_BYTES, get_segment_access_rights(ds));
printk(KERN_INFO
"[*] ds: %#llx %#llx %#llx %#llx\n"
, (__u64)ds, (__u64)get_segment_base(ds), (__u64)get_segment_limit(ds), (__u64)(get_segment_access_rights(ds) & 0xffffffff));
asm_vmwrite(GUEST_FS_SELECTOR, fs);
asm_vmwrite(GUEST_FS_BASE, asm_rdmsr2(IA32_FS_BASE));
asm_vmwrite(GUEST_FS_LIMIT, get_segment_limit(fs));
asm_vmwrite(GUEST_FS_AR_BYTES, get_segment_access_rights(fs));
printk(KERN_INFO
"[*] fs: %#llx %#llx %#llx %#llx\n"
, (__u64)fs, (__u64)get_segment_base(fs), (__u64)get_segment_limit(fs), (__u64)(get_segment_access_rights(fs) & 0xffffffff));
asm_vmwrite(GUEST_GS_SELECTOR, gs);
asm_vmwrite(GUEST_GS_BASE, asm_rdmsr2(IA32_GS_BASE));
asm_vmwrite(GUEST_GS_LIMIT, get_segment_limit(gs));
asm_vmwrite(GUEST_GS_AR_BYTES, get_segment_access_rights(gs));
printk(KERN_INFO
"[*] gs: %#llx %#llx %#llx %#llx\n"
, (__u64)gs, (__u64)get_segment_base(gs), (__u64)get_segment_limit(gs), (__u64)(get_segment_access_rights(gs) & 0xffffffff));
asm_vmwrite(GUEST_SS_SELECTOR, ss);
asm_vmwrite(GUEST_SS_BASE, get_segment_base(ss));
asm_vmwrite(GUEST_SS_LIMIT, get_segment_limit(ss));
asm_vmwrite(GUEST_SS_AR_BYTES, get_segment_access_rights(ss));
printk(KERN_INFO
"[*] ss: %#llx %#llx %#llx %#llx\n"
, (__u64)ss, (__u64)get_segment_base(ss), (__u64)get_segment_limit(ss), (__u64)(get_segment_access_rights(ss) & 0xffffffff));
asm_vmwrite(GUEST_TR_SELECTOR, tr);
asm_vmwrite(GUEST_TR_BASE, get_segment_base(tr));
asm_vmwrite(GUEST_TR_LIMIT, get_segment_limit(tr));
asm_vmwrite(GUEST_TR_AR_BYTES, get_segment_access_rights(tr));
printk(KERN_INFO
"[*] tr: %#llx %#llx %#llx %#llx\n"
, (__u64)tr, (__u64)get_segment_base(tr), (__u64)get_segment_limit(tr), (__u64)(get_segment_access_rights(tr) & 0xffffffff));
asm_vmwrite(GUEST_LDTR_SELECTOR, ldtr);
asm_vmwrite(GUEST_LDTR_BASE, get_segment_base(ldtr));
asm_vmwrite(GUEST_LDTR_LIMIT, get_segment_limit(ldtr));
asm_vmwrite(GUEST_LDTR_AR_BYTES, get_segment_access_rights(ldtr));
printk(KERN_INFO
"[*] ldtr: %#llx %#llx %#llx %#llx\n"
, (__u64)ldtr, (__u64)get_segment_base(ldtr), (__u64)get_segment_limit(ldtr), (__u64)(get_segment_access_rights(ldtr) & 0xffffffff));
asm_vmwrite(GUEST_GDTR_BASE, (__u64)asm_get_gdtr_base());
asm_vmwrite(GUEST_GDTR_LIMIT, asm_get_gdtr_limit());
printk(KERN_INFO
"[*] gdtr: %#llx %#llx\n"
, (__u64)asm_get_gdtr_base(), (__u64)asm_get_gdtr_limit());
asm_vmwrite(GUEST_IDTR_BASE, (__u64)asm_get_idtr_base());
asm_vmwrite(GUEST_IDTR_LIMIT, asm_get_idtr_limit());
printk(KERN_INFO
"[*] idtr: %#llx %#llx\n"
, (__u64)asm_get_idtr_base(), (__u64)asm_get_idtr_limit());
asm_vmwrite(GUEST_IA32_DEBUGCTL, asm_rdmsr2(IA32_DEBUGCTL));
asm_vmwrite(GUEST_SYSENTER_CS, asm_rdmsr2(IA32_SYSENTER_CS));
asm_vmwrite(GUEST_SYSENTER_ESP, asm_rdmsr2(IA32_SYSENTER_ESP));
asm_vmwrite(GUEST_SYSENTER_EIP, asm_rdmsr2(IA32_SYSENTER_EIP));
asm_vmwrite(GUEST_IA32_EFER, asm_rdmsr2(IA32_EFER));
asm_vmwrite(GUEST_RSP, guest_regs.rsp);
asm_vmwrite(GUEST_RIP, (__u64)&__guest_entry);
asm_vmwrite(GUEST_RFLAGS, guest_regs.rflags);
asm_vmwrite(VMCS_LINK_POINTER, -1);
asm_vmwrite(HOST_CR0, cr0);
asm_vmwrite(HOST_CR3, cr3);
asm_vmwrite(HOST_CR4, cr4);
asm_vmwrite(HOST_ES_SELECTOR, es);
asm_vmwrite(HOST_CS_SELECTOR, cs);
asm_vmwrite(HOST_SS_SELECTOR, ss);
asm_vmwrite(HOST_DS_SELECTOR, ds);
asm_vmwrite(HOST_FS_SELECTOR, fs);
asm_vmwrite(HOST_GS_SELECTOR, gs);
asm_vmwrite(HOST_TR_SELECTOR, tr);
asm_vmwrite(HOST_FS_BASE, asm_rdmsr2(IA32_FS_BASE));
asm_vmwrite(HOST_GS_BASE, asm_rdmsr2(IA32_GS_BASE));
asm_vmwrite(HOST_TR_BASE, get_segment_base(tr));
asm_vmwrite(HOST_GDTR_BASE, (__u64)asm_get_gdtr_base());
asm_vmwrite(HOST_IDTR_BASE, (__u64)asm_get_idtr_base());
asm_vmwrite(HOST_IA32_SYSENTER_CS, asm_rdmsr2(IA32_SYSENTER_CS));
asm_vmwrite(HOST_IA32_SYSENTER_ESP, asm_rdmsr2(IA32_SYSENTER_ESP));
asm_vmwrite(HOST_IA32_SYSENTER_EIP, asm_rdmsr2(IA32_SYSENTER_EIP));
asm_vmwrite(HOST_IA32_EFER, asm_rdmsr2(IA32_EFER));
host_stack = vmalloc(0x2000);
memset
(host_stack, 0, 0x2000);
vmx_config.host_stack = host_stack;
asm_vmwrite(HOST_RSP, (__u64)host_stack + 0x2000);
asm_vmwrite(HOST_RIP, (__u64)&__host_entry);
if
(asm_rdmsr2(IA32_VMX_BASIC) & 0x0080000000000000)
{
pin_base.all = asm_rdmsr2(IA32_VMX_TRUE_PINBASED_CTLS) & 0xffffffff;
process_base.all = asm_rdmsr2(IA32_VMX_TRUE_PROCBASED_CTLS) & 0xffffffff;
entry.all = asm_rdmsr2(IA32_VMX_TRUE_ENTRY_CTLS) & 0xffffffff;
exit
.all = asm_rdmsr2(IA32_VMX_TRUE_EXIT_CTLS) & 0xffffffff;
}
else
{
pin_base.all = asm_rdmsr2(IA32_VMX_PINBASED_CTLS) & 0xffffffff;
process_base.all = asm_rdmsr2(IA32_VMX_PROCBASED_CTLS) & 0xffffffff;
entry.all = asm_rdmsr2(IA32_VMX_ENTRY_CTLS) & 0xffffffff;
exit
.all = asm_rdmsr2(IA32_VMX_EXIT_CTLS) & 0xffffffff;
}
if
(asm_rdmsr2(IA32_VMX_PROCBASED_CTLS) & 0x8000000000000000)
{
printk(KERN_INFO
"[+] 启用Secondary Processor-Based VM-Execution Controls\n"
);
secondary_process_base.all = asm_rdmsr2(IA32_VMX_PROCBASED_CTLS2);
}
process_base.Bits.activate_secondary_control =
true
;
if
(vmx_config.vmcs_controls.enable_msr_bitmap)
{
process_base.Bits.use_msr_bitmaps =
true
;
msr_bitmap_page = alloc_pages(GFP_KERNEL, 0);
msr_bitmap = page_address(msr_bitmap_page);
memset
(msr_bitmap, 0, 0x1000);
msr_bitmap_phys = (
void
*)page_to_phys(msr_bitmap_page);
asm_vmwrite(MSR_BITMAP_ADDRESS, (__u64)msr_bitmap_phys);
vmx_config.msr_bitmap_page = msr_bitmap_page;
}
secondary_process_base.Bits.enable_rdtscp =
true
;
secondary_process_base.Bits.enable_invpcid =
true
;
secondary_process_base.Bits.enable_xsaves_xstors =
true
;
entry.Bits.ia32e_mode_guest =
true
;
entry.Bits.load_ia32_efer =
true
;
entry.Bits.load_debug_controls =
true
;
exit
.Bits.host_address_space_size =
true
;
exit
.Bits.load_ia32_efer =
true
;
exit
.Bits.save_ia32_efer =
true
;
exit
.Bits.acknowledge_interrupt_on_exit =
true
;
exit
.Bits.save_debug_controls =
true
;
asm_vmwrite(PIN_BASED_VM_EXEC_CONTROL, pin_base.all);
asm_vmwrite(CPU_BASED_VM_EXEC_CONTROL, process_base.all);
asm_vmwrite(SECONDARY_VM_EXEC_CONTROL, secondary_process_base.all);
asm_vmwrite(VM_ENTRY_CONTROLS, entry.all);
asm_vmwrite(VM_EXIT_CONTROLS,
exit
.all);