2 #include <xen/events.h>
3 #include <xen/grant_table.h>
5 #include <xen/interface/vcpu.h>
6 #include <xen/interface/xen.h>
7 #include <xen/interface/memory.h>
8 #include <xen/interface/hvm/params.h>
9 #include <xen/features.h>
10 #include <xen/platform_pci.h>
11 #include <xen/xenbus.h>
13 #include <xen/interface/sched.h>
14 #include <xen/xen-ops.h>
15 #include <asm/xen/hypervisor.h>
16 #include <asm/xen/hypercall.h>
17 #include <asm/system_misc.h>
18 #include <linux/interrupt.h>
19 #include <linux/irqreturn.h>
20 #include <linux/module.h>
22 #include <linux/of_irq.h>
23 #include <linux/of_address.h>
24 #include <linux/cpuidle.h>
25 #include <linux/cpufreq.h>
26 #include <linux/cpu.h>
27 #include <linux/console.h>
31 struct start_info _xen_start_info
;
32 struct start_info
*xen_start_info
= &_xen_start_info
;
33 EXPORT_SYMBOL(xen_start_info
);
35 enum xen_domain_type xen_domain_type
= XEN_NATIVE
;
36 EXPORT_SYMBOL(xen_domain_type
);
38 struct shared_info xen_dummy_shared_info
;
39 struct shared_info
*HYPERVISOR_shared_info
= (void *)&xen_dummy_shared_info
;
41 DEFINE_PER_CPU(struct vcpu_info
*, xen_vcpu
);
42 static struct vcpu_info __percpu
*xen_vcpu_info
;
44 /* These are unused until we support booting "pre-ballooned" */
45 unsigned long xen_released_pages
;
46 struct xen_memory_region xen_extra_mem
[XEN_EXTRA_MEM_MAX_REGIONS
] __initdata
;
48 static __read_mostly
unsigned int xen_events_irq
;
50 static __initdata
struct device_node
*xen_node
;
52 int xen_remap_domain_gfn_array(struct vm_area_struct
*vma
,
54 xen_pfn_t
*gfn
, int nr
,
55 int *err_ptr
, pgprot_t prot
,
59 return xen_xlate_remap_gfn_array(vma
, addr
, gfn
, nr
, err_ptr
,
62 EXPORT_SYMBOL_GPL(xen_remap_domain_gfn_array
);
64 /* Not used by XENFEAT_auto_translated guests. */
65 int xen_remap_domain_gfn_range(struct vm_area_struct
*vma
,
67 xen_pfn_t gfn
, int nr
,
68 pgprot_t prot
, unsigned domid
,
73 EXPORT_SYMBOL_GPL(xen_remap_domain_gfn_range
);
75 int xen_unmap_domain_gfn_range(struct vm_area_struct
*vma
,
76 int nr
, struct page
**pages
)
78 return xen_xlate_unmap_gfn_range(vma
, nr
, pages
);
80 EXPORT_SYMBOL_GPL(xen_unmap_domain_gfn_range
);
82 static void xen_percpu_init(void)
84 struct vcpu_register_vcpu_info info
;
85 struct vcpu_info
*vcpup
;
90 * VCPUOP_register_vcpu_info cannot be called twice for the same
91 * vcpu, so if vcpu_info is already registered, just get out. This
92 * can happen with cpu-hotplug.
94 if (per_cpu(xen_vcpu
, cpu
) != NULL
)
95 goto after_register_vcpu_info
;
97 pr_info("Xen: initializing cpu%d\n", cpu
);
98 vcpup
= per_cpu_ptr(xen_vcpu_info
, cpu
);
100 info
.mfn
= virt_to_gfn(vcpup
);
101 info
.offset
= xen_offset_in_page(vcpup
);
103 err
= HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info
, cpu
, &info
);
105 per_cpu(xen_vcpu
, cpu
) = vcpup
;
107 after_register_vcpu_info
:
108 enable_percpu_irq(xen_events_irq
, 0);
112 static void xen_restart(enum reboot_mode reboot_mode
, const char *cmd
)
114 struct sched_shutdown r
= { .reason
= SHUTDOWN_reboot
};
116 rc
= HYPERVISOR_sched_op(SCHEDOP_shutdown
, &r
);
120 static void xen_power_off(void)
122 struct sched_shutdown r
= { .reason
= SHUTDOWN_poweroff
};
124 rc
= HYPERVISOR_sched_op(SCHEDOP_shutdown
, &r
);
128 static int xen_cpu_notification(struct notifier_block
*self
,
129 unsigned long action
,
137 disable_percpu_irq(xen_events_irq
);
146 static struct notifier_block xen_cpu_notifier
= {
147 .notifier_call
= xen_cpu_notification
,
150 static irqreturn_t
xen_arm_callback(int irq
, void *arg
)
152 xen_hvm_evtchn_do_upcall();
157 * see Documentation/devicetree/bindings/arm/xen.txt for the
158 * documentation of the Xen Device Tree format.
160 #define GRANT_TABLE_PHYSADDR 0
161 void __init
xen_early_init(void)
164 const char *s
= NULL
;
165 const char *version
= NULL
;
166 const char *xen_prefix
= "xen,xen-";
168 xen_node
= of_find_compatible_node(NULL
, NULL
, "xen,xen");
170 pr_debug("No Xen support\n");
173 s
= of_get_property(xen_node
, "compatible", &len
);
174 if (strlen(xen_prefix
) + 3 < len
&&
175 !strncmp(xen_prefix
, s
, strlen(xen_prefix
)))
176 version
= s
+ strlen(xen_prefix
);
177 if (version
== NULL
) {
178 pr_debug("Xen version not found\n");
182 pr_info("Xen %s support found\n", version
);
184 xen_domain_type
= XEN_HVM_DOMAIN
;
186 xen_setup_features();
188 if (xen_feature(XENFEAT_dom0
))
189 xen_start_info
->flags
|= SIF_INITDOMAIN
|SIF_PRIVILEGED
;
191 xen_start_info
->flags
&= ~(SIF_INITDOMAIN
|SIF_PRIVILEGED
);
193 if (!console_set_on_cmdline
&& !xen_initial_domain())
194 add_preferred_console("hvc", 0, NULL
);
197 static int __init
xen_guest_init(void)
199 struct xen_add_to_physmap xatp
;
200 struct shared_info
*shared_info_page
= NULL
;
202 phys_addr_t grant_frames
;
207 if (of_address_to_resource(xen_node
, GRANT_TABLE_PHYSADDR
, &res
)) {
208 pr_err("Xen grant table base address not found\n");
211 grant_frames
= res
.start
;
213 xen_events_irq
= irq_of_parse_and_map(xen_node
, 0);
214 if (!xen_events_irq
) {
215 pr_err("Xen event channel interrupt not found\n");
219 shared_info_page
= (struct shared_info
*)get_zeroed_page(GFP_KERNEL
);
221 if (!shared_info_page
) {
222 pr_err("not enough memory\n");
225 xatp
.domid
= DOMID_SELF
;
227 xatp
.space
= XENMAPSPACE_shared_info
;
228 xatp
.gpfn
= virt_to_gfn(shared_info_page
);
229 if (HYPERVISOR_memory_op(XENMEM_add_to_physmap
, &xatp
))
232 HYPERVISOR_shared_info
= (struct shared_info
*)shared_info_page
;
234 /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info
235 * page, we use it in the event channel upcall and in some pvclock
237 * The shared info contains exactly 1 CPU (the boot CPU). The guest
238 * is required to use VCPUOP_register_vcpu_info to place vcpu info
239 * for secondary CPUs as they are brought up.
240 * For uniformity we use VCPUOP_register_vcpu_info even on cpu0.
242 xen_vcpu_info
= __alloc_percpu(sizeof(struct vcpu_info
),
243 sizeof(struct vcpu_info
));
244 if (xen_vcpu_info
== NULL
)
247 if (gnttab_setup_auto_xlat_frames(grant_frames
)) {
248 free_percpu(xen_vcpu_info
);
252 if (!xen_initial_domain())
256 * Making sure board specific code will not set up ops for
257 * cpu idle and cpu freq.
264 if (request_percpu_irq(xen_events_irq
, xen_arm_callback
,
265 "events", &xen_vcpu
)) {
266 pr_err("Error request IRQ %d\n", xen_events_irq
);
272 register_cpu_notifier(&xen_cpu_notifier
);
276 early_initcall(xen_guest_init
);
278 static int __init
xen_pm_init(void)
283 pm_power_off
= xen_power_off
;
284 arm_pm_restart
= xen_restart
;
288 late_initcall(xen_pm_init
);
292 void xen_arch_pre_suspend(void) { }
293 void xen_arch_post_suspend(int suspend_cancelled
) { }
294 void xen_timer_resume(void) { }
295 void xen_arch_resume(void) { }
296 void xen_arch_suspend(void) { }
299 /* In the hypercall.S file. */
300 EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op
);
301 EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op
);
302 EXPORT_SYMBOL_GPL(HYPERVISOR_xen_version
);
303 EXPORT_SYMBOL_GPL(HYPERVISOR_console_io
);
304 EXPORT_SYMBOL_GPL(HYPERVISOR_sched_op
);
305 EXPORT_SYMBOL_GPL(HYPERVISOR_hvm_op
);
306 EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op
);
307 EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op
);
308 EXPORT_SYMBOL_GPL(HYPERVISOR_vcpu_op
);
309 EXPORT_SYMBOL_GPL(HYPERVISOR_tmem_op
);
310 EXPORT_SYMBOL_GPL(HYPERVISOR_multicall
);
311 EXPORT_SYMBOL_GPL(privcmd_call
);