From mboxrd@z Thu Jan 1 00:00:00 1970 From: David Vrabel Subject: [PATCH 08/12] xen/events: add struct evtchn_ops for the low-level port operations Date: Tue, 19 Mar 2013 21:04:55 +0000 Message-ID: <1363727099-25519-9-git-send-email-david.vrabel@citrix.com> References: <1363727099-25519-1-git-send-email-david.vrabel@citrix.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1363727099-25519-1-git-send-email-david.vrabel@citrix.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xen.org Cc: Wei Liu , Keir Fraser , David Vrabel , Konrad Rzeszutek Wilk List-Id: xen-devel@lists.xenproject.org From: David Vrabel evtchn_ops contains the low-level operations that access the shared data structures. This allows alternate ABIs to be supported. Signed-off-by: David Vrabel --- drivers/xen/events/events.c | 4 ++ drivers/xen/events/events_internal.h | 61 +++++++++++++++++++++++++++++---- drivers/xen/events/n-level.c | 27 ++++++++++---- 3 files changed, 76 insertions(+), 16 deletions(-) diff --git a/drivers/xen/events/events.c b/drivers/xen/events/events.c index e85c00a..1017d9f 100644 --- a/drivers/xen/events/events.c +++ b/drivers/xen/events/events.c @@ -58,6 +58,8 @@ #include "events_internal.h" +struct evtchn_ops evtchn_ops; + /* * This lock protects updates to the following mapping and reference-count * arrays. The lock does not need to be acquired to read the mapping tables. @@ -1482,6 +1484,8 @@ void __init xen_init_IRQ(void) { int i; + evtchn_ops = evtchn_ops_nlevel; + evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq), GFP_KERNEL); BUG_ON(!evtchn_to_irq); diff --git a/drivers/xen/events/events_internal.h b/drivers/xen/events/events_internal.h index 79ac70b..6badb05 100644 --- a/drivers/xen/events/events_internal.h +++ b/drivers/xen/events/events_internal.h @@ -54,21 +54,66 @@ struct irq_info { #define PIRQ_NEEDS_EOI (1 << 0) #define PIRQ_SHAREABLE (1 << 1) +struct evtchn_ops { + void (*bind_to_cpu)(struct irq_info *info, int cpu); + + void (*clear_pending)(int port); + void (*set_pending)(int port); + bool (*is_pending)(int port); + bool (*test_and_set_mask)(int port); + void (*mask)(int port); + void (*unmask)(int port); + + void (*handle_events)(int cpu); +}; + +extern struct evtchn_ops evtchn_ops; +extern struct evtchn_ops evtchn_ops_nlevel; + extern int *evtchn_to_irq; struct irq_info *info_for_irq(unsigned irq); unsigned cpu_from_irq(unsigned irq); unsigned cpu_from_evtchn(unsigned int evtchn); -void xen_evtchn_port_bind_to_cpu(struct irq_info *info, int cpu); +static inline void xen_evtchn_port_bind_to_cpu(struct irq_info *info, int cpu) +{ + evtchn_ops.bind_to_cpu(info, cpu); +} + +static inline void clear_evtchn(int port) +{ + evtchn_ops.clear_pending(port); +} + +static inline void set_evtchn(int port) +{ + evtchn_ops.set_pending(port); +} + +static inline bool test_evtchn(int port) +{ + return evtchn_ops.is_pending(port); +} + +static inline bool test_and_set_mask(int port) +{ + return evtchn_ops.test_and_set_mask(port); +} + +static inline void mask_evtchn(int port) +{ + return evtchn_ops.mask(port); +} -void clear_evtchn(int port); -void set_evtchn(int port); -int test_evtchn(int port); -int test_and_set_mask(int port); -void mask_evtchn(int port); -void unmask_evtchn(int port); +static inline void unmask_evtchn(int port) +{ + return evtchn_ops.unmask(port); +} -void xen_evtchn_handle_events(int cpu); +static inline void xen_evtchn_handle_events(int cpu) +{ + return evtchn_ops.handle_events(cpu); +} #endif /* #ifndef __EVENTS_INTERNAL_H__ */ diff --git a/drivers/xen/events/n-level.c b/drivers/xen/events/n-level.c index 05762d5..74f8e94 100644 --- a/drivers/xen/events/n-level.c +++ b/drivers/xen/events/n-level.c @@ -39,43 +39,43 @@ static DEFINE_PER_CPU(xen_ulong_t [NR_EVENT_CHANNELS/BITS_PER_EVTCHN_WORD], cpu_evtchn_mask); -void xen_evtchn_port_bind_to_cpu(struct irq_info *info, int cpu) +static void nlevel_bind_to_cpu(struct irq_info *info, int cpu) { clear_bit(info->evtchn, BM(per_cpu(cpu_evtchn_mask, info->cpu))); set_bit(info->evtchn, BM(per_cpu(cpu_evtchn_mask, cpu))); } -void clear_evtchn(int port) +static void nlevel_clear_pending(int port) { struct shared_info *s = HYPERVISOR_shared_info; sync_clear_bit(port, BM(&s->evtchn_pending[0])); } -void set_evtchn(int port) +static void nlevel_set_pending(int port) { struct shared_info *s = HYPERVISOR_shared_info; sync_set_bit(port, BM(&s->evtchn_pending[0])); } -int test_evtchn(int port) +static bool nlevel_is_pending(int port) { struct shared_info *s = HYPERVISOR_shared_info; return sync_test_bit(port, BM(&s->evtchn_pending[0])); } -int test_and_set_mask(int port) +static bool nlevel_test_and_set_mask(int port) { struct shared_info *s = HYPERVISOR_shared_info; return sync_test_and_set_bit(port, BM(&s->evtchn_mask[0])); } -void mask_evtchn(int port) +static void nlevel_mask(int port) { struct shared_info *s = HYPERVISOR_shared_info; sync_set_bit(port, BM(&s->evtchn_mask[0])); } -void unmask_evtchn(int port) +static void nlevel_unmask(int port) { struct shared_info *s = HYPERVISOR_shared_info; unsigned int cpu = get_cpu(); @@ -141,7 +141,7 @@ static inline xen_ulong_t active_evtchns(unsigned int cpu, * a bitset of words which contain pending event bits. The second * level is a bitset of pending events themselves. */ -void xen_evtchn_handle_events(int cpu) +static void nlevel_handle_events(int cpu) { xen_ulong_t pending_words; int start_word_idx, start_bit_idx; @@ -313,3 +313,14 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } + +struct evtchn_ops evtchn_ops_nlevel = { + .bind_to_cpu = nlevel_bind_to_cpu, + .clear_pending = nlevel_clear_pending, + .set_pending = nlevel_set_pending, + .is_pending = nlevel_is_pending, + .test_and_set_mask = nlevel_test_and_set_mask, + .mask = nlevel_mask, + .unmask = nlevel_unmask, + .handle_events = nlevel_handle_events, +}; -- 1.7.2.5