aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-06 18:13:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-06 18:13:01 -0400
commitf1c6872e4980bc4078cfaead05f892b3d78dea64 (patch)
tree24c18bb07714109296638b3193b35bdcc4098f7c /arch
parent5f3d2f2e1a63679cf1c4a4210f2f1cc2f335bef6 (diff)
parent4ed5978bdd99114db7773cb3d78f2998bd17f694 (diff)
Merge tag 'stable/for-linus-3.7-arm-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen
Pull ADM Xen support from Konrad Rzeszutek Wilk: Features: * Allow a Linux guest to boot as initial domain and as normal guests on Xen on ARM (specifically ARMv7 with virtualized extensions). PV console, block and network frontend/backends are working. Bug-fixes: * Fix compile linux-next fallout. * Fix PVHVM bootup crashing. The Xen-unstable hypervisor (so will be 4.3 in a ~6 months), supports ARMv7 platforms. The goal in implementing this architecture is to exploit the hardware as much as possible. That means use as little as possible of PV operations (so no PV MMU) - and use existing PV drivers for I/Os (network, block, console, etc). This is similar to how PVHVM guests operate in X86 platform nowadays - except that on ARM there is no need for QEMU. The end result is that we share a lot of the generic Xen drivers and infrastructure. Details on how to compile/boot/etc are available at this Wiki: http://wiki.xen.org/wiki/Xen_ARMv7_with_Virtualization_Extensions and this blog has links to a technical discussion/presentations on the overall architecture: http://blog.xen.org/index.php/2012/09/21/xensummit-sessions-new-pvh-virtualisation-mode-for-arm-cortex-a15arm-servers-and-x86/ * tag 'stable/for-linus-3.7-arm-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen: (21 commits) xen/xen_initial_domain: check that xen_start_info is initialized xen: mark xen_init_IRQ __init xen/Makefile: fix dom-y build arm: introduce a DTS for Xen unprivileged virtual machines MAINTAINERS: add myself as Xen ARM maintainer xen/arm: compile netback xen/arm: compile blkfront and blkback xen/arm: implement alloc/free_xenballooned_pages with alloc_pages/kfree xen/arm: receive Xen events on ARM xen/arm: initialize grant_table on ARM xen/arm: get privilege status xen/arm: introduce CONFIG_XEN on ARM xen: do not compile manage, balloon, pci, acpi, pcpu and cpu_hotplug on ARM xen/arm: Introduce xen_ulong_t for unsigned long xen/arm: Xen detection and shared_info page mapping docs: Xen ARM DT bindings xen/arm: empty implementation of grant_table arch specific functions xen/arm: sync_bitops xen/arm: page.h definitions xen/arm: hypercalls ...
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig10
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/boot/dts/Makefile3
-rw-r--r--arch/arm/boot/dts/xenvm-4.2.dts68
-rw-r--r--arch/arm/include/asm/hypervisor.h6
-rw-r--r--arch/arm/include/asm/sync_bitops.h27
-rw-r--r--arch/arm/include/asm/xen/events.h18
-rw-r--r--arch/arm/include/asm/xen/hypercall.h69
-rw-r--r--arch/arm/include/asm/xen/hypervisor.h19
-rw-r--r--arch/arm/include/asm/xen/interface.h73
-rw-r--r--arch/arm/include/asm/xen/page.h82
-rw-r--r--arch/arm/mach-vexpress/v2m.c1
-rw-r--r--arch/arm/xen/Makefile1
-rw-r--r--arch/arm/xen/enlighten.c168
-rw-r--r--arch/arm/xen/grant-table.c53
-rw-r--r--arch/arm/xen/hypercall.S106
-rw-r--r--arch/ia64/include/asm/xen/interface.h1
-rw-r--r--arch/x86/include/asm/xen/interface.h1
-rw-r--r--arch/x86/xen/enlighten.c1
-rw-r--r--arch/x86/xen/irq.c1
-rw-r--r--arch/x86/xen/xen-ops.h1
21 files changed, 708 insertions, 2 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 7bab17ed2972..3975d10cb3ed 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1829,6 +1829,16 @@ config DEPRECATED_PARAM_STRUCT
1829 This was deprecated in 2001 and announced to live on for 5 years. 1829 This was deprecated in 2001 and announced to live on for 5 years.
1830 Some old boot loaders still use this way. 1830 Some old boot loaders still use this way.
1831 1831
1832config XEN_DOM0
1833 def_bool y
1834 depends on XEN
1835
1836config XEN
1837 bool "Xen guest support on ARM (EXPERIMENTAL)"
1838 depends on EXPERIMENTAL && ARM && OF
1839 help
1840 Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
1841
1832endmenu 1842endmenu
1833 1843
1834menu "Boot options" 1844menu "Boot options"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index b86e57ef146b..40ea991b6782 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -250,6 +250,7 @@ endif
250core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/ 250core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
251core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ) 251core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
252core-$(CONFIG_VFP) += arch/arm/vfp/ 252core-$(CONFIG_VFP) += arch/arm/vfp/
253core-$(CONFIG_XEN) += arch/arm/xen/
253 254
254# If we have a machine-specific directory, then include it in the build. 255# If we have a machine-specific directory, then include it in the build.
255core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ 256core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 43c084c2cd66..4745c1f68b49 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -96,6 +96,7 @@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \
96dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \ 96dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \
97 vexpress-v2p-ca9.dtb \ 97 vexpress-v2p-ca9.dtb \
98 vexpress-v2p-ca15-tc1.dtb \ 98 vexpress-v2p-ca15-tc1.dtb \
99 vexpress-v2p-ca15_a7.dtb 99 vexpress-v2p-ca15_a7.dtb \
100 xenvm-4.2.dtb
100 101
101endif 102endif
diff --git a/arch/arm/boot/dts/xenvm-4.2.dts b/arch/arm/boot/dts/xenvm-4.2.dts
new file mode 100644
index 000000000000..ec3f9528e180
--- /dev/null
+++ b/arch/arm/boot/dts/xenvm-4.2.dts
@@ -0,0 +1,68 @@
1/*
2 * Xen Virtual Machine for unprivileged guests
3 *
4 * Based on ARM Ltd. Versatile Express CoreTile Express (single CPU)
5 * Cortex-A15 MPCore (V2P-CA15)
6 *
7 */
8
9/dts-v1/;
10
11/ {
12 model = "XENVM-4.2";
13 compatible = "xen,xenvm-4.2", "xen,xenvm";
14 interrupt-parent = <&gic>;
15 #address-cells = <2>;
16 #size-cells = <2>;
17
18 chosen {
19 /* this field is going to be adjusted by the hypervisor */
20 bootargs = "console=hvc0 root=/dev/xvda";
21 };
22
23 cpus {
24 #address-cells = <1>;
25 #size-cells = <0>;
26
27 cpu@0 {
28 device_type = "cpu";
29 compatible = "arm,cortex-a15";
30 reg = <0>;
31 };
32 };
33
34 memory@80000000 {
35 device_type = "memory";
36 /* this field is going to be adjusted by the hypervisor */
37 reg = <0 0x80000000 0 0x08000000>;
38 };
39
40 gic: interrupt-controller@2c001000 {
41 compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
42 #interrupt-cells = <3>;
43 #address-cells = <0>;
44 interrupt-controller;
45 reg = <0 0x2c001000 0 0x1000>,
46 <0 0x2c002000 0 0x100>;
47 };
48
49 timer {
50 compatible = "arm,armv7-timer";
51 interrupts = <1 13 0xf08>,
52 <1 14 0xf08>,
53 <1 11 0xf08>,
54 <1 10 0xf08>;
55 };
56
57 hypervisor {
58 compatible = "xen,xen-4.2", "xen,xen";
59 /* this field is going to be adjusted by the hypervisor */
60 reg = <0 0xb0000000 0 0x20000>;
61 /* this field is going to be adjusted by the hypervisor */
62 interrupts = <1 15 0xf08>;
63 };
64
65 motherboard {
66 arm,v2m-memory-map = "rs1";
67 };
68};
diff --git a/arch/arm/include/asm/hypervisor.h b/arch/arm/include/asm/hypervisor.h
new file mode 100644
index 000000000000..b90d9e523d6f
--- /dev/null
+++ b/arch/arm/include/asm/hypervisor.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_ARM_HYPERVISOR_H
2#define _ASM_ARM_HYPERVISOR_H
3
4#include <asm/xen/hypervisor.h>
5
6#endif
diff --git a/arch/arm/include/asm/sync_bitops.h b/arch/arm/include/asm/sync_bitops.h
new file mode 100644
index 000000000000..63479eecbf76
--- /dev/null
+++ b/arch/arm/include/asm/sync_bitops.h
@@ -0,0 +1,27 @@
1#ifndef __ASM_SYNC_BITOPS_H__
2#define __ASM_SYNC_BITOPS_H__
3
4#include <asm/bitops.h>
5#include <asm/system.h>
6
7/* sync_bitops functions are equivalent to the SMP implementation of the
8 * original functions, independently from CONFIG_SMP being defined.
9 *
10 * We need them because _set_bit etc are not SMP safe if !CONFIG_SMP. But
11 * under Xen you might be communicating with a completely external entity
12 * who might be on another CPU (e.g. two uniprocessor guests communicating
13 * via event channels and grant tables). So we need a variant of the bit
14 * ops which are SMP safe even on a UP kernel.
15 */
16
17#define sync_set_bit(nr, p) _set_bit(nr, p)
18#define sync_clear_bit(nr, p) _clear_bit(nr, p)
19#define sync_change_bit(nr, p) _change_bit(nr, p)
20#define sync_test_and_set_bit(nr, p) _test_and_set_bit(nr, p)
21#define sync_test_and_clear_bit(nr, p) _test_and_clear_bit(nr, p)
22#define sync_test_and_change_bit(nr, p) _test_and_change_bit(nr, p)
23#define sync_test_bit(nr, addr) test_bit(nr, addr)
24#define sync_cmpxchg cmpxchg
25
26
27#endif
diff --git a/arch/arm/include/asm/xen/events.h b/arch/arm/include/asm/xen/events.h
new file mode 100644
index 000000000000..94b4e9020b02
--- /dev/null
+++ b/arch/arm/include/asm/xen/events.h
@@ -0,0 +1,18 @@
1#ifndef _ASM_ARM_XEN_EVENTS_H
2#define _ASM_ARM_XEN_EVENTS_H
3
4#include <asm/ptrace.h>
5
6enum ipi_vector {
7 XEN_PLACEHOLDER_VECTOR,
8
9 /* Xen IPIs go here */
10 XEN_NR_IPIS,
11};
12
13static inline int xen_irqs_disabled(struct pt_regs *regs)
14{
15 return raw_irqs_disabled_flags(regs->ARM_cpsr);
16}
17
18#endif /* _ASM_ARM_XEN_EVENTS_H */
diff --git a/arch/arm/include/asm/xen/hypercall.h b/arch/arm/include/asm/xen/hypercall.h
new file mode 100644
index 000000000000..8a823253d775
--- /dev/null
+++ b/arch/arm/include/asm/xen/hypercall.h
@@ -0,0 +1,69 @@
1/******************************************************************************
2 * hypercall.h
3 *
4 * Linux-specific hypervisor handling.
5 *
6 * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation; or, when distributed
11 * separately from the Linux kernel or incorporated into other
12 * software packages, subject to the following license:
13 *
14 * Permission is hereby granted, free of charge, to any person obtaining a copy
15 * of this source file (the "Software"), to deal in the Software without
16 * restriction, including without limitation the rights to use, copy, modify,
17 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
18 * and to permit persons to whom the Software is furnished to do so, subject to
19 * the following conditions:
20 *
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30 * IN THE SOFTWARE.
31 */
32
33#ifndef _ASM_ARM_XEN_HYPERCALL_H
34#define _ASM_ARM_XEN_HYPERCALL_H
35
36#include <xen/interface/xen.h>
37
38long privcmd_call(unsigned call, unsigned long a1,
39 unsigned long a2, unsigned long a3,
40 unsigned long a4, unsigned long a5);
41int HYPERVISOR_xen_version(int cmd, void *arg);
42int HYPERVISOR_console_io(int cmd, int count, char *str);
43int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
44int HYPERVISOR_sched_op(int cmd, void *arg);
45int HYPERVISOR_event_channel_op(int cmd, void *arg);
46unsigned long HYPERVISOR_hvm_op(int op, void *arg);
47int HYPERVISOR_memory_op(unsigned int cmd, void *arg);
48int HYPERVISOR_physdev_op(int cmd, void *arg);
49
50static inline void
51MULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va,
52 unsigned int new_val, unsigned long flags)
53{
54 BUG();
55}
56
57static inline void
58MULTI_mmu_update(struct multicall_entry *mcl, struct mmu_update *req,
59 int count, int *success_count, domid_t domid)
60{
61 BUG();
62}
63
64static inline int
65HYPERVISOR_multicall(void *call_list, int nr_calls)
66{
67 BUG();
68}
69#endif /* _ASM_ARM_XEN_HYPERCALL_H */
diff --git a/arch/arm/include/asm/xen/hypervisor.h b/arch/arm/include/asm/xen/hypervisor.h
new file mode 100644
index 000000000000..d7ab99a0c9eb
--- /dev/null
+++ b/arch/arm/include/asm/xen/hypervisor.h
@@ -0,0 +1,19 @@
1#ifndef _ASM_ARM_XEN_HYPERVISOR_H
2#define _ASM_ARM_XEN_HYPERVISOR_H
3
4extern struct shared_info *HYPERVISOR_shared_info;
5extern struct start_info *xen_start_info;
6
7/* Lazy mode for batching updates / context switch */
8enum paravirt_lazy_mode {
9 PARAVIRT_LAZY_NONE,
10 PARAVIRT_LAZY_MMU,
11 PARAVIRT_LAZY_CPU,
12};
13
14static inline enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
15{
16 return PARAVIRT_LAZY_NONE;
17}
18
19#endif /* _ASM_ARM_XEN_HYPERVISOR_H */
diff --git a/arch/arm/include/asm/xen/interface.h b/arch/arm/include/asm/xen/interface.h
new file mode 100644
index 000000000000..ae05e56dd17d
--- /dev/null
+++ b/arch/arm/include/asm/xen/interface.h
@@ -0,0 +1,73 @@
1/******************************************************************************
2 * Guest OS interface to ARM Xen.
3 *
4 * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
5 */
6
7#ifndef _ASM_ARM_XEN_INTERFACE_H
8#define _ASM_ARM_XEN_INTERFACE_H
9
10#include <linux/types.h>
11
12#define uint64_aligned_t uint64_t __attribute__((aligned(8)))
13
14#define __DEFINE_GUEST_HANDLE(name, type) \
15 typedef struct { union { type *p; uint64_aligned_t q; }; } \
16 __guest_handle_ ## name
17
18#define DEFINE_GUEST_HANDLE_STRUCT(name) \
19 __DEFINE_GUEST_HANDLE(name, struct name)
20#define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name)
21#define GUEST_HANDLE(name) __guest_handle_ ## name
22
23#define set_xen_guest_handle(hnd, val) \
24 do { \
25 if (sizeof(hnd) == 8) \
26 *(uint64_t *)&(hnd) = 0; \
27 (hnd).p = val; \
28 } while (0)
29
30#ifndef __ASSEMBLY__
31/* Explicitly size integers that represent pfns in the interface with
32 * Xen so that we can have one ABI that works for 32 and 64 bit guests. */
33typedef uint64_t xen_pfn_t;
34typedef uint64_t xen_ulong_t;
35/* Guest handles for primitive C types. */
36__DEFINE_GUEST_HANDLE(uchar, unsigned char);
37__DEFINE_GUEST_HANDLE(uint, unsigned int);
38__DEFINE_GUEST_HANDLE(ulong, unsigned long);
39DEFINE_GUEST_HANDLE(char);
40DEFINE_GUEST_HANDLE(int);
41DEFINE_GUEST_HANDLE(long);
42DEFINE_GUEST_HANDLE(void);
43DEFINE_GUEST_HANDLE(uint64_t);
44DEFINE_GUEST_HANDLE(uint32_t);
45DEFINE_GUEST_HANDLE(xen_pfn_t);
46
47/* Maximum number of virtual CPUs in multi-processor guests. */
48#define MAX_VIRT_CPUS 1
49
50struct arch_vcpu_info { };
51struct arch_shared_info { };
52
53/* TODO: Move pvclock definitions some place arch independent */
54struct pvclock_vcpu_time_info {
55 u32 version;
56 u32 pad0;
57 u64 tsc_timestamp;
58 u64 system_time;
59 u32 tsc_to_system_mul;
60 s8 tsc_shift;
61 u8 flags;
62 u8 pad[2];
63} __attribute__((__packed__)); /* 32 bytes */
64
65/* It is OK to have a 12 bytes struct with no padding because it is packed */
66struct pvclock_wall_clock {
67 u32 version;
68 u32 sec;
69 u32 nsec;
70} __attribute__((__packed__));
71#endif
72
73#endif /* _ASM_ARM_XEN_INTERFACE_H */
diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
new file mode 100644
index 000000000000..174202318dff
--- /dev/null
+++ b/arch/arm/include/asm/xen/page.h
@@ -0,0 +1,82 @@
1#ifndef _ASM_ARM_XEN_PAGE_H
2#define _ASM_ARM_XEN_PAGE_H
3
4#include <asm/page.h>
5#include <asm/pgtable.h>
6
7#include <linux/pfn.h>
8#include <linux/types.h>
9
10#include <xen/interface/grant_table.h>
11
12#define pfn_to_mfn(pfn) (pfn)
13#define phys_to_machine_mapping_valid (1)
14#define mfn_to_pfn(mfn) (mfn)
15#define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT))
16
17#define pte_mfn pte_pfn
18#define mfn_pte pfn_pte
19
20/* Xen machine address */
21typedef struct xmaddr {
22 phys_addr_t maddr;
23} xmaddr_t;
24
25/* Xen pseudo-physical address */
26typedef struct xpaddr {
27 phys_addr_t paddr;
28} xpaddr_t;
29
30#define XMADDR(x) ((xmaddr_t) { .maddr = (x) })
31#define XPADDR(x) ((xpaddr_t) { .paddr = (x) })
32
33static inline xmaddr_t phys_to_machine(xpaddr_t phys)
34{
35 unsigned offset = phys.paddr & ~PAGE_MASK;
36 return XMADDR(PFN_PHYS(pfn_to_mfn(PFN_DOWN(phys.paddr))) | offset);
37}
38
39static inline xpaddr_t machine_to_phys(xmaddr_t machine)
40{
41 unsigned offset = machine.maddr & ~PAGE_MASK;
42 return XPADDR(PFN_PHYS(mfn_to_pfn(PFN_DOWN(machine.maddr))) | offset);
43}
44/* VIRT <-> MACHINE conversion */
45#define virt_to_machine(v) (phys_to_machine(XPADDR(__pa(v))))
46#define virt_to_pfn(v) (PFN_DOWN(__pa(v)))
47#define virt_to_mfn(v) (pfn_to_mfn(virt_to_pfn(v)))
48#define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT))
49
50static inline xmaddr_t arbitrary_virt_to_machine(void *vaddr)
51{
52 /* TODO: assuming it is mapped in the kernel 1:1 */
53 return virt_to_machine(vaddr);
54}
55
56/* TODO: this shouldn't be here but it is because the frontend drivers
57 * are using it (its rolled in headers) even though we won't hit the code path.
58 * So for right now just punt with this.
59 */
60static inline pte_t *lookup_address(unsigned long address, unsigned int *level)
61{
62 BUG();
63 return NULL;
64}
65
66static inline int m2p_add_override(unsigned long mfn, struct page *page,
67 struct gnttab_map_grant_ref *kmap_op)
68{
69 return 0;
70}
71
72static inline int m2p_remove_override(struct page *page, bool clear_pte)
73{
74 return 0;
75}
76
77static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
78{
79 BUG();
80 return false;
81}
82#endif /* _ASM_ARM_XEN_PAGE_H */
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 5f6b7d543e55..560e0df728f8 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -659,6 +659,7 @@ static void __init v2m_dt_init(void)
659 659
660const static char *v2m_dt_match[] __initconst = { 660const static char *v2m_dt_match[] __initconst = {
661 "arm,vexpress", 661 "arm,vexpress",
662 "xen,xenvm",
662 NULL, 663 NULL,
663}; 664};
664 665
diff --git a/arch/arm/xen/Makefile b/arch/arm/xen/Makefile
new file mode 100644
index 000000000000..43841033afd3
--- /dev/null
+++ b/arch/arm/xen/Makefile
@@ -0,0 +1 @@
obj-y := enlighten.o hypercall.o grant-table.o
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
new file mode 100644
index 000000000000..59bcb96ac369
--- /dev/null
+++ b/arch/arm/xen/enlighten.c
@@ -0,0 +1,168 @@
1#include <xen/xen.h>
2#include <xen/events.h>
3#include <xen/grant_table.h>
4#include <xen/hvm.h>
5#include <xen/interface/xen.h>
6#include <xen/interface/memory.h>
7#include <xen/interface/hvm/params.h>
8#include <xen/features.h>
9#include <xen/platform_pci.h>
10#include <xen/xenbus.h>
11#include <asm/xen/hypervisor.h>
12#include <asm/xen/hypercall.h>
13#include <linux/interrupt.h>
14#include <linux/irqreturn.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/of_irq.h>
18#include <linux/of_address.h>
19
20struct start_info _xen_start_info;
21struct start_info *xen_start_info = &_xen_start_info;
22EXPORT_SYMBOL_GPL(xen_start_info);
23
24enum xen_domain_type xen_domain_type = XEN_NATIVE;
25EXPORT_SYMBOL_GPL(xen_domain_type);
26
27struct shared_info xen_dummy_shared_info;
28struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info;
29
30DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
31
32/* TODO: to be removed */
33__read_mostly int xen_have_vector_callback;
34EXPORT_SYMBOL_GPL(xen_have_vector_callback);
35
36int xen_platform_pci_unplug = XEN_UNPLUG_ALL;
37EXPORT_SYMBOL_GPL(xen_platform_pci_unplug);
38
39static __read_mostly int xen_events_irq = -1;
40
41int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
42 unsigned long addr,
43 unsigned long mfn, int nr,
44 pgprot_t prot, unsigned domid)
45{
46 return -ENOSYS;
47}
48EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
49
50/*
51 * see Documentation/devicetree/bindings/arm/xen.txt for the
52 * documentation of the Xen Device Tree format.
53 */
54#define GRANT_TABLE_PHYSADDR 0
55static int __init xen_guest_init(void)
56{
57 struct xen_add_to_physmap xatp;
58 static struct shared_info *shared_info_page = 0;
59 struct device_node *node;
60 int len;
61 const char *s = NULL;
62 const char *version = NULL;
63 const char *xen_prefix = "xen,xen-";
64 struct resource res;
65
66 node = of_find_compatible_node(NULL, NULL, "xen,xen");
67 if (!node) {
68 pr_debug("No Xen support\n");
69 return 0;
70 }
71 s = of_get_property(node, "compatible", &len);
72 if (strlen(xen_prefix) + 3 < len &&
73 !strncmp(xen_prefix, s, strlen(xen_prefix)))
74 version = s + strlen(xen_prefix);
75 if (version == NULL) {
76 pr_debug("Xen version not found\n");
77 return 0;
78 }
79 if (of_address_to_resource(node, GRANT_TABLE_PHYSADDR, &res))
80 return 0;
81 xen_hvm_resume_frames = res.start >> PAGE_SHIFT;
82 xen_events_irq = irq_of_parse_and_map(node, 0);
83 pr_info("Xen %s support found, events_irq=%d gnttab_frame_pfn=%lx\n",
84 version, xen_events_irq, xen_hvm_resume_frames);
85 xen_domain_type = XEN_HVM_DOMAIN;
86
87 xen_setup_features();
88 if (xen_feature(XENFEAT_dom0))
89 xen_start_info->flags |= SIF_INITDOMAIN|SIF_PRIVILEGED;
90 else
91 xen_start_info->flags &= ~(SIF_INITDOMAIN|SIF_PRIVILEGED);
92
93 if (!shared_info_page)
94 shared_info_page = (struct shared_info *)
95 get_zeroed_page(GFP_KERNEL);
96 if (!shared_info_page) {
97 pr_err("not enough memory\n");
98 return -ENOMEM;
99 }
100 xatp.domid = DOMID_SELF;
101 xatp.idx = 0;
102 xatp.space = XENMAPSPACE_shared_info;
103 xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT;
104 if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
105 BUG();
106
107 HYPERVISOR_shared_info = (struct shared_info *)shared_info_page;
108
109 /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info
110 * page, we use it in the event channel upcall and in some pvclock
111 * related functions. We don't need the vcpu_info placement
112 * optimizations because we don't use any pv_mmu or pv_irq op on
113 * HVM.
114 * The shared info contains exactly 1 CPU (the boot CPU). The guest
115 * is required to use VCPUOP_register_vcpu_info to place vcpu info
116 * for secondary CPUs as they are brought up. */
117 per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
118
119 gnttab_init();
120 if (!xen_initial_domain())
121 xenbus_probe(NULL);
122
123 return 0;
124}
125core_initcall(xen_guest_init);
126
127static irqreturn_t xen_arm_callback(int irq, void *arg)
128{
129 xen_hvm_evtchn_do_upcall();
130 return IRQ_HANDLED;
131}
132
133static int __init xen_init_events(void)
134{
135 if (!xen_domain() || xen_events_irq < 0)
136 return -ENODEV;
137
138 xen_init_IRQ();
139
140 if (request_percpu_irq(xen_events_irq, xen_arm_callback,
141 "events", xen_vcpu)) {
142 pr_err("Error requesting IRQ %d\n", xen_events_irq);
143 return -EINVAL;
144 }
145
146 enable_percpu_irq(xen_events_irq, 0);
147
148 return 0;
149}
150postcore_initcall(xen_init_events);
151
152/* XXX: only until balloon is properly working */
153int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem)
154{
155 *pages = alloc_pages(highmem ? GFP_HIGHUSER : GFP_KERNEL,
156 get_order(nr_pages));
157 if (*pages == NULL)
158 return -ENOMEM;
159 return 0;
160}
161EXPORT_SYMBOL_GPL(alloc_xenballooned_pages);
162
163void free_xenballooned_pages(int nr_pages, struct page **pages)
164{
165 kfree(*pages);
166 *pages = NULL;
167}
168EXPORT_SYMBOL_GPL(free_xenballooned_pages);
diff --git a/arch/arm/xen/grant-table.c b/arch/arm/xen/grant-table.c
new file mode 100644
index 000000000000..dbd1330c0196
--- /dev/null
+++ b/arch/arm/xen/grant-table.c
@@ -0,0 +1,53 @@
1/******************************************************************************
2 * grant_table.c
3 * ARM specific part
4 *
5 * Granting foreign access to our memory reservation.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version 2
9 * as published by the Free Software Foundation; or, when distributed
10 * separately from the Linux kernel or incorporated into other
11 * software packages, subject to the following license:
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining a copy
14 * of this source file (the "Software"), to deal in the Software without
15 * restriction, including without limitation the rights to use, copy, modify,
16 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
17 * and to permit persons to whom the Software is furnished to do so, subject to
18 * the following conditions:
19 *
20 * The above copyright notice and this permission notice shall be included in
21 * all copies or substantial portions of the Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
29 * IN THE SOFTWARE.
30 */
31
32#include <xen/interface/xen.h>
33#include <xen/page.h>
34#include <xen/grant_table.h>
35
36int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
37 unsigned long max_nr_gframes,
38 void **__shared)
39{
40 return -ENOSYS;
41}
42
43void arch_gnttab_unmap(void *shared, unsigned long nr_gframes)
44{
45 return;
46}
47
48int arch_gnttab_map_status(uint64_t *frames, unsigned long nr_gframes,
49 unsigned long max_nr_gframes,
50 grant_status_t **__shared)
51{
52 return -ENOSYS;
53}
diff --git a/arch/arm/xen/hypercall.S b/arch/arm/xen/hypercall.S
new file mode 100644
index 000000000000..074f5ed101b9
--- /dev/null
+++ b/arch/arm/xen/hypercall.S
@@ -0,0 +1,106 @@
1/******************************************************************************
2 * hypercall.S
3 *
4 * Xen hypercall wrappers
5 *
6 * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation; or, when distributed
11 * separately from the Linux kernel or incorporated into other
12 * software packages, subject to the following license:
13 *
14 * Permission is hereby granted, free of charge, to any person obtaining a copy
15 * of this source file (the "Software"), to deal in the Software without
16 * restriction, including without limitation the rights to use, copy, modify,
17 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
18 * and to permit persons to whom the Software is furnished to do so, subject to
19 * the following conditions:
20 *
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30 * IN THE SOFTWARE.
31 */
32
33/*
34 * The Xen hypercall calling convention is very similar to the ARM
35 * procedure calling convention: the first paramter is passed in r0, the
36 * second in r1, the third in r2 and the fourth in r3. Considering that
37 * Xen hypercalls have 5 arguments at most, the fifth paramter is passed
38 * in r4, differently from the procedure calling convention of using the
39 * stack for that case.
40 *
41 * The hypercall number is passed in r12.
42 *
43 * The return value is in r0.
44 *
45 * The hvc ISS is required to be 0xEA1, that is the Xen specific ARM
46 * hypercall tag.
47 */
48
49#include <linux/linkage.h>
50#include <asm/assembler.h>
51#include <xen/interface/xen.h>
52
53
54/* HVC 0xEA1 */
55#ifdef CONFIG_THUMB2_KERNEL
56#define xen_hvc .word 0xf7e08ea1
57#else
58#define xen_hvc .word 0xe140ea71
59#endif
60
61#define HYPERCALL_SIMPLE(hypercall) \
62ENTRY(HYPERVISOR_##hypercall) \
63 mov r12, #__HYPERVISOR_##hypercall; \
64 xen_hvc; \
65 mov pc, lr; \
66ENDPROC(HYPERVISOR_##hypercall)
67
68#define HYPERCALL0 HYPERCALL_SIMPLE
69#define HYPERCALL1 HYPERCALL_SIMPLE
70#define HYPERCALL2 HYPERCALL_SIMPLE
71#define HYPERCALL3 HYPERCALL_SIMPLE
72#define HYPERCALL4 HYPERCALL_SIMPLE
73
74#define HYPERCALL5(hypercall) \
75ENTRY(HYPERVISOR_##hypercall) \
76 stmdb sp!, {r4} \
77 ldr r4, [sp, #4] \
78 mov r12, #__HYPERVISOR_##hypercall; \
79 xen_hvc \
80 ldm sp!, {r4} \
81 mov pc, lr \
82ENDPROC(HYPERVISOR_##hypercall)
83
84 .text
85
86HYPERCALL2(xen_version);
87HYPERCALL3(console_io);
88HYPERCALL3(grant_table_op);
89HYPERCALL2(sched_op);
90HYPERCALL2(event_channel_op);
91HYPERCALL2(hvm_op);
92HYPERCALL2(memory_op);
93HYPERCALL2(physdev_op);
94
95ENTRY(privcmd_call)
96 stmdb sp!, {r4}
97 mov r12, r0
98 mov r0, r1
99 mov r1, r2
100 mov r2, r3
101 ldr r3, [sp, #8]
102 ldr r4, [sp, #4]
103 xen_hvc
104 ldm sp!, {r4}
105 mov pc, lr
106ENDPROC(privcmd_call);
diff --git a/arch/ia64/include/asm/xen/interface.h b/arch/ia64/include/asm/xen/interface.h
index 3d52a5bbd857..e88c5de27410 100644
--- a/arch/ia64/include/asm/xen/interface.h
+++ b/arch/ia64/include/asm/xen/interface.h
@@ -71,6 +71,7 @@
71 * with Xen so that we could have one ABI that works for 32 and 64 bit 71 * with Xen so that we could have one ABI that works for 32 and 64 bit
72 * guests. */ 72 * guests. */
73typedef unsigned long xen_pfn_t; 73typedef unsigned long xen_pfn_t;
74typedef unsigned long xen_ulong_t;
74/* Guest handles for primitive C types. */ 75/* Guest handles for primitive C types. */
75__DEFINE_GUEST_HANDLE(uchar, unsigned char); 76__DEFINE_GUEST_HANDLE(uchar, unsigned char);
76__DEFINE_GUEST_HANDLE(uint, unsigned int); 77__DEFINE_GUEST_HANDLE(uint, unsigned int);
diff --git a/arch/x86/include/asm/xen/interface.h b/arch/x86/include/asm/xen/interface.h
index 1707cfa928fb..6d2f75a82a14 100644
--- a/arch/x86/include/asm/xen/interface.h
+++ b/arch/x86/include/asm/xen/interface.h
@@ -51,6 +51,7 @@
51 * with Xen so that on ARM we can have one ABI that works for 32 and 64 51 * with Xen so that on ARM we can have one ABI that works for 32 and 64
52 * bit guests. */ 52 * bit guests. */
53typedef unsigned long xen_pfn_t; 53typedef unsigned long xen_pfn_t;
54typedef unsigned long xen_ulong_t;
54/* Guest handles for primitive C types. */ 55/* Guest handles for primitive C types. */
55__DEFINE_GUEST_HANDLE(uchar, unsigned char); 56__DEFINE_GUEST_HANDLE(uchar, unsigned char);
56__DEFINE_GUEST_HANDLE(uint, unsigned int); 57__DEFINE_GUEST_HANDLE(uint, unsigned int);
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 2d932c351f91..bf788d34530d 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -33,6 +33,7 @@
33#include <linux/memblock.h> 33#include <linux/memblock.h>
34 34
35#include <xen/xen.h> 35#include <xen/xen.h>
36#include <xen/events.h>
36#include <xen/interface/xen.h> 37#include <xen/interface/xen.h>
37#include <xen/interface/version.h> 38#include <xen/interface/version.h>
38#include <xen/interface/physdev.h> 39#include <xen/interface/physdev.h>
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index 157337657971..01a4dc015ae1 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -5,6 +5,7 @@
5#include <xen/interface/xen.h> 5#include <xen/interface/xen.h>
6#include <xen/interface/sched.h> 6#include <xen/interface/sched.h>
7#include <xen/interface/vcpu.h> 7#include <xen/interface/vcpu.h>
8#include <xen/events.h>
8 9
9#include <asm/xen/hypercall.h> 10#include <asm/xen/hypercall.h>
10#include <asm/xen/hypervisor.h> 11#include <asm/xen/hypervisor.h>
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index bb5a8105ea86..a95b41744ad0 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -35,7 +35,6 @@ void xen_set_pat(u64);
35 35
36char * __init xen_memory_setup(void); 36char * __init xen_memory_setup(void);
37void __init xen_arch_setup(void); 37void __init xen_arch_setup(void);
38void __init xen_init_IRQ(void);
39void xen_enable_sysenter(void); 38void xen_enable_sysenter(void);
40void xen_enable_syscall(void); 39void xen_enable_syscall(void);
41void xen_vcpu_restore(void); 40void xen_vcpu_restore(void);