+#ifndef CONFIG_USER_ONLY
+static const int xlat_gdb_type[] = {
+ [GDB_WATCHPOINT_WRITE] = BP_GDB | BP_MEM_WRITE,
+ [GDB_WATCHPOINT_READ] = BP_GDB | BP_MEM_READ,
+ [GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
+};
+#endif
+
+static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
+{
+ CPUState *env;
+ int err = 0;
+
+ if (kvm_enabled())
+ return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type);
+
+ switch (type) {
+ case GDB_BREAKPOINT_SW:
+ case GDB_BREAKPOINT_HW:
+ for (env = first_cpu; env != NULL; env = env->next_cpu) {
+ err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
+ if (err)
+ break;
+ }
+ return err;
+#ifndef CONFIG_USER_ONLY
+ case GDB_WATCHPOINT_WRITE:
+ case GDB_WATCHPOINT_READ:
+ case GDB_WATCHPOINT_ACCESS:
+ for (env = first_cpu; env != NULL; env = env->next_cpu) {
+ err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
+ NULL);
+ if (err)
+ break;
+ }
+ return err;
+#endif
+ default:
+ return -ENOSYS;
+ }
+}
+
+static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
+{
+ CPUState *env;
+ int err = 0;
+
+ if (kvm_enabled())
+ return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type);
+
+ switch (type) {
+ case GDB_BREAKPOINT_SW:
+ case GDB_BREAKPOINT_HW:
+ for (env = first_cpu; env != NULL; env = env->next_cpu) {
+ err = cpu_breakpoint_remove(env, addr, BP_GDB);
+ if (err)
+ break;
+ }
+ return err;
+#ifndef CONFIG_USER_ONLY
+ case GDB_WATCHPOINT_WRITE:
+ case GDB_WATCHPOINT_READ:
+ case GDB_WATCHPOINT_ACCESS:
+ for (env = first_cpu; env != NULL; env = env->next_cpu) {
+ err = cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);
+ if (err)
+ break;
+ }
+ return err;
+#endif
+ default:
+ return -ENOSYS;
+ }
+}
+
+static void gdb_breakpoint_remove_all(void)
+{
+ CPUState *env;
+
+ if (kvm_enabled()) {
+ kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
+ return;
+ }
+
+ for (env = first_cpu; env != NULL; env = env->next_cpu) {
+ cpu_breakpoint_remove_all(env, BP_GDB);
+#ifndef CONFIG_USER_ONLY
+ cpu_watchpoint_remove_all(env, BP_GDB);
+#endif
+ }
+}
+
+static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)