qemu的cpu加速器分析笔记

每个加速器(accelerator)都必须配套一组 accel_ops;accel 管整机,accel_ops 管 CPU 执行。

|-------|---------|-------------|-----|---------|------------|
| 加速器 | 类型 | 平台 | 跨架构 | 性能 | 典型用途 |
| KVM | 硬件加速 | Linux | ❌ | 95%+ | 生产虚拟化、云 |
| HVF | 硬件加速 | macOS | ❌ | 90%+ | macOS 跑虚拟机 |
| Xen | 半虚 / 全虚 | Linux(Dom0) | ❌ | 85--95% | 老企业虚拟化 |
| TCG | 软件翻译 | 全平台 | ✅ | 50--80% | 跨架构、调试、开发 |
| stubs | 空占位 | 编译可选 | --- | 极低 | 测试 / 编译占位 |

1、注册TCG类型,位于源文件:tcg-all.c

cpp 复制代码
static const TypeInfo tcg_accel_type = {
    .name = TYPE_TCG_ACCEL,
    .parent = TYPE_ACCEL,
    .instance_init = tcg_accel_instance_init,
    .class_init = tcg_accel_class_init,
    .instance_size = sizeof(TCGState),
};
module_obj(TYPE_TCG_ACCEL);

static void register_accel_types(void)
{
    type_register_static(&tcg_accel_type);
}
type_init(register_accel_types);

类初始化实现了tcg初始化函数。

cpp 复制代码
static void tcg_accel_class_init(ObjectClass *oc, void *data)
{
    AccelClass *ac = ACCEL_CLASS(oc);
    ac->name = "tcg";
    ac->init_machine = tcg_init_machine;
    ac->allowed = &tcg_allowed;
    ac->gdbstub_supported_sstep_flags = tcg_gdbstub_supported_sstep_flags;

    object_class_property_add_str(oc, "thread", tcg_get_thread, tcg_set_thread);
    object_class_property_add(oc, "tb-size", "int", tcg_get_tb_size, tcg_set_tb_size, NULL, NULL);
    object_class_property_set_description(oc, "tb-size", "TCG translation block cache size");
    object_class_property_add_bool(oc, "split-wx", tcg_get_splitwx, tcg_set_splitwx);
    object_class_property_set_description(oc, "split-wx", "Map jit pages into separate RW and RX regions");
    object_class_property_add_bool(oc, "one-insn-per-tb", tcg_get_one_insn_per_tb, tcg_set_one_insn_per_tb);
    object_class_property_set_description(oc, "one-insn-per-tb", "Only put one guest insn in each translation block");
}

tcg加速器操作回调函数

cpp 复制代码
static void tcg_accel_ops_init(AccelOpsClass *ops)
{
    if (qemu_tcg_mttcg_enabled()) {
        ops->create_vcpu_thread = mttcg_start_vcpu_thread;
        ops->kick_vcpu_thread = mttcg_kick_vcpu_thread;
        ops->handle_interrupt = tcg_handle_interrupt;
    } else {
        ops->create_vcpu_thread = rr_start_vcpu_thread;
        ops->kick_vcpu_thread = rr_kick_vcpu_thread;


        if (icount_enabled()) {
            ops->handle_interrupt = icount_handle_interrupt;
            ops->get_virtual_clock = icount_get;
            ops->get_elapsed_ticks = icount_get;
        } else {
            ops->handle_interrupt = tcg_handle_interrupt;
        }
    }
    ops->supports_guest_debug = tcg_supports_guest_debug;
    ops->insert_breakpoint = tcg_insert_breakpoint;
    ops->remove_breakpoint = tcg_remove_breakpoint;
    ops->remove_all_breakpoints = tcg_remove_all_breakpoints;
}

static void tcg_accel_ops_class_init(ObjectClass *oc, void *data)
{
    AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
    ops->ops_init = tcg_accel_ops_init;
}

static const TypeInfo tcg_accel_ops_type = {
    .name = ACCEL_OPS_NAME("tcg"),
    .parent = TYPE_ACCEL_OPS,
    .class_init = tcg_accel_ops_class_init,
    .abstract = true,
};
module_obj(ACCEL_OPS_NAME("tcg"));

static void tcg_accel_ops_register_types(void)
{
    type_register_static(&tcg_accel_ops_type);
}
type_init(tcg_accel_ops_register_types);

2、注册kvm类型,位于源文件:kvm-all.c

cpp 复制代码
static const TypeInfo kvm_accel_type = {
    .name = TYPE_KVM_ACCEL,
    .parent = TYPE_ACCEL,
    .instance_init = kvm_accel_instance_init,
    .class_init = kvm_accel_class_init,
    .instance_size = sizeof(KVMState),
};

static void kvm_type_init(void)
{
    type_register_static(&kvm_accel_type);
}

type_init(kvm_type_init);

类初始化实现了kvm初始化函数。

cpp 复制代码
static void kvm_accel_class_init(ObjectClass *oc, void *data)
{
    AccelClass *ac = ACCEL_CLASS(oc);
    ac->name = "KVM";
    ac->init_machine = kvm_init;
    ac->has_memory = kvm_accel_has_memory;
    ac->allowed = &kvm_allowed;
    ac->gdbstub_supported_sstep_flags = kvm_gdbstub_sstep_flags;

    object_class_property_add(oc, "kernel-irqchip", "on|off|split", NULL, kvm_set_kernel_irqchip, NULL, NULL);
    object_class_property_set_description(oc, "kernel-irqchip", "Configure KVM in-kernel irqchip");
    object_class_property_add(oc, "kvm-shadow-mem", "int", kvm_get_kvm_shadow_mem, kvm_set_kvm_shadow_mem, NULL, NULL);
    object_class_property_set_description(oc, "kvm-shadow-mem", "KVM shadow MMU size");
    object_class_property_add(oc, "dirty-ring-size", "uint32", kvm_get_dirty_ring_size, kvm_set_dirty_ring_size, NULL, NULL);
    object_class_property_set_description(oc, "dirty-ring-size", "Size of KVM dirty page ring buffer (default: 0, i.e. use bitmap)");
    kvm_arch_accel_class_init(oc);
}
kvm加速器操作回调函数
static void kvm_accel_ops_class_init(ObjectClass *oc, void *data)
{
    AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
    ops->create_vcpu_thread = kvm_start_vcpu_thread;
    ops->cpu_thread_is_idle = kvm_vcpu_thread_is_idle;
    ops->cpus_are_resettable = kvm_cpus_are_resettable;
    ops->synchronize_post_reset = kvm_cpu_synchronize_post_reset;
    ops->synchronize_post_init = kvm_cpu_synchronize_post_init;
    ops->synchronize_state = kvm_cpu_synchronize_state;
    ops->synchronize_pre_loadvm = kvm_cpu_synchronize_pre_loadvm;

#ifdef KVM_CAP_SET_GUEST_DEBUG
    ops->update_guest_debug = kvm_update_guest_debug_ops;
    ops->supports_guest_debug = kvm_supports_guest_debug;
    ops->insert_breakpoint = kvm_insert_breakpoint;
    ops->remove_breakpoint = kvm_remove_breakpoint;
    ops->remove_all_breakpoints = kvm_remove_all_breakpoints;
#endif
}

static const TypeInfo kvm_accel_ops_type = {
    .name = ACCEL_OPS_NAME("kvm"),
    .parent = TYPE_ACCEL_OPS,
    .class_init = kvm_accel_ops_class_init,
    .abstract = true,
};

static void kvm_accel_ops_register_types(void)
{
    type_register_static(&kvm_accel_ops_type);
}
type_init(kvm_accel_ops_register_types);
相关推荐
牛奶咖啡138 天前
KVM虚拟化与企业应用实践——给远端主机创建虚拟机
云原生·qemu·kvm·给远端主机创建虚拟机·创建uefi模式的虚拟机·安装openeulersp2·vnc与虚拟机环境搭建
牛奶咖啡139 天前
KVM虚拟化与企业应用实践——通过网络介质配合ks自动应答文件实现自动安装KVM虚拟机
云原生·qemu·kvm·系统网络引导与ks自动应答环境·远程资源+ks文件安装虚拟机·通过网络介质引导自动安装虚拟机·qemu的总线类型详解
冰山一脚20139 天前
kvm驱动学习笔记
qemu
ggaofeng13 天前
如何通过uboot加载硬盘
linux·qemu·uboot
ScilogyHunter13 天前
QEMU完全指南
linux·qemu
longji1 个月前
win11 使用 QEMU11 模拟器跑龙芯系统(debian13,openKylin,openEuler,uos,Loongnix)
qemu·龙芯模拟器
冰山一脚20132 个月前
qemu的板级初始化笔记(以i4ffx为例)
qemu
冰山一脚20132 个月前
CPU的L1、L2、L3缓存笔记
qemu