我想拦截系统调用/系统调用,
所以我取消了 EFER.SCE ,
所以系统调用/系统调用会陷入Xen,然后我会模拟系统调用/系统调用。
但我只看到系统调用,并没有看到一个系统,客人像往常一样运行。
任何人都能给我一个暗示吗?
来宾VM是在Xen-4.1.4上运行的xubuntu_14_x64 代码如下,我只做了一点修改,什么都错了?
取消设置EFER.SCE的代码如下
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;
}
处理#UP的代码如下
case TRAP_invalid_op:
{
vmx_vmexit_ud_intercept(regs);
break;
}
模拟系统调用和系统调用的代码如下,这是Xen的源代码。我只是注释了 " 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;