/[pkg-src]/tags/kernel26-xen-2_6_25_r1-fedora9-patches/kernel26-xen/patches-2.6.25-r1/1097-2.6.25-xen-Pull-xen-genapic-implementation-from-upstream-Xen.patch |
Contents of /tags/kernel26-xen-2_6_25_r1-fedora9-patches/kernel26-xen/patches-2.6.25-r1/1097-2.6.25-xen-Pull-xen-genapic-implementation-from-upstream-Xen.patch
Parent Directory | Revision Log
Revision 608 -
(show annotations)
(download)
Fri May 23 12:17:32 2008 UTC (16 years, 4 months ago) by (unknown author)
File size: 5842 byte(s)
Fri May 23 12:17:32 2008 UTC (16 years, 4 months ago) by (unknown author)
File size: 5842 byte(s)
This commit was manufactured by cvs2svn to create tag 'kernel26-xen-2_6_25_r1-fedora9-patches'.
1 | From b7348c664b725564f88323ed77a870b6b831d5cd Mon Sep 17 00:00:00 2001 |
2 | From: Eduardo Habkost <ehabkost@redhat.com> |
3 | Date: Fri, 4 Jan 2008 11:40:38 -0200 |
4 | Subject: [PATCH] Pull xen genapic implementation from upstream Xen |
5 | |
6 | Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> |
7 | --- |
8 | arch/x86/xen/Makefile | 2 +- |
9 | arch/x86/xen/genapic.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++ |
10 | 2 files changed, 191 insertions(+), 1 deletions(-) |
11 | create mode 100644 arch/x86/xen/genapic.c |
12 | |
13 | diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile |
14 | index e2dc9c1..147dde2 100644 |
15 | --- a/arch/x86/xen/Makefile |
16 | +++ b/arch/x86/xen/Makefile |
17 | @@ -4,7 +4,7 @@ obj-y := enlighten.o setup.o features.o multicalls.o mmu.o \ |
18 | ifeq ($(CONFIG_X86_32),y) |
19 | obj-y += init_32.o |
20 | else |
21 | -obj-y += init_64.o |
22 | +obj-y += init_64.o genapic.o |
23 | endif |
24 | |
25 | obj-$(CONFIG_SMP) += smp.o |
26 | diff --git a/arch/x86/xen/genapic.c b/arch/x86/xen/genapic.c |
27 | new file mode 100644 |
28 | index 0000000..0b9e74e |
29 | --- /dev/null |
30 | +++ b/arch/x86/xen/genapic.c |
31 | @@ -0,0 +1,190 @@ |
32 | +/* |
33 | + * Copyright 2004 James Cleverdon, IBM. |
34 | + * Subject to the GNU Public License, v.2 |
35 | + * |
36 | + * Xen APIC subarch code. Maximum 8 CPUs, logical delivery. |
37 | + * |
38 | + * Hacked for x86-64 by James Cleverdon from i386 architecture code by |
39 | + * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and |
40 | + * James Cleverdon. |
41 | + * |
42 | + * Hacked to pieces for Xen by Chris Wright. |
43 | + */ |
44 | +#include <linux/threads.h> |
45 | +#include <linux/cpumask.h> |
46 | +#include <linux/string.h> |
47 | +#include <linux/kernel.h> |
48 | +#include <linux/ctype.h> |
49 | +#include <linux/init.h> |
50 | +#ifdef CONFIG_XEN_PRIVILEGED_GUEST |
51 | +#include <asm/smp.h> |
52 | +#include <asm/ipi.h> |
53 | +#else |
54 | +#include <asm/apic.h> |
55 | +#include <asm/apicdef.h> |
56 | +#endif |
57 | +#include <asm/genapic.h> |
58 | +#include <xen/events.h> |
59 | + |
60 | +DECLARE_PER_CPU(int, ipi_to_irq[XEN_NR_IPIS]); |
61 | + |
62 | +static inline void __send_IPI_one(unsigned int cpu, int vector) |
63 | +{ |
64 | + int irq = per_cpu(ipi_to_irq, cpu)[vector]; |
65 | + BUG_ON(irq < 0); |
66 | + notify_remote_via_irq(irq); |
67 | +} |
68 | + |
69 | +void xen_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int dest) |
70 | +{ |
71 | + int cpu; |
72 | + |
73 | + switch (shortcut) { |
74 | + case APIC_DEST_SELF: |
75 | + __send_IPI_one(smp_processor_id(), vector); |
76 | + break; |
77 | + case APIC_DEST_ALLBUT: |
78 | + for (cpu = 0; cpu < NR_CPUS; ++cpu) { |
79 | + if (cpu == smp_processor_id()) |
80 | + continue; |
81 | + if (cpu_isset(cpu, cpu_online_map)) { |
82 | + __send_IPI_one(cpu, vector); |
83 | + } |
84 | + } |
85 | + break; |
86 | + case APIC_DEST_ALLINC: |
87 | + for (cpu = 0; cpu < NR_CPUS; ++cpu) { |
88 | + if (cpu_isset(cpu, cpu_online_map)) { |
89 | + __send_IPI_one(cpu, vector); |
90 | + } |
91 | + } |
92 | + break; |
93 | + default: |
94 | + printk("XXXXXX __send_IPI_shortcut %08x vector %d\n", shortcut, |
95 | + vector); |
96 | + break; |
97 | + } |
98 | +} |
99 | + |
100 | +static cpumask_t xen_target_cpus(void) |
101 | +{ |
102 | + return cpu_online_map; |
103 | +} |
104 | + |
105 | +static cpumask_t xen_vector_allocation_domain(int cpu) |
106 | +{ |
107 | + /* Careful. Some cpus do not strictly honor the set of cpus |
108 | + * specified in the interrupt destination when using lowest |
109 | + * priority interrupt delivery mode. |
110 | + * |
111 | + * In particular there was a hyperthreading cpu observed to |
112 | + * deliver interrupts to the wrong hyperthread when only one |
113 | + * hyperthread was specified in the interrupt desitination. |
114 | + */ |
115 | + cpumask_t domain = { { [0] = APIC_ALL_CPUS, } }; |
116 | + return domain; |
117 | +} |
118 | + |
119 | +/* |
120 | + * Set up the logical destination ID. |
121 | + * Do nothing, not called now. |
122 | + */ |
123 | +static void xen_init_apic_ldr(void) |
124 | +{ |
125 | + Dprintk("%s\n", __FUNCTION__); |
126 | + return; |
127 | +} |
128 | + |
129 | +static void xen_send_IPI_mask(cpumask_t cpumask, int vector) |
130 | +{ |
131 | + unsigned long mask = cpus_addr(cpumask)[0]; |
132 | + unsigned int cpu; |
133 | + unsigned long flags; |
134 | + |
135 | + Dprintk("%s\n", __FUNCTION__); |
136 | + local_irq_save(flags); |
137 | + WARN_ON(mask & ~cpus_addr(cpu_online_map)[0]); |
138 | + |
139 | + for (cpu = 0; cpu < NR_CPUS; ++cpu) { |
140 | + if (cpu_isset(cpu, cpumask)) { |
141 | + __send_IPI_one(cpu, vector); |
142 | + } |
143 | + } |
144 | + local_irq_restore(flags); |
145 | +} |
146 | + |
147 | +static void xen_send_IPI_allbutself(int vector) |
148 | +{ |
149 | +#ifdef CONFIG_HOTPLUG_CPU |
150 | + int hotplug = 1; |
151 | +#else |
152 | + int hotplug = 0; |
153 | +#endif |
154 | + /* |
155 | + * if there are no other CPUs in the system then |
156 | + * we get an APIC send error if we try to broadcast. |
157 | + * thus we have to avoid sending IPIs in this case. |
158 | + */ |
159 | + Dprintk("%s\n", __FUNCTION__); |
160 | + if (hotplug || vector == NMI_VECTOR) { |
161 | + cpumask_t allbutme = cpu_online_map; |
162 | + |
163 | + cpu_clear(smp_processor_id(), allbutme); |
164 | + |
165 | + if (!cpus_empty(allbutme)) |
166 | + xen_send_IPI_mask(allbutme, vector); |
167 | + } else if (num_online_cpus() > 1) { |
168 | + xen_send_IPI_shortcut(APIC_DEST_ALLBUT, vector, APIC_DEST_LOGICAL); |
169 | + } |
170 | +} |
171 | + |
172 | +static void xen_send_IPI_all(int vector) |
173 | +{ |
174 | + Dprintk("%s\n", __FUNCTION__); |
175 | + if (vector == NMI_VECTOR) |
176 | + xen_send_IPI_mask(cpu_online_map, vector); |
177 | + else |
178 | + xen_send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL); |
179 | +} |
180 | + |
181 | +#ifdef CONFIG_XEN_PRIVILEGED_GUEST |
182 | +static int xen_apic_id_registered(void) |
183 | +{ |
184 | + /* better be set */ |
185 | + Dprintk("%s\n", __FUNCTION__); |
186 | + return physid_isset(smp_processor_id(), phys_cpu_present_map); |
187 | +} |
188 | +#endif |
189 | + |
190 | +static unsigned int xen_cpu_mask_to_apicid(cpumask_t cpumask) |
191 | +{ |
192 | + Dprintk("%s\n", __FUNCTION__); |
193 | + return cpus_addr(cpumask)[0] & APIC_ALL_CPUS; |
194 | +} |
195 | + |
196 | +static unsigned int phys_pkg_id(int index_msb) |
197 | +{ |
198 | + int ebx; |
199 | + Dprintk("%s\n", __FUNCTION__); |
200 | + ebx = cpuid_ebx(1); |
201 | + return ((ebx >> 24) & 0xFF) >> index_msb; |
202 | +} |
203 | + |
204 | +struct genapic apic_xen = { |
205 | + .name = "xen", |
206 | +#ifdef CONFIG_XEN_PRIVILEGED_GUEST |
207 | + .int_delivery_mode = dest_LowestPrio, |
208 | +#endif |
209 | + .int_dest_mode = (APIC_DEST_LOGICAL != 0), |
210 | + .target_cpus = xen_target_cpus, |
211 | + .vector_allocation_domain = xen_vector_allocation_domain, |
212 | +#ifdef CONFIG_XEN_PRIVILEGED_GUEST |
213 | + .apic_id_registered = xen_apic_id_registered, |
214 | +#endif |
215 | + .init_apic_ldr = xen_init_apic_ldr, |
216 | + .send_IPI_all = xen_send_IPI_all, |
217 | + .send_IPI_allbutself = xen_send_IPI_allbutself, |
218 | + .send_IPI_mask = xen_send_IPI_mask, |
219 | + .cpu_mask_to_apicid = xen_cpu_mask_to_apicid, |
220 | + .phys_pkg_id = phys_pkg_id, |
221 | +}; |
222 | -- |
223 | 1.5.4.1 |
224 |