All of lore.kernel.org
 help / color / mirror / Atom feed
* there is no sysret in X86_emulate, why?
@ 2014-10-30  1:46 hanyandong
  2014-10-30 10:04 ` Jan Beulich
  0 siblings, 1 reply; 5+ messages in thread
From: hanyandong @ 2014-10-30  1:46 UTC (permalink / raw)
  To: xen-devel


[-- Attachment #1.1: Type: text/plain, Size: 359 bytes --]

hi, all


(1)In x86_emulate(), there are sysenter/sysexit, syscall. But why no sysret?


(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?


--
Best Regards,
yandong



[-- Attachment #1.2: Type: text/html, Size: 620 bytes --]

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: there is no sysret in X86_emulate, why?
  2014-10-30  1:46 there is no sysret in X86_emulate, why? hanyandong
@ 2014-10-30 10:04 ` Jan Beulich
  2014-10-30 10:22   ` Egger, Christoph
  2014-10-30 11:59   ` hanyandong
  0 siblings, 2 replies; 5+ messages in thread
From: Jan Beulich @ 2014-10-30 10:04 UTC (permalink / raw)
  To: Christoph Egger, hanyandong; +Cc: xen-devel

>>> On 30.10.14 at 02:46, <hanyandong@iie.ac.cn> 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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: there is no sysret in X86_emulate, why?
  2014-10-30 10:04 ` Jan Beulich
@ 2014-10-30 10:22   ` Egger, Christoph
  2014-10-31  1:56     ` hanyandong
  2014-10-30 11:59   ` hanyandong
  1 sibling, 1 reply; 5+ messages in thread
From: Egger, Christoph @ 2014-10-30 10:22 UTC (permalink / raw)
  To: Jan Beulich, hanyandong; +Cc: xen-devel

On 2014/10/30 12:04, Jan Beulich wrote:
>>>> On 30.10.14 at 02:46, <hanyandong@iie.ac.cn> 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?

Back at that time I was working on live migration between AMD and Intel
forth and back. The sysenter/sysexit emulation covers the case of
running 32bit binaries in compat mode in a 64bit DomU.
The syscall emulation also covers a case I do not remember anymore.

Christoph

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: there is no sysret in X86_emulate, why?
  2014-10-30 10:04 ` Jan Beulich
  2014-10-30 10:22   ` Egger, Christoph
@ 2014-10-30 11:59   ` hanyandong
  1 sibling, 0 replies; 5+ messages in thread
From: hanyandong @ 2014-10-30 11:59 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Christoph Egger, xen-devel


[-- Attachment #1.1: Type: text/plain, Size: 4838 bytes --]




> -----原始邮件-----
> 发件人: "Jan Beulich" <JBeulich@suse.com>
> 发送时间: 2014年10月30日 星期四
> 收件人: "Christoph Egger" <chegger@amazon.de>, hanyandong <hanyandong@iie.ac.cn>
> 抄送: xen-devel@lists.xen.org
> 主题: Re: [Xen-devel] there is no sysret in X86_emulate, why?
> 
> >>> On 30.10.14 at 02:46, <hanyandong@iie.ac.cn> 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@lists.xen.org
> http://lists.xen.org/xen-devel



--
Best Regards,
yandong




[-- Attachment #1.2: Type: text/html, Size: 37661 bytes --]

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: there is no sysret in X86_emulate, why?
  2014-10-30 10:22   ` Egger, Christoph
@ 2014-10-31  1:56     ` hanyandong
  0 siblings, 0 replies; 5+ messages in thread
From: hanyandong @ 2014-10-31  1:56 UTC (permalink / raw)
  To: Egger, Christoph; +Cc: Jan Beulich, xen-devel


[-- Attachment #1.1: Type: text/plain, Size: 3969 bytes --]




> -----原始邮件-----
> 发件人: "Egger, Christoph" <chegger@amazon.de>
> 发送时间: 2014年10月30日 星期四
> 收件人: "Jan Beulich" <JBeulich@suse.com>, hanyandong <hanyandong@iie.ac.cn>
> 抄送: xen-devel@lists.xen.org
> 主题: Re: [Xen-devel] there is no sysret in X86_emulate, why?
> 
> On 2014/10/30 12:04, Jan Beulich wrote:
> >>>> On 30.10.14 at 02:46, <hanyandong@iie.ac.cn> 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?
> 
> Back at that time I was working on live migration between AMD and Intel
> forth and back. The sysenter/sysexit emulation covers the case of
> running 32bit binaries in compat mode in a 64bit DomU.
> The syscall emulation also covers a case I do not remember anymore.
> 
> Christoph
thank you.
if I want to intercept sysenter/sysexit, what I need pay  attention to?


I set GUEST_SYSENTER_CS to 0x0, then sysenter/sysexit will triggle a #GP, then will trap into Xen.

for_each_vcpu(d,v)
{
vmx_vmcs_enter(v);
d->arch.hvm_domain.mitctl_op.imaginary_sysenter_cs  =  __vmread(GUEST_SYSENTER_CS);
d->arch.hvm_domain.mitctl_op.forced_sysenter_cs = 0x0;
/*setXentotrap #GP */
__vmwrite(EXCEPTION_BITMAP, __vmread(EXCEPTION_BITMAP) | (1U<<TRAP_gp_fault) );
/*load0x0toGUEST_SYSENTER_CS, next sysenter/sysexit will trap into Xen  for #GP*/
__vmwrite(GUEST_SYSENTER_CS, 0x0);
vmx_vmcs_exit(v);
}

In xen, at vmx_vmexit_handler(), I hanlde #GP as below

caseTRAP_gp_fault:
{


__vmwrite(GUEST_SYSENTER_CS, current->domain->arch.hvm_domain.mitctl_op.imaginary_sysenter_cs);
vmx_vmexit_syscall_intercept(regs); 
__vmwrite(GUEST_SYSENTER_CS, 0x0);      
break;

}

/* use Xen code to emulated sysenter/syexit */
static void vmx_vmexit_syscall_intercept(struct cpu_user_regs *regs)
{
    struct hvm_emulate_ctxt ctxt;
    int rc;

    hvm_emulate_prepare(&ctxt, regs);

    rc = hvm_emulate_one(&ctxt);

    switch ( rc )
    {
        case X86EMUL_UNHANDLEABLE:
            printk("X86EMUL_UNHANDLEABLE\n");
            vmx_inject_hw_exception(TRAP_gp_fault, HVM_DELIVER_NO_ERROR_CODE);
            break;
        case X86EMUL_EXCEPTION:
            printk("X86EMUL_EXCEPTION\n");
            if ( ctxt.exn_pending )
                hvm_inject_exception(ctxt.exn_vector, ctxt.exn_error_code, 0);
            /* fall through */
        default:
            printk("default[%d]\n", rc);
            hvm_emulate_writeback(&ctxt);
            break;
    }
}

But after intercept some pairs of sysenter/sysexit, the vm go to crash,

and I got the follow dmesg, what's wrong with it? thank you very much

#sudo xm dmesg 

(XEN) event_channel.c:250:d1 EVTCHNOP failure: error -17
(XEN) event_channel.c:250:d1 EVTCHNOP failure: error -17
(XEN) irq.c:1954: dom1: pirq 55 or emuirq 8 already mapped
(XEN) irq.c:1954: dom1: pirq 55 or emuirq 12 already mapped
(XEN) irq.c:1954: dom1: pirq 55 or emuirq 1 already mapped
(XEN) irq.c:1954: dom1: pirq 55 or emuirq 6 already mapped
(XEN) irq.c:1954: dom1: pirq 55 or emuirq 4 already mapped
(XEN) irq.c:1954: dom1: pirq 55 or emuirq 7 already mapped
(XEN) irq.c:1954: dom1: pirq 55 or emuirq 23 already mapped
(XEN) irq.c:1954: dom1: pirq 55 or emuirq 28 already mapped



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



--
Best Regards,
yandong




[-- Attachment #1.2: Type: text/html, Size: 16192 bytes --]

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-10-31  1:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-30  1:46 there is no sysret in X86_emulate, why? hanyandong
2014-10-30 10:04 ` Jan Beulich
2014-10-30 10:22   ` Egger, Christoph
2014-10-31  1:56     ` hanyandong
2014-10-30 11:59   ` hanyandong

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.