1 Star 0 Fork 22

OpenCloudOS-fork/qemu

forked from OpenCloudOS Stream/qemu 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0081-target-loongarch-kvm-Add-software-breakpoint-support.patch 3.50 KB
一键复制 编辑 原始数据 按行查看 历史
From 3be9d3c66430bb9152bcfc8e2c042292d7450527 Mon Sep 17 00:00:00 2001
From: Bibo Mao <[email protected]>
Date: Sun, 18 Feb 2024 15:00:25 +0800
Subject: [PATCH] target/loongarch/kvm: Add software breakpoint support
With KVM virtualization, debug exception is passthrough to
to guest kernel rather than host mode. Here hypercall
instruction with special hypercall code is used for sw
breakpoint usage.
Now only software breakpoint is supported, and itt is allowed
to insert/remove software breakpoint. Later hardware breakpoint
will be added.
Signed-off-by: Bibo Mao <[email protected]>
---
target/loongarch/kvm/kvm.c | 77 ++++++++++++++++++++++++++++++++++++++
1 file changed, 77 insertions(+)
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index c19978a970..49d02076ad 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -29,6 +29,7 @@
#include "trace.h"
static bool cap_has_mp_state;
+static unsigned int brk_insn;
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_LAST_INFO
};
@@ -675,7 +676,14 @@ static void kvm_loongarch_vm_stage_change(void *opaque, bool running,
int kvm_arch_init_vcpu(CPUState *cs)
{
+ uint64_t val;
+
qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs);
+
+ if (!kvm_get_one_reg(cs, KVM_REG_LOONGARCH_DEBUG_INST, &val)) {
+ brk_insn = val;
+ }
+
return 0;
}
@@ -755,6 +763,68 @@ bool kvm_arch_cpu_check_are_resettable(void)
return true;
}
+
+void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg)
+{
+ if (kvm_sw_breakpoints_active(cpu)) {
+ dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP;
+ }
+}
+
+int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
+{
+ if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) ||
+ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk_insn, 4, 1)) {
+ error_report("%s failed", __func__);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
+{
+ static uint32_t brk;
+
+ if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk, 4, 0) ||
+ brk != brk_insn ||
+ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 1)) {
+ error_report("%s failed", __func__);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int kvm_arch_insert_hw_breakpoint(vaddr addr, vaddr len, int type)
+{
+ return -ENOSYS;
+}
+
+int kvm_arch_remove_hw_breakpoint(vaddr addr, vaddr len, int type)
+{
+ return -ENOSYS;
+}
+
+void kvm_arch_remove_all_hw_breakpoints(void)
+{
+}
+
+static bool kvm_loongarch_handle_debug(CPUState *cs, struct kvm_run *run)
+{
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+ CPULoongArchState *env = &cpu->env;
+
+ kvm_cpu_synchronize_state(cs);
+ if (cs->singlestep_enabled) {
+ return true;
+ }
+
+ if (kvm_find_sw_breakpoint(cs, env->pc)) {
+ return true;
+ }
+
+ return false;
+}
+
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
{
int ret = 0;
@@ -774,6 +844,13 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
run->iocsr_io.len,
run->iocsr_io.is_write);
break;
+
+ case KVM_EXIT_DEBUG:
+ if (kvm_loongarch_handle_debug(cs, run)) {
+ ret = EXCP_DEBUG;
+ }
+ break;
+
default:
ret = -1;
warn_report("KVM: unknown exit reason %d", run->exit_reason);
--
2.33.0
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/OpenCloudOS-fork/qemu.git
[email protected]:OpenCloudOS-fork/qemu.git
OpenCloudOS-fork
qemu
qemu
master

搜索帮助