aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-07 18:11:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-07 18:11:43 -0400
commitd75e2f902318cc20f3218e6823fe5463a8126bde (patch)
treea08a87bab72df38d2f7f865bcb59cc43f608245b /arch/arm
parentde9c9f86be0dc3495de98dc65c80abe6e7c7d643 (diff)
parent9bc25a1d5f95f97e9e378620a46e954d3f842641 (diff)
Merge tag '3.9-rc3-smp-6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/sstabellini/xen
Pull ARM Xen SMP updates from Stefano Stabellini: "This contains a bunch of Xen/ARM specific changes, including some fixes, SMP support for Xen on ARM, and moving the xenvm machine from mach-vexpress to mach-virt. The non-Xen files that are touched are arch/arm/Kconfig, to select ARM_PSCI on XEN, and arch/arm/boot/dts/Makefile, to build the xenvm DTB if CONFIG_ARCH_VIRT. Highlights: - Move xenvm to mach-virt. - Implement SMP support in Xen on ARM. - Add support for machine reboot and power off via Xen hypercalls" * tag '3.9-rc3-smp-6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/sstabellini/xen: xen/arm: remove duplicated include from enlighten.c xen/arm: use sched_op hypercalls for machine reboot and power off xenvm: add a simple PSCI node and a second cpu xen/arm: XEN selects ARM_PSCI xen: move the xenvm machine to mach-virt xen/arm: SMP support xen/arm: implement HYPERVISOR_vcpu_op xen/arm: actually pass a non-NULL percpu pointer to request_percpu_irq
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/boot/dts/Makefile4
-rw-r--r--arch/arm/boot/dts/xenvm-4.2.dts13
-rw-r--r--arch/arm/include/asm/xen/hypercall.h1
-rw-r--r--arch/arm/mach-vexpress/v2m.c1
-rw-r--r--arch/arm/mach-virt/virt.c1
-rw-r--r--arch/arm/xen/enlighten.c74
-rw-r--r--arch/arm/xen/hypercall.S1
8 files changed, 86 insertions, 10 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 34ef016626ff..aa71a2321040 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1794,6 +1794,7 @@ config XEN
1794 depends on ARM && AEABI && OF 1794 depends on ARM && AEABI && OF
1795 depends on CPU_V7 && !CPU_V6 1795 depends on CPU_V7 && !CPU_V6
1796 depends on !GENERIC_ATOMIC64 1796 depends on !GENERIC_ATOMIC64
1797 select ARM_PSCI
1797 help 1798 help
1798 Say Y if you want to run Linux in a Virtual Machine on Xen on ARM. 1799 Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
1799 1800
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 8562af4fe8fd..b9f7121e6ecf 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -200,8 +200,8 @@ dtb-$(CONFIG_ARCH_VERSATILE) += versatile-ab.dtb \
200dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \ 200dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \
201 vexpress-v2p-ca9.dtb \ 201 vexpress-v2p-ca9.dtb \
202 vexpress-v2p-ca15-tc1.dtb \ 202 vexpress-v2p-ca15-tc1.dtb \
203 vexpress-v2p-ca15_a7.dtb \ 203 vexpress-v2p-ca15_a7.dtb
204 xenvm-4.2.dtb 204dtb-$(CONFIG_ARCH_VIRT) += xenvm-4.2.dtb
205dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \ 205dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \
206 wm8505-ref.dtb \ 206 wm8505-ref.dtb \
207 wm8650-mid.dtb \ 207 wm8650-mid.dtb \
diff --git a/arch/arm/boot/dts/xenvm-4.2.dts b/arch/arm/boot/dts/xenvm-4.2.dts
index ec3f9528e180..336915151398 100644
--- a/arch/arm/boot/dts/xenvm-4.2.dts
+++ b/arch/arm/boot/dts/xenvm-4.2.dts
@@ -29,6 +29,19 @@
29 compatible = "arm,cortex-a15"; 29 compatible = "arm,cortex-a15";
30 reg = <0>; 30 reg = <0>;
31 }; 31 };
32
33 cpu@1 {
34 device_type = "cpu";
35 compatible = "arm,cortex-a15";
36 reg = <1>;
37 };
38 };
39
40 psci {
41 compatible = "arm,psci";
42 method = "hvc";
43 cpu_off = <1>;
44 cpu_on = <2>;
32 }; 45 };
33 46
34 memory@80000000 { 47 memory@80000000 {
diff --git a/arch/arm/include/asm/xen/hypercall.h b/arch/arm/include/asm/xen/hypercall.h
index 8a823253d775..799f42ecca63 100644
--- a/arch/arm/include/asm/xen/hypercall.h
+++ b/arch/arm/include/asm/xen/hypercall.h
@@ -46,6 +46,7 @@ int HYPERVISOR_event_channel_op(int cmd, void *arg);
46unsigned long HYPERVISOR_hvm_op(int op, void *arg); 46unsigned long HYPERVISOR_hvm_op(int op, void *arg);
47int HYPERVISOR_memory_op(unsigned int cmd, void *arg); 47int HYPERVISOR_memory_op(unsigned int cmd, void *arg);
48int HYPERVISOR_physdev_op(int cmd, void *arg); 48int HYPERVISOR_physdev_op(int cmd, void *arg);
49int HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args);
49 50
50static inline void 51static inline void
51MULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va, 52MULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va,
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index b6083bb1eb8c..8802030df98d 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -450,7 +450,6 @@ static void __init v2m_dt_init(void)
450 450
451static const char * const v2m_dt_match[] __initconst = { 451static const char * const v2m_dt_match[] __initconst = {
452 "arm,vexpress", 452 "arm,vexpress",
453 "xen,xenvm",
454 NULL, 453 NULL,
455}; 454};
456 455
diff --git a/arch/arm/mach-virt/virt.c b/arch/arm/mach-virt/virt.c
index adc0945255ae..061f283f579e 100644
--- a/arch/arm/mach-virt/virt.c
+++ b/arch/arm/mach-virt/virt.c
@@ -32,6 +32,7 @@ static void __init virt_init(void)
32 32
33static const char *virt_dt_match[] = { 33static const char *virt_dt_match[] = {
34 "linux,dummy-virt", 34 "linux,dummy-virt",
35 "xen,xenvm",
35 NULL 36 NULL
36}; 37};
37 38
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 8dc0605a9ce9..d30042e39974 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -2,6 +2,7 @@
2#include <xen/events.h> 2#include <xen/events.h>
3#include <xen/grant_table.h> 3#include <xen/grant_table.h>
4#include <xen/hvm.h> 4#include <xen/hvm.h>
5#include <xen/interface/vcpu.h>
5#include <xen/interface/xen.h> 6#include <xen/interface/xen.h>
6#include <xen/interface/memory.h> 7#include <xen/interface/memory.h>
7#include <xen/interface/hvm/params.h> 8#include <xen/interface/hvm/params.h>
@@ -9,9 +10,11 @@
9#include <xen/platform_pci.h> 10#include <xen/platform_pci.h>
10#include <xen/xenbus.h> 11#include <xen/xenbus.h>
11#include <xen/page.h> 12#include <xen/page.h>
13#include <xen/interface/sched.h>
12#include <xen/xen-ops.h> 14#include <xen/xen-ops.h>
13#include <asm/xen/hypervisor.h> 15#include <asm/xen/hypervisor.h>
14#include <asm/xen/hypercall.h> 16#include <asm/xen/hypercall.h>
17#include <asm/system_misc.h>
15#include <linux/interrupt.h> 18#include <linux/interrupt.h>
16#include <linux/irqreturn.h> 19#include <linux/irqreturn.h>
17#include <linux/module.h> 20#include <linux/module.h>
@@ -32,6 +35,7 @@ struct shared_info xen_dummy_shared_info;
32struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info; 35struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info;
33 36
34DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); 37DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
38static struct vcpu_info __percpu *xen_vcpu_info;
35 39
36/* These are unused until we support booting "pre-ballooned" */ 40/* These are unused until we support booting "pre-ballooned" */
37unsigned long xen_released_pages; 41unsigned long xen_released_pages;
@@ -148,6 +152,47 @@ int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
148} 152}
149EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range); 153EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range);
150 154
155static int __init xen_secondary_init(unsigned int cpu)
156{
157 struct vcpu_register_vcpu_info info;
158 struct vcpu_info *vcpup;
159 int err;
160
161 pr_info("Xen: initializing cpu%d\n", cpu);
162 vcpup = per_cpu_ptr(xen_vcpu_info, cpu);
163
164 info.mfn = __pa(vcpup) >> PAGE_SHIFT;
165 info.offset = offset_in_page(vcpup);
166
167 err = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info);
168 if (err) {
169 pr_debug("register_vcpu_info failed: err=%d\n", err);
170 } else {
171 /* This cpu is using the registered vcpu info, even if
172 later ones fail to. */
173 per_cpu(xen_vcpu, cpu) = vcpup;
174 }
175 return 0;
176}
177
178static void xen_restart(char str, const char *cmd)
179{
180 struct sched_shutdown r = { .reason = SHUTDOWN_reboot };
181 int rc;
182 rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &r);
183 if (rc)
184 BUG();
185}
186
187static void xen_power_off(void)
188{
189 struct sched_shutdown r = { .reason = SHUTDOWN_poweroff };
190 int rc;
191 rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &r);
192 if (rc)
193 BUG();
194}
195
151/* 196/*
152 * see Documentation/devicetree/bindings/arm/xen.txt for the 197 * see Documentation/devicetree/bindings/arm/xen.txt for the
153 * documentation of the Xen Device Tree format. 198 * documentation of the Xen Device Tree format.
@@ -163,6 +208,7 @@ static int __init xen_guest_init(void)
163 const char *version = NULL; 208 const char *version = NULL;
164 const char *xen_prefix = "xen,xen-"; 209 const char *xen_prefix = "xen,xen-";
165 struct resource res; 210 struct resource res;
211 int i;
166 212
167 node = of_find_compatible_node(NULL, NULL, "xen,xen"); 213 node = of_find_compatible_node(NULL, NULL, "xen,xen");
168 if (!node) { 214 if (!node) {
@@ -209,18 +255,26 @@ static int __init xen_guest_init(void)
209 255
210 /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info 256 /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info
211 * page, we use it in the event channel upcall and in some pvclock 257 * page, we use it in the event channel upcall and in some pvclock
212 * related functions. We don't need the vcpu_info placement 258 * related functions.
213 * optimizations because we don't use any pv_mmu or pv_irq op on
214 * HVM.
215 * The shared info contains exactly 1 CPU (the boot CPU). The guest 259 * The shared info contains exactly 1 CPU (the boot CPU). The guest
216 * is required to use VCPUOP_register_vcpu_info to place vcpu info 260 * is required to use VCPUOP_register_vcpu_info to place vcpu info
217 * for secondary CPUs as they are brought up. */ 261 * for secondary CPUs as they are brought up.
218 per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; 262 * For uniformity we use VCPUOP_register_vcpu_info even on cpu0.
263 */
264 xen_vcpu_info = __alloc_percpu(sizeof(struct vcpu_info),
265 sizeof(struct vcpu_info));
266 if (xen_vcpu_info == NULL)
267 return -ENOMEM;
268 for_each_online_cpu(i)
269 xen_secondary_init(i);
219 270
220 gnttab_init(); 271 gnttab_init();
221 if (!xen_initial_domain()) 272 if (!xen_initial_domain())
222 xenbus_probe(NULL); 273 xenbus_probe(NULL);
223 274
275 pm_power_off = xen_power_off;
276 arm_pm_restart = xen_restart;
277
224 return 0; 278 return 0;
225} 279}
226core_initcall(xen_guest_init); 280core_initcall(xen_guest_init);
@@ -231,6 +285,11 @@ static irqreturn_t xen_arm_callback(int irq, void *arg)
231 return IRQ_HANDLED; 285 return IRQ_HANDLED;
232} 286}
233 287
288static __init void xen_percpu_enable_events(void *unused)
289{
290 enable_percpu_irq(xen_events_irq, 0);
291}
292
234static int __init xen_init_events(void) 293static int __init xen_init_events(void)
235{ 294{
236 if (!xen_domain() || xen_events_irq < 0) 295 if (!xen_domain() || xen_events_irq < 0)
@@ -239,12 +298,12 @@ static int __init xen_init_events(void)
239 xen_init_IRQ(); 298 xen_init_IRQ();
240 299
241 if (request_percpu_irq(xen_events_irq, xen_arm_callback, 300 if (request_percpu_irq(xen_events_irq, xen_arm_callback,
242 "events", xen_vcpu)) { 301 "events", &xen_vcpu)) {
243 pr_err("Error requesting IRQ %d\n", xen_events_irq); 302 pr_err("Error requesting IRQ %d\n", xen_events_irq);
244 return -EINVAL; 303 return -EINVAL;
245 } 304 }
246 305
247 enable_percpu_irq(xen_events_irq, 0); 306 on_each_cpu(xen_percpu_enable_events, NULL, 0);
248 307
249 return 0; 308 return 0;
250} 309}
@@ -259,4 +318,5 @@ EXPORT_SYMBOL_GPL(HYPERVISOR_sched_op);
259EXPORT_SYMBOL_GPL(HYPERVISOR_hvm_op); 318EXPORT_SYMBOL_GPL(HYPERVISOR_hvm_op);
260EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op); 319EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op);
261EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op); 320EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op);
321EXPORT_SYMBOL_GPL(HYPERVISOR_vcpu_op);
262EXPORT_SYMBOL_GPL(privcmd_call); 322EXPORT_SYMBOL_GPL(privcmd_call);
diff --git a/arch/arm/xen/hypercall.S b/arch/arm/xen/hypercall.S
index 71f723984cbd..199cb2da7663 100644
--- a/arch/arm/xen/hypercall.S
+++ b/arch/arm/xen/hypercall.S
@@ -87,6 +87,7 @@ HYPERCALL2(event_channel_op);
87HYPERCALL2(hvm_op); 87HYPERCALL2(hvm_op);
88HYPERCALL2(memory_op); 88HYPERCALL2(memory_op);
89HYPERCALL2(physdev_op); 89HYPERCALL2(physdev_op);
90HYPERCALL3(vcpu_op);
90 91
91ENTRY(privcmd_call) 92ENTRY(privcmd_call)
92 stmdb sp!, {r4} 93 stmdb sp!, {r4}