Projects
Eulaceura:Mainline:GA
qemu
_service:obs_scm:target-loongarch-kvm-Add-softw...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:target-loongarch-kvm-Add-software-breakpoint-support.patch of Package qemu
From 6a301af275fd684c197cf7a2e73fc265993478da Mon Sep 17 00:00:00 2001 From: Bibo Mao <maobibo@loongson.cn> 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 <maobibo@loongson.cn> --- 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
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2