]>
Commit | Line | Data |
---|---|---|
cc90b958 BS |
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 | */ |