diff options
-rw-r--r-- | arch/ia64/include/asm/xen/hypervisor.h | 14 | ||||
-rw-r--r-- | arch/ia64/xen/Makefile | 2 | ||||
-rw-r--r-- | arch/ia64/xen/hypervisor.c | 96 | ||||
-rw-r--r-- | arch/ia64/xen/xen_pv_ops.c | 110 |
4 files changed, 221 insertions, 1 deletions
diff --git a/arch/ia64/include/asm/xen/hypervisor.h b/arch/ia64/include/asm/xen/hypervisor.h index d1f84e12c0ed..7a804e80fc67 100644 --- a/arch/ia64/include/asm/xen/hypervisor.h +++ b/arch/ia64/include/asm/xen/hypervisor.h | |||
@@ -59,8 +59,22 @@ extern enum xen_domain_type xen_domain_type; | |||
59 | /* deprecated. remove this */ | 59 | /* deprecated. remove this */ |
60 | #define is_running_on_xen() (xen_domain_type == XEN_PV_DOMAIN) | 60 | #define is_running_on_xen() (xen_domain_type == XEN_PV_DOMAIN) |
61 | 61 | ||
62 | extern struct shared_info *HYPERVISOR_shared_info; | ||
62 | extern struct start_info *xen_start_info; | 63 | extern struct start_info *xen_start_info; |
63 | 64 | ||
65 | void __init xen_setup_vcpu_info_placement(void); | ||
66 | void force_evtchn_callback(void); | ||
67 | |||
68 | /* for drivers/xen/balloon/balloon.c */ | ||
69 | #ifdef CONFIG_XEN_SCRUB_PAGES | ||
70 | #define scrub_pages(_p, _n) memset((void *)(_p), 0, (_n) << PAGE_SHIFT) | ||
71 | #else | ||
72 | #define scrub_pages(_p, _n) ((void)0) | ||
73 | #endif | ||
74 | |||
75 | /* For setup_arch() in arch/ia64/kernel/setup.c */ | ||
76 | void xen_ia64_enable_opt_feature(void); | ||
77 | |||
64 | #else /* CONFIG_XEN */ | 78 | #else /* CONFIG_XEN */ |
65 | 79 | ||
66 | #define xen_domain() (0) | 80 | #define xen_domain() (0) |
diff --git a/arch/ia64/xen/Makefile b/arch/ia64/xen/Makefile index abc356f0c5da..7cb4247f90be 100644 --- a/arch/ia64/xen/Makefile +++ b/arch/ia64/xen/Makefile | |||
@@ -3,4 +3,4 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := hypercall.o xensetup.o xen_pv_ops.o \ | 5 | obj-y := hypercall.o xensetup.o xen_pv_ops.o \ |
6 | xencomm.o xcom_hcall.o grant-table.o | 6 | hypervisor.o xencomm.o xcom_hcall.o grant-table.o |
diff --git a/arch/ia64/xen/hypervisor.c b/arch/ia64/xen/hypervisor.c new file mode 100644 index 000000000000..cac4d97c0b5a --- /dev/null +++ b/arch/ia64/xen/hypervisor.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /****************************************************************************** | ||
2 | * arch/ia64/xen/hypervisor.c | ||
3 | * | ||
4 | * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp> | ||
5 | * VA Linux Systems Japan K.K. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/efi.h> | ||
24 | #include <asm/xen/hypervisor.h> | ||
25 | #include <asm/xen/privop.h> | ||
26 | |||
27 | #include "irq_xen.h" | ||
28 | |||
29 | struct shared_info *HYPERVISOR_shared_info __read_mostly = | ||
30 | (struct shared_info *)XSI_BASE; | ||
31 | EXPORT_SYMBOL(HYPERVISOR_shared_info); | ||
32 | |||
33 | DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); | ||
34 | |||
35 | struct start_info *xen_start_info; | ||
36 | EXPORT_SYMBOL(xen_start_info); | ||
37 | |||
38 | EXPORT_SYMBOL(xen_domain_type); | ||
39 | |||
40 | EXPORT_SYMBOL(__hypercall); | ||
41 | |||
42 | /* Stolen from arch/x86/xen/enlighten.c */ | ||
43 | /* | ||
44 | * Flag to determine whether vcpu info placement is available on all | ||
45 | * VCPUs. We assume it is to start with, and then set it to zero on | ||
46 | * the first failure. This is because it can succeed on some VCPUs | ||
47 | * and not others, since it can involve hypervisor memory allocation, | ||
48 | * or because the guest failed to guarantee all the appropriate | ||
49 | * constraints on all VCPUs (ie buffer can't cross a page boundary). | ||
50 | * | ||
51 | * Note that any particular CPU may be using a placed vcpu structure, | ||
52 | * but we can only optimise if the all are. | ||
53 | * | ||
54 | * 0: not available, 1: available | ||
55 | */ | ||
56 | |||
57 | static void __init xen_vcpu_setup(int cpu) | ||
58 | { | ||
59 | /* | ||
60 | * WARNING: | ||
61 | * before changing MAX_VIRT_CPUS, | ||
62 | * check that shared_info fits on a page | ||
63 | */ | ||
64 | BUILD_BUG_ON(sizeof(struct shared_info) > PAGE_SIZE); | ||
65 | per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; | ||
66 | } | ||
67 | |||
68 | void __init xen_setup_vcpu_info_placement(void) | ||
69 | { | ||
70 | int cpu; | ||
71 | |||
72 | for_each_possible_cpu(cpu) | ||
73 | xen_vcpu_setup(cpu); | ||
74 | } | ||
75 | |||
76 | void __cpuinit | ||
77 | xen_cpu_init(void) | ||
78 | { | ||
79 | xen_smp_intr_init(); | ||
80 | } | ||
81 | |||
82 | /************************************************************************** | ||
83 | * opt feature | ||
84 | */ | ||
85 | void | ||
86 | xen_ia64_enable_opt_feature(void) | ||
87 | { | ||
88 | /* Enable region 7 identity map optimizations in Xen */ | ||
89 | struct xen_ia64_opt_feature optf; | ||
90 | |||
91 | optf.cmd = XEN_IA64_OPTF_IDENT_MAP_REG7; | ||
92 | optf.on = XEN_IA64_OPTF_ON; | ||
93 | optf.pgprot = pgprot_val(PAGE_KERNEL); | ||
94 | optf.key = 0; /* No key on linux. */ | ||
95 | HYPERVISOR_opt_feature(&optf); | ||
96 | } | ||
diff --git a/arch/ia64/xen/xen_pv_ops.c b/arch/ia64/xen/xen_pv_ops.c index 77db214b116c..fc9d599b62ae 100644 --- a/arch/ia64/xen/xen_pv_ops.c +++ b/arch/ia64/xen/xen_pv_ops.c | |||
@@ -54,6 +54,115 @@ xen_info_init(void) | |||
54 | } | 54 | } |
55 | 55 | ||
56 | /*************************************************************************** | 56 | /*************************************************************************** |
57 | * pv_init_ops | ||
58 | * initialization hooks. | ||
59 | */ | ||
60 | |||
61 | static void | ||
62 | xen_panic_hypercall(struct unw_frame_info *info, void *arg) | ||
63 | { | ||
64 | current->thread.ksp = (__u64)info->sw - 16; | ||
65 | HYPERVISOR_shutdown(SHUTDOWN_crash); | ||
66 | /* we're never actually going to get here... */ | ||
67 | } | ||
68 | |||
69 | static int | ||
70 | xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr) | ||
71 | { | ||
72 | unw_init_running(xen_panic_hypercall, NULL); | ||
73 | /* we're never actually going to get here... */ | ||
74 | return NOTIFY_DONE; | ||
75 | } | ||
76 | |||
77 | static struct notifier_block xen_panic_block = { | ||
78 | xen_panic_event, NULL, 0 /* try to go last */ | ||
79 | }; | ||
80 | |||
81 | static void xen_pm_power_off(void) | ||
82 | { | ||
83 | local_irq_disable(); | ||
84 | HYPERVISOR_shutdown(SHUTDOWN_poweroff); | ||
85 | } | ||
86 | |||
87 | static void __init | ||
88 | xen_banner(void) | ||
89 | { | ||
90 | printk(KERN_INFO | ||
91 | "Running on Xen! pl = %d start_info_pfn=0x%lx nr_pages=%ld " | ||
92 | "flags=0x%x\n", | ||
93 | xen_info.kernel_rpl, | ||
94 | HYPERVISOR_shared_info->arch.start_info_pfn, | ||
95 | xen_start_info->nr_pages, xen_start_info->flags); | ||
96 | } | ||
97 | |||
98 | static int __init | ||
99 | xen_reserve_memory(struct rsvd_region *region) | ||
100 | { | ||
101 | region->start = (unsigned long)__va( | ||
102 | (HYPERVISOR_shared_info->arch.start_info_pfn << PAGE_SHIFT)); | ||
103 | region->end = region->start + PAGE_SIZE; | ||
104 | return 1; | ||
105 | } | ||
106 | |||
107 | static void __init | ||
108 | xen_arch_setup_early(void) | ||
109 | { | ||
110 | struct shared_info *s; | ||
111 | BUG_ON(!xen_pv_domain()); | ||
112 | |||
113 | s = HYPERVISOR_shared_info; | ||
114 | xen_start_info = __va(s->arch.start_info_pfn << PAGE_SHIFT); | ||
115 | |||
116 | /* Must be done before any hypercall. */ | ||
117 | xencomm_initialize(); | ||
118 | |||
119 | xen_setup_features(); | ||
120 | /* Register a call for panic conditions. */ | ||
121 | atomic_notifier_chain_register(&panic_notifier_list, | ||
122 | &xen_panic_block); | ||
123 | pm_power_off = xen_pm_power_off; | ||
124 | |||
125 | xen_ia64_enable_opt_feature(); | ||
126 | } | ||
127 | |||
128 | static void __init | ||
129 | xen_arch_setup_console(char **cmdline_p) | ||
130 | { | ||
131 | add_preferred_console("xenboot", 0, NULL); | ||
132 | add_preferred_console("tty", 0, NULL); | ||
133 | /* use hvc_xen */ | ||
134 | add_preferred_console("hvc", 0, NULL); | ||
135 | |||
136 | #if !defined(CONFIG_VT) || !defined(CONFIG_DUMMY_CONSOLE) | ||
137 | conswitchp = NULL; | ||
138 | #endif | ||
139 | } | ||
140 | |||
141 | static int __init | ||
142 | xen_arch_setup_nomca(void) | ||
143 | { | ||
144 | return 1; | ||
145 | } | ||
146 | |||
147 | static void __init | ||
148 | xen_post_smp_prepare_boot_cpu(void) | ||
149 | { | ||
150 | xen_setup_vcpu_info_placement(); | ||
151 | } | ||
152 | |||
153 | static const struct pv_init_ops xen_init_ops __initdata = { | ||
154 | .banner = xen_banner, | ||
155 | |||
156 | .reserve_memory = xen_reserve_memory, | ||
157 | |||
158 | .arch_setup_early = xen_arch_setup_early, | ||
159 | .arch_setup_console = xen_arch_setup_console, | ||
160 | .arch_setup_nomca = xen_arch_setup_nomca, | ||
161 | |||
162 | .post_smp_prepare_boot_cpu = xen_post_smp_prepare_boot_cpu, | ||
163 | }; | ||
164 | |||
165 | /*************************************************************************** | ||
57 | * pv_ops initialization | 166 | * pv_ops initialization |
58 | */ | 167 | */ |
59 | 168 | ||
@@ -62,4 +171,5 @@ xen_setup_pv_ops(void) | |||
62 | { | 171 | { |
63 | xen_info_init(); | 172 | xen_info_init(); |
64 | pv_info = xen_info; | 173 | pv_info = xen_info; |
174 | pv_init_ops = xen_init_ops; | ||
65 | } | 175 | } |