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/paravirt.h>
16 #include <asm/xen/hypervisor.h>
17 #include <asm/xen/hypercall.h>
18 #include <asm/system_misc.h>
19 #include <linux/interrupt.h>
20 #include <linux/irqreturn.h>
21 #include <linux/module.h>
23 #include <linux/of_irq.h>
24 #include <linux/of_address.h>
25 #include <linux/cpuidle.h>
26 #include <linux/cpufreq.h>
27 #include <linux/cpu.h>
28 #include <linux/console.h>
32 struct start_info _xen_start_info
;
33 struct start_info
*xen_start_info
= &_xen_start_info
;
34 EXPORT_SYMBOL(xen_start_info
);
36 enum xen_domain_type xen_domain_type
= XEN_NATIVE
;
37 EXPORT_SYMBOL(xen_domain_type
);
39 struct shared_info xen_dummy_shared_info
;
40 struct shared_info
*HYPERVISOR_shared_info
= (void *)&xen_dummy_shared_info
;
42 DEFINE_PER_CPU(struct vcpu_info
*, xen_vcpu
);
43 static struct vcpu_info __percpu
*xen_vcpu_info
;
45 /* These are unused until we support booting "pre-ballooned" */
46 unsigned long xen_released_pages
;
47 struct xen_memory_region xen_extra_mem
[XEN_EXTRA_MEM_MAX_REGIONS
] __initdata
;
49 static __read_mostly
unsigned int xen_events_irq
;
51 static __initdata
struct device_node
*xen_node
;
53 int xen_remap_domain_gfn_array(struct vm_area_struct
*vma
,
55 xen_pfn_t
*gfn
, int nr
,
56 int *err_ptr
, pgprot_t prot
,
60 return xen_xlate_remap_gfn_array(vma
, addr
, gfn
, nr
, err_ptr
,
63 EXPORT_SYMBOL_GPL(xen_remap_domain_gfn_array
);
65 /* Not used by XENFEAT_auto_translated guests. */
66 int xen_remap_domain_gfn_range(struct vm_area_struct
*vma
,
68 xen_pfn_t gfn
, int nr
,
69 pgprot_t prot
, unsigned domid
,
74 EXPORT_SYMBOL_GPL(xen_remap_domain_gfn_range
);
76 int xen_unmap_domain_gfn_range(struct vm_area_struct
*vma
,
77 int nr
, struct page
**pages
)
79 return xen_xlate_unmap_gfn_range(vma
, nr
, pages
);
81 EXPORT_SYMBOL_GPL(xen_unmap_domain_gfn_range
);
83 static unsigned long long xen_stolen_accounting(int cpu
)
85 struct vcpu_runstate_info state
;
87 BUG_ON(cpu
!= smp_processor_id());
89 xen_get_runstate_snapshot(&state
);
91 WARN_ON(state
.state
!= RUNSTATE_running
);
93 return state
.time
[RUNSTATE_runnable
] + state
.time
[RUNSTATE_offline
];
96 static void xen_percpu_init(void)
98 struct vcpu_register_vcpu_info info
;
99 struct vcpu_info
*vcpup
;
104 * VCPUOP_register_vcpu_info cannot be called twice for the same
105 * vcpu, so if vcpu_info is already registered, just get out. This
106 * can happen with cpu-hotplug.
108 if (per_cpu(xen_vcpu
, cpu
) != NULL
)
109 goto after_register_vcpu_info
;
111 pr_info("Xen: initializing cpu%d\n", cpu
);
112 vcpup
= per_cpu_ptr(xen_vcpu_info
, cpu
);
114 info
.mfn
= virt_to_gfn(vcpup
);
115 info
.offset
= xen_offset_in_page(vcpup
);
117 err
= HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info
, cpu
, &info
);
119 per_cpu(xen_vcpu
, cpu
) = vcpup
;
121 xen_setup_runstate_info(cpu
);
123 after_register_vcpu_info
:
124 enable_percpu_irq(xen_events_irq
, 0);
128 static void xen_restart(enum reboot_mode reboot_mode
, const char *cmd
)
130 struct sched_shutdown r
= { .reason
= SHUTDOWN_reboot
};
132 rc
= HYPERVISOR_sched_op(SCHEDOP_shutdown
, &r
);
136 static void xen_power_off(void)
138 struct sched_shutdown r
= { .reason
= SHUTDOWN_poweroff
};
140 rc
= HYPERVISOR_sched_op(SCHEDOP_shutdown
, &r
);
144 static int xen_cpu_notification(struct notifier_block
*self
,
145 unsigned long action
,
153 disable_percpu_irq(xen_events_irq
);
162 static struct notifier_block xen_cpu_notifier
= {
163 .notifier_call
= xen_cpu_notification
,
166 static irqreturn_t
xen_arm_callback(int irq
, void *arg
)
168 xen_hvm_evtchn_do_upcall();
173 * see Documentation/devicetree/bindings/arm/xen.txt for the
174 * documentation of the Xen Device Tree format.
176 #define GRANT_TABLE_PHYSADDR 0
177 void __init
xen_early_init(void)
180 const char *s
= NULL
;
181 const char *version
= NULL
;
182 const char *xen_prefix
= "xen,xen-";
184 xen_node
= of_find_compatible_node(NULL
, NULL
, "xen,xen");
186 pr_debug("No Xen support\n");
189 s
= of_get_property(xen_node
, "compatible", &len
);
190 if (strlen(xen_prefix
) + 3 < len
&&
191 !strncmp(xen_prefix
, s
, strlen(xen_prefix
)))
192 version
= s
+ strlen(xen_prefix
);
193 if (version
== NULL
) {
194 pr_debug("Xen version not found\n");
198 pr_info("Xen %s support found\n", version
);
200 xen_domain_type
= XEN_HVM_DOMAIN
;
202 xen_setup_features();
204 if (xen_feature(XENFEAT_dom0
))
205 xen_start_info
->flags
|= SIF_INITDOMAIN
|SIF_PRIVILEGED
;
207 xen_start_info
->flags
&= ~(SIF_INITDOMAIN
|SIF_PRIVILEGED
);
209 if (!console_set_on_cmdline
&& !xen_initial_domain())
210 add_preferred_console("hvc", 0, NULL
);
213 static int __init
xen_guest_init(void)
215 struct xen_add_to_physmap xatp
;
216 struct shared_info
*shared_info_page
= NULL
;
218 phys_addr_t grant_frames
;
223 if (of_address_to_resource(xen_node
, GRANT_TABLE_PHYSADDR
, &res
)) {
224 pr_err("Xen grant table base address not found\n");
227 grant_frames
= res
.start
;
229 xen_events_irq
= irq_of_parse_and_map(xen_node
, 0);
230 if (!xen_events_irq
) {
231 pr_err("Xen event channel interrupt not found\n");
235 shared_info_page
= (struct shared_info
*)get_zeroed_page(GFP_KERNEL
);
237 if (!shared_info_page
) {
238 pr_err("not enough memory\n");
241 xatp
.domid
= DOMID_SELF
;
243 xatp
.space
= XENMAPSPACE_shared_info
;
244 xatp
.gpfn
= virt_to_gfn(shared_info_page
);
245 if (HYPERVISOR_memory_op(XENMEM_add_to_physmap
, &xatp
))
248 HYPERVISOR_shared_info
= (struct shared_info
*)shared_info_page
;
250 /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info
251 * page, we use it in the event channel upcall and in some pvclock
253 * The shared info contains exactly 1 CPU (the boot CPU). The guest
254 * is required to use VCPUOP_register_vcpu_info to place vcpu info
255 * for secondary CPUs as they are brought up.
256 * For uniformity we use VCPUOP_register_vcpu_info even on cpu0.
258 xen_vcpu_info
= __alloc_percpu(sizeof(struct vcpu_info
),
259 sizeof(struct vcpu_info
));
260 if (xen_vcpu_info
== NULL
)
263 if (gnttab_setup_auto_xlat_frames(grant_frames
)) {
264 free_percpu(xen_vcpu_info
);
268 if (!xen_initial_domain())
272 * Making sure board specific code will not set up ops for
273 * cpu idle and cpu freq.
280 if (request_percpu_irq(xen_events_irq
, xen_arm_callback
,
281 "events", &xen_vcpu
)) {
282 pr_err("Error request IRQ %d\n", xen_events_irq
);
288 register_cpu_notifier(&xen_cpu_notifier
);
290 pv_time_ops
.steal_clock
= xen_stolen_accounting
;
291 static_key_slow_inc(¶virt_steal_enabled
);
295 early_initcall(xen_guest_init
);
297 static int __init
xen_pm_init(void)
302 pm_power_off
= xen_power_off
;
303 arm_pm_restart
= xen_restart
;
307 late_initcall(xen_pm_init
);
311 void xen_arch_pre_suspend(void) { }
312 void xen_arch_post_suspend(int suspend_cancelled
) { }
313 void xen_timer_resume(void) { }
314 void xen_arch_resume(void) { }
315 void xen_arch_suspend(void) { }
318 /* In the hypercall.S file. */
319 EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op
);
320 EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op
);
321 EXPORT_SYMBOL_GPL(HYPERVISOR_xen_version
);
322 EXPORT_SYMBOL_GPL(HYPERVISOR_console_io
);
323 EXPORT_SYMBOL_GPL(HYPERVISOR_sched_op
);
324 EXPORT_SYMBOL_GPL(HYPERVISOR_hvm_op
);
325 EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op
);
326 EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op
);
327 EXPORT_SYMBOL_GPL(HYPERVISOR_vcpu_op
);
328 EXPORT_SYMBOL_GPL(HYPERVISOR_tmem_op
);
329 EXPORT_SYMBOL_GPL(HYPERVISOR_multicall
);
330 EXPORT_SYMBOL_GPL(privcmd_call
);