Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 29 Mar 2023 07:52:30 GMT
From:      =?utf-8?Q?Roger=20Pau=20Monn=C3=A9?= <royger@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 49ca3167b7be - main - xen/intr: add check for intr_register_source() errors
Message-ID:  <202303290752.32T7qU1t052037@gitrepo.freebsd.org>

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

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

commit 49ca3167b7be6145b238588573673a0f14f9e7e2
Author:     Elliott Mitchell <ehem+freebsd@m5p.com>
AuthorDate: 2021-09-13 06:12:08 +0000
Commit:     Roger Pau Monné <royger@FreeBSD.org>
CommitDate: 2023-03-29 07:51:41 +0000

    xen/intr: add check for intr_register_source() errors
    
    While unusual, intr_register_source() can return failure.  A likely
    cause might be another device grabbing from Xen's interrupt range.
    This should NOT happen, but could happen due to a bug.  As such check
    for this and fail if it occurs.
    
    This theoretical situation also effects xen_intr_find_unused_isrc().
    There, .is_pic must be tested to ensure such an intrusion doesn't cause
    misbehavior.
    
    Reviewed by: royger
    MFC after: 1 week
    Differential Revision: https://reviews.freebsd.org/D31995
---
 sys/x86/xen/xen_intr.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/sys/x86/xen/xen_intr.c b/sys/x86/xen/xen_intr.c
index 3a053b10f915..cf4560b6b5fb 100644
--- a/sys/x86/xen/xen_intr.c
+++ b/sys/x86/xen/xen_intr.c
@@ -285,8 +285,16 @@ xen_intr_find_unused_isrc(enum evtchn_type type)
 
 		vector = first_evtchn_irq + isrc_idx;
 		isrc = (struct xenisrc *)intr_lookup_source(vector);
-		if (isrc != NULL
-		 && isrc->xi_type == EVTCHN_TYPE_UNBOUND) {
+		/*
+		 * Since intr_register_source() must be called while unlocked,
+		 * isrc == NULL *will* occur, though very infrequently.
+		 *
+		 * This also allows a very small gap where a foreign intrusion
+		 * into Xen's interrupt range could be examined by this test.
+		 */
+		if (__predict_true(isrc != NULL) &&
+		    __predict_true(isrc->xi_intsrc.is_pic == &xen_intr_pic) &&
+		    isrc->xi_type == EVTCHN_TYPE_UNBOUND) {
 			KASSERT(isrc->xi_intsrc.is_handlers == 0,
 			    ("Free evtchn still has handlers"));
 			isrc->xi_type = type;
@@ -310,6 +318,7 @@ xen_intr_alloc_isrc(enum evtchn_type type)
 	static int warned;
 	struct xenisrc *isrc;
 	unsigned int vector;
+	int error;
 
 	KASSERT(mtx_owned(&xen_intr_isrc_lock), ("Evtchn alloc lock not held"));
 
@@ -332,7 +341,10 @@ xen_intr_alloc_isrc(enum evtchn_type type)
 	isrc->xi_intsrc.is_pic = &xen_intr_pic;
 	isrc->xi_vector = vector;
 	isrc->xi_type = type;
-	intr_register_source(&isrc->xi_intsrc);
+	error = intr_register_source(&isrc->xi_intsrc);
+	if (error != 0)
+		panic("%s(): failed registering interrupt %u, error=%d\n",
+		    __func__, vector, error);
 	mtx_lock(&xen_intr_isrc_lock);
 
 	return (isrc);



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