git: 49ca3167b7be - main - xen/intr: add check for intr_register_source() errors
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 29 Mar 2023 07:52:30 UTC
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);