gdbstub is broken on qemu-system-riscv64 with KVM enabled
Host environment
- Operating system: Ubuntu/Linux
- OS/kernel version: Linux ubuntu 6.6.21-ganboing #14 SMP PREEMPT_DYNAMIC Tue Jun 3 16:12:55 PDT 2025 riscv64 riscv64 riscv64 GNU/Linux
- Architecture: RISCV
- QEMU flavor: qemu-system-riscv64
- QEMU version: 9.2.4
- QEMU command line:
qemu-system-riscv64 --enable-kvm -cpu rv64,pmp=off -machine virt -smp 4 -nographic -m size=3072 -bios none
Emulated/Virtualized environment
- Operating system: seL4
- OS/kernel version: 13.0.0
- Architecture: RISCV
Description of problem
On RISCV Linux with KVM enabled, gdbstub is broken. The get_physical_address isn't able to page-walk correctly and resolve the physical page. This is due to that the vcpu is being treated as starting in M mode even if KVM enabled. However, with KVM, the vcpu is actually started in S mode. The mmu_idx will give 3 (M), instead of 1 (S), resulting in Guest PA == VA (wrong)! I did a hack to set the correct vcpu mode in the following patch, and the problem went away:
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 6d1284c42f..880200659f 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -1653,6 +1653,7 @@ void kvm_riscv_reset_vcpu(RISCVCPU *cpu)
env->scause = 0;
env->stval = 0;
env->mip = 0;
+ env->priv = PRV_S;
}
void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level)
Additional information
I suspect that we never tried gdbstub with KVM enabled, because apart from this get_physical_address issue, I also need to turn off PMP (with -cpu rv64,pmp=off), otherwise, get_physical_address_pmp will also bail out due to no PMP configured (no permission). We probably need a comprehensive test and ensure gdbstub works with KVM. Thanks.