summary refs log tree commit diff stats
path: root/accel/tcg/tcg-accel-ops.c
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2022-10-06 07:11:56 -0400
committerStefan Hajnoczi <stefanha@redhat.com>2022-10-06 07:11:56 -0400
commitf1d33f55c47dfdaf8daacd618588ad3ae4c452d1 (patch)
treec759a5deb49756097f301652837b14ffc91ef6b2 /accel/tcg/tcg-accel-ops.c
parent1dcdc92c72af5311666df64f5f04d6600af262ed (diff)
parentf7e15affa8e574a800180de3bde1a6462aec7241 (diff)
downloadfocaccia-qemu-f1d33f55c47dfdaf8daacd618588ad3ae4c452d1.tar.gz
focaccia-qemu-f1d33f55c47dfdaf8daacd618588ad3ae4c452d1.zip
Merge tag 'pull-testing-gdbstub-plugins-gitdm-061022-3' of https://github.com/stsquad/qemu into staging
testing, gdbstub, plugin and gitdm updates

  - cleanup scripts/ci/setup in advance of ppc64 runner
  - ensure detected gdb reported to TCG tests
  - update hexagon container with build deps
  - move alpine container to tagged release
  - fix overflow during qos-test test tree iteration
  - allow bios blobs to be built with test cross compilers
  - introduce monitor_puts for plain strings
  - share disas code between monitor and plugins
  - fix bug in execlog plugin
  - add more tcg plugin documentation, reorg
  - fix link to semihosting spec
  - re-factor gdbstub to use AccelClass/Ops
  - many gitdm updates
  - fix race with plugin mutex lock and linux-user fork()

# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmM+s+YACgkQ+9DbCVqe
# KkSDwgf/Qj0OScOr5Bfw3/KAV0/SFL1vHISb2r5qZVG4DvdY/c/sitPBHPJ8N5jQ
# 918M8AiI3+4Mb/GwkdYBEyWgVZ5ELOkJTObypa5pwmF1K/xDUlG7ZRmJ9+xkJ44Q
# TmrVLQyw6d907B2u+DfqX68AYYnto1yQT/eUo6TiLdIJ5NXIYRn5u34snG9qWHja
# b/Dp7DxnoJMS1EhlMhukekCHGGNUeYn4ewIKbsG1EouH5PndzrvP8LRAcWyxv0m4
# tD2bEAHCMKqTqefkNgG7GCO3HND1JBfWdckx3OD4hBnMnuNtsZBL23QN7MDytgnv
# 0JnYSwkWZCuMIt7oKCOXLUbCjQG97Q==
# =1vZ4
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 06 Oct 2022 06:54:30 EDT
# gpg:                using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44
# gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 6685 AE99 E751 67BC AFC8  DF35 FBD0 DB09 5A9E 2A44

* tag 'pull-testing-gdbstub-plugins-gitdm-061022-3' of https://github.com/stsquad/qemu: (52 commits)
  plugins: add [pre|post]fork helpers to linux-user
  contrib/gitdm: add Université Grenoble Alpes
  contrib/gitdm: add Simon to individual contributors
  contrib/gitdm: add China Telecom to the domain map
  contrib/gitdm: add ISCAS to the academics group
  contrib/gitdm: add WANG Xuerui to individual contributers
  contrib/gitdm: add Paul to individual contributors
  contrib/gitdm: add mapping for Loongson Technology
  accel/kvm: move kvm_update_guest_debug to inline stub
  gdbstub: move guest debug support check to ops
  gdbstub: move breakpoint logic to accel ops
  gdbstub: move sstep flags probing into AccelClass
  gdbstub: move into its own sub directory
  semihosting: update link to spec
  docs/devel: document the test plugins
  contrib/plugins: reset skip when matching in execlog
  docs/devel: move API to end of tcg-plugins.rst
  docs/devel: clean-up qemu invocations in tcg-plugins
  plugins: Assert mmu_idx in range before use in qemu_plugin_get_hwaddr
  plugins: extend execlog to filter matches
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'accel/tcg/tcg-accel-ops.c')
-rw-r--r--accel/tcg/tcg-accel-ops.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/accel/tcg/tcg-accel-ops.c b/accel/tcg/tcg-accel-ops.c
index 786d90c08f..19cbf1db3a 100644
--- a/accel/tcg/tcg-accel-ops.c
+++ b/accel/tcg/tcg-accel-ops.c
@@ -32,6 +32,8 @@
 #include "qemu/main-loop.h"
 #include "qemu/guest-random.h"
 #include "exec/exec-all.h"
+#include "exec/hwaddr.h"
+#include "exec/gdbstub.h"
 
 #include "tcg-accel-ops.h"
 #include "tcg-accel-ops-mttcg.h"
@@ -91,6 +93,97 @@ void tcg_handle_interrupt(CPUState *cpu, int mask)
     }
 }
 
+static bool tcg_supports_guest_debug(void)
+{
+    return true;
+}
+
+/* Translate GDB watchpoint type to a flags value for cpu_watchpoint_* */
+static inline int xlat_gdb_type(CPUState *cpu, int gdbtype)
+{
+    static const int xlat[] = {
+        [GDB_WATCHPOINT_WRITE]  = BP_GDB | BP_MEM_WRITE,
+        [GDB_WATCHPOINT_READ]   = BP_GDB | BP_MEM_READ,
+        [GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
+    };
+
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+    int cputype = xlat[gdbtype];
+
+    if (cc->gdb_stop_before_watchpoint) {
+        cputype |= BP_STOP_BEFORE_ACCESS;
+    }
+    return cputype;
+}
+
+static int tcg_insert_breakpoint(CPUState *cs, int type, hwaddr addr, hwaddr len)
+{
+    CPUState *cpu;
+    int err = 0;
+
+    switch (type) {
+    case GDB_BREAKPOINT_SW:
+    case GDB_BREAKPOINT_HW:
+        CPU_FOREACH(cpu) {
+            err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
+            if (err) {
+                break;
+            }
+        }
+        return err;
+    case GDB_WATCHPOINT_WRITE:
+    case GDB_WATCHPOINT_READ:
+    case GDB_WATCHPOINT_ACCESS:
+        CPU_FOREACH(cpu) {
+            err = cpu_watchpoint_insert(cpu, addr, len,
+                                        xlat_gdb_type(cpu, type), NULL);
+            if (err) {
+                break;
+            }
+        }
+        return err;
+    default:
+        return -ENOSYS;
+    }
+}
+
+static int tcg_remove_breakpoint(CPUState *cs, int type, hwaddr addr, hwaddr len)
+{
+    CPUState *cpu;
+    int err = 0;
+
+    switch (type) {
+    case GDB_BREAKPOINT_SW:
+    case GDB_BREAKPOINT_HW:
+        CPU_FOREACH(cpu) {
+            err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
+            if (err) {
+                break;
+            }
+        }
+        return err;
+    case GDB_WATCHPOINT_WRITE:
+    case GDB_WATCHPOINT_READ:
+    case GDB_WATCHPOINT_ACCESS:
+        CPU_FOREACH(cpu) {
+            err = cpu_watchpoint_remove(cpu, addr, len,
+                                        xlat_gdb_type(cpu, type));
+            if (err) {
+                break;
+            }
+        }
+        return err;
+    default:
+        return -ENOSYS;
+    }
+}
+
+static inline void tcg_remove_all_breakpoints(CPUState *cpu)
+{
+    cpu_breakpoint_remove_all(cpu, BP_GDB);
+    cpu_watchpoint_remove_all(cpu, BP_GDB);
+}
+
 static void tcg_accel_ops_init(AccelOpsClass *ops)
 {
     if (qemu_tcg_mttcg_enabled()) {
@@ -109,6 +202,11 @@ static void tcg_accel_ops_init(AccelOpsClass *ops)
             ops->handle_interrupt = tcg_handle_interrupt;
         }
     }
+
+    ops->supports_guest_debug = tcg_supports_guest_debug;
+    ops->insert_breakpoint = tcg_insert_breakpoint;
+    ops->remove_breakpoint = tcg_remove_breakpoint;
+    ops->remove_all_breakpoints = tcg_remove_all_breakpoints;
 }
 
 static void tcg_accel_ops_class_init(ObjectClass *oc, void *data)