[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] there is no sysret in X86_emulate, why?






> -----原始邮件-----
> 发件人: "Jan Beulich" <JBeulich@xxxxxxxx>
> 发送时间: 2014年10月30日 星期四
> 收件人: "Christoph Egger" <chegger@xxxxxxxxx>, hanyandong <hanyandong@xxxxxxxxx>
> 抄送: xen-devel@xxxxxxxxxxxxx
> 主题: Re: [Xen-devel] there is no sysret in X86_emulate, why?

> >>> On 30.10.14 at 02:46, <hanyandong@xxxxxxxxx> wrote:
> > (1)In x86_emulate(), there are sysenter/sysexit, syscall. But why no sysret?

> Perhaps on the basis that this already when introduced was only
> meant to be usable on 64-bit hypervisors, and 64-bit capable CPUs
> always support SYSRET (whereas the scope of support for the
> other three varies)? Christoph, you added that code years ago - is
> there any other explanation for this?

> > (2)I want to iuntercept syscall/sysret, so I unset the EFER.SCE, so 
> > syscall/sysret will trap into Xen, then I emulate syscall/sysret.
> > But  I only see syscall and did not see one sysret,  the guest run as usual. 
> >  any one can give me an hint?

> Assuming you did everything correctly, this seems odd. But in any
> event I'd suggest confirming such behavior in a native environment
> first.

> Jan
thanks for your reply.
the guest VM is xubuntu_14_x64 running on Xen-4.1.4.
the code is as below , I only did a little modification , anything is wrong? 

the code to unset EFER.SCE is as below

                    case HVM_MIT_SYSCALL_ring :
                    
{
                        
struct vcpu   *v;
                        
for_each_vcpu (d, v)
                        
{
                            v->arch.hvm_vcpu.guest_efer  =  v->arch.hvm_vcpu.guest_efer  &  ~EFER_SCE;
                        
}
                        
break;
                    
}

the code to handle #UP is as below

        case TRAP_invalid_op:
        
{
            
vmx_vmexit_ud_intercept(regs);
            
break;

}



the code to emulate syscall and sysret is as below, this is the source code of Xen. I only annotate the " generate_exception_if((msr_content & EFER_SCE) == 0, EXC_UD, -1);"

    case 0x05: /* syscall */ {
        
uint64_t msr_content;
        
struct segment_register cs = { 0 }, ss = { 0 };
        
int rc;
        
printk("emulate syscall");

        
generate_exception_if(in_realmode(ctxt, ops), EXC_UD, -1);
        
generate_exception_if(!in_protmode(ctxt, ops), EXC_UD, -1);

        
/* Inject #UD if syscall/sysret are disabled. */
        
fail_if(ops->read_msr == NULL);
        
if ( (rc = ops->read_msr(MSR_EFER, &msr_content, ctxt)) != 0 )
            
goto done;
        
//generate_exception_if((msr_content & EFER_SCE) == 0, EXC_UD, -1);

        
if ( (rc = ops->read_msr(MSR_STAR, &msr_content, ctxt)) != 0 )
            
goto done;

        
msr_content >>= 32;
        
cs.sel = (uint16_t)(msr_content & 0xfffc);
        
ss.sel = (uint16_t)(msr_content + 8);

        
cs.base = ss.base = 0; /* flat segment */
        
cs.limit = ss.limit = ~0u;  /* 4GB limit */
        
cs.attr.bytes = 0xc9b; /* G+DB+P+S+Code */
        
ss.attr.bytes = 0xc93; /* G+DB+P+S+Data */

#ifdef __x86_64__
        
rc = in_longmode(ctxt, ops);
        
printk(" in longmode  \n");
        
if ( rc < 0 )
            
goto cannot_emulate;
        
if ( rc )
        
{
            
cs.attr.fields.db = 0;
            
cs.attr.fields.l = 1;

            
_regs.rcx = _regs.rip;
            
_regs.r11 = _regs.eflags & ~EFLG_RF;

            
if ( (rc = ops->read_msr(mode_64bit() ? MSR_LSTAR : MSR_CSTAR,
                                     
&msr_content, ctxt)) != 0 )
                
goto done;
            
_regs.rip = msr_content;

            
if ( (rc = ops->read_msr(MSR_FMASK, &msr_content, ctxt)) != 0 )
                
goto done;
            
_regs.eflags &= ~(msr_content | EFLG_RF);
        
}
        
else
#endif
        
{
            
printk(" not here\n  ");
            
if ( (rc = ops->read_msr(MSR_STAR, &msr_content, ctxt)) != 0 )
                
goto done;

            
_regs.ecx = _regs.eip;
            
_regs.eip = (uint32_t)msr_content;
            
_regs.eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF);
        
}

        
fail_if(ops->write_segment == NULL);
        
if ( (rc = ops->write_segment(x86_seg_cs, &cs, ctxt)) ||
             
(rc = ops->write_segment(x86_seg_ss, &ss, ctxt)) )
            
goto done;

        
break;
    
}
    
    
case 0x06: /* clts */
        
generate_exception_if(!mode_ring0(), EXC_GP, 0);
        
fail_if((ops->read_cr == NULL) || (ops->write_cr == NULL));
        
if ( (rc = ops->read_cr(0, &dst.val, ctxt)) ||
             
(rc = ops->write_cr(0, dst.val&~8, ctxt)) )
            
goto done;
        
break;
        
    
case 0x07: 
        
printk("emulate sysret, \n");
        
break;



> _______________________________________________
> Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
> http://lists.xen.org/xen-devel



--
Best Regards,
yandong




_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.