15741Smrj /*
25741Smrj * CDDL HEADER START
35741Smrj *
45741Smrj * The contents of this file are subject to the terms of the
55741Smrj * Common Development and Distribution License (the "License").
65741Smrj * You may not use this file except in compliance with the License.
75741Smrj *
85741Smrj * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95741Smrj * or http://www.opensolaris.org/os/licensing.
105741Smrj * See the License for the specific language governing permissions
115741Smrj * and limitations under the License.
125741Smrj *
135741Smrj * When distributing Covered Code, include this CDDL HEADER in each
145741Smrj * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155741Smrj * If applicable, add the following below this CDDL HEADER, with the
165741Smrj * fields enclosed by brackets "[]" replaced with your own identifying
175741Smrj * information: Portions Copyright [yyyy] [name of copyright owner]
185741Smrj *
195741Smrj * CDDL HEADER END
205741Smrj */
215741Smrj
225741Smrj /*
2310175SStuart.Maybee@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
245741Smrj * Use is subject to license terms.
255741Smrj */
265741Smrj
275741Smrj /*
285741Smrj * Provides basic C wrappers around hypervisor invocation.
295741Smrj *
305741Smrj * i386: eax = vector: ebx, ecx, edx, esi, edi = args 1-5
315741Smrj * eax = return value
325741Smrj * (argument registers may be clobbered on return)
335741Smrj *
345741Smrj * amd64:rax = vector: rdi, rsi, rdx, r10, r8, r9 = args 1-6
355741Smrj * rax = return value
365741Smrj * (arguments registers not clobbered on return; rcx, r11 are)
375741Smrj */
385741Smrj
395741Smrj #include <sys/types.h>
4010175SStuart.Maybee@Sun.COM #ifndef __xpv
415741Smrj #include <sys/xpv_support.h>
4210175SStuart.Maybee@Sun.COM #else
4310175SStuart.Maybee@Sun.COM #include <sys/xpv_user.h>
445741Smrj #endif
455741Smrj
465741Smrj #include <sys/hypervisor.h>
475741Smrj #include <xen/public/sched.h>
485741Smrj #include <sys/debug.h>
495741Smrj #include <sys/archsystm.h>
505741Smrj
515741Smrj long
HYPERVISOR_set_trap_table(trap_info_t * table)525741Smrj HYPERVISOR_set_trap_table(trap_info_t *table)
535741Smrj {
545741Smrj return (__hypercall1(__HYPERVISOR_set_trap_table, (ulong_t)table));
555741Smrj }
565741Smrj
575741Smrj int
HYPERVISOR_mmu_update(mmu_update_t * req,int count,int * success_count,domid_t domain_id)585741Smrj HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count,
595741Smrj domid_t domain_id)
605741Smrj {
615741Smrj return (__hypercall4_int(__HYPERVISOR_mmu_update,
625741Smrj (ulong_t)req, (long)count, (ulong_t)success_count,
635741Smrj (ulong_t)domain_id));
645741Smrj }
655741Smrj
665741Smrj long
HYPERVISOR_set_gdt(ulong_t * frame_list,int entries)675741Smrj HYPERVISOR_set_gdt(ulong_t *frame_list, int entries)
685741Smrj {
695741Smrj return (__hypercall2(
705741Smrj __HYPERVISOR_set_gdt, (ulong_t)frame_list, (long)entries));
715741Smrj }
725741Smrj
735741Smrj /*
745741Smrj * XXPV Seems like "sp" would be a better name for both amd64 and i386?
755741Smrj * For now stay consistent with xen project source.
765741Smrj */
775741Smrj long
HYPERVISOR_stack_switch(ulong_t ss,ulong_t esp)785741Smrj HYPERVISOR_stack_switch(ulong_t ss, ulong_t esp)
795741Smrj {
805741Smrj return (__hypercall2(__HYPERVISOR_stack_switch, ss, esp));
815741Smrj }
825741Smrj
835741Smrj #if defined(__amd64)
845741Smrj
855741Smrj long
HYPERVISOR_set_callbacks(ulong_t event_address,ulong_t failsafe_address,ulong_t syscall_address)865741Smrj HYPERVISOR_set_callbacks(ulong_t event_address, ulong_t failsafe_address,
875741Smrj ulong_t syscall_address)
885741Smrj {
895741Smrj return (__hypercall3(__HYPERVISOR_set_callbacks,
905741Smrj event_address, failsafe_address, syscall_address));
915741Smrj }
925741Smrj
935741Smrj #elif defined(__i386)
945741Smrj
955741Smrj long
HYPERVISOR_set_callbacks(ulong_t event_selector,ulong_t event_address,ulong_t failsafe_selector,ulong_t failsafe_address)965741Smrj HYPERVISOR_set_callbacks(
975741Smrj ulong_t event_selector, ulong_t event_address,
985741Smrj ulong_t failsafe_selector, ulong_t failsafe_address)
995741Smrj {
1005741Smrj return (__hypercall4(__HYPERVISOR_set_callbacks,
1015741Smrj event_selector, event_address,
1025741Smrj failsafe_selector, failsafe_address));
1035741Smrj }
1045741Smrj
1055741Smrj #endif /* __amd64 */
1065741Smrj
1075741Smrj long
HYPERVISOR_fpu_taskswitch(int set)1085741Smrj HYPERVISOR_fpu_taskswitch(int set)
1095741Smrj {
1105741Smrj return (__hypercall1(__HYPERVISOR_fpu_taskswitch, (long)set));
1115741Smrj }
1125741Smrj
1135741Smrj /* *** __HYPERVISOR_sched_op_compat *** OBSOLETED */
1145741Smrj
1155741Smrj long
HYPERVISOR_platform_op(xen_platform_op_t * platform_op)1165741Smrj HYPERVISOR_platform_op(xen_platform_op_t *platform_op)
1175741Smrj {
1185741Smrj return (__hypercall1(__HYPERVISOR_platform_op, (ulong_t)platform_op));
1195741Smrj }
1205741Smrj
1215741Smrj /* *** __HYPERVISOR_set_debugreg *** NOT IMPLEMENTED */
1225741Smrj
1235741Smrj /* *** __HYPERVISOR_get_debugreg *** NOT IMPLEMENTED */
1245741Smrj
1255741Smrj long
HYPERVISOR_update_descriptor(maddr_t ma,uint64_t desc)1265741Smrj HYPERVISOR_update_descriptor(maddr_t ma, uint64_t desc)
1275741Smrj {
1285741Smrj #if defined(__amd64)
1295741Smrj
1305741Smrj return (__hypercall2(__HYPERVISOR_update_descriptor, ma, desc));
1315741Smrj
1325741Smrj #elif defined(__i386)
1335741Smrj
1345741Smrj return (__hypercall4(__HYPERVISOR_update_descriptor,
1355741Smrj (ulong_t)ma, (ulong_t)(ma >>32),
1365741Smrj (ulong_t)desc, (ulong_t)(desc >> 32)));
1375741Smrj
1385741Smrj #endif
1395741Smrj }
1405741Smrj
1415741Smrj long
HYPERVISOR_memory_op(int cmd,void * arg)1425741Smrj HYPERVISOR_memory_op(int cmd, void *arg)
1435741Smrj {
1445741Smrj return (__hypercall2(__HYPERVISOR_memory_op, (long)cmd,
1455741Smrj (ulong_t)arg));
1465741Smrj }
1475741Smrj
1485741Smrj long
HYPERVISOR_multicall(void * call_list,uint_t nr_calls)1495741Smrj HYPERVISOR_multicall(void *call_list, uint_t nr_calls)
1505741Smrj {
1515741Smrj return (__hypercall2(__HYPERVISOR_multicall,
1525741Smrj (ulong_t)call_list, (ulong_t)nr_calls));
1535741Smrj }
1545741Smrj
1555741Smrj int
HYPERVISOR_update_va_mapping(ulong_t va,uint64_t new_pte,ulong_t flags)1565741Smrj HYPERVISOR_update_va_mapping(ulong_t va, uint64_t new_pte, ulong_t flags)
1575741Smrj {
1585741Smrj #if !defined(_BOOT)
1595741Smrj if (IN_XPV_PANIC())
1605741Smrj return (0);
1615741Smrj #endif
1625741Smrj #if defined(__amd64)
1635741Smrj
1645741Smrj return (__hypercall3_int(__HYPERVISOR_update_va_mapping, va,
1655741Smrj new_pte, flags));
1665741Smrj
1675741Smrj #elif defined(__i386)
1685741Smrj
1695741Smrj return (__hypercall4_int(__HYPERVISOR_update_va_mapping, va,
1705741Smrj (ulong_t)new_pte, (ulong_t)(new_pte >> 32), flags));
1715741Smrj
1725741Smrj #endif /* __i386 */
1735741Smrj }
1745741Smrj
1755741Smrj /*
1765741Smrj * Note: this timeout must be the Xen system time not hrtime (see
1775741Smrj * xpv_timestamp.c).
1785741Smrj */
1795741Smrj long
HYPERVISOR_set_timer_op(uint64_t timeout)1805741Smrj HYPERVISOR_set_timer_op(uint64_t timeout)
1815741Smrj {
1825741Smrj #if defined(__amd64)
1835741Smrj
1845741Smrj return (__hypercall1(__HYPERVISOR_set_timer_op, timeout));
1855741Smrj
1865741Smrj #elif defined(__i386)
1875741Smrj
1885741Smrj uint32_t timeout_hi = (uint32_t)(timeout >> 32);
1895741Smrj uint32_t timeout_lo = (uint32_t)timeout;
1905741Smrj return (__hypercall2(__HYPERVISOR_set_timer_op,
1915741Smrj (ulong_t)timeout_lo, (ulong_t)timeout_hi));
1925741Smrj
1935741Smrj #endif /* __i386 */
1945741Smrj }
1955741Smrj
1965741Smrj /* *** __HYPERVISOR_event_channel_op_compat *** OBSOLETED */
1975741Smrj
1985741Smrj long
HYPERVISOR_xen_version(int cmd,void * arg)1995741Smrj HYPERVISOR_xen_version(int cmd, void *arg)
2005741Smrj {
2015741Smrj return (__hypercall2(__HYPERVISOR_xen_version, (long)cmd,
2025741Smrj (ulong_t)arg));
2035741Smrj }
2045741Smrj
2055741Smrj long
HYPERVISOR_console_io(int cmd,int count,char * str)2065741Smrj HYPERVISOR_console_io(int cmd, int count, char *str)
2075741Smrj {
2085741Smrj return (__hypercall3(__HYPERVISOR_console_io, (long)cmd, (long)count,
2095741Smrj (ulong_t)str));
2105741Smrj }
2115741Smrj
2125741Smrj /* *** __HYPERVISOR_physdev_op_compat *** OBSOLETED */
2135741Smrj
2147756SMark.Johnson@Sun.COM /*
2157756SMark.Johnson@Sun.COM * ****
2167756SMark.Johnson@Sun.COM * NOTE: this hypercall should not be called directly for a
2177756SMark.Johnson@Sun.COM * GNTTABOP_map_grant_ref. Instead xen_map_gref() should be called.
2187756SMark.Johnson@Sun.COM * ****
2197756SMark.Johnson@Sun.COM */
2205741Smrj long
HYPERVISOR_grant_table_op(uint_t cmd,void * uop,uint_t count)2215741Smrj HYPERVISOR_grant_table_op(uint_t cmd, void *uop, uint_t count)
2225741Smrj {
2235741Smrj int ret_val;
2245741Smrj ret_val = __hypercall3(__HYPERVISOR_grant_table_op,
2255741Smrj (long)cmd, (ulong_t)uop, (ulong_t)count);
2265741Smrj return (ret_val);
2275741Smrj }
2285741Smrj
2295741Smrj long
HYPERVISOR_vm_assist(uint_t cmd,uint_t type)2305741Smrj HYPERVISOR_vm_assist(uint_t cmd, uint_t type)
2315741Smrj {
2325741Smrj return (__hypercall2(__HYPERVISOR_vm_assist,
2335741Smrj (ulong_t)cmd, (ulong_t)type));
2345741Smrj }
2355741Smrj
2365741Smrj int
HYPERVISOR_update_va_mapping_otherdomain(ulong_t va,uint64_t new_pte,ulong_t flags,domid_t domain_id)2375741Smrj HYPERVISOR_update_va_mapping_otherdomain(ulong_t va,
2385741Smrj uint64_t new_pte, ulong_t flags, domid_t domain_id)
2395741Smrj {
2405741Smrj #if defined(__amd64)
2415741Smrj
2425741Smrj return (__hypercall4_int(__HYPERVISOR_update_va_mapping_otherdomain,
2435741Smrj va, new_pte, flags, (ulong_t)domain_id));
2445741Smrj
2455741Smrj #elif defined(__i386)
2465741Smrj
2475741Smrj return (__hypercall5_int(__HYPERVISOR_update_va_mapping_otherdomain,
2485741Smrj va, (ulong_t)new_pte, (ulong_t)(new_pte >> 32), flags,
2495741Smrj (ulong_t)domain_id));
2505741Smrj
2515741Smrj #endif /* __i386 */
2525741Smrj }
2535741Smrj
2545741Smrj /*
2555741Smrj * *** __HYPERVISOR_iret ***
2565741Smrj * see HYPERVISOR_IRET() macro in i86xpv/sys/machprivregs.h
2575741Smrj */
2585741Smrj
2595741Smrj long
HYPERVISOR_vcpu_op(int cmd,int vcpuid,void * extra_args)2605741Smrj HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args)
2615741Smrj {
2625741Smrj return (__hypercall3(__HYPERVISOR_vcpu_op, (long)cmd, (long)vcpuid,
2635741Smrj (ulong_t)extra_args));
2645741Smrj }
2655741Smrj
2665741Smrj #if defined(__amd64)
2675741Smrj
2685741Smrj long
HYPERVISOR_set_segment_base(int reg,ulong_t value)2695741Smrj HYPERVISOR_set_segment_base(int reg, ulong_t value)
2705741Smrj {
2715741Smrj return (__hypercall2(__HYPERVISOR_set_segment_base, (long)reg, value));
2725741Smrj }
2735741Smrj
2745741Smrj #endif /* __amd64 */
2755741Smrj
2765741Smrj int
HYPERVISOR_mmuext_op(struct mmuext_op * req,int count,uint_t * success_count,domid_t domain_id)2775741Smrj HYPERVISOR_mmuext_op(struct mmuext_op *req, int count, uint_t *success_count,
2785741Smrj domid_t domain_id)
2795741Smrj {
2805741Smrj return (__hypercall4_int(__HYPERVISOR_mmuext_op,
2815741Smrj (ulong_t)req, (long)count, (ulong_t)success_count,
2825741Smrj (ulong_t)domain_id));
2835741Smrj }
2845741Smrj
2855741Smrj long
HYPERVISOR_nmi_op(int cmd,void * arg)2865741Smrj HYPERVISOR_nmi_op(int cmd, void *arg)
2875741Smrj {
2885741Smrj return (__hypercall2(__HYPERVISOR_nmi_op, (long)cmd, (ulong_t)arg));
2895741Smrj }
2905741Smrj
2915741Smrj long
HYPERVISOR_sched_op(int cmd,void * arg)2925741Smrj HYPERVISOR_sched_op(int cmd, void *arg)
2935741Smrj {
2945741Smrj return (__hypercall2(__HYPERVISOR_sched_op,
2955741Smrj (ulong_t)cmd, (ulong_t)arg));
2965741Smrj }
2975741Smrj
2985741Smrj long
HYPERVISOR_callback_op(int cmd,void * arg)2995741Smrj HYPERVISOR_callback_op(int cmd, void *arg)
3005741Smrj {
3015741Smrj return (__hypercall2(__HYPERVISOR_callback_op,
3025741Smrj (ulong_t)cmd, (ulong_t)arg));
3035741Smrj }
3045741Smrj
3055741Smrj /* *** __HYPERVISOR_xenoprof_op *** NOT IMPLEMENTED */
3065741Smrj
3075741Smrj long
HYPERVISOR_event_channel_op(int cmd,void * arg)3085741Smrj HYPERVISOR_event_channel_op(int cmd, void *arg)
3095741Smrj {
3105741Smrj return (__hypercall2(__HYPERVISOR_event_channel_op, (long)cmd,
3115741Smrj (ulong_t)arg));
3125741Smrj }
3135741Smrj
3145741Smrj long
HYPERVISOR_physdev_op(int cmd,void * arg)3155741Smrj HYPERVISOR_physdev_op(int cmd, void *arg)
3165741Smrj {
3175741Smrj return (__hypercall2(__HYPERVISOR_physdev_op, (long)cmd,
3185741Smrj (ulong_t)arg));
3195741Smrj }
3205741Smrj
3215741Smrj long
HYPERVISOR_hvm_op(int cmd,void * arg)3225741Smrj HYPERVISOR_hvm_op(int cmd, void *arg)
3235741Smrj {
3245741Smrj return (__hypercall2(__HYPERVISOR_hvm_op, (long)cmd, (ulong_t)arg));
3255741Smrj }
3265741Smrj
32710175SStuart.Maybee@Sun.COM #if defined(__xpv)
32810175SStuart.Maybee@Sun.COM long
HYPERVISOR_xsm_op(struct xen_acmctl * arg)32910175SStuart.Maybee@Sun.COM HYPERVISOR_xsm_op(struct xen_acmctl *arg)
33010175SStuart.Maybee@Sun.COM {
33110175SStuart.Maybee@Sun.COM return (__hypercall1(__HYPERVISOR_xsm_op, (ulong_t)arg));
33210175SStuart.Maybee@Sun.COM }
33310175SStuart.Maybee@Sun.COM
3345741Smrj long
HYPERVISOR_sysctl(xen_sysctl_t * sysctl)3355741Smrj HYPERVISOR_sysctl(xen_sysctl_t *sysctl)
3365741Smrj {
3375741Smrj return (__hypercall1(__HYPERVISOR_sysctl, (ulong_t)sysctl));
3385741Smrj }
3395741Smrj
3405741Smrj long
HYPERVISOR_domctl(xen_domctl_t * domctl)3415741Smrj HYPERVISOR_domctl(xen_domctl_t *domctl)
3425741Smrj {
3435741Smrj return (__hypercall1(__HYPERVISOR_domctl, (ulong_t)domctl));
3445741Smrj }
34510175SStuart.Maybee@Sun.COM #endif /* __xpv */
3465741Smrj
3475741Smrj /* *** __HYPERVISOR_kexec_op *** NOT IMPLEMENTED */
3485741Smrj
3495741Smrj /*
3505741Smrj *
3515741Smrj * HYPERCALL HELPER ROUTINES
3525741Smrj * These don't have there own unique hypercalls.
3535741Smrj *
3545741Smrj */
3555741Smrj
3565741Smrj long
HYPERVISOR_yield(void)3575741Smrj HYPERVISOR_yield(void)
3585741Smrj {
3595741Smrj return (HYPERVISOR_sched_op(SCHEDOP_yield, NULL));
3605741Smrj }
3615741Smrj
3625741Smrj long
HYPERVISOR_block(void)3635741Smrj HYPERVISOR_block(void)
3645741Smrj {
3655741Smrj return (HYPERVISOR_sched_op(SCHEDOP_block, NULL));
3665741Smrj }
3675741Smrj
3685741Smrj long
HYPERVISOR_shutdown(uint_t reason)3695741Smrj HYPERVISOR_shutdown(uint_t reason)
3705741Smrj {
3715741Smrj struct sched_shutdown sched_shutdown;
3725741Smrj
3735741Smrj sched_shutdown.reason = reason;
3745741Smrj
3755741Smrj return (HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown));
3765741Smrj }
3775741Smrj
3785741Smrj /*
3795741Smrj * Poll one or more event-channel ports, and return when pending.
3805741Smrj * An optional timeout (in nanoseconds, absolute time since boot) may be
3815741Smrj * specified. Note: this timeout must be the Xen system time not hrtime (see
3825741Smrj * xpv_timestamp.c).
3835741Smrj */
3845741Smrj long
HYPERVISOR_poll(evtchn_port_t * ports,uint_t nr_ports,uint64_t timeout)3855741Smrj HYPERVISOR_poll(evtchn_port_t *ports, uint_t nr_ports, uint64_t timeout)
3865741Smrj {
3875741Smrj struct sched_poll sched_poll;
3885741Smrj
3895741Smrj /*LINTED: constant in conditional context*/
3905741Smrj set_xen_guest_handle(sched_poll.ports, ports);
3915741Smrj sched_poll.nr_ports = nr_ports;
3925741Smrj sched_poll.timeout = timeout;
3935741Smrj
3945741Smrj return (HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll));
3955741Smrj }
3965741Smrj
3975741Smrj long
HYPERVISOR_suspend(ulong_t start_info_mfn)3985741Smrj HYPERVISOR_suspend(ulong_t start_info_mfn)
3995741Smrj {
4005741Smrj struct sched_shutdown sched_shutdown;
4015741Smrj
4025741Smrj sched_shutdown.reason = SHUTDOWN_suspend;
4035741Smrj
4045741Smrj return (__hypercall3(__HYPERVISOR_sched_op, SCHEDOP_shutdown,
4055741Smrj (ulong_t)&sched_shutdown, start_info_mfn));
4065741Smrj }
4077532SSean.Ye@Sun.COM
4087532SSean.Ye@Sun.COM long
HYPERVISOR_mca(uint32_t cmd,xen_mc_t * xmcp)409*11120SMark.Johnson@Sun.COM HYPERVISOR_mca(uint32_t cmd, xen_mc_t *xmcp)
4107532SSean.Ye@Sun.COM {
4117532SSean.Ye@Sun.COM long rv;
4127532SSean.Ye@Sun.COM
4137532SSean.Ye@Sun.COM switch (cmd) {
41410175SStuart.Maybee@Sun.COM case XEN_MC_fetch:
41510175SStuart.Maybee@Sun.COM case XEN_MC_physcpuinfo:
41610175SStuart.Maybee@Sun.COM case XEN_MC_msrinject:
41710175SStuart.Maybee@Sun.COM case XEN_MC_mceinject:
4187532SSean.Ye@Sun.COM break;
4197532SSean.Ye@Sun.COM
42010175SStuart.Maybee@Sun.COM case XEN_MC_notifydomain:
4217532SSean.Ye@Sun.COM return (ENOTSUP);
4227532SSean.Ye@Sun.COM
4237532SSean.Ye@Sun.COM default:
4247532SSean.Ye@Sun.COM return (EINVAL);
4257532SSean.Ye@Sun.COM }
4267532SSean.Ye@Sun.COM
427*11120SMark.Johnson@Sun.COM xmcp->interface_version = XEN_MCA_INTERFACE_VERSION;
428*11120SMark.Johnson@Sun.COM xmcp->cmd = cmd;
4297532SSean.Ye@Sun.COM
430*11120SMark.Johnson@Sun.COM rv = __hypercall1(__HYPERVISOR_mca, (ulong_t)xmcp);
4317532SSean.Ye@Sun.COM
4327532SSean.Ye@Sun.COM return (rv);
4337532SSean.Ye@Sun.COM }
434