aboutsummaryrefslogtreecommitdiff
path: root/accel
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2023-06-06 12:11:34 -0700
committerRichard Henderson <richard.henderson@linaro.org>2023-06-06 12:11:34 -0700
commitf5e6786de4815751b0a3d2235c760361f228ea48 (patch)
tree544d0ff2d361be94e83bc620ea0e57b2886487ac /accel
parentc0dde5fc5ccce56b69095bc29af72987efd65d1e (diff)
parentf9ac778898cb28307e0f91421aba34d43c34b679 (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.c119
-rw-r--r--accel/hvf/hvf-all.c23
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;
+}