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