xref: /illumos-gate/usr/src/uts/common/xen/os/hypercall.c (revision e4b86885)
1843e1988Sjohnlev /*
2843e1988Sjohnlev  * CDDL HEADER START
3843e1988Sjohnlev  *
4843e1988Sjohnlev  * The contents of this file are subject to the terms of the
5843e1988Sjohnlev  * Common Development and Distribution License (the "License").
6843e1988Sjohnlev  * You may not use this file except in compliance with the License.
7843e1988Sjohnlev  *
8843e1988Sjohnlev  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9843e1988Sjohnlev  * or http://www.opensolaris.org/os/licensing.
10843e1988Sjohnlev  * See the License for the specific language governing permissions
11843e1988Sjohnlev  * and limitations under the License.
12843e1988Sjohnlev  *
13843e1988Sjohnlev  * When distributing Covered Code, include this CDDL HEADER in each
14843e1988Sjohnlev  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15843e1988Sjohnlev  * If applicable, add the following below this CDDL HEADER, with the
16843e1988Sjohnlev  * fields enclosed by brackets "[]" replaced with your own identifying
17843e1988Sjohnlev  * information: Portions Copyright [yyyy] [name of copyright owner]
18843e1988Sjohnlev  *
19843e1988Sjohnlev  * CDDL HEADER END
20843e1988Sjohnlev  */
21843e1988Sjohnlev 
22843e1988Sjohnlev /*
23a576ab5bSrab  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24843e1988Sjohnlev  * Use is subject to license terms.
25843e1988Sjohnlev  */
26843e1988Sjohnlev 
27843e1988Sjohnlev /*
28843e1988Sjohnlev  * Provides basic C wrappers around hypervisor invocation.
29843e1988Sjohnlev  *
30843e1988Sjohnlev  * i386: eax = vector: ebx, ecx, edx, esi, edi = args 1-5
31843e1988Sjohnlev  *	 eax = return value
32843e1988Sjohnlev  *	 (argument registers may be clobbered on return)
33843e1988Sjohnlev  *
34843e1988Sjohnlev  * amd64:rax = vector: rdi, rsi, rdx, r10, r8, r9 = args 1-6
35843e1988Sjohnlev  *	 rax = return value
36843e1988Sjohnlev  *	 (arguments registers not clobbered on return; rcx, r11 are)
37843e1988Sjohnlev  */
38843e1988Sjohnlev 
39843e1988Sjohnlev #include <sys/types.h>
40551bc2a6Smrj #ifdef XPV_HVM_DRIVER
41551bc2a6Smrj #include <sys/xpv_support.h>
42551bc2a6Smrj #endif
43843e1988Sjohnlev 
44843e1988Sjohnlev #include <sys/hypervisor.h>
45843e1988Sjohnlev #include <xen/public/sched.h>
46843e1988Sjohnlev #include <sys/debug.h>
47843e1988Sjohnlev #include <sys/archsystm.h>
48843e1988Sjohnlev 
49843e1988Sjohnlev long
50843e1988Sjohnlev HYPERVISOR_set_trap_table(trap_info_t *table)
51843e1988Sjohnlev {
52843e1988Sjohnlev 	return (__hypercall1(__HYPERVISOR_set_trap_table, (ulong_t)table));
53843e1988Sjohnlev }
54843e1988Sjohnlev 
55843e1988Sjohnlev int
56843e1988Sjohnlev HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count,
57843e1988Sjohnlev     domid_t domain_id)
58843e1988Sjohnlev {
59843e1988Sjohnlev 	return (__hypercall4_int(__HYPERVISOR_mmu_update,
60843e1988Sjohnlev 	    (ulong_t)req, (long)count, (ulong_t)success_count,
61843e1988Sjohnlev 	    (ulong_t)domain_id));
62843e1988Sjohnlev }
63843e1988Sjohnlev 
64843e1988Sjohnlev long
65843e1988Sjohnlev HYPERVISOR_set_gdt(ulong_t *frame_list, int entries)
66843e1988Sjohnlev {
67843e1988Sjohnlev 	return (__hypercall2(
68843e1988Sjohnlev 	    __HYPERVISOR_set_gdt, (ulong_t)frame_list, (long)entries));
69843e1988Sjohnlev }
70843e1988Sjohnlev 
71843e1988Sjohnlev /*
72843e1988Sjohnlev  * XXPV Seems like "sp" would be a better name for both amd64 and i386?
73843e1988Sjohnlev  * For now stay consistent with xen project source.
74843e1988Sjohnlev  */
75843e1988Sjohnlev long
76843e1988Sjohnlev HYPERVISOR_stack_switch(ulong_t ss, ulong_t esp)
77843e1988Sjohnlev {
78843e1988Sjohnlev 	return (__hypercall2(__HYPERVISOR_stack_switch, ss, esp));
79843e1988Sjohnlev }
80843e1988Sjohnlev 
81843e1988Sjohnlev #if defined(__amd64)
82843e1988Sjohnlev 
83843e1988Sjohnlev long
84843e1988Sjohnlev HYPERVISOR_set_callbacks(ulong_t event_address, ulong_t failsafe_address,
85843e1988Sjohnlev     ulong_t syscall_address)
86843e1988Sjohnlev {
87843e1988Sjohnlev 	return (__hypercall3(__HYPERVISOR_set_callbacks,
88843e1988Sjohnlev 	    event_address, failsafe_address, syscall_address));
89843e1988Sjohnlev }
90843e1988Sjohnlev 
91843e1988Sjohnlev #elif defined(__i386)
92843e1988Sjohnlev 
93843e1988Sjohnlev long
94843e1988Sjohnlev HYPERVISOR_set_callbacks(
95843e1988Sjohnlev     ulong_t event_selector, ulong_t event_address,
96843e1988Sjohnlev     ulong_t failsafe_selector, ulong_t failsafe_address)
97843e1988Sjohnlev {
98843e1988Sjohnlev 	return (__hypercall4(__HYPERVISOR_set_callbacks,
99843e1988Sjohnlev 	    event_selector, event_address,
100843e1988Sjohnlev 	    failsafe_selector, failsafe_address));
101843e1988Sjohnlev }
102843e1988Sjohnlev 
103843e1988Sjohnlev #endif	/* __amd64 */
104843e1988Sjohnlev 
105843e1988Sjohnlev long
106843e1988Sjohnlev HYPERVISOR_fpu_taskswitch(int set)
107843e1988Sjohnlev {
108843e1988Sjohnlev 	return (__hypercall1(__HYPERVISOR_fpu_taskswitch, (long)set));
109843e1988Sjohnlev }
110843e1988Sjohnlev 
111843e1988Sjohnlev /* *** __HYPERVISOR_sched_op_compat *** OBSOLETED */
112843e1988Sjohnlev 
113843e1988Sjohnlev long
114843e1988Sjohnlev HYPERVISOR_platform_op(xen_platform_op_t *platform_op)
115843e1988Sjohnlev {
116843e1988Sjohnlev 	return (__hypercall1(__HYPERVISOR_platform_op, (ulong_t)platform_op));
117843e1988Sjohnlev }
118843e1988Sjohnlev 
119843e1988Sjohnlev /* *** __HYPERVISOR_set_debugreg *** NOT IMPLEMENTED */
120843e1988Sjohnlev 
121843e1988Sjohnlev /* *** __HYPERVISOR_get_debugreg *** NOT IMPLEMENTED */
122843e1988Sjohnlev 
123843e1988Sjohnlev long
124843e1988Sjohnlev HYPERVISOR_update_descriptor(maddr_t ma, uint64_t desc)
125843e1988Sjohnlev {
126843e1988Sjohnlev #if defined(__amd64)
127843e1988Sjohnlev 
128843e1988Sjohnlev 	return (__hypercall2(__HYPERVISOR_update_descriptor, ma, desc));
129843e1988Sjohnlev 
130843e1988Sjohnlev #elif defined(__i386)
131843e1988Sjohnlev 
132843e1988Sjohnlev 	return (__hypercall4(__HYPERVISOR_update_descriptor,
133843e1988Sjohnlev 	    (ulong_t)ma, (ulong_t)(ma >>32),
134843e1988Sjohnlev 	    (ulong_t)desc, (ulong_t)(desc >> 32)));
135843e1988Sjohnlev 
136843e1988Sjohnlev #endif
137843e1988Sjohnlev }
138843e1988Sjohnlev 
139843e1988Sjohnlev long
140843e1988Sjohnlev HYPERVISOR_memory_op(int cmd, void *arg)
141843e1988Sjohnlev {
142843e1988Sjohnlev 	return (__hypercall2(__HYPERVISOR_memory_op, (long)cmd,
143843e1988Sjohnlev 	    (ulong_t)arg));
144843e1988Sjohnlev }
145843e1988Sjohnlev 
146843e1988Sjohnlev long
147843e1988Sjohnlev HYPERVISOR_multicall(void *call_list, uint_t nr_calls)
148843e1988Sjohnlev {
149843e1988Sjohnlev 	return (__hypercall2(__HYPERVISOR_multicall,
150843e1988Sjohnlev 	    (ulong_t)call_list, (ulong_t)nr_calls));
151843e1988Sjohnlev }
152843e1988Sjohnlev 
153843e1988Sjohnlev int
154843e1988Sjohnlev HYPERVISOR_update_va_mapping(ulong_t va, uint64_t new_pte, ulong_t flags)
155843e1988Sjohnlev {
156843e1988Sjohnlev #if !defined(_BOOT)
157843e1988Sjohnlev 	if (IN_XPV_PANIC())
158843e1988Sjohnlev 		return (0);
159843e1988Sjohnlev #endif
160843e1988Sjohnlev #if defined(__amd64)
161843e1988Sjohnlev 
162843e1988Sjohnlev 	return (__hypercall3_int(__HYPERVISOR_update_va_mapping, va,
163843e1988Sjohnlev 	    new_pte, flags));
164843e1988Sjohnlev 
165843e1988Sjohnlev #elif defined(__i386)
166843e1988Sjohnlev 
167843e1988Sjohnlev 	return (__hypercall4_int(__HYPERVISOR_update_va_mapping, va,
168843e1988Sjohnlev 	    (ulong_t)new_pte, (ulong_t)(new_pte >> 32), flags));
169843e1988Sjohnlev 
170843e1988Sjohnlev #endif	/* __i386 */
171843e1988Sjohnlev }
172843e1988Sjohnlev 
173843e1988Sjohnlev /*
174843e1988Sjohnlev  * Note: this timeout must be the Xen system time not hrtime (see
175843e1988Sjohnlev  * xpv_timestamp.c).
176843e1988Sjohnlev  */
177843e1988Sjohnlev long
178843e1988Sjohnlev HYPERVISOR_set_timer_op(uint64_t timeout)
179843e1988Sjohnlev {
180843e1988Sjohnlev #if defined(__amd64)
181843e1988Sjohnlev 
182843e1988Sjohnlev 	return (__hypercall1(__HYPERVISOR_set_timer_op, timeout));
183843e1988Sjohnlev 
184843e1988Sjohnlev #elif defined(__i386)
185843e1988Sjohnlev 
186843e1988Sjohnlev 	uint32_t timeout_hi = (uint32_t)(timeout >> 32);
187843e1988Sjohnlev 	uint32_t timeout_lo = (uint32_t)timeout;
188843e1988Sjohnlev 	return (__hypercall2(__HYPERVISOR_set_timer_op,
189843e1988Sjohnlev 	    (ulong_t)timeout_lo, (ulong_t)timeout_hi));
190843e1988Sjohnlev 
191843e1988Sjohnlev #endif	/* __i386 */
192843e1988Sjohnlev }
193843e1988Sjohnlev 
194843e1988Sjohnlev /* *** __HYPERVISOR_event_channel_op_compat *** OBSOLETED */
195843e1988Sjohnlev 
196843e1988Sjohnlev long
197843e1988Sjohnlev HYPERVISOR_xen_version(int cmd, void *arg)
198843e1988Sjohnlev {
199843e1988Sjohnlev 	return (__hypercall2(__HYPERVISOR_xen_version, (long)cmd,
200843e1988Sjohnlev 	    (ulong_t)arg));
201843e1988Sjohnlev }
202843e1988Sjohnlev 
203843e1988Sjohnlev long
204843e1988Sjohnlev HYPERVISOR_console_io(int cmd, int count, char *str)
205843e1988Sjohnlev {
206843e1988Sjohnlev 	return (__hypercall3(__HYPERVISOR_console_io, (long)cmd, (long)count,
207843e1988Sjohnlev 	    (ulong_t)str));
208843e1988Sjohnlev }
209843e1988Sjohnlev 
210843e1988Sjohnlev /* *** __HYPERVISOR_physdev_op_compat *** OBSOLETED */
211843e1988Sjohnlev 
212843e1988Sjohnlev long
213843e1988Sjohnlev HYPERVISOR_grant_table_op(uint_t cmd, void *uop, uint_t count)
214843e1988Sjohnlev {
215843e1988Sjohnlev 	int ret_val;
216843e1988Sjohnlev 	ret_val = __hypercall3(__HYPERVISOR_grant_table_op,
217843e1988Sjohnlev 	    (long)cmd, (ulong_t)uop, (ulong_t)count);
218843e1988Sjohnlev 
219551bc2a6Smrj #if !defined(_BOOT) && !defined(XPV_HVM_DRIVER)
220843e1988Sjohnlev 	/*
221843e1988Sjohnlev 	 * XXPV --
222843e1988Sjohnlev 	 * The map_grant_ref call suffers a poor design flaw.
223843e1988Sjohnlev 	 * It's the only hypervisor interface that creates page table mappings
224843e1988Sjohnlev 	 * that doesn't take an entire PTE. Hence we can't create the
225843e1988Sjohnlev 	 * mapping with a particular setting of the software PTE bits, NX, etc.
226843e1988Sjohnlev 	 *
227843e1988Sjohnlev 	 * Until the interface is fixed, we need to minimize the possiblity
228843e1988Sjohnlev 	 * of dtrace or kmdb blowing up on a foreign mapping that doesn't
229843e1988Sjohnlev 	 * have a correct setting for the soft bits. We'll force them here.
230843e1988Sjohnlev 	 */
231843e1988Sjohnlev 	if (ret_val == 0 && cmd == GNTTABOP_map_grant_ref) {
232843e1988Sjohnlev 		extern void xen_fix_foreign(uint64_t);
233843e1988Sjohnlev 		gnttab_map_grant_ref_t *mapops = (gnttab_map_grant_ref_t *)uop;
234843e1988Sjohnlev 		uint_t i;
235843e1988Sjohnlev 		for (i = 0; i < count; ++i) {
236843e1988Sjohnlev 			if (mapops[i].status == GNTST_okay)
237843e1988Sjohnlev 				xen_fix_foreign(mapops[i].host_addr);
238843e1988Sjohnlev 		}
239843e1988Sjohnlev 	}
240843e1988Sjohnlev #endif
241843e1988Sjohnlev 	return (ret_val);
242843e1988Sjohnlev }
243843e1988Sjohnlev 
244843e1988Sjohnlev long
245843e1988Sjohnlev HYPERVISOR_vm_assist(uint_t cmd, uint_t type)
246843e1988Sjohnlev {
247843e1988Sjohnlev 	return (__hypercall2(__HYPERVISOR_vm_assist,
248843e1988Sjohnlev 	    (ulong_t)cmd, (ulong_t)type));
249843e1988Sjohnlev }
250843e1988Sjohnlev 
251843e1988Sjohnlev int
252843e1988Sjohnlev HYPERVISOR_update_va_mapping_otherdomain(ulong_t va,
253843e1988Sjohnlev     uint64_t new_pte, ulong_t flags, domid_t domain_id)
254843e1988Sjohnlev {
255843e1988Sjohnlev #if defined(__amd64)
256843e1988Sjohnlev 
257843e1988Sjohnlev 	return (__hypercall4_int(__HYPERVISOR_update_va_mapping_otherdomain,
258843e1988Sjohnlev 	    va, new_pte, flags, (ulong_t)domain_id));
259843e1988Sjohnlev 
260843e1988Sjohnlev #elif defined(__i386)
261843e1988Sjohnlev 
262843e1988Sjohnlev 	return (__hypercall5_int(__HYPERVISOR_update_va_mapping_otherdomain,
263843e1988Sjohnlev 	    va, (ulong_t)new_pte, (ulong_t)(new_pte >> 32), flags,
264843e1988Sjohnlev 	    (ulong_t)domain_id));
265843e1988Sjohnlev 
266843e1988Sjohnlev #endif	/* __i386 */
267843e1988Sjohnlev }
268843e1988Sjohnlev 
269843e1988Sjohnlev /*
270843e1988Sjohnlev  * *** __HYPERVISOR_iret ***
271843e1988Sjohnlev  *   see HYPERVISOR_IRET() macro in i86xpv/sys/machprivregs.h
272843e1988Sjohnlev  */
273843e1988Sjohnlev 
274843e1988Sjohnlev long
275843e1988Sjohnlev HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args)
276843e1988Sjohnlev {
277843e1988Sjohnlev 	return (__hypercall3(__HYPERVISOR_vcpu_op, (long)cmd, (long)vcpuid,
278843e1988Sjohnlev 	    (ulong_t)extra_args));
279843e1988Sjohnlev }
280843e1988Sjohnlev 
281843e1988Sjohnlev #if defined(__amd64)
282843e1988Sjohnlev 
283843e1988Sjohnlev long
284843e1988Sjohnlev HYPERVISOR_set_segment_base(int reg, ulong_t value)
285843e1988Sjohnlev {
286843e1988Sjohnlev 	return (__hypercall2(__HYPERVISOR_set_segment_base, (long)reg, value));
287843e1988Sjohnlev }
288843e1988Sjohnlev 
289843e1988Sjohnlev #endif	/* __amd64 */
290843e1988Sjohnlev 
291843e1988Sjohnlev int
292843e1988Sjohnlev HYPERVISOR_mmuext_op(struct mmuext_op *req, int count, uint_t *success_count,
293843e1988Sjohnlev     domid_t domain_id)
294843e1988Sjohnlev {
295843e1988Sjohnlev 	return (__hypercall4_int(__HYPERVISOR_mmuext_op,
296843e1988Sjohnlev 	    (ulong_t)req, (long)count, (ulong_t)success_count,
297843e1988Sjohnlev 	    (ulong_t)domain_id));
298843e1988Sjohnlev }
299843e1988Sjohnlev 
300843e1988Sjohnlev long
301a576ab5bSrab HYPERVISOR_acm_op(struct xen_acmctl *arg)
302843e1988Sjohnlev {
303a576ab5bSrab 	return (__hypercall1(__HYPERVISOR_acm_op, (ulong_t)arg));
304843e1988Sjohnlev }
305843e1988Sjohnlev 
306843e1988Sjohnlev long
307843e1988Sjohnlev HYPERVISOR_nmi_op(int cmd, void *arg)
308843e1988Sjohnlev {
309843e1988Sjohnlev 	return (__hypercall2(__HYPERVISOR_nmi_op, (long)cmd, (ulong_t)arg));
310843e1988Sjohnlev }
311843e1988Sjohnlev 
312843e1988Sjohnlev long
313843e1988Sjohnlev HYPERVISOR_sched_op(int cmd, void *arg)
314843e1988Sjohnlev {
315843e1988Sjohnlev 	return (__hypercall2(__HYPERVISOR_sched_op,
316843e1988Sjohnlev 	    (ulong_t)cmd, (ulong_t)arg));
317843e1988Sjohnlev }
318843e1988Sjohnlev 
319843e1988Sjohnlev long
320843e1988Sjohnlev HYPERVISOR_callback_op(int cmd, void *arg)
321843e1988Sjohnlev {
322843e1988Sjohnlev 	return (__hypercall2(__HYPERVISOR_callback_op,
323843e1988Sjohnlev 	    (ulong_t)cmd, (ulong_t)arg));
324843e1988Sjohnlev }
325843e1988Sjohnlev 
326843e1988Sjohnlev /* *** __HYPERVISOR_xenoprof_op *** NOT IMPLEMENTED */
327843e1988Sjohnlev 
328843e1988Sjohnlev long
329843e1988Sjohnlev HYPERVISOR_event_channel_op(int cmd, void *arg)
330843e1988Sjohnlev {
331843e1988Sjohnlev 	return (__hypercall2(__HYPERVISOR_event_channel_op, (long)cmd,
332843e1988Sjohnlev 	    (ulong_t)arg));
333843e1988Sjohnlev }
334843e1988Sjohnlev 
335843e1988Sjohnlev long
336843e1988Sjohnlev HYPERVISOR_physdev_op(int cmd, void *arg)
337843e1988Sjohnlev {
338843e1988Sjohnlev 	return (__hypercall2(__HYPERVISOR_physdev_op, (long)cmd,
339843e1988Sjohnlev 	    (ulong_t)arg));
340843e1988Sjohnlev }
341843e1988Sjohnlev 
342843e1988Sjohnlev long
343843e1988Sjohnlev HYPERVISOR_hvm_op(int cmd, void *arg)
344843e1988Sjohnlev {
345843e1988Sjohnlev 	return (__hypercall2(__HYPERVISOR_hvm_op, (long)cmd, (ulong_t)arg));
346843e1988Sjohnlev }
347843e1988Sjohnlev 
348843e1988Sjohnlev long
349843e1988Sjohnlev HYPERVISOR_sysctl(xen_sysctl_t *sysctl)
350843e1988Sjohnlev {
351843e1988Sjohnlev 	return (__hypercall1(__HYPERVISOR_sysctl, (ulong_t)sysctl));
352843e1988Sjohnlev }
353843e1988Sjohnlev 
354843e1988Sjohnlev long
355843e1988Sjohnlev HYPERVISOR_domctl(xen_domctl_t *domctl)
356843e1988Sjohnlev {
357843e1988Sjohnlev 	return (__hypercall1(__HYPERVISOR_domctl, (ulong_t)domctl));
358843e1988Sjohnlev }
359843e1988Sjohnlev 
360843e1988Sjohnlev /* *** __HYPERVISOR_kexec_op *** NOT IMPLEMENTED */
361843e1988Sjohnlev 
362843e1988Sjohnlev /*
363843e1988Sjohnlev  *
364843e1988Sjohnlev  * HYPERCALL HELPER ROUTINES
365843e1988Sjohnlev  *    These don't have there own unique hypercalls.
366843e1988Sjohnlev  *
367843e1988Sjohnlev  */
368843e1988Sjohnlev 
369843e1988Sjohnlev long
370843e1988Sjohnlev HYPERVISOR_yield(void)
371843e1988Sjohnlev {
372843e1988Sjohnlev 	return (HYPERVISOR_sched_op(SCHEDOP_yield, NULL));
373843e1988Sjohnlev }
374843e1988Sjohnlev 
375843e1988Sjohnlev long
376843e1988Sjohnlev HYPERVISOR_block(void)
377843e1988Sjohnlev {
378843e1988Sjohnlev 	return (HYPERVISOR_sched_op(SCHEDOP_block, NULL));
379843e1988Sjohnlev }
380843e1988Sjohnlev 
381843e1988Sjohnlev long
382843e1988Sjohnlev HYPERVISOR_shutdown(uint_t reason)
383843e1988Sjohnlev {
384843e1988Sjohnlev 	struct sched_shutdown sched_shutdown;
385843e1988Sjohnlev 
386843e1988Sjohnlev 	sched_shutdown.reason = reason;
387843e1988Sjohnlev 
388843e1988Sjohnlev 	return (HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown));
389843e1988Sjohnlev }
390843e1988Sjohnlev 
391843e1988Sjohnlev /*
392843e1988Sjohnlev  * Poll one or more event-channel ports, and return when pending.
393843e1988Sjohnlev  * An optional timeout (in nanoseconds, absolute time since boot) may be
394843e1988Sjohnlev  * specified. Note: this timeout must be the Xen system time not hrtime (see
395843e1988Sjohnlev  * xpv_timestamp.c).
396843e1988Sjohnlev  */
397843e1988Sjohnlev long
398843e1988Sjohnlev HYPERVISOR_poll(evtchn_port_t *ports, uint_t nr_ports, uint64_t timeout)
399843e1988Sjohnlev {
400843e1988Sjohnlev 	struct sched_poll sched_poll;
401843e1988Sjohnlev 
402843e1988Sjohnlev 	/*LINTED: constant in conditional context*/
403843e1988Sjohnlev 	set_xen_guest_handle(sched_poll.ports, ports);
404843e1988Sjohnlev 	sched_poll.nr_ports = nr_ports;
405843e1988Sjohnlev 	sched_poll.timeout = timeout;
406843e1988Sjohnlev 
407843e1988Sjohnlev 	return (HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll));
408843e1988Sjohnlev }
409843e1988Sjohnlev 
410843e1988Sjohnlev long
411843e1988Sjohnlev HYPERVISOR_suspend(ulong_t start_info_mfn)
412843e1988Sjohnlev {
413843e1988Sjohnlev 	struct sched_shutdown sched_shutdown;
414843e1988Sjohnlev 
415843e1988Sjohnlev 	sched_shutdown.reason = SHUTDOWN_suspend;
416843e1988Sjohnlev 
417843e1988Sjohnlev 	return (__hypercall3(__HYPERVISOR_sched_op, SCHEDOP_shutdown,
418843e1988Sjohnlev 	    (ulong_t)&sched_shutdown, start_info_mfn));
419843e1988Sjohnlev }
420*e4b86885SCheng Sean Ye 
421*e4b86885SCheng Sean Ye long
422*e4b86885SCheng Sean Ye HYPERVISOR_mca(uint32_t cmd, xen_mc_arg_t *arg)
423*e4b86885SCheng Sean Ye {
424*e4b86885SCheng Sean Ye 	xen_mc_t xmc;
425*e4b86885SCheng Sean Ye 	long rv;
426*e4b86885SCheng Sean Ye 
427*e4b86885SCheng Sean Ye 	switch (cmd) {
428*e4b86885SCheng Sean Ye 	case XEN_MC_CMD_fetch:
429*e4b86885SCheng Sean Ye 	case XEN_MC_CMD_physcpuinfo:
430*e4b86885SCheng Sean Ye 	case XEN_MC_CMD_msrinject:
431*e4b86885SCheng Sean Ye 	case XEN_MC_CMD_mceinject:
432*e4b86885SCheng Sean Ye 	case XEN_MC_CMD_offlinecpu:
433*e4b86885SCheng Sean Ye 		if (arg == NULL)
434*e4b86885SCheng Sean Ye 			return (EINVAL);
435*e4b86885SCheng Sean Ye 		break;
436*e4b86885SCheng Sean Ye 
437*e4b86885SCheng Sean Ye 	case XEN_MC_CMD_notifydomain:
438*e4b86885SCheng Sean Ye 		return (ENOTSUP);
439*e4b86885SCheng Sean Ye 
440*e4b86885SCheng Sean Ye 	default:
441*e4b86885SCheng Sean Ye 		return (EINVAL);
442*e4b86885SCheng Sean Ye 	}
443*e4b86885SCheng Sean Ye 
444*e4b86885SCheng Sean Ye 	xmc.interface_version = XEN_MCA_INTERFACE_VERSION;
445*e4b86885SCheng Sean Ye 	xmc.cmd = cmd;
446*e4b86885SCheng Sean Ye 	if (arg != NULL)
447*e4b86885SCheng Sean Ye 		xmc.u = *arg;
448*e4b86885SCheng Sean Ye 
449*e4b86885SCheng Sean Ye 	rv = __hypercall1(__HYPERVISOR_mca, (ulong_t)&xmc);
450*e4b86885SCheng Sean Ye 
451*e4b86885SCheng Sean Ye 	if (rv == XEN_MC_HCALL_SUCCESS && arg != NULL)
452*e4b86885SCheng Sean Ye 		*arg = xmc.u;
453*e4b86885SCheng Sean Ye 
454*e4b86885SCheng Sean Ye 	return (rv);
455*e4b86885SCheng Sean Ye }
456