System calls 拦截syscall,但不是sysret,为什么?
我想拦截syscall/sysret, 所以我取消了EFER.SCE, 所以syscall/sysret将被困到Xen中,然后我模拟syscall/sysret。 但是我只看到syscall,没有看到一个sysret,客户机照常运行。 谁能给我一个提示 来宾VM是Xun-4.1.4上运行的xubuntu_14_x64。 代码如下,我只做了一点修改,有什么问题吗 取消设置EFER.SCE的代码如下System calls 拦截syscall,但不是sysret,为什么?,system-calls,xen,System Calls,Xen,我想拦截syscall/sysret, 所以我取消了EFER.SCE, 所以syscall/sysret将被困到Xen中,然后我模拟syscall/sysret。 但是我只看到syscall,没有看到一个sysret,客户机照常运行。 谁能给我一个提示 来宾VM是Xun-4.1.4上运行的xubuntu_14_x64。 代码如下,我只做了一点修改,有什么问题吗 取消设置EFER.SCE的代码如下 case HVM_MIT_SYSCALL_ring :
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;
}
case TRAP_invalid_op:
{
vmx_vmexit_ud_intercept(regs);
break;
}
要处理的代码如下所示
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;
}
case TRAP_invalid_op:
{
vmx_vmexit_ud_intercept(regs);
break;
}
模拟syscall和sysret的代码如下所示,这是Xen的源代码。我只注释
生成异常ifmsr\u内容&EFER\u SCE==0,EXC\u 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;