From nobody Sun Jul 26 11:08:12 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=univ-lille.fr ARC-Seal: i=1; a=rsa-sha256; t=1783291470; cv=none; d=zohomail.com; s=zohoarc; b=PWpGmygODP6SWq65HD4FIPJcjB0KGC/JSorqfQ2ZxFvkjFyaEqwv6GyQ88f2fF7YdF61MHKqXOF0Thu+8HjT6xo7vTg/opUJsihMEBgI2/3fLXfvSxNI7O6ussc3PyWIztUHHLmnvWKnVXAobua//uIVX9109l2Y+ObUKy/FzYc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783291470; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=YMmoU0jvgKSG+M2L3MmCP5eAIwuoW7CiBLxgNApfjXo=; b=T6uuCr25BXlksSx5bivymWritypP1c3lFHWwBFZmX/7luSsG+tDmerkibMTt1rC4VBBxzC/57DQu7DiRvmYV6bcIZEunPPE/JB+yHwiJNDKIUN8dx9gP0S5lzKOpNoa4RarUdbVbOh0n4mt4+7UbjshAGToGxrjKOG8qcp86VOE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 178329147076138.46373805385804; Sun, 5 Jul 2026 15:44:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wgVZQ-0005BP-78; Sun, 05 Jul 2026 18:44:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wgVZN-00053M-Gj; Sun, 05 Jul 2026 18:44:13 -0400 Received: from smtp-out-1.univ-lille.fr ([194.254.129.82]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wgVZL-00029X-5W; Sun, 05 Jul 2026 18:44:13 -0400 Received: from smtp02.univ-lille.fr (smtp02.univ-lille.fr [194.254.129.96]) by smtp-out-1.univ-lille.fr (Postfix) with ESMTPS id 4gtjGJ2c3szBsVY; Mon, 6 Jul 2026 00:44:08 +0200 (CEST) Received: from mac.home (lfbn-lil-1-243-101.w90-45.abo.wanadoo.fr [90.45.87.101]) (Authenticated sender: gilles.grimaud) by smtp02.univ-lille.fr (Postfix) with ESMTPSA id 4gtjGJ1T2hz6sT6; Mon, 6 Jul 2026 00:44:08 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=univ-lille.fr; s=dkim; t=1783291448; bh=YMmoU0jvgKSG+M2L3MmCP5eAIwuoW7CiBLxgNApfjXo=; h=From:To:Cc:Subject:Date:From; b=qgoTzMiycLdNT3P2Od9rhdT0UhJHNE2NvcPgh+FsY1pj3f3WBBESuJA6Vf3WkUv2V YmKKOVP8eOt3qTjJ7QQmWh7HVKJy+/KmpQr++bzhkkoUinh56gQv5TnyqmTA16WFPT +PkP5gY7vv9t3FUbXbC+x2urMKaDq24rPvLraLqWwGSk/nqPyw/5gZrGEFWHGWcJhU NbzuCI9wgsi4U7SQxBybKnjWwzzLX0P8yPG0Iwl/lKl49hZ/p8WFFcIPArYCBbbMlu b1tAttDGAoiATO5tXani2qRxnEzGo2CT/SoH3izcSHAgaWpb3EHwxiMNWWcq0pRf3I IqhRRqSNi4W3Q== From: Gilles Grimaud To: qemu-devel@nongnu.org Cc: qemu-arm@nongnu.org, Gilles Grimaud Subject: [RFC PATCH] target/arm: report M-profile BKPT to gdbstub when attached Date: Mon, 6 Jul 2026 00:44:07 +0200 Message-ID: <20260705224407.32464-1-gilles.grimaud@univ-lille.fr> X-Mailer: git-send-email 2.55.0 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=194.254.129.82; envelope-from=gilles.grimaud@univ-lille.fr; helo=smtp-out-1.univ-lille.fr X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @univ-lille.fr) X-ZM-MESSAGEID: 1783291472027158500 Content-Type: text/plain; charset="utf-8" While working on Raspberry Pi Pico/RP2040 support, I noticed that Pico SDK programs deliberately execute BKPT from _exit(). On real hardware this is useful when a debug probe is attached: returning from main() stops the debugger at the program exit point. Under QEMU this currently does not behave like the debug-probe case. For M-profile guests, the BKPT instruction is routed through the architectural guest debug exception path. Without halting debug, that path should remain a guest-visible DebugMonitor exception when DebugMonitor is enabled, or escal= ate towards HardFault otherwise. This patch deliberately leaves that no-debugger architectural path unchanged. The problem addressed here is the case where GDB is connected to QEMU's gdbstub. In that situation, firmware that uses BKPT as a debugger stop point should stop in the attached debugger. Instead, the M-profile guest currently continues down the guest exception path and may end in HardFault/lockup rat= her than reporting a clean trap to GDB. This is not specific to the RP2040 machine model. It is a generic Cortex-M/gdbstub interaction: firmware that uses BKPT as a debugger stop po= int should be reported to the attached debugger, while keeping the guest architectural exception path when no debugger is attached. Expose a small gdbstub helper to test whether a CPU is visible to an attach= ed debugger. When an M-profile BKPT instruction is executed with such a debugg= er attached, leave the translated block with EXCP_DEBUG so the existing gdbstub stop path reports a trap to GDB. Signed-off-by: Gilles Grimaud --- gdbstub/gdbstub.c | 13 ++++++++++++- include/exec/gdbstub.h | 6 ++++++ target/arm/tcg/debug.c | 9 +++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c index c3c944e965..9f259fc005 100644 --- a/gdbstub/gdbstub.c +++ b/gdbstub/gdbstub.c @@ -237,6 +237,18 @@ static GDBProcess *gdb_get_cpu_process(CPUState *cpu) return gdb_get_process(gdb_get_cpu_pid(cpu)); } =20 +bool gdb_cpu_is_attached(CPUState *cpu) +{ + GDBProcess *process; + + if (!gdbserver_state.init || !cpu) { + return false; + } + + process =3D gdb_get_cpu_process(cpu); + return process && process->attached; +} + static CPUState *find_cpu(uint32_t thread_id) { CPUState *cpu; @@ -2520,4 +2532,3 @@ void gdb_create_default_process(GDBState *s) process->attached =3D false; process->target_xml =3D NULL; } - diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index 75eb4d9c36..6e5f75a1f3 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -59,6 +59,12 @@ void gdb_unregister_coprocessor_all(CPUState *cpu); */ bool gdbserver_start(const char *port_or_device, Error **errp); =20 +/** + * gdb_cpu_is_attached() - return whether @cpu is visible to an attached G= DB + * @cpu: The CPU to test. + */ +bool gdb_cpu_is_attached(CPUState *cpu); + /** * gdb_feature_builder_init() - Initialize GDBFeatureBuilder. * @builder: The builder to be initialized. diff --git a/target/arm/tcg/debug.c b/target/arm/tcg/debug.c index 07a52643e7..2c60f1c49f 100644 --- a/target/arm/tcg/debug.c +++ b/target/arm/tcg/debug.c @@ -12,7 +12,9 @@ #include "internals.h" #include "cpu-features.h" #include "cpregs.h" +#include "accel/tcg/cpu-loop.h" #include "exec/watchpoint.h" +#include "exec/gdbstub.h" #include "system/tcg.h" =20 /* Return the Exception Level targeted by debug exceptions. */ @@ -513,6 +515,7 @@ void arm_debug_excp_handler(CPUState *cs) */ void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome) { + CPUState *cs =3D env_cpu(env); int debug_el =3D arm_debug_target_el(env); int cur_el =3D arm_current_el(env); =20 @@ -535,6 +538,12 @@ void HELPER(exception_bkpt_insn)(CPUARMState *env, uin= t32_t syndrome) if (debug_el < cur_el) { debug_el =3D cur_el; } + + if (arm_feature(env, ARM_FEATURE_M) && gdb_cpu_is_attached(cs)) { + cs->exception_index =3D EXCP_DEBUG; + cpu_loop_exit(cs); + } + raise_exception(env, EXCP_BKPT, syndrome, debug_el); } =20 --=20 2.55.0