Magellan Linux

Contents of /trunk/kernel26-xen/patches-2.6.25-r1/1097-2.6.25-xen-Pull-xen-genapic-implementation-from-upstream-Xen.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 606 - (show annotations) (download)
Thu May 22 23:13:13 2008 UTC (16 years ago) by niro
File size: 5842 byte(s)
-ver bump to 2.6.25-magellan-r1:
- linux-2.6.25.4
- fbcondecor-0.9.4
- squashfs-3.3
- unionfs-2.3.3
- tuxonice-3.0-rc7
- linux-phc-0.3.0
- acpi-dstd-0.9a
- reiser4
- xen-3.2.0
. ipw3945-1.2.2

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