]>
Commit | Line | Data |
---|---|---|
cc90b958 | 1 | From: 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 | |
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 | ||
00e5a55c BS |
16 | From: http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/ca213a56dba1 |
17 | Subject: evtchn, phydev: rename PHYSDEVOP_pirq_eoi_mfn to PHYSDEVOP_pirq_eoi_gmfn | |
18 | ||
19 | Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> | |
20 | Signed-off-by: Keir Fraser <keir.fraser@citrix.com> | |
21 | ||
22 | From: http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/0d10be086a78 | |
23 | Subject: linux/evtchn: allocate pirq_needs_eoi bitmap dynamically | |
24 | ||
25 | Original patch from: Isaku Yamahata <yamahata@valinux.co.jp> | |
26 | Signed-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 | */ |