[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
 
 
    
     |