]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/60020_746-pirq-status-page.patch1
Corrected links and text on ids.cgi
[people/pmueller/ipfire-2.x.git] / src / patches / 60020_746-pirq-status-page.patch1
1 From: http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/d545a95fca73
2 # HG changeset 746+749 patch
3 # User Keir Fraser <keir.fraser@citrix.com>
4 # Date 1227879027 0
5 # Node ID d545a95fca739d0b1963b73a9eb64ea64a244e76
6 # Parent 2268be46c75ec6eddb7cd387af8a236a565f6140
7 Subject: linux/x86: use shared page indicating the need for an EOI notification
8 Patch-mainline: obsolete
9
10 Signed-off-by: Jan Beulich <jbeulich@novell.com>
11
12 From: http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/cdc6729dc702
13 Subject: evtchn: Fix the build.
14 Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
15
16 Index: head-2008-12-01/drivers/xen/core/evtchn.c
17 ===================================================================
18 --- head-2008-12-01.orig/drivers/xen/core/evtchn.c 2008-12-01 11:22:35.000000000 +0100
19 +++ head-2008-12-01/drivers/xen/core/evtchn.c 2008-12-01 11:23:06.000000000 +0100
20 @@ -123,9 +123,6 @@ DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS])
21 /* Reference counts for bindings to IRQs. */
22 static int irq_bindcount[NR_IRQS];
23
24 -/* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
25 -static DECLARE_BITMAP(pirq_needs_eoi, NR_PIRQS);
26 -
27 #ifdef CONFIG_SMP
28
29 static u8 cpu_evtchn[NR_EVENT_CHANNELS];
30 @@ -756,16 +753,48 @@ static struct hw_interrupt_type dynirq_t
31 .retrigger = resend_irq_on_evtchn,
32 };
33
34 -static inline void pirq_unmask_notify(int irq)
35 +/* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
36 +static int pirq_eoi_does_unmask;
37 +static DECLARE_BITMAP(pirq_needs_eoi, ALIGN(NR_PIRQS, PAGE_SIZE * 8))
38 + __attribute__ ((__section__(".bss.page_aligned"), __aligned__(PAGE_SIZE)));
39 +
40 +static void pirq_unmask_and_notify(unsigned int evtchn, unsigned int irq)
41 {
42 struct physdev_eoi eoi = { .irq = evtchn_get_xen_pirq(irq) };
43 - if (unlikely(test_bit(irq - PIRQ_BASE, pirq_needs_eoi)))
44 - VOID(HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi));
45 +
46 + if (pirq_eoi_does_unmask) {
47 + if (test_bit(eoi.irq, pirq_needs_eoi))
48 + VOID(HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi));
49 + else
50 + unmask_evtchn(evtchn);
51 + } else if (test_bit(irq - PIRQ_BASE, pirq_needs_eoi)) {
52 + if (smp_processor_id() != cpu_from_evtchn(evtchn)) {
53 + struct evtchn_unmask unmask = { .port = evtchn };
54 + struct multicall_entry mcl[2];
55 +
56 + mcl[0].op = __HYPERVISOR_event_channel_op;
57 + mcl[0].args[0] = EVTCHNOP_unmask;
58 + mcl[0].args[1] = (unsigned long)&unmask;
59 + mcl[1].op = __HYPERVISOR_physdev_op;
60 + mcl[1].args[0] = PHYSDEVOP_eoi;
61 + mcl[1].args[1] = (unsigned long)&eoi;
62 +
63 + if (HYPERVISOR_multicall(mcl, 2))
64 + BUG();
65 + } else {
66 + unmask_evtchn(evtchn);
67 + VOID(HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi));
68 + }
69 + } else
70 + unmask_evtchn(evtchn);
71 }
72
73 static inline void pirq_query_unmask(int irq)
74 {
75 struct physdev_irq_status_query irq_status;
76 +
77 + if (pirq_eoi_does_unmask)
78 + return;
79 irq_status.irq = evtchn_get_xen_pirq(irq);
80 if (HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status))
81 irq_status.flags = 0;
82 @@ -806,8 +835,7 @@ static unsigned int startup_pirq(unsigne
83 irq_info[irq] = mk_irq_info(IRQT_PIRQ, bind_pirq.pirq, evtchn);
84
85 out:
86 - unmask_evtchn(evtchn);
87 - pirq_unmask_notify(irq);
88 + pirq_unmask_and_notify(evtchn, irq);
89
90 return 0;
91 }
92 @@ -859,10 +887,8 @@ static void end_pirq(unsigned int irq)
93 if ((irq_desc[irq].status & (IRQ_DISABLED|IRQ_PENDING)) ==
94 (IRQ_DISABLED|IRQ_PENDING)) {
95 shutdown_pirq(irq);
96 - } else if (VALID_EVTCHN(evtchn)) {
97 - unmask_evtchn(evtchn);
98 - pirq_unmask_notify(irq);
99 - }
100 + } else if (VALID_EVTCHN(evtchn))
101 + pirq_unmask_and_notify(evtchn, irq);
102 }
103
104 static struct hw_interrupt_type pirq_type = {
105 @@ -1012,6 +1038,14 @@ void irq_resume(void)
106
107 init_evtchn_cpu_bindings();
108
109 + if (pirq_eoi_does_unmask) {
110 + struct physdev_pirq_eoi_mfn eoi_mfn;
111 +
112 + eoi_mfn.mfn = virt_to_bus(pirq_needs_eoi) >> PAGE_SHIFT;
113 + if (HYPERVISOR_physdev_op(PHYSDEVOP_pirq_eoi_mfn, &eoi_mfn))
114 + BUG();
115 + }
116 +
117 /* New event-channel space is not 'live' yet. */
118 for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++)
119 mask_evtchn(evtchn);
120 @@ -1098,9 +1132,15 @@ int evtchn_get_xen_pirq(int irq)
121 void __init xen_init_IRQ(void)
122 {
123 unsigned int i;
124 + struct physdev_pirq_eoi_mfn eoi_mfn;
125
126 init_evtchn_cpu_bindings();
127
128 + BUG_ON(!bitmap_empty(pirq_needs_eoi, PAGE_SIZE * 8));
129 + eoi_mfn.mfn = virt_to_bus(pirq_needs_eoi) >> PAGE_SHIFT;
130 + if (HYPERVISOR_physdev_op(PHYSDEVOP_pirq_eoi_mfn, &eoi_mfn) == 0)
131 + pirq_eoi_does_unmask = 1;
132 +
133 /* No event channels are 'live' right now. */
134 for (i = 0; i < NR_EVENT_CHANNELS; i++)
135 mask_evtchn(i);
136 Index: head-2008-12-01/include/xen/interface/physdev.h
137 ===================================================================
138 --- head-2008-12-01.orig/include/xen/interface/physdev.h 2008-12-01 11:22:59.000000000 +0100
139 +++ head-2008-12-01/include/xen/interface/physdev.h 2008-12-01 11:23:06.000000000 +0100
140 @@ -41,6 +41,21 @@ typedef struct physdev_eoi physdev_eoi_t
141 DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);
142
143 /*
144 + * Register a shared page for the hypervisor to indicate whether the guest
145 + * must issue PHYSDEVOP_eoi. The semantics of PHYSDEVOP_eoi change slightly
146 + * once the guest used this function in that the associated event channel
147 + * will automatically get unmasked. The page registered is used as a bit
148 + * array indexed by Xen's PIRQ value.
149 + */
150 +#define PHYSDEVOP_pirq_eoi_mfn 17
151 +struct physdev_pirq_eoi_mfn {
152 + /* IN */
153 + xen_pfn_t mfn;
154 +};
155 +typedef struct physdev_pirq_eoi_mfn physdev_pirq_eoi_mfn_t;
156 +DEFINE_XEN_GUEST_HANDLE(physdev_pirq_eoi_mfn_t);
157 +
158 +/*
159 * Query the status of an IRQ line.
160 * @arg == pointer to physdev_irq_status_query structure.
161 */