aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen/events
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@citrix.com>2013-03-14 08:49:19 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2014-01-06 10:07:43 -0500
commitab9a1cca3d172876ae9d5edb63abce7986045597 (patch)
tree1ae3ed8c8f54b7e50abf9336643c7f8110eca880 /drivers/xen/events
parent9a489f45a155fe96b9b55fbbef2b757ef7737cfc (diff)
xen/events: add struct evtchn_ops for the low-level port operations
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 <david.vrabel@citrix.com> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Diffstat (limited to 'drivers/xen/events')
-rw-r--r--drivers/xen/events/events_2l.c33
-rw-r--r--drivers/xen/events/events_base.c4
-rw-r--r--drivers/xen/events/events_internal.h63
3 files changed, 84 insertions, 16 deletions
diff --git a/drivers/xen/events/events_2l.c b/drivers/xen/events/events_2l.c
index a77e98d025fa..e55677cca745 100644
--- a/drivers/xen/events/events_2l.c
+++ b/drivers/xen/events/events_2l.c
@@ -41,43 +41,43 @@
41static DEFINE_PER_CPU(xen_ulong_t [NR_EVENT_CHANNELS/BITS_PER_EVTCHN_WORD], 41static DEFINE_PER_CPU(xen_ulong_t [NR_EVENT_CHANNELS/BITS_PER_EVTCHN_WORD],
42 cpu_evtchn_mask); 42 cpu_evtchn_mask);
43 43
44void xen_evtchn_port_bind_to_cpu(struct irq_info *info, int cpu) 44static void evtchn_2l_bind_to_cpu(struct irq_info *info, unsigned cpu)
45{ 45{
46 clear_bit(info->evtchn, BM(per_cpu(cpu_evtchn_mask, info->cpu))); 46 clear_bit(info->evtchn, BM(per_cpu(cpu_evtchn_mask, info->cpu)));
47 set_bit(info->evtchn, BM(per_cpu(cpu_evtchn_mask, cpu))); 47 set_bit(info->evtchn, BM(per_cpu(cpu_evtchn_mask, cpu)));
48} 48}
49 49
50void clear_evtchn(int port) 50static void evtchn_2l_clear_pending(unsigned port)
51{ 51{
52 struct shared_info *s = HYPERVISOR_shared_info; 52 struct shared_info *s = HYPERVISOR_shared_info;
53 sync_clear_bit(port, BM(&s->evtchn_pending[0])); 53 sync_clear_bit(port, BM(&s->evtchn_pending[0]));
54} 54}
55 55
56void set_evtchn(int port) 56static void evtchn_2l_set_pending(unsigned port)
57{ 57{
58 struct shared_info *s = HYPERVISOR_shared_info; 58 struct shared_info *s = HYPERVISOR_shared_info;
59 sync_set_bit(port, BM(&s->evtchn_pending[0])); 59 sync_set_bit(port, BM(&s->evtchn_pending[0]));
60} 60}
61 61
62int test_evtchn(int port) 62static bool evtchn_2l_is_pending(unsigned port)
63{ 63{
64 struct shared_info *s = HYPERVISOR_shared_info; 64 struct shared_info *s = HYPERVISOR_shared_info;
65 return sync_test_bit(port, BM(&s->evtchn_pending[0])); 65 return sync_test_bit(port, BM(&s->evtchn_pending[0]));
66} 66}
67 67
68int test_and_set_mask(int port) 68static bool evtchn_2l_test_and_set_mask(unsigned port)
69{ 69{
70 struct shared_info *s = HYPERVISOR_shared_info; 70 struct shared_info *s = HYPERVISOR_shared_info;
71 return sync_test_and_set_bit(port, BM(&s->evtchn_mask[0])); 71 return sync_test_and_set_bit(port, BM(&s->evtchn_mask[0]));
72} 72}
73 73
74void mask_evtchn(int port) 74static void evtchn_2l_mask(unsigned port)
75{ 75{
76 struct shared_info *s = HYPERVISOR_shared_info; 76 struct shared_info *s = HYPERVISOR_shared_info;
77 sync_set_bit(port, BM(&s->evtchn_mask[0])); 77 sync_set_bit(port, BM(&s->evtchn_mask[0]));
78} 78}
79 79
80void unmask_evtchn(int port) 80static void evtchn_2l_unmask(unsigned port)
81{ 81{
82 struct shared_info *s = HYPERVISOR_shared_info; 82 struct shared_info *s = HYPERVISOR_shared_info;
83 unsigned int cpu = get_cpu(); 83 unsigned int cpu = get_cpu();
@@ -153,7 +153,7 @@ static inline xen_ulong_t active_evtchns(unsigned int cpu,
153 * a bitset of words which contain pending event bits. The second 153 * a bitset of words which contain pending event bits. The second
154 * level is a bitset of pending events themselves. 154 * level is a bitset of pending events themselves.
155 */ 155 */
156void xen_evtchn_handle_events(int cpu) 156static void evtchn_2l_handle_events(unsigned cpu)
157{ 157{
158 int irq; 158 int irq;
159 xen_ulong_t pending_words; 159 xen_ulong_t pending_words;
@@ -346,3 +346,20 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id)
346 346
347 return IRQ_HANDLED; 347 return IRQ_HANDLED;
348} 348}
349
350static const struct evtchn_ops evtchn_ops_2l = {
351 .bind_to_cpu = evtchn_2l_bind_to_cpu,
352 .clear_pending = evtchn_2l_clear_pending,
353 .set_pending = evtchn_2l_set_pending,
354 .is_pending = evtchn_2l_is_pending,
355 .test_and_set_mask = evtchn_2l_test_and_set_mask,
356 .mask = evtchn_2l_mask,
357 .unmask = evtchn_2l_unmask,
358 .handle_events = evtchn_2l_handle_events,
359};
360
361void __init xen_evtchn_2l_init(void)
362{
363 pr_info("Using 2-level ABI\n");
364 evtchn_ops = &evtchn_ops_2l;
365}
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 8771b740e30f..7c7b744cd13d 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -61,6 +61,8 @@
61 61
62#include "events_internal.h" 62#include "events_internal.h"
63 63
64const struct evtchn_ops *evtchn_ops;
65
64/* 66/*
65 * This lock protects updates to the following mapping and reference-count 67 * This lock protects updates to the following mapping and reference-count
66 * arrays. The lock does not need to be acquired to read the mapping tables. 68 * arrays. The lock does not need to be acquired to read the mapping tables.
@@ -1523,6 +1525,8 @@ void __init xen_init_IRQ(void)
1523{ 1525{
1524 int i; 1526 int i;
1525 1527
1528 xen_evtchn_2l_init();
1529
1526 evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq), 1530 evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq),
1527 GFP_KERNEL); 1531 GFP_KERNEL);
1528 BUG_ON(!evtchn_to_irq); 1532 BUG_ON(!evtchn_to_irq);
diff --git a/drivers/xen/events/events_internal.h b/drivers/xen/events/events_internal.h
index 79ac70bbbd26..ba8142f0c635 100644
--- a/drivers/xen/events/events_internal.h
+++ b/drivers/xen/events/events_internal.h
@@ -54,21 +54,68 @@ struct irq_info {
54#define PIRQ_NEEDS_EOI (1 << 0) 54#define PIRQ_NEEDS_EOI (1 << 0)
55#define PIRQ_SHAREABLE (1 << 1) 55#define PIRQ_SHAREABLE (1 << 1)
56 56
57struct evtchn_ops {
58 void (*bind_to_cpu)(struct irq_info *info, unsigned cpu);
59
60 void (*clear_pending)(unsigned port);
61 void (*set_pending)(unsigned port);
62 bool (*is_pending)(unsigned port);
63 bool (*test_and_set_mask)(unsigned port);
64 void (*mask)(unsigned port);
65 void (*unmask)(unsigned port);
66
67 void (*handle_events)(unsigned cpu);
68};
69
70extern const struct evtchn_ops *evtchn_ops;
71
57extern int *evtchn_to_irq; 72extern int *evtchn_to_irq;
58 73
59struct irq_info *info_for_irq(unsigned irq); 74struct irq_info *info_for_irq(unsigned irq);
60unsigned cpu_from_irq(unsigned irq); 75unsigned cpu_from_irq(unsigned irq);
61unsigned cpu_from_evtchn(unsigned int evtchn); 76unsigned cpu_from_evtchn(unsigned int evtchn);
62 77
63void xen_evtchn_port_bind_to_cpu(struct irq_info *info, int cpu); 78static inline void xen_evtchn_port_bind_to_cpu(struct irq_info *info,
79 unsigned cpu)
80{
81 evtchn_ops->bind_to_cpu(info, cpu);
82}
83
84static inline void clear_evtchn(unsigned port)
85{
86 evtchn_ops->clear_pending(port);
87}
88
89static inline void set_evtchn(unsigned port)
90{
91 evtchn_ops->set_pending(port);
92}
93
94static inline bool test_evtchn(unsigned port)
95{
96 return evtchn_ops->is_pending(port);
97}
98
99static inline bool test_and_set_mask(unsigned port)
100{
101 return evtchn_ops->test_and_set_mask(port);
102}
103
104static inline void mask_evtchn(unsigned port)
105{
106 return evtchn_ops->mask(port);
107}
108
109static inline void unmask_evtchn(unsigned port)
110{
111 return evtchn_ops->unmask(port);
112}
64 113
65void clear_evtchn(int port); 114static inline void xen_evtchn_handle_events(unsigned cpu)
66void set_evtchn(int port); 115{
67int test_evtchn(int port); 116 return evtchn_ops->handle_events(cpu);
68int test_and_set_mask(int port); 117}
69void mask_evtchn(int port);
70void unmask_evtchn(int port);
71 118
72void xen_evtchn_handle_events(int cpu); 119void xen_evtchn_2l_init(void);
73 120
74#endif /* #ifndef __EVENTS_INTERNAL_H__ */ 121#endif /* #ifndef __EVENTS_INTERNAL_H__ */