diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2023-06-06 12:11:34 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2023-06-06 12:11:34 -0700 |
commit | f5e6786de4815751b0a3d2235c760361f228ea48 (patch) | |
tree | 544d0ff2d361be94e83bc620ea0e57b2886487ac /accel | |
parent | c0dde5fc5ccce56b69095bc29af72987efd65d1e (diff) | |
parent | f9ac778898cb28307e0f91421aba34d43c34b679 (diff) |
Merge tag 'pull-target-arm-20230606' of https://git.linaro.org/people/pmaydell/qemu-arm into staging
target-arm queue:
* Support gdbstub (guest debug) in HVF
* xnlx-versal: Support CANFD controller
* bpim2u: New board model: Banana Pi BPI-M2 Ultra
* Emulate FEAT_LSE2
* allow DC CVA[D]P in user mode emulation
* trap DCC access in user mode emulation
# -----BEGIN PGP SIGNATURE-----
#
# iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmR/AKUZHHBldGVyLm1h
# eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3jzIEACNepQGY44yPhrEG+wD4WAB
# fH670KI33HcsFd2rGsC369gcssQbRIW/29reOzNhRMuol+kHI6OFaONpuKSdO0Rz
# TLVIsnT2Uq8KwbYfLtDQt5knj027amPy75d4re8wIK1eZB4dOIHysqAvQrJYeync
# 9obKku8xXGLwZh/mYHoVgHcZU0cPJO9nri39n1tV3JUBsgmqEURjzbZrMcF+yMX7
# bUzOYQvC1Iedmo+aWfx43u82AlNQFz1lsqmnQj7Z5rvv0HT+BRF5WzVMP0qRh5+Z
# njkqmBH9xb9kkgeHmeMvHpWox+J+obeSmVg/4gDNlJpThmpuU0Vr7EXUN3MBQlV9
# lhyy6zrTwC/BToiQqdT2dnpao9FzXy5exfnqi/py5IuqfjAzSO+p61LlPPZ4cJri
# pCK4yq2gzQXYfrlZkUJipvRMH8Xa4IdQx+w7lXrQoJdduF4/+6aJW/GAWSu0e7eC
# zgBwaJjI7ENce8ixJnuEFUxUnaBo8dl72a0PGA1UU8PL+cJNOIpyhPk4goWQprdn
# iFF4ZnjhBRZ2gk/4HGD9u5Vo2lNqP93YS5QhkGkF+HJsBmcOZgidIUpfHhPQvvHO
# Np196T2cAETCWGV1xG4CaTpxN2ndRReq3C0/mzfhIbwhXEACtvAiSlO4KB8t6pJj
# MzinCABXHcovJbGbxZ9j6w==
# =8SdN
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 06 Jun 2023 02:47:17 AM PDT
# gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg: issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full]
# gpg: aka "Peter Maydell <pmaydell@gmail.com>" [full]
# gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full]
# gpg: aka "Peter Maydell <peter@archaic.org.uk>" [unknown]
* tag 'pull-target-arm-20230606' of https://git.linaro.org/people/pmaydell/qemu-arm: (42 commits)
target/arm: trap DCC access in user mode emulation
tests/tcg/aarch64: add DC CVA[D]P tests
target/arm: allow DC CVA[D]P in user mode emulation
target/arm: Enable FEAT_LSE2 for -cpu max
tests/tcg/multiarch: Adjust sigbus.c
tests/tcg/aarch64: Use stz2g in mte-7.c
target/arm: Move mte check for store-exclusive
target/arm: Relax ordered/atomic alignment checks for LSE2
target/arm: Add SCTLR.nAA to TBFLAG_A64
target/arm: Check alignment in helper_mte_check
target/arm: Pass single_memop to gen_mte_checkN
target/arm: Pass memop to gen_mte_check1*
target/arm: Hoist finalize_memop out of do_fp_{ld, st}
target/arm: Hoist finalize_memop out of do_gpr_{ld, st}
target/arm: Load/store integer pair with one tcg operation
target/arm: Sink gen_mte_check1 into load/store_exclusive
target/arm: Use tcg_gen_qemu_{ld, st}_i128 in gen_sve_{ld, st}r
target/arm: Use tcg_gen_qemu_st_i128 for STZG, STZ2G
target/arm: Use tcg_gen_qemu_{st, ld}_i128 for do_fp_{st, ld}
target/arm: Use tcg_gen_qemu_ld_i128 for LDXP
...
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'accel')
-rw-r--r-- | accel/hvf/hvf-accel-ops.c | 119 | ||||
-rw-r--r-- | accel/hvf/hvf-all.c | 23 |
2 files changed, 142 insertions, 0 deletions
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c index 24913ca9c4..9c3da03c94 100644 --- a/accel/hvf/hvf-accel-ops.c +++ b/accel/hvf/hvf-accel-ops.c @@ -52,6 +52,7 @@ #include "qemu/main-loop.h" #include "exec/address-spaces.h" #include "exec/exec-all.h" +#include "exec/gdbstub.h" #include "sysemu/cpus.h" #include "sysemu/hvf.h" #include "sysemu/hvf_int.h" @@ -334,18 +335,26 @@ static int hvf_accel_init(MachineState *ms) s->slots[x].slot_id = x; } + QTAILQ_INIT(&s->hvf_sw_breakpoints); + hvf_state = s; memory_listener_register(&hvf_memory_listener, &address_space_memory); return hvf_arch_init(); } +static inline int hvf_gdbstub_sstep_flags(void) +{ + return SSTEP_ENABLE | SSTEP_NOIRQ; +} + static void hvf_accel_class_init(ObjectClass *oc, void *data) { AccelClass *ac = ACCEL_CLASS(oc); ac->name = "HVF"; ac->init_machine = hvf_accel_init; ac->allowed = &hvf_allowed; + ac->gdbstub_supported_sstep_flags = hvf_gdbstub_sstep_flags; } static const TypeInfo hvf_accel_type = { @@ -395,6 +404,8 @@ static int hvf_init_vcpu(CPUState *cpu) cpu->vcpu_dirty = 1; assert_hvf_ok(r); + cpu->hvf->guest_debug_enabled = false; + return hvf_arch_init_vcpu(cpu); } @@ -462,6 +473,108 @@ static void hvf_start_vcpu_thread(CPUState *cpu) cpu, QEMU_THREAD_JOINABLE); } +static int hvf_insert_breakpoint(CPUState *cpu, int type, hwaddr addr, hwaddr len) +{ + struct hvf_sw_breakpoint *bp; + int err; + + if (type == GDB_BREAKPOINT_SW) { + bp = hvf_find_sw_breakpoint(cpu, addr); + if (bp) { + bp->use_count++; + return 0; + } + + bp = g_new(struct hvf_sw_breakpoint, 1); + bp->pc = addr; + bp->use_count = 1; + err = hvf_arch_insert_sw_breakpoint(cpu, bp); + if (err) { + g_free(bp); + return err; + } + + QTAILQ_INSERT_HEAD(&hvf_state->hvf_sw_breakpoints, bp, entry); + } else { + err = hvf_arch_insert_hw_breakpoint(addr, len, type); + if (err) { + return err; + } + } + + CPU_FOREACH(cpu) { + err = hvf_update_guest_debug(cpu); + if (err) { + return err; + } + } + return 0; +} + +static int hvf_remove_breakpoint(CPUState *cpu, int type, hwaddr addr, hwaddr len) +{ + struct hvf_sw_breakpoint *bp; + int err; + + if (type == GDB_BREAKPOINT_SW) { + bp = hvf_find_sw_breakpoint(cpu, addr); + if (!bp) { + return -ENOENT; + } + + if (bp->use_count > 1) { + bp->use_count--; + return 0; + } + + err = hvf_arch_remove_sw_breakpoint(cpu, bp); + if (err) { + return err; + } + + QTAILQ_REMOVE(&hvf_state->hvf_sw_breakpoints, bp, entry); + g_free(bp); + } else { + err = hvf_arch_remove_hw_breakpoint(addr, len, type); + if (err) { + return err; + } + } + + CPU_FOREACH(cpu) { + err = hvf_update_guest_debug(cpu); + if (err) { + return err; + } + } + return 0; +} + +static void hvf_remove_all_breakpoints(CPUState *cpu) +{ + struct hvf_sw_breakpoint *bp, *next; + CPUState *tmpcpu; + + QTAILQ_FOREACH_SAFE(bp, &hvf_state->hvf_sw_breakpoints, entry, next) { + if (hvf_arch_remove_sw_breakpoint(cpu, bp) != 0) { + /* Try harder to find a CPU that currently sees the breakpoint. */ + CPU_FOREACH(tmpcpu) + { + if (hvf_arch_remove_sw_breakpoint(tmpcpu, bp) == 0) { + break; + } + } + } + QTAILQ_REMOVE(&hvf_state->hvf_sw_breakpoints, bp, entry); + g_free(bp); + } + hvf_arch_remove_all_hw_breakpoints(); + + CPU_FOREACH(cpu) { + hvf_update_guest_debug(cpu); + } +} + static void hvf_accel_ops_class_init(ObjectClass *oc, void *data) { AccelOpsClass *ops = ACCEL_OPS_CLASS(oc); @@ -473,6 +586,12 @@ static void hvf_accel_ops_class_init(ObjectClass *oc, void *data) ops->synchronize_post_init = hvf_cpu_synchronize_post_init; ops->synchronize_state = hvf_cpu_synchronize_state; ops->synchronize_pre_loadvm = hvf_cpu_synchronize_pre_loadvm; + + ops->insert_breakpoint = hvf_insert_breakpoint; + ops->remove_breakpoint = hvf_remove_breakpoint; + ops->remove_all_breakpoints = hvf_remove_all_breakpoints; + ops->update_guest_debug = hvf_update_guest_debug; + ops->supports_guest_debug = hvf_arch_supports_guest_debug; }; static const TypeInfo hvf_accel_ops_type = { .name = ACCEL_OPS_NAME("hvf"), diff --git a/accel/hvf/hvf-all.c b/accel/hvf/hvf-all.c index 0043f4d308..754707dbfb 100644 --- a/accel/hvf/hvf-all.c +++ b/accel/hvf/hvf-all.c @@ -44,3 +44,26 @@ void assert_hvf_ok(hv_return_t ret) abort(); } + +struct hvf_sw_breakpoint *hvf_find_sw_breakpoint(CPUState *cpu, target_ulong pc) +{ + struct hvf_sw_breakpoint *bp; + + QTAILQ_FOREACH(bp, &hvf_state->hvf_sw_breakpoints, entry) { + if (bp->pc == pc) { + return bp; + } + } + return NULL; +} + +int hvf_sw_breakpoints_active(CPUState *cpu) +{ + return !QTAILQ_EMPTY(&hvf_state->hvf_sw_breakpoints); +} + +int hvf_update_guest_debug(CPUState *cpu) +{ + hvf_arch_update_guest_debug(cpu); + return 0; +} |