ioctl KVM_RUN在什么情况下返回?

辣椒

https://github.com/qemu/qemu/blob/stable-4.2/cpus.c#L1290中,有一个非常重要的Qemu。我猜这是KVM上CPU的事件循环。

这是代码:

static void *qemu_kvm_cpu_thread_fn(void *arg)
{
    CPUState *cpu = arg;
    int r;

    rcu_register_thread();

    qemu_mutex_lock_iothread();
    qemu_thread_get_self(cpu->thread);
    cpu->thread_id = qemu_get_thread_id();
    cpu->can_do_io = 1;
    current_cpu = cpu;

    r = kvm_init_vcpu(cpu);
    if (r < 0) {
        error_report("kvm_init_vcpu failed: %s", strerror(-r));
        exit(1);
    }

    kvm_init_cpu_signals(cpu);

    /* signal CPU creation */
    cpu->created = true;
    qemu_cond_signal(&qemu_cpu_cond);
    qemu_guest_random_seed_thread_part2(cpu->random_seed);

    do {
        if (cpu_can_run(cpu)) {
            r = kvm_cpu_exec(cpu);
            if (r == EXCP_DEBUG) {
                cpu_handle_guest_debug(cpu);
            }
        }
        qemu_wait_io_event(cpu);
    } while (!cpu->unplug || cpu_can_run(cpu));

    qemu_kvm_destroy_vcpu(cpu);
    cpu->created = false;
    qemu_cond_signal(&qemu_cpu_cond);
    qemu_mutex_unlock_iothread();
    rcu_unregister_thread();
    return NULL;
}

我对do循环感兴趣它调用kvm_cpu_exec一个循环,该循环在这里定义:https : //github.com/qemu/qemu/blob/stable-4.2/accel/kvm/kvm-all.c#L2285

在的一点kvm_cpu_exec,它调用run_ret = kvm_vcpu_ioctl(cpu, KVM_RUN, 0);,它调用KVM_RUN此处记录ioctl:https : //www.kernel.org/doc/Documentation/virtual/kvm/api.txt

4.10 KVM_RUN

功能:基本
体系结构:全部
类型:vcpu ioctl
参数:无
返回值:成功时为0,错误时为-1
错误:
EINTR:未屏蔽的信号正在等待处理

该ioctl用于运行来宾虚拟cpu。虽然没有
显式参数,但可以
通过mmap()将vcpu fd偏移为0获得隐式参数块,其大小由
KVM_GET_VCPU_MMAP_SIZE给出参数块的格式为“ struct
kvm_run”(请参见下文)。

我正在努力了解此ioctl是否会阻止执行?在什么情况下返回?

我想对正在发生的事情有一点了解。给定该行qemu_wait_io_event(cpu),至少在每次要向CPU读取/写入事件时ioctl都会返回。我不知道,我很困惑。

彼得·梅德尔

KVM API设计要求VM中的每个虚拟CPU在诸如QEMU之类的程序中具有关联的用户空间线程,该线程控制着该VM(该程序通常称为“虚拟机监视器”或VMM,并且不必QEMU;其他示例是kvmtool和firecracker。

该线程的行为就像QEMU中的普通用户空间线程一样,直到生成KVM_RUN ioctl为止。此时,内核使用该线程在与该线程关联的vCPU上执行客户代码。这一直持续到遇到某种情况为止,这意味着来宾执行无法继续进行。(一个常见的条件是“来宾对QEMU正在模拟的设备进行内存访问”。)这时,内核停止在该线程上运行来宾代码,而是使其从KVM_RUN ioctl返回。然后,QEMU中的代码查看返回代码,以此类推,以找出为什么获得控制权,处理任何情况,然后循环回以再次调用KVM_RUN以要求内核继续运行来宾代码。

通常,在运行VM时,您几乎会看到线程一直在KVM_RUN ioctl内部运行,并一直在运行真实的来宾代码。有时执行会返回,QEMU将花费尽可能少的时间做任何需要做的事情,然后循环运行并再次运行来宾代码。一种提高VM效率的方法是,尝试确保这些“ VM出口”的数量尽可能少(例如,通过仔细选择来宾所使用的网络或块设备类型)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么ioctl调用未传递给sys_ioctl?

ioctl(),unlocked_ioctl()和compat_ioctl()有什么区别?

在Linux下使用ioctl重新映射键盘

Linux ioctl的返回值由谁解释?

为什么ioctl命令报告“ KVM不支持IOMMU”?

IOCTL_DISK_VERIFY是做什么的?

ioctl CDROMPLAYMSF命令的作用是什么?

为什么某些ioctl案例总是失败?

在Python中运行ioctl会返回ENOTTY-设备不适合的ioctl

为什么 Kubernetes 为 ioctl 返回奇怪的结果

Linux内核模块-IOCTL使用率返回ENOTTY

ioctl返回一个空的winsize结构

ethtool ioctl返回未填充的ethtool_link_settings

Linux中的ioctl函数集的目的是什么?

为什么我不能从ioctl函数接收SIGPOLL信号?

使用SIOCSIFFLAGS的setsockopt和ioctl有什么区别?

SGX为什么这么多次调用ioctl?

在什么情况下SynchronizedCollection <T> .Remove()返回false?

在什么情况下PDO:execute()会返回false?

在什么情况下ConcurrentDictionary.TryRemove()返回false?

unlocked_ioctl与普通的ioctl

为什么 ioctl I_SENDFD 没有返回权限(EPERM)?

在什么情况下,CopyOnWriteArrayList是合适的?

在什么情况下删除指针

在Jenkins下运行时,maven-gpg-plugin失败,并显示“设备的不适当的ioctl”

用FIONREAD调用ioctl()会在明显的竞争条件下产生奇怪的副作用,

ioctl返回ENOENT,尝试将URB请求发布到Isoc设备端点(从android的JNI访问)

我如何从DeviceIoControl返回值中知道IOCTL代码是否有效

为什么ioctl调用的原型使用unsigned long作为第三个参数?