From c76e8d338ca6a9e5c417933bec534fb8d919a9a9 Mon Sep 17 00:00:00 2001 From: Roger Pau Monne Date: Wed, 4 Nov 2015 16:34:02 +0100 Subject: [PATCH] xen/intr: fix the event channel enabled per-cpu mask BITSET cannot be used to store the per-cpu event channel masks because its underlying storage is an array of longs. This is fine on x86, but on ARM the event channel pending and masked arrays shared with the hypervisor is an uint64_t regardless of the bitness of the guest. Switch back to using xen_ulong_t, which will always match the type of the arrays shared with the hypervisor. --- sys/x86/xen/xen_intr.c | 38 ++++++++++++++++---------------------- sys/xen/xen-os.h | 12 +++++++++--- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/sys/x86/xen/xen_intr.c b/sys/x86/xen/xen_intr.c index 5fd50d8..9069f32 100644 --- a/sys/x86/xen/xen_intr.c +++ b/sys/x86/xen/xen_intr.c @@ -71,9 +71,6 @@ __FBSDID("$FreeBSD$"); static MALLOC_DEFINE(M_XENINTR, "xen_intr", "Xen Interrupt Services"); -#define ENABLED_SETSIZE (sizeof(u_long) * 8) -BITSET_DEFINE(enabledbits, ENABLED_SETSIZE); - /** * Per-cpu event channel processing state. */ @@ -81,7 +78,7 @@ struct xen_intr_pcpu_data { /** * The last event channel bitmap section (level one bit) processed. * This is used to ensure we scan all ports before - * servicing an already servied port again. + * servicing an already serviced port again. */ u_int last_processed_l1i; @@ -98,7 +95,7 @@ struct xen_intr_pcpu_data { * A bitmap of ports that can be serviced from this CPU. * A set bit means interrupt handling is enabled. */ - struct enabledbits evtchn_enabled; + xen_ulong_t evtchn_enabled[sizeof(xen_ulong_t) * 8]; }; /* @@ -133,8 +130,6 @@ struct xenisrc { 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); @@ -192,7 +187,7 @@ struct pic xen_intr_pirq_pic = { 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]; -static u_long *xen_intr_pirq_eoi_map; +static xen_ulong_t *xen_intr_pirq_eoi_map; static boolean_t xen_intr_pirq_eoi_map_enabled; /*------------------------- Private Functions --------------------------------*/ @@ -215,7 +210,7 @@ evtchn_cpu_mask_port(u_int cpu, evtchn_port_t port) struct xen_intr_pcpu_data *pcpu; pcpu = DPCPU_ID_PTR(cpu, xen_intr_pcpu); - BIT_CLR_ATOMIC(ENABLED_SETSIZE, port, &pcpu->evtchn_enabled); + xen_clear_bit(port, pcpu->evtchn_enabled); } /** @@ -237,7 +232,7 @@ evtchn_cpu_unmask_port(u_int cpu, evtchn_port_t port) struct xen_intr_pcpu_data *pcpu; pcpu = DPCPU_ID_PTR(cpu, xen_intr_pcpu); - BIT_SET_ATOMIC(ENABLED_SETSIZE, port, &pcpu->evtchn_enabled); + xen_set_bit(port, pcpu->evtchn_enabled); } /** @@ -499,9 +494,14 @@ static inline u_long xen_intr_active_ports(struct xen_intr_pcpu_data *pcpu, shared_info_t *sh, u_int idx) { + + CTASSERT(sizeof(sh->evtchn_mask[0]) == sizeof(sh->evtchn_pending[0])); + CTASSERT(sizeof(sh->evtchn_mask[0]) == sizeof(pcpu->evtchn_enabled[0])); + CTASSERT(sizeof(sh->evtchn_mask) == sizeof(sh->evtchn_pending)); + CTASSERT(sizeof(sh->evtchn_mask) == sizeof(pcpu->evtchn_enabled)); return (sh->evtchn_pending[idx] & ~sh->evtchn_mask[idx] - & pcpu->evtchn_enabled.__bits[idx]); + & pcpu->evtchn_enabled[idx]); } /** @@ -637,10 +637,8 @@ xen_intr_init(void *dummy __unused) */ CPU_FOREACH(i) { pcpu = DPCPU_ID_PTR(i, xen_intr_pcpu); - if (i == 0) - BIT_FILL(ENABLED_SETSIZE, &pcpu->evtchn_enabled); - else - BIT_ZERO(ENABLED_SETSIZE, &pcpu->evtchn_enabled); + memset(pcpu->evtchn_enabled, i == 0 ? ~0 : 0, + sizeof(pcpu->evtchn_enabled)); xen_intr_intrcnt_add(i); } @@ -753,11 +751,8 @@ xen_intr_resume(struct pic *unused, bool suspend_cancelled) struct xen_intr_pcpu_data *pcpu; pcpu = DPCPU_ID_PTR(i, xen_intr_pcpu); - - if (i == 0) - BIT_FILL(ENABLED_SETSIZE, &pcpu->evtchn_enabled); - else - BIT_ZERO(ENABLED_SETSIZE, &pcpu->evtchn_enabled); + memset(pcpu->evtchn_enabled, i == 0 ? ~0 : 0, + sizeof(pcpu->evtchn_enabled)); } /* Mask all event channels. */ @@ -1612,8 +1607,7 @@ xen_intr_dump_port(struct xenisrc *isrc) CPU_FOREACH(i) { pcpu = DPCPU_ID_PTR(i, xen_intr_pcpu); db_printf("cpu#%d: %d ", i, - BIT_ISSET(ENABLED_SETSIZE, isrc->xi_port, - &pcpu->evtchn_enabled)); + xen_test_bit(isrc->xi_port, pcpu->evtchn_enabled)); } db_printf("\n"); } diff --git a/sys/xen/xen-os.h b/sys/xen/xen-os.h index eec8244..f224c14 100644 --- a/sys/xen/xen-os.h +++ b/sys/xen/xen-os.h @@ -96,10 +96,10 @@ xen_initial_domain(void) * and we don't want the other drivers using them. * */ -#define NBPL (NBBY * sizeof(long)) +#define NBPL (NBBY * sizeof(xen_ulong_t)) static inline bool -xen_test_bit(int bit, volatile long *addr) +xen_test_bit(int bit, volatile xen_ulong_t *addr) { unsigned long mask = 1UL << (bit % NBPL); @@ -107,11 +107,17 @@ xen_test_bit(int bit, volatile long *addr) } static inline void -xen_set_bit(int bit, volatile long *addr) +xen_set_bit(int bit, volatile xen_ulong_t *addr) { atomic_set_long(&addr[bit / NBPL], 1UL << (bit % NBPL)); } +static inline void +xen_clear_bit(int bit, volatile xen_ulong_t *addr) +{ + atomic_clear_long(&addr[bit / NBPL], 1UL << (bit % NBPL)); +} + #undef NPBL /* -- 1.9.5 (Apple Git-50.3)