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>