You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调试KVM子系统?树莓派4上QEMU调用KVM内核流程调试疑问

调试QEMU中KVM ioctl调用的方案

问题背景

你在调试QEMU源码时,发现kvm_ioctl、kvm_vm_ioctl等函数会通过ioctl@plt切换到内核上下文,但尝试通过修改kvm.ko模块调试时,发现树莓派4(Raspbian Lite 64位)中找不到该模块,且lsmod无KVM相关条目,仅/dev/kvm存在。

为什么看不到kvm.ko?

因为你的系统中KVM是**编译进内核(built-in)**而非可加载模块,所以没有独立的kvm.ko文件,lsmod也无法列出。可以通过以下命令确认:

cat /boot/config-$(uname -r) | grep CONFIG_KVM

如果输出是CONFIG_KVM=y,说明KVM是内置内核组件;若为CONFIG_KVM=m则是可加载模块。


具体调试方案

1. 内核层面调试(内置KVM)

方案A:修改内核源码添加调试输出并重新编译

  • 获取对应版本的Raspbian内核源码:
    sudo apt install raspberrypi-kernel-headers
    # 或从官方仓库克隆源码
    git clone --depth=1 https://github.com/raspberrypi/linux.git -b rpi-$(uname -r | cut -d. -f1-2).y
    
  • 进入内核源码目录,修改KVM相关代码(比如virt/kvm/kvm_main.c中的kvm_dev_ioctl_create_vm函数),添加printk输出:
    printk(KERN_DEBUG "KVM_CREATE_VM called, fd: %d\n", fd);
    
  • 开启内核调试配置:
    make bcm2711_defconfig # 树莓派4的配置文件
    make menuconfig
    # 开启:Kernel hacking -> Compile-time checks and compiler options -> Compile the kernel with debug info
    # 保存配置后编译
    make -j$(nproc) Image modules dtbs
    
  • 替换树莓派的内核镜像:
    sudo cp arch/arm64/boot/Image /boot/kernel8.img
    sudo cp arch/arm64/boot/dts/broadcom/*.dtb /boot/
    sudo cp arch/arm64/boot/dts/overlays/*.dtb* /boot/overlays/
    sudo reboot
    
  • 重启后查看内核日志:
    dmesg | grep KVM
    

方案B:使用ftrace追踪KVM调用(无需重新编译内核)

ftrace是内核自带的追踪工具,可以快速定位KVM函数调用:

  • 挂载tracefs:
    sudo mount -t tracefs nodev /sys/kernel/tracing
    
  • 追踪KVM的VM创建ioctl处理函数:
    sudo echo kvm_dev_ioctl_create_vm > /sys/kernel/tracing/set_function
    sudo echo 1 > /sys/kernel/tracing/tracing_on
    # 运行你的QEMU测试程序
    cat /sys/kernel/tracing/trace_pipe
    
  • 也可以用function_graph查看调用栈:
    sudo echo function_graph > /sys/kernel/tracing/current_tracer
    sudo echo kvm_* > /sys/kernel/tracing/set_ftrace_filter
    sudo echo 1 > /sys/kernel/tracing/tracing_on
    # 运行QEMU后查看输出
    cat /sys/kernel/tracing/trace
    

方案C:用gdb调试内核

  • 准备:树莓派开启serial控制台,或使用gdbserver通过网络连接
  • 在主机上启动gdb,加载内核符号:
    gdb vmlinux # vmlinux是编译内核时生成的带符号的镜像
    target remote <树莓派IP>:1234 # 假设树莓派上运行了gdbserver :1234
    
  • 设置断点在KVM的ioctl处理函数:
    b kvm_dev_ioctl_create_vm
    c
    
  • 运行QEMU触发调用,即可在gdb中调试内核上下文。

2. 用户态QEMU调试结合内核调试

  • 先在QEMU中设置断点,定位到kvm_vm_ioctl(KVM_CREATE_VM)的调用处:
    gdb qemu-system-aarch64
    b kvm_vm_ioctl
    c
    
  • 当触发断点后,使用si跟进到ioctl@plt,此时切换到内核调试工具(如gdb连接内核),即可追踪内核侧的处理流程。

内容的提问来源于stack exchange,提问作者Yuv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 03:37:31