git: ab7ce14b1d9d - main - xen/intr: introduce dev/xen/bus/intr-internal.h

From: Roger Pau Monné <royger_at_FreeBSD.org>
Date: Fri, 14 Apr 2023 14:00:59 UTC
The branch main has been updated by royger:

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

commit ab7ce14b1d9da0cc2f77102be7ac287f8df5c52c
Author:     Julien Grall <julien@xen.org>
AuthorDate: 2015-10-20 16:14:56 +0000
Commit:     Roger Pau Monné <royger@FreeBSD.org>
CommitDate: 2023-04-14 13:58:53 +0000

    xen/intr: introduce dev/xen/bus/intr-internal.h
    
    Move the xenisrc structure which needs to be shared between the core Xen
    interrupt code and architecture-dependent code into a separate header.  A
    similar situation exists for the NR_EVENT_CHANNELS constant.
    
    Turn xi_intsrc into a type definition named xi_arch to reflect the new
    purpose of being an architectural variable for the interrupt source.
    
    This was originally implemented by Julien Grall, but has been heavily
    modified.  The core side was renamed "intr-internal.h" and is #include'd
    by "arch-intr.h" instead of the other way around.  This allows the
    architecture to add function definitions which use struct xenisrc.
    
    The original version only moved xi_intsrc into xen_arch_isrc_t.  Moving
    xi_vector was done by the submitter.
    
    The submitter had also moved xi_activehi and xi_edgetrigger into
    xen_arch_isrc_t.  Those disappeared with the removal of PVHv1 support.
    
    Copyright note.  The current xenisrc structure was introduced at
    76acc41fb7c7 by Justin T. Gibbs.  Traces remain, but the strength of
    Copyright claims from before 2013 seem pretty weak.
    
    Reviewed by: royger
    Submitted by: Elliott Mitchell <ehem+freebsd@m5p.com>, 2021-03-17 19:09:01
    Original implementation: Julien Grall <julien@xen.org>, 2015-10-20 09:14:56
    Differential Revision: https://reviews.freebsd.org/D30648
    [royger]
     - Adjust some line lengths
     - Fix comment about NR_EVENT_CHANNELS after movement.
     - Use #include instead of symlinks.
---
 sys/amd64/include/xen/arch-intr.h |  3 +++
 sys/dev/xen/bus/intr-internal.h   | 54 +++++++++++++++++++++++++++++++++++++++
 sys/i386/include/xen/arch-intr.h  |  3 +++
 sys/x86/include/xen/arch-intr.h   | 41 +++++++++++++++++++++++++++++
 sys/x86/xen/xen_intr.c            | 52 ++++++++++++++-----------------------
 5 files changed, 120 insertions(+), 33 deletions(-)

diff --git a/sys/amd64/include/xen/arch-intr.h b/sys/amd64/include/xen/arch-intr.h
new file mode 100644
index 000000000000..6ea4b79be03f
--- /dev/null
+++ b/sys/amd64/include/xen/arch-intr.h
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+#include <x86/include/xen/arch-intr.h>
diff --git a/sys/dev/xen/bus/intr-internal.h b/sys/dev/xen/bus/intr-internal.h
new file mode 100644
index 000000000000..222e0665b14d
--- /dev/null
+++ b/sys/dev/xen/bus/intr-internal.h
@@ -0,0 +1,54 @@
+/*-
+ * SPDX-License-Identifier: MIT OR GPL-2.0-only
+ *
+ * Copyright © 2002-2005 K A Fraser
+ * Copyright © 2005 Intel Corporation <xiaofeng.ling@intel.com>
+ * Copyright © 2013 Spectra Logic Corporation
+ * Copyright © 2015 Julien Grall
+ * Copyright © 2021,2022 Elliott Mitchell
+ *
+ * This file may be distributed separately from the Linux kernel, or
+ * incorporated into other software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef	_XEN_INTR_INTERNAL_H_
+#define	_XEN_INTR_INTERNAL_H_
+
+#ifndef	_MACHINE__XEN_ARCH_INTR_H_
+#error	"do not #include intr-internal.h, #include machine/arch-intr.h instead"
+#endif
+
+/* Current implementation only supports 2L event channels. */
+#define NR_EVENT_CHANNELS EVTCHN_2L_NR_CHANNELS
+
+struct xenisrc {
+	xen_arch_isrc_t		xi_arch;	/* @TOP -> *xi_arch=*xenisrc */
+	enum evtchn_type	xi_type;
+	u_int			xi_cpu;		/* VCPU for delivery */
+	evtchn_port_t		xi_port;
+	u_int			xi_virq;
+	void			*xi_cookie;
+	bool			xi_close:1;	/* close on unbind? */
+	bool			xi_masked:1;
+	volatile u_int		xi_refcount;
+};
+
+#endif	/* _XEN_INTR_INTERNAL_H_ */
diff --git a/sys/i386/include/xen/arch-intr.h b/sys/i386/include/xen/arch-intr.h
new file mode 100644
index 000000000000..6ea4b79be03f
--- /dev/null
+++ b/sys/i386/include/xen/arch-intr.h
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+#include <x86/include/xen/arch-intr.h>
diff --git a/sys/x86/include/xen/arch-intr.h b/sys/x86/include/xen/arch-intr.h
new file mode 100644
index 000000000000..b721e744852a
--- /dev/null
+++ b/sys/x86/include/xen/arch-intr.h
@@ -0,0 +1,41 @@
+/*-
+ * SPDX-License-Identifier: MIT OR GPL-2.0-only
+ *
+ * Copyright © 2015 Julien Grall
+ * Copyright © 2021 Elliott Mitchell
+ *
+ * This file may be distributed separately from the Linux kernel, or
+ * incorporated into other software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef	_MACHINE__XEN_ARCH_INTR_H_
+#define	_MACHINE__XEN_ARCH_INTR_H_
+
+#include <x86/intr_machdep.h>
+
+typedef struct {
+	struct intsrc		intsrc;		/* @TOP -> *xen_arch_isrc */
+	u_int			vector;		/* Global isrc vector number */
+} xen_arch_isrc_t;
+
+#include <dev/xen/bus/intr-internal.h>
+
+#endif	/* _MACHINE__XEN_ARCH_INTR_H_ */
diff --git a/sys/x86/xen/xen_intr.c b/sys/x86/xen/xen_intr.c
index 0c4d2cd9222b..e23a021c069b 100644
--- a/sys/x86/xen/xen_intr.c
+++ b/sys/x86/xen/xen_intr.c
@@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm.h>
 #include <vm/pmap.h>
 
-#include <machine/intr_machdep.h>
 #include <machine/smp.h>
 #include <machine/stdarg.h>
 
@@ -63,14 +62,12 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/xen/xenpci/xenpcivar.h>
 #include <dev/pci/pcivar.h>
+#include <machine/xen/arch-intr.h>
 
 #ifdef DDB
 #include <ddb/ddb.h>
 #endif
 
-/* The code below is the implementation of 2L event channels. */
-#define NR_EVENT_CHANNELS EVTCHN_2L_NR_CHANNELS
-
 static MALLOC_DEFINE(M_XENINTR, "xen_intr", "Xen Interrupt Services");
 
 /*
@@ -123,19 +120,6 @@ DPCPU_DECLARE(struct vcpu_info *, vcpu_info);
 #define	INVALID_EVTCHN		(~(evtchn_port_t)0) /* Invalid event channel */
 #define	is_valid_evtchn(x)	((uintmax_t)(x) < NR_EVENT_CHANNELS)
 
-struct xenisrc {
-	struct intsrc	xi_intsrc;
-	enum evtchn_type xi_type;
-	u_int		xi_cpu;		/* VCPU for delivery. */
-	u_int		xi_vector;	/* Global isrc vector number. */
-	evtchn_port_t	xi_port;
-	u_int		xi_virq;
-	void		*xi_cookie;
-	bool		xi_close:1;	/* close on unbind? */
-	bool		xi_masked:1;
-	volatile u_int	xi_refcount;
-};
-
 static void	xen_intr_suspend(struct pic *);
 static void	xen_intr_resume(struct pic *, bool suspend_cancelled);
 static void	xen_intr_enable_source(struct intsrc *isrc);
@@ -288,9 +272,10 @@ xen_intr_find_unused_isrc(enum evtchn_type type)
 		 * 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) &&
+		    __predict_true(isrc->xi_arch.intsrc.is_pic ==
+		    &xen_intr_pic) &&
 		    isrc->xi_type == EVTCHN_TYPE_UNBOUND) {
-			KASSERT(isrc->xi_intsrc.is_handlers == 0,
+			KASSERT(isrc->xi_arch.intsrc.is_handlers == 0,
 			    ("Free evtchn still has handlers"));
 			isrc->xi_type = type;
 			return (isrc);
@@ -339,10 +324,10 @@ xen_intr_alloc_isrc(enum evtchn_type type)
 
 	mtx_unlock(&xen_intr_x86_lock);
 	isrc = malloc(sizeof(*isrc), M_XENINTR, M_WAITOK | M_ZERO);
-	isrc->xi_intsrc.is_pic = &xen_intr_pic;
-	isrc->xi_vector = vector;
+	isrc->xi_arch.intsrc.is_pic = &xen_intr_pic;
+	isrc->xi_arch.vector = vector;
 	isrc->xi_type = type;
-	error = intr_register_source(&isrc->xi_intsrc);
+	error = intr_register_source(&isrc->xi_arch.intsrc);
 	if (error != 0)
 		panic("%s(): failed registering interrupt %u, error=%d\n",
 		    __func__, vector, error);
@@ -361,7 +346,7 @@ static int
 xen_intr_release_isrc(struct xenisrc *isrc)
 {
 
-	KASSERT(isrc->xi_intsrc.is_handlers == 0,
+	KASSERT(isrc->xi_arch.intsrc.is_handlers == 0,
 	    ("Release called, but xenisrc still in use"));
 	mtx_lock(&xen_intr_isrc_lock);
 	if (is_valid_evtchn(isrc->xi_port)) {
@@ -447,7 +432,7 @@ xen_intr_bind_isrc(struct xenisrc **isrcp, evtchn_port_t local_port,
 		 * unless specified otherwise, so shuffle them to balance
 		 * the interrupt load.
 		 */
-		xen_intr_assign_cpu(&isrc->xi_intsrc,
+		xen_intr_assign_cpu(&isrc->xi_arch.intsrc,
 		    apic_cpuid(intr_next_cpu(0)));
 	}
 #endif
@@ -578,7 +563,8 @@ xen_intr_handle_upcall(void *unused __unused)
 				("Received unexpected event on vCPU#%u, event bound to vCPU#%u",
 				PCPU_GET(cpuid), isrc->xi_cpu));
 
-			intr_execute_handlers(&isrc->xi_intsrc, trap_frame);
+			intr_execute_handlers(&isrc->xi_arch.intsrc,
+			    trap_frame);
 
 			/*
 			 * If this is the final port processed,
@@ -732,7 +718,7 @@ xen_intr_rebind_isrc(struct xenisrc *isrc)
 
 #ifdef SMP
 	isrc->xi_cpu = 0;
-	error = xen_intr_assign_cpu(&isrc->xi_intsrc, cpu);
+	error = xen_intr_assign_cpu(&isrc->xi_arch.intsrc, cpu);
 	if (error)
 		panic("%s(): unable to rebind Xen channel %u to vCPU%u: %d",
 		    __func__, isrc->xi_port, cpu, error);
@@ -821,7 +807,7 @@ xen_intr_vector(struct intsrc *base_isrc)
 {
 	struct xenisrc *isrc = (struct xenisrc *)base_isrc;
 
-	return (isrc->xi_vector);
+	return (isrc->xi_arch.vector);
 }
 
 /**
@@ -1124,7 +1110,7 @@ xen_intr_bind_virq(device_t dev, u_int virq, u_int cpu,
 
 #ifdef SMP
 	if (error == 0)
-		error = intr_event_bind(isrc->xi_intsrc.is_event, cpu);
+		error = intr_event_bind(isrc->xi_arch.intsrc.is_event, cpu);
 #endif
 
 	if (error != 0) {
@@ -1144,7 +1130,7 @@ xen_intr_bind_virq(device_t dev, u_int virq, u_int cpu,
 		 * masks manually so events can't fire on the wrong cpu
 		 * during AP startup.
 		 */
-		xen_intr_assign_cpu(&isrc->xi_intsrc, cpu);
+		xen_intr_assign_cpu(&isrc->xi_arch.intsrc, cpu);
 	}
 #endif
 
@@ -1200,7 +1186,7 @@ xen_intr_alloc_and_bind_ipi(u_int cpu, driver_filter_t filter,
 		 * masks manually so events can't fire on the wrong cpu
 		 * during AP startup.
 		 */
-		xen_intr_assign_cpu(&isrc->xi_intsrc, cpu);
+		xen_intr_assign_cpu(&isrc->xi_arch.intsrc, cpu);
 	}
 
 	/*
@@ -1228,7 +1214,7 @@ xen_intr_describe(xen_intr_handle_t port_handle, const char *fmt, ...)
 	va_start(ap, fmt);
 	vsnprintf(descr, sizeof(descr), fmt, ap);
 	va_end(ap);
-	return (intr_describe(isrc->xi_vector, isrc->xi_cookie, descr));
+	return (intr_describe(isrc->xi_arch.vector, isrc->xi_cookie, descr));
 }
 
 void
@@ -1295,8 +1281,8 @@ xen_intr_add_handler(const char *name, driver_filter_t filter,
 	if (isrc == NULL || isrc->xi_cookie != NULL)
 		return (EINVAL);
 
-	error = intr_add_handler(name, isrc->xi_vector,filter, handler, arg,
-	    flags|INTR_EXCL, &isrc->xi_cookie, 0);
+	error = intr_add_handler(name, isrc->xi_arch.vector, filter, handler,
+	    arg, flags|INTR_EXCL, &isrc->xi_cookie, 0);
 	if (error != 0)
 		printf("%s: %s: add handler failed: %d\n", name, __func__,
 		    error);