From: Julien Grall Date: Tue, 20 Oct 2015 16:14:56 +0000 (+0100) Subject: xen/intr: Introduce xen_arch_intr.c X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=54ceb55806eb36aac5747064764ec71f679ef970;p=people%2Fjulieng%2Ffreebsd.git xen/intr: Introduce xen_arch_intr.c --- diff --git a/sys/amd64/include/xen/arch-intr.h b/sys/amd64/include/xen/arch-intr.h new file mode 100644 index 000000000000..aadfd47a2f23 --- /dev/null +++ b/sys/amd64/include/xen/arch-intr.h @@ -0,0 +1,6 @@ +/*- + * This file is in the public domain. + */ +/* $FreeBSD$ */ + +#include diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 3cb59cb9b90c..9132f7b56d3c 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -617,6 +617,7 @@ x86/xen/hvm.c optional xenhvm x86/xen/pv.c optional xenhvm x86/xen/pvcpu_enum.c optional xenhvm x86/xen/xen_apic.c optional xenhvm +x86/xen/xen_arch_intr.c optional xenhvm x86/xen/xen_nexus.c optional xenhvm x86/xen/xen_msi.c optional xenhvm x86/xen/xen_pci_bus.c optional xenhvm diff --git a/sys/x86/include/xen/arch-intr.h b/sys/x86/include/xen/arch-intr.h new file mode 100644 index 000000000000..522e9ea75dea --- /dev/null +++ b/sys/x86/include/xen/arch-intr.h @@ -0,0 +1,8 @@ +#ifndef _MACHINE_X86_XEN_ARCH_INTR_H_ +#define _MACHINE_X86_XEN_ARCH_INTR_H_ + +#include + +typedef struct intsrc xen_arch_isrc_t; + +#endif /* _MACHINE_X86_XEN_ARCH_INTR_H_ */ diff --git a/sys/x86/xen/xen_arch_intr.c b/sys/x86/xen/xen_arch_intr.c new file mode 100644 index 000000000000..439ed04dea78 --- /dev/null +++ b/sys/x86/xen/xen_arch_intr.c @@ -0,0 +1,253 @@ +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +/********************************* EVTCHN PIC ********************************/ + +static void +xen_intr_pic_enable_source(struct intsrc *isrc) +{ + + xen_intr_enable_source((struct xenisrc *)isrc); +} + +static void +xen_intr_pic_disable_source(struct intsrc *isrc, int eoi) +{ + + xen_intr_disable_source((struct xenisrc *)isrc, eoi == PIC_EOI); +} + +static void +xen_intr_pic_eoi_source(struct intsrc *isrc) +{ + + xen_intr_eoi_source((struct xenisrc *)isrc); +} + +static void +xen_intr_pic_enable_intr(struct intsrc *isrc) +{ + + xen_intr_enable_intr((struct xenisrc *)isrc); +} + +static void +xen_intr_pic_disable_intr(struct intsrc *isrc) +{ + + xen_intr_disable_intr((struct xenisrc *)isrc); +} + +static int +xen_intr_pic_vector(struct intsrc *isrc) +{ + + return (xen_intr_vector((struct xenisrc *)isrc)); +} + +static int +xen_intr_pic_source_pending(struct intsrc *isrc) +{ + + return (xen_intr_source_pending((struct xenisrc *)isrc)); +} + +static void +xen_intr_pic_suspend(struct pic *pic) +{ + + xen_intr_suspend(); +} + +static void +xen_intr_pic_resume(struct pic *pic, bool suspend_cancelled) +{ + + xen_intr_resume(suspend_cancelled); +} + +static int +xen_intr_pic_config_intr(struct intsrc *isrc, enum intr_trigger trig, + enum intr_polarity pol) +{ + + return (xen_intr_config_intr((struct xenisrc *)isrc, trig, pol)); +} + + +static int +xen_intr_pic_assign_cpu(struct intsrc *isrc, u_int apic_id) +{ + + return (xen_intr_assign_cpu((struct xenisrc *)isrc, + apic_cpuid(apic_id))); +} + +/** + * PIC interface for all event channel port types except physical IRQs. + */ +static struct pic xen_intr_pic = { + .pic_enable_source = xen_intr_pic_enable_source, + .pic_disable_source = xen_intr_pic_disable_source, + .pic_eoi_source = xen_intr_pic_eoi_source, + .pic_enable_intr = xen_intr_pic_enable_intr, + .pic_disable_intr = xen_intr_pic_disable_intr, + .pic_vector = xen_intr_pic_vector, + .pic_source_pending = xen_intr_pic_source_pending, + .pic_suspend = xen_intr_pic_suspend, + .pic_resume = xen_intr_pic_resume, + .pic_config_intr = xen_intr_pic_config_intr, + .pic_assign_cpu = xen_intr_pic_assign_cpu +}; + +/****************************** PIRQ PIC *************************************/ + +static void +xen_intr_pirq_pic_enable_source(struct intsrc *isrc) +{ + + xen_intr_pirq_enable_source((struct xenisrc *)isrc); +} + +static void +xen_intr_pirq_pic_disable_source(struct intsrc *isrc, int eoi) +{ + + xen_intr_pirq_disable_source((struct xenisrc *)isrc, eoi == PIC_EOI); +} + +static void +xen_intr_pirq_pic_eoi_source(struct intsrc *isrc) +{ + + xen_intr_pirq_eoi_source((struct xenisrc *)isrc); +} + +static void +xen_intr_pirq_pic_enable_intr(struct intsrc *isrc) +{ + + xen_intr_pirq_enable_intr((struct xenisrc *)isrc); +} + +static void +xen_intr_pirq_pic_disable_intr(struct intsrc *isrc) +{ + + xen_intr_pirq_disable_intr((struct xenisrc *)isrc); +} + +static int +xen_intr_pirq_pic_config_intr(struct intsrc *isrc, enum intr_trigger trig, + enum intr_polarity pol) +{ + + return (xen_intr_pirq_config_intr((struct xenisrc *)isrc, trig, pol)); +} + +/** + * PIC interface for all event channel representing + * physical interrupt sources. + */ +static struct pic xen_intr_pirq_pic = { + .pic_enable_source = xen_intr_pirq_pic_enable_source, + .pic_disable_source = xen_intr_pirq_pic_disable_source, + .pic_eoi_source = xen_intr_pirq_pic_eoi_source, + .pic_enable_intr = xen_intr_pirq_pic_enable_intr, + .pic_disable_intr = xen_intr_pirq_pic_disable_intr, + .pic_vector = xen_intr_pic_vector, + .pic_source_pending = xen_intr_pic_source_pending, + .pic_config_intr = xen_intr_pirq_pic_config_intr, + .pic_assign_cpu = xen_intr_pic_assign_cpu +}; + +/****************************** ARCH wrappers ********************************/ + +void +xen_arch_intr_init(void) +{ + + intr_register_pic(&xen_intr_pic); + intr_register_pic(&xen_intr_pirq_pic); +} + +int +xen_arch_intr_setup(struct xenisrc *isrc) +{ + + KASSERT((intr_lookup_source(isrc->xi_vector) == NULL), + ("Trying to use an already allocated vector")); + + if (isrc->xi_type == EVTCHN_TYPE_PIRQ) + isrc->xi_intsrc.is_pic = &xen_intr_pirq_pic; + else + isrc->xi_intsrc.is_pic = &xen_intr_pic; + + return (intr_register_source(&isrc->xi_intsrc)); +} + +struct xenisrc * +xen_arch_intr_lookup_source(int vector) +{ + + return ((struct xenisrc *)intr_lookup_source(vector)); +} + +bool +xen_arch_intr_has_handlers(struct xenisrc *isrc) +{ + + return (isrc->xi_intsrc.is_handlers != 0); +} + +void +xen_arch_intr_execute_handlers(struct xenisrc *isrc, struct trapframe *frame) +{ + + intr_execute_handlers(&isrc->xi_intsrc, frame); +} + +int +xen_arch_intr_add_handler(device_t dev, driver_filter_t filter, + driver_intr_t handler, void *arg, enum intr_type flags, + struct xenisrc *isrc) +{ + return (intr_add_handler(device_get_nameunit(dev), isrc->xi_vector, + filter, handler, arg, flags, &isrc->xi_cookie)); +} + +int +xen_arch_intr_describe(struct xenisrc *isrc, const char *descr) +{ + return (intr_describe(isrc->xi_vector, isrc->xi_cookie, descr)); +} + +int +xen_arch_intr_remove_handler(struct xenisrc *isrc) +{ + return (intr_remove_handler(isrc->xi_cookie)); +} + +int +xen_arch_intr_event_bind(struct xenisrc *isrc, u_int cpu) +{ + return (intr_event_bind(isrc->xi_intsrc.is_event, cpu)); +} diff --git a/sys/xen/arch-intr.h b/sys/xen/arch-intr.h new file mode 100644 index 000000000000..a1b65e2a6f8a --- /dev/null +++ b/sys/xen/arch-intr.h @@ -0,0 +1,61 @@ +#ifndef _XEN_ARCH_INTR_H_ +#define _XEN_ARCH_INTR_H_ + +#include + +#include + +struct xenisrc { + xen_arch_isrc_t xi_intsrc; + enum evtchn_type xi_type; + int xi_cpu; /* VCPU for delivery */ + int xi_vector; /* Global isrc vector number */ + evtchn_port_t xi_port; + int xi_pirq; + int xi_virq; + void *xi_cookie; + u_int xi_close:1; /* close on unbind? */ + u_int xi_activehi:1; + u_int xi_edgetrigger:1; + u_int xi_masked:1; +}; + +/***************** Functions called by the architecture code *****************/ + +void xen_intr_suspend(void); +void xen_intr_resume(bool suspend_cancelled); +void xen_intr_enable_source(struct xenisrc *isrc); +void xen_intr_disable_source(struct xenisrc *isrc, bool need_eoi); +void xen_intr_eoi_source(struct xenisrc *isrc); +void xen_intr_enable_intr(struct xenisrc *isrc); +void xen_intr_disable_intr(struct xenisrc *isrc); +int xen_intr_vector(struct xenisrc *isrc); +int xen_intr_source_pending(struct xenisrc *isrc); +int xen_intr_config_intr(struct xenisrc *isrc, + enum intr_trigger trig, enum intr_polarity pol); +int xen_intr_assign_cpu(struct xenisrc *isrc, u_int to_cpu); + +void xen_intr_pirq_enable_source(struct xenisrc *isrc); +void xen_intr_pirq_disable_source(struct xenisrc *isrc, bool need_eoi); +void xen_intr_pirq_eoi_source(struct xenisrc *isrc); +void xen_intr_pirq_enable_intr(struct xenisrc *isrc); +void xen_intr_pirq_disable_intr(struct xenisrc *isrc); +int xen_intr_pirq_config_intr(struct xenisrc *isrc, + enum intr_trigger trig, enum intr_polarity pol); + +/******************* Functions implemented by each architecture **************/ + +void xen_arch_intr_init(void); +int xen_arch_intr_setup(struct xenisrc *isrc); +struct xenisrc *xen_arch_intr_lookup_source(int vector); +bool xen_arch_intr_has_handlers(struct xenisrc *isrc); +void xen_arch_intr_execute_handlers(struct xenisrc *isrc, + struct trapframe *frame); +int xen_arch_intr_add_handler(device_t dev, driver_filter_t filter, + driver_intr_t handler, void *arg, enum intr_type flags, + struct xenisrc *isrc); +int xen_arch_intr_describe(struct xenisrc *isrc, const char *descr); +int xen_arch_intr_remove_handler(struct xenisrc *isrc); +int xen_arch_intr_event_bind(struct xenisrc *isrc, u_int cpu); + +#endif /* _XEN_ARCH_INTR_H_ */ diff --git a/sys/xen/evtchn/evtchnvar.h b/sys/xen/evtchn/evtchnvar.h index 8008d23297d3..0da62aab0167 100644 --- a/sys/xen/evtchn/evtchnvar.h +++ b/sys/xen/evtchn/evtchnvar.h @@ -37,6 +37,8 @@ #include #include +#include + enum evtchn_type { EVTCHN_TYPE_UNBOUND, EVTCHN_TYPE_PIRQ, diff --git a/sys/xen/xen_intr.c b/sys/xen/xen_intr.c index 014050631a74..0cba754940d3 100644 --- a/sys/xen/xen_intr.c +++ b/sys/xen/xen_intr.c @@ -49,18 +49,16 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include -#include #include #include +#include +#include +#include #include -#include #include #include -#include #include #include @@ -118,78 +116,8 @@ DPCPU_DECLARE(struct vcpu_info *, vcpu_info); #define is_valid_evtchn(x) ((x) != XEN_INVALID_EVTCHN) -struct xenisrc { - struct intsrc xi_intsrc; - enum evtchn_type xi_type; - int xi_cpu; /* VCPU for delivery. */ - int xi_vector; /* Global isrc vector number. */ - evtchn_port_t xi_port; - int xi_pirq; - int xi_virq; - void *xi_cookie; - u_int xi_close:1; /* close on unbind? */ - u_int xi_activehi:1; - u_int xi_edgetrigger:1; - u_int xi_masked:1; -}; - #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) -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); -static void xen_intr_disable_source(struct intsrc *isrc, int eoi); -static void xen_intr_eoi_source(struct intsrc *isrc); -static void xen_intr_enable_intr(struct intsrc *isrc); -static void xen_intr_disable_intr(struct intsrc *isrc); -static int xen_intr_vector(struct intsrc *isrc); -static int xen_intr_source_pending(struct intsrc *isrc); -static int xen_intr_config_intr(struct intsrc *isrc, - enum intr_trigger trig, enum intr_polarity pol); -static int xen_intr_assign_cpu(struct intsrc *isrc, u_int to_cpu); -static int xen_pic_assign_cpu(struct intsrc *isrc, u_int apic_id); - -static void xen_intr_pirq_enable_source(struct intsrc *isrc); -static void xen_intr_pirq_disable_source(struct intsrc *isrc, int eoi); -static void xen_intr_pirq_eoi_source(struct intsrc *isrc); -static void xen_intr_pirq_enable_intr(struct intsrc *isrc); -static void xen_intr_pirq_disable_intr(struct intsrc *isrc); -static int xen_intr_pirq_config_intr(struct intsrc *isrc, - enum intr_trigger trig, enum intr_polarity pol); - -/** - * PIC interface for all event channel port types except physical IRQs. - */ -struct pic xen_intr_pic = { - .pic_enable_source = xen_intr_enable_source, - .pic_disable_source = xen_intr_disable_source, - .pic_eoi_source = xen_intr_eoi_source, - .pic_enable_intr = xen_intr_enable_intr, - .pic_disable_intr = xen_intr_disable_intr, - .pic_vector = xen_intr_vector, - .pic_source_pending = xen_intr_source_pending, - .pic_suspend = xen_intr_suspend, - .pic_resume = xen_intr_resume, - .pic_config_intr = xen_intr_config_intr, - .pic_assign_cpu = xen_pic_assign_cpu -}; - -/** - * PIC interface for all event channel representing - * physical interrupt sources. - */ -struct pic xen_intr_pirq_pic = { - .pic_enable_source = xen_intr_pirq_enable_source, - .pic_disable_source = xen_intr_pirq_disable_source, - .pic_eoi_source = xen_intr_pirq_eoi_source, - .pic_enable_intr = xen_intr_pirq_enable_intr, - .pic_disable_intr = xen_intr_pirq_disable_intr, - .pic_vector = xen_intr_vector, - .pic_source_pending = xen_intr_source_pending, - .pic_config_intr = xen_intr_pirq_config_intr, - .pic_assign_cpu = xen_pic_assign_cpu -}; - static struct mtx xen_intr_isrc_lock; static int xen_intr_auto_vector_count; static struct xenisrc *xen_intr_port_to_isrc[NR_EVENT_CHANNELS]; @@ -241,6 +169,11 @@ evtchn_cpu_unmask_port(u_int cpu, evtchn_port_t port) BIT_SET_ATOMIC(ENABLED_SETSIZE, port, &pcpu->evtchn_enabled); } +/* + * XXX: FIXME. Use the arch intrcnt counter + */ +static DPCPU_DEFINE(u_long, xen_intrcnt); + /** * Allocate and register a per-cpu Xen upcall interrupt counter. * @@ -249,15 +182,21 @@ evtchn_cpu_unmask_port(u_int cpu, evtchn_port_t port) static void xen_intr_intrcnt_add(u_int cpu) { +#if 0 char buf[MAXCOMLEN + 1]; +#endif struct xen_intr_pcpu_data *pcpu; pcpu = DPCPU_ID_PTR(cpu, xen_intr_pcpu); if (pcpu->evtchn_intrcnt != NULL) return; + pcpu->evtchn_intrcnt = DPCPU_ID_PTR(cpu, xen_intrcnt); + +#if 0 snprintf(buf, sizeof(buf), "cpu%d:xen", cpu); intrcnt_add(buf, &pcpu->evtchn_intrcnt); +#endif } /** @@ -281,10 +220,10 @@ xen_intr_find_unused_isrc(enum evtchn_type type) u_int vector; vector = FIRST_EVTCHN_INT + isrc_idx; - isrc = (struct xenisrc *)intr_lookup_source(vector); + isrc = xen_arch_intr_lookup_source(vector); if (isrc != NULL && isrc->xi_type == EVTCHN_TYPE_UNBOUND) { - KASSERT(isrc->xi_intsrc.is_handlers == 0, + KASSERT(xen_arch_intr_has_handlers(isrc), ("Free evtchn still has handlers")); isrc->xi_type = type; return (isrc); @@ -306,6 +245,7 @@ xen_intr_alloc_isrc(enum evtchn_type type, int vector) { static int warned; struct xenisrc *isrc; + int ret; KASSERT(mtx_owned(&xen_intr_isrc_lock), ("Evtchn alloc lock not held")); @@ -322,18 +262,21 @@ xen_intr_alloc_isrc(enum evtchn_type type, int vector) xen_intr_auto_vector_count++; } - KASSERT((intr_lookup_source(vector) == NULL), - ("Trying to use an already allocated vector")); - mtx_unlock(&xen_intr_isrc_lock); isrc = malloc(sizeof(*isrc), M_XENINTR, M_WAITOK | M_ZERO); - isrc->xi_intsrc.is_pic = - (type == EVTCHN_TYPE_PIRQ) ? &xen_intr_pirq_pic : &xen_intr_pic; isrc->xi_vector = vector; isrc->xi_type = type; - intr_register_source(&isrc->xi_intsrc); + + ret = xen_arch_intr_setup(isrc); + mtx_lock(&xen_intr_isrc_lock); + if (!ret) { + printf("xen_intr_alloc: Unable to setup the interrupt\n"); + free(isrc, M_XENINTR); + return (NULL); + } + return (isrc); } @@ -349,7 +292,7 @@ xen_intr_release_isrc(struct xenisrc *isrc) { mtx_lock(&xen_intr_isrc_lock); - if (isrc->xi_intsrc.is_handlers != 0) { + if (xen_arch_intr_has_handlers(isrc)) { mtx_unlock(&xen_intr_isrc_lock); return (EBUSY); } @@ -435,7 +378,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, intr_next_cpu()); + xen_intr_assign_cpu(isrc, intr_next_cpu()); } #endif @@ -593,7 +536,7 @@ xen_intr_handle_upcall(struct trapframe *trap_frame) ("Received unexpected event on vCPU#%d, event bound to vCPU#%d", PCPU_GET(cpuid), isrc->xi_cpu)); - intr_execute_handlers(&isrc->xi_intsrc, trap_frame); + xen_arch_intr_execute_handlers(isrc, trap_frame); /* * If this is the final port processed, @@ -657,8 +600,7 @@ xen_intr_init(void *dummy __unused) else xen_intr_pirq_eoi_map_enabled = true; - intr_register_pic(&xen_intr_pic); - intr_register_pic(&xen_intr_pirq_pic); + xen_arch_intr_init(); if (bootverbose) printf("Xen interrupt system initialized\n"); @@ -668,12 +610,10 @@ xen_intr_init(void *dummy __unused) SYSINIT(xen_intr_init, SI_SUB_INTR, SI_ORDER_SECOND, xen_intr_init, NULL); /*--------------------------- Common PIC Functions ---------------------------*/ -/** - * Prepare this PIC for system suspension. - */ -static void -xen_intr_suspend(struct pic *unused) +void +xen_intr_suspend(void) { + /* Nothing to do on suspend */ } static void @@ -694,7 +634,7 @@ xen_rebind_ipi(struct xenisrc *isrc) isrc->xi_cpu = 0; xen_intr_port_to_isrc[bind_ipi.port] = isrc; - error = xen_intr_assign_cpu(&isrc->xi_intsrc, cpu); + error = xen_intr_assign_cpu(isrc, cpu); if (error) panic("unable to bind xen IPI to CPU#%d: %d", cpu, error); @@ -724,7 +664,7 @@ xen_rebind_virq(struct xenisrc *isrc) xen_intr_port_to_isrc[bind_virq.port] = isrc; #ifdef SMP - error = xen_intr_assign_cpu(&isrc->xi_intsrc, cpu); + error = xen_intr_assign_cpu(isrc, cpu); if (error) panic("unable to bind xen VIRQ#%d to CPU#%d: %d", isrc->xi_virq, cpu, error); @@ -733,11 +673,8 @@ xen_rebind_virq(struct xenisrc *isrc) evtchn_unmask_port(bind_virq.port); } -/** - * Return this PIC to service after being suspended. - */ -static void -xen_intr_resume(struct pic *unused, bool suspend_cancelled) +void +xen_intr_resume(bool suspend_cancelled) { shared_info_t *s = HYPERVISOR_shared_info; struct xenisrc *isrc; @@ -771,7 +708,7 @@ xen_intr_resume(struct pic *unused, bool suspend_cancelled) u_int vector; vector = FIRST_EVTCHN_INT + isrc_idx; - isrc = (struct xenisrc *)intr_lookup_source(vector); + isrc = xen_arch_intr_lookup_source(vector); if (isrc != NULL) { isrc->xi_port = 0; switch (isrc->xi_type) { @@ -794,10 +731,9 @@ xen_intr_resume(struct pic *unused, bool suspend_cancelled) * * \param isrc The interrupt source to disable. */ -static void -xen_intr_disable_intr(struct intsrc *base_isrc) +void +xen_intr_disable_intr(struct xenisrc *isrc) { - struct xenisrc *isrc = (struct xenisrc *)base_isrc; evtchn_mask_port(isrc->xi_port); } @@ -810,10 +746,9 @@ xen_intr_disable_intr(struct intsrc *base_isrc) * * \return The vector number corresponding to the given interrupt source. */ -static int -xen_intr_vector(struct intsrc *base_isrc) +int +xen_intr_vector(struct xenisrc *isrc) { - struct xenisrc *isrc = (struct xenisrc *)base_isrc; return (isrc->xi_vector); } @@ -826,8 +761,8 @@ xen_intr_vector(struct intsrc *base_isrc) * * \returns 0 if no events are pending, otherwise non-zero. */ -static int -xen_intr_source_pending(struct intsrc *isrc) +int +xen_intr_source_pending(struct xenisrc *isrc) { /* * EventChannels are edge triggered and never masked. @@ -845,8 +780,8 @@ xen_intr_source_pending(struct intsrc *isrc) * * \returns 0 if no events are pending, otherwise non-zero. */ -static int -xen_intr_config_intr(struct intsrc *isrc, enum intr_trigger trig, +int +xen_intr_config_intr(struct xenisrc *isrc, enum intr_trigger trig, enum intr_polarity pol) { /* Configuration is only possible via the evtchn apis. */ @@ -861,14 +796,13 @@ xen_intr_config_intr(struct intsrc *isrc, enum intr_trigger trig, * * \returns 0 if successful, otherwise an errno. */ -static int -xen_intr_assign_cpu(struct intsrc *base_isrc, u_int to_cpu) +int +xen_intr_assign_cpu(struct xenisrc *isrc, u_int to_cpu) { #ifdef SMP struct evtchn_bind_vcpu bind_vcpu; - struct xenisrc *isrc; u_int vcpu_id = cpu_to_vcpu_id(to_cpu); - int error; + int error, masked; if (!xen_support_evtchn_rebind()) return (EOPNOTSUPP); @@ -876,7 +810,6 @@ xen_intr_assign_cpu(struct intsrc *base_isrc, u_int to_cpu) xen_intr_intrcnt_add(to_cpu); mtx_lock(&xen_intr_isrc_lock); - isrc = (struct xenisrc *)base_isrc; if (!is_valid_evtchn(isrc->xi_port)) { mtx_unlock(&xen_intr_isrc_lock); return (EINVAL); @@ -923,27 +856,17 @@ out: #endif } -/* Wrapper of xen_intr_assign_cpu to use as pic callbacks */ -static int -xen_pic_assign_cpu(struct intsrc *isrc, u_int apic_id) -{ - return xen_intr_assign_cpu(isrc, apic_cpuid(apic_id)); -} - /*------------------- Virtual Interrupt Source PIC Functions -----------------*/ /* * Mask a level triggered interrupt source. * - * \param isrc The interrupt source to mask (if necessary). - * \param eoi If non-zero, perform any necessary end-of-interrupt - * acknowledgements. + * \param isrc The interrupt source to mask (if necessary). + * \param need_eoi If true, perform any necessary end-of-interrupt + * acknowledgements. */ -static void -xen_intr_disable_source(struct intsrc *base_isrc, int eoi) +void +xen_intr_disable_source(struct xenisrc *isrc, bool need_eoi) { - struct xenisrc *isrc; - - isrc = (struct xenisrc *)base_isrc; /* * NB: checking if the event channel is already masked is @@ -961,13 +884,9 @@ xen_intr_disable_source(struct intsrc *base_isrc, int eoi) * * \param isrc The interrupt source to unmask (if necessary). */ -static void -xen_intr_enable_source(struct intsrc *base_isrc) +void +xen_intr_enable_source(struct xenisrc *isrc) { - struct xenisrc *isrc; - - isrc = (struct xenisrc *)base_isrc; - if (isrc->xi_masked == 0) evtchn_unmask_port(isrc->xi_port); } @@ -977,8 +896,8 @@ xen_intr_enable_source(struct intsrc *base_isrc) * * \param isrc The interrupt source to EOI. */ -static void -xen_intr_eoi_source(struct intsrc *base_isrc) +void +xen_intr_eoi_source(struct xenisrc *isrc) { } @@ -987,10 +906,9 @@ xen_intr_eoi_source(struct intsrc *base_isrc) * * \param isrc The interrupt source to enable. */ -static void -xen_intr_enable_intr(struct intsrc *base_isrc) +void +xen_intr_enable_intr(struct xenisrc *isrc) { - struct xenisrc *isrc = (struct xenisrc *)base_isrc; evtchn_unmask_port(isrc->xi_port); } @@ -1000,20 +918,17 @@ xen_intr_enable_intr(struct intsrc *base_isrc) * Mask a level triggered interrupt source. * * \param isrc The interrupt source to mask (if necessary). - * \param eoi If non-zero, perform any necessary end-of-interrupt + * \param need_eoi If true, perform any necessary end-of-interrupt * acknowledgements. */ -static void -xen_intr_pirq_disable_source(struct intsrc *base_isrc, int eoi) +void +xen_intr_pirq_disable_source(struct xenisrc *isrc, bool need_eoi) { - struct xenisrc *isrc; - - isrc = (struct xenisrc *)base_isrc; if (isrc->xi_edgetrigger == 0) evtchn_mask_port(isrc->xi_port); - if (eoi == PIC_EOI) - xen_intr_pirq_eoi_source(base_isrc); + if (need_eoi) + xen_intr_pirq_eoi_source(isrc); } /* @@ -1021,12 +936,9 @@ xen_intr_pirq_disable_source(struct intsrc *base_isrc, int eoi) * * \param isrc The interrupt source to unmask (if necessary). */ -static void -xen_intr_pirq_enable_source(struct intsrc *base_isrc) +void +xen_intr_pirq_enable_source(struct xenisrc *isrc) { - struct xenisrc *isrc; - - isrc = (struct xenisrc *)base_isrc; if (isrc->xi_edgetrigger == 0) evtchn_unmask_port(isrc->xi_port); @@ -1037,14 +949,11 @@ xen_intr_pirq_enable_source(struct intsrc *base_isrc) * * \param isrc The interrupt source to EOI. */ -static void -xen_intr_pirq_eoi_source(struct intsrc *base_isrc) +void +xen_intr_pirq_eoi_source(struct xenisrc *isrc) { - struct xenisrc *isrc; int error; - isrc = (struct xenisrc *)base_isrc; - if (xen_test_bit(isrc->xi_pirq, xen_intr_pirq_eoi_map)) { struct physdev_eoi eoi = { .irq = isrc->xi_pirq }; @@ -1060,16 +969,13 @@ xen_intr_pirq_eoi_source(struct intsrc *base_isrc) * * \param isrc The interrupt source to enable. */ -static void -xen_intr_pirq_enable_intr(struct intsrc *base_isrc) +void +xen_intr_pirq_enable_intr(struct xenisrc *isrc) { - struct xenisrc *isrc; struct evtchn_bind_pirq bind_pirq; struct physdev_irq_status_query irq_status; int error; - isrc = (struct xenisrc *)base_isrc; - if (!xen_intr_pirq_eoi_map_enabled) { irq_status.irq = isrc->xi_pirq; error = HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, @@ -1108,15 +1014,12 @@ xen_intr_pirq_enable_intr(struct intsrc *base_isrc) * * \param isrc The interrupt source to disable. */ -static void -xen_intr_pirq_disable_intr(struct intsrc *base_isrc) +void +xen_intr_pirq_disable_intr(struct xenisrc *isrc) { - struct xenisrc *isrc; struct evtchn_close close; int error; - isrc = (struct xenisrc *)base_isrc; - evtchn_mask_port(isrc->xi_port); close.port = isrc->xi_port; @@ -1141,11 +1044,10 @@ xen_intr_pirq_disable_intr(struct intsrc *base_isrc) * * \returns 0 if no events are pending, otherwise non-zero. */ -static int -xen_intr_pirq_config_intr(struct intsrc *base_isrc, enum intr_trigger trig, +int +xen_intr_pirq_config_intr(struct xenisrc *isrc, enum intr_trigger trig, enum intr_polarity pol) { - struct xenisrc *isrc = (struct xenisrc *)base_isrc; struct physdev_setup_gsi setup_gsi; int error; @@ -1298,7 +1200,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 = xen_arch_intr_event_bind(isrc, cpu); #endif if (error != 0) { @@ -1318,7 +1220,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, cpu); } #endif @@ -1360,7 +1262,7 @@ xen_intr_alloc_and_bind_ipi(device_t dev, u_int cpu, dev, filter, NULL, NULL, flags, port_handlep); if (error == 0) - error = intr_event_bind(isrc->xi_intsrc.is_event, cpu); + error = xen_arch_intr_event_bind(isrc, cpu); if (error != 0) { evtchn_close_t close = { .port = bind_ipi.port }; @@ -1378,7 +1280,7 @@ xen_intr_alloc_and_bind_ipi(device_t dev, 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, cpu); } /* @@ -1473,7 +1375,7 @@ xen_release_msi(int vector) struct xenisrc *isrc; int ret; - isrc = (struct xenisrc *)intr_lookup_source(vector); + isrc = xen_arch_intr_lookup_source(vector); if (isrc == NULL) return (ENXIO); @@ -1501,7 +1403,8 @@ 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 (xen_arch_intr_describe(isrc, descr)); } void @@ -1518,7 +1421,7 @@ xen_intr_unbind(xen_intr_handle_t *port_handlep) return; if (isrc->xi_cookie != NULL) - intr_remove_handler(isrc->xi_cookie); + xen_arch_intr_remove_handler(isrc); xen_intr_release_isrc(isrc); } @@ -1545,7 +1448,7 @@ xen_intr_port(xen_intr_handle_t handle) isrc = xen_intr_isrc(handle); if (isrc == NULL) return (0); - + return (isrc->xi_port); } @@ -1561,8 +1464,8 @@ xen_intr_add_handler(device_t dev, driver_filter_t filter, if (isrc == NULL || isrc->xi_cookie != NULL) return (EINVAL); - error = intr_add_handler(device_get_nameunit(dev), isrc->xi_vector, - filter, handler, arg, flags|INTR_EXCL, &isrc->xi_cookie); + error = xen_arch_intr_add_handler(dev, filter, handler, arg, + flags | INTR_EXCL, isrc); if (error != 0) { device_printf(dev, "xen_intr_add_handler: intr_add_handler failed: %d\n",