[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Xen-devel] intercept and capture fast system call of linux
hi all,I want to intercept and capture fast system call of linux. (1)I set GUEST_SYSENTER_EIP to 0xDDDDD0AE in vmx_vmexit_handler, and save the real value.
in vmx_vmexit_handler() { .... //yandong if( is_hvm_domain(current->domain) ) { //printk("MITCTL:is_hvm_domain\n"); switch (current->domain->arch.hvm_domain.mitctl_op.xen_vmexit_handler_mitctl_method) { case -1: break; case XEN_VMEXIT_HANDLER_MITCTL_libvmi : { //printk("MITCTL:vmexit set_trap\n"); vmx_properly_set_trap_flag(current->domain); break; } default: break;
} } return ... }
inline void vmx_properly_set_trap_flag(struct domain *d) { //set sysenter_eip if(d->arch.hvm_domain.mitctl_op.xen_vmexit_handler_mitctl_method != -1) { vmx_set_sysenter_msrs(d); //current->arch.hvm_vmx.exec_control |= CPU_BASED_MONITOR_TRAP_FLAG; //vmx_update_cpu_exec_control(current); //current->arch.hvm_vcpu.single_step = 1; } return; }
/* force user supplied msr values on this guest */ inline void vmx_set_sysenter_msrs(struct domain *d) { u64 new_cs; u64 new_eip; u64 old_MSR_EIP = __vmread(GUEST_SYSENTER_EIP); u64 old_MSR_CS = __vmread(GUEST_SYSENTER_CS); if( 0xDDDDD0AE != old_MSR_EIP) { printk("MITCTL:old_MSR_EIP %lx\n",old_MSR_EIP); ether_set_imaginary_sysenter_eip(d, old_MSR_EIP); ether_set_imaginary_sysenter_cs(d, old_MSR_CS); } printk("MITCTL:vmx_set_sysenter_msrs GUEST_SYSENTER_EIP %lx %lx\n",old_MSR_EIP, old_MSR_CS); /* write MSR registers */
/* default to writing old(imaginary) values to guest */ new_cs = ether_get_imaginary_sysenter_cs(d); new_eip = ether_get_imaginary_sysenter_eip(d);
if(d->arch.hvm_domain.mitctl_op.xen_vmexit_handler_mitctl_method != -1) { /* it seems that we should write user supplied * values instead */ u64 forced_cs; u64 forced_eip; /* writing user supplied forced values to guest */ forced_cs = ether_get_sysenter_cs(d); forced_eip = ether_get_sysenter_eip(d);
if(forced_cs) new_cs = forced_cs;
if(forced_eip) new_eip = forced_eip; }
vmx_write_sysenter_msr(GUEST_SYSENTER_CS, new_cs); vmx_write_sysenter_msr(GUEST_SYSENTER_EIP, new_eip); }
(2)When a fast syscall come, I will caputue it in sh_page_fault.
(3) Then I set the real GUEST_SYSENTER_EIP(c0103ef0, ia32_sysenter_target) to GUEST_RIP. static int sh_page_fault(struct vcpu *v, unsigned long va, struct cpu_user_regs *regs) { ...
/*yandong*/ /* Check if this page fault occurs on our magic address */ if(unlikely(ether_get_sysenter_eip(d) != 0 && ether_get_sysenter_eip(d) == va)) { /* only go through * with the fault notification if it occurred during * an instruction fetch. */ if ( regs->error_code & PFEC_insn_fetch ) { unsigned long real_rip = ether_get_imaginary_sysenter_eip(d);
/* process system call notification */ shadow_lock(d); ether_handle_syscall(v, regs); shadow_unlock(d);
/* lets update rip to put us in a much happier * place in memory, notably the actual * sysenter handling address */ printk("MITCTL: sh_page_fault syscall real_rip %lx %lx\n", va, ether_get_sysenter_eip(d)); printk("MITCTL: sh_page_fault syscall real_rip %lx\n", __vmread(GUEST_RIP)); //printk("MITCTL: sh_page_fault syscall %lx %lx %lx %lx\n"); __vmwrite(GUEST_RIP, real_rip); printk("MITCTL: sh_page_fault syscall real_rip %lx\n", __vmread(GUEST_RIP)); return 1; } } ... }
But, I encounter Infinite loops as below. I always capture the same syscall. In sh_page_fault, I have successfully set c0103ef0 to GUEST_RIP.But I still capure a page fault , the GUEST_RIP is ddddd0ae. why? Thank you very much.
(XEN) MIT SYSCALL 7 (XEN) MITCTL: sh_page_fault syscall real_rip ddddd0ae ddddd0ae (XEN) MITCTL: sh_page_fault syscall real_rip ddddd0ae (XEN) MITCTL: sh_page_fault syscall real_rip c0103ef0 (XEN) MITCTL:vmx_set_sysenter_msrs GUEST_SYSENTER_EIP ddddd0ae 60 (XEN) vmx_vmenter_helper MITCTL: sh_page_fault syscall real_rip c0103ef0 (XEN) TRAP_page_fault (XEN) MIT SYSCALL 7 (XEN) MITCTL: sh_page_fault syscall real_rip ddddd0ae ddddd0ae (XEN) MITCTL: sh_page_fault syscall real_rip ddddd0ae (XEN) MITCTL: sh_page_fault syscall real_rip c0103ef0 (XEN) MITCTL:vmx_set_sysenter_msrs GUEST_SYSENTER_EIP ddddd0ae 60 (XEN) vmx_vmenter_helper MITCTL: sh_page_fault syscall real_rip c0103ef0 (XEN) TRAP_page_fault (XEN) MIT SYSCALL 7
Best Regards
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|