学习和研究中前行,并在分享中提升自己

欢迎订阅阿里内推邮件



虚拟化环境中的hypercall介绍

阅读次数: 432| 时间:2017年12月22日 22:18 | 标签:hypercall

虚拟化环境中的hypercall介绍

前言

大家都知道linux环境下有个syscall,俗称系统调用。他通常用在用户态调用内核态的一些函数的场景,当用户态进程使用ioctl调用内核函数时,进程这时就会从用户态陷入到内核态,这种场景就会发生context switch. 而hypercall主要用在虚拟化场景,而当guest使用hypercall时就会产生VM-Exit,也即从vmx non-root状态退出到vmx root 状态。

kvm环境x86平台那些hypercall

  • KVM_HC_KICK_CPU:主要是用来唤醒HLT状态的vcpu
  • KVM_HC_CLOCK_PAIRING:主要用来guest和Host之间同步时钟
  • KVM_HC_VAPIC_POLL_IRQ: 主要触发vm-Exit,从而让VM处理pending状态的IRQ

目前,x86平台主要提供了这三个hypercall,因为hypercall 会导致vm-exit,所以过多调用会影响VM性能。

host vmx 对hypercall处理

上面已经说过,使用hypercall会导致vm-exit,那么vmx 里面肯定有相应的vm exit handle,具体处理逻辑如下:

static int handle_vmcall(struct kvm_vcpu *vcpu)
{
        return kvm_emulate_hypercall(vcpu);
}

截取 kvm_emulate_hypercall代码片断如下

  switch (nr) {
        case KVM_HC_VAPIC_POLL_IRQ:
                ret = 0;
                break;
        case KVM_HC_KICK_CPU:
                kvm_pv_kick_cpu_op(vcpu->kvm, a0, a1);
                ret = 0;
                break;
#ifdef CONFIG_X86_64
        case KVM_HC_CLOCK_PAIRING:
                ret = kvm_pv_clock_pairing(vcpu, a0, a1);
                break;
#endif
        default:
                ret = -KVM_ENOSYS;
                break;
        }

实践

想玩玩,其实也很简单。自己可以在guest写个内核模块,然后在host端通过ftrace去看一下是否有调用下来。好吧,就写到这里,祝玩的开心