Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 21 Mar 2024 10:13:47 GMT
From:      Andrew Turner <andrew@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: ed3c6cd76de8 - main - arm64: Mask non-debug exceptions when single stepping
Message-ID:  <202403211013.42LADloU032400@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by andrew:

URL: https://cgit.FreeBSD.org/src/commit/?id=ed3c6cd76de8560c46607abe506a03568e9acab2

commit ed3c6cd76de8560c46607abe506a03568e9acab2
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2024-03-14 14:02:56 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2024-03-21 10:13:24 +0000

    arm64: Mask non-debug exceptions when single stepping
    
    When an exception is pending when single stepping we may execute the
    handler for that exception rather than the single step handler. This
    could cause the scheduler to fire to run a new thread. This will mean
    we single step to a new thread causing unexpected results.
    
    Handle this by masking non-debug exceptions. This will cause issues
    when stepping over instructions that access the DAIF values so future
    work is needed to handle these cases, but for most code this now works
    as expected.
    
    Reviewed by:    jhb
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D44350
---
 sys/arm64/arm64/debug_monitor.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/sys/arm64/arm64/debug_monitor.c b/sys/arm64/arm64/debug_monitor.c
index b8164b70c5c8..480a6da817a2 100644
--- a/sys/arm64/arm64/debug_monitor.c
+++ b/sys/arm64/arm64/debug_monitor.c
@@ -193,6 +193,15 @@ kdb_cpu_set_singlestep(void)
 	    ("%s: debug exceptions are not masked", __func__));
 
 	kdb_frame->tf_spsr |= PSR_SS;
+
+	/*
+	 * TODO: Handle single stepping over instructions that access
+	 * the DAIF values. On a read the value will be incorrect.
+	 */
+	kernel_monitor.dbg_flags &= ~PSR_DAIF;
+	kernel_monitor.dbg_flags |= kdb_frame->tf_spsr & PSR_DAIF;
+	kdb_frame->tf_spsr |= (PSR_A | PSR_I | PSR_F);
+
 	WRITE_SPECIALREG(mdscr_el1, READ_SPECIALREG(mdscr_el1) |
 	    MDSCR_SS | MDSCR_KDE);
 
@@ -214,6 +223,9 @@ kdb_cpu_clear_singlestep(void)
 	KASSERT((READ_SPECIALREG(daif) & PSR_D) == PSR_D,
 	    ("%s: debug exceptions are not masked", __func__));
 
+	kdb_frame->tf_spsr &= ~PSR_DAIF;
+	kdb_frame->tf_spsr |= kernel_monitor.dbg_flags & PSR_DAIF;
+
 	WRITE_SPECIALREG(mdscr_el1, READ_SPECIALREG(mdscr_el1) &
 	    ~(MDSCR_SS | MDSCR_KDE));
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202403211013.42LADloU032400>