kvm的vmcall

这几个接口的区别在于参数个数的不用,本质是一样的。挑个参数最多的看下:
static inline long kvm_hypercall4(unsigned int nr, unsigned long p1,unsigned long p2, unsigned long p3, unsigned long p4)
{
    long ret;
    asm volatile(KVM_HYPERCALL
             : "=a"(ret)
             : "a"(nr), "b"(p1), "c"(p2), "d"(p3), "S"(p4)
             : "memory"); return ret;
}将由客户机调用该函数发生vmexit
 
执行asm汇编代码时,首先将 "a"(nr), "b"(p1), "c"(p2), "d"(p3), "S"(p4)输入,当执行KVM_HYPERCALL时,#define KVM_HYPERCALL ".byte 0x0f,0x01,0xc1",表示该指令序列为0F01C1,此时VMM根据vmx.c中的kvm_vmx_exit_handlers中将会调用handle_vmcall,调用kvm_emulate_hypercall进行相应操作,并将结果返回给RAX寄存器,并返回"=a"(ret)。hypercall是同步执行的,如果host中kvm_emulate_hypercall不返回(比如睡眠10秒),那么guest中kvm_hypercall也不会返回,直到host里睡眠结束。
 
如果想要在非根模式下运行的客户机的每一个IO指令都产生VM-Exit,那么可以将Use I/O bitmaps 比特位所在字段设置为0,同时将Unconditional I/O exiting字段设为1即可。这样的话在客户机中运行的每一个IO指令(IN, INS, INSB, etc, etc...)都将导致VM-Exit从而陷入到VMM中。但是如果我们将Use I/O bitmaps字段置1,则Unconditional I/O exiting就无效了。此时在客户机中运行的IO指令是否陷入到VMM中由IO位图(bitmap)来指定:如果IO指令访问的某一端口地址在IO bitmap中对应位为1,则该条指令导致VM-Exit,否则意味着该端口可以被客户机直接所访问而无需VMM的介入。
在vmx_init中,将vmx_io_bitmap_a设置为0xff全1(memset(vmx_io_bitmap_a, 0xff, PAGE_SIZE)),在vmx_vcpu_setup中将vmx_io_bitmap_a读入IO_BITMAP_A(vmcs_write64(IO_BITMAP_A, __pa(vmx_io_bitmap_a))),则将端口地址对应IO bitmap位设为1,执行该指令将导师vm-exit。
 
host对于即将到来的根模式非根模式切换所做的准备,vmx_create_vcpu->vmx_vcpu_setup->vmx_set_constant_host_state
原文地址:https://www.cnblogs.com/scu-cjx/p/6878309.html